Posts

Install Caddy on Ubuntu VPS

Setting Caddy Up on Ubuntu

  1. First we need to install caddy on the server:
    ```

    sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl

    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg

    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list

    sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg

    sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list

    sudo apt update
    sudo apt install caddy

    ```

1. Next, let's reconfigure caddy:

    Change /etc/caddy/Caddyfile to read:

    ```json
    {
            log {
                    output file /var/log/caddy/caddy_log.txt
                    level DEBUG
            }
    }
    import sites-enabled/*

    ```

1. Make sure we have a 404 error page:
    
    the Caddyfile should look something like this:
    ```json
    ```
    {
            log {
                    output file /var/log/caddy/caddy_log.txt
                    level DEBUG
            }
           
    }
    
    :443 {
    
            handle_errors {
                header Content-Type text/html
                respond <<HTML
                        <html>
                            <head><title>Oops</title></head>
                            <body>
                                <h5>whoa, we have a problem partner...</h5>
                            </body>
                        </html>
                    HTML 200
            }
    
    }
    import sites-enabled/*
    ```
    ```


1. make sure we have have these directories and that they are owned 
   by the caddy user:

    * /var/log/caddy
    * /etc/caddy/sites-enabled
    * /etc/caddy/sites-disabled

1. restart caddy:

    ```bash
    ... sudo systemctl restart caddy.service
    ```


1. create a new static site file so we can test the setup:


    ```json
    [site-url]  {
            root * /var/www/site_dir
            file_server
    }
    ```
    ```

1. make sure ports 80 and 443 is open on the firewall:


    ```bash
    ... sudo ufw allow http 
    ... sudo ufw allow https 

    ```

Ubuntu VPS Security

Optimizing Ubuntu Server

Services and programs you can likely kill:

This was taken from this site

  1. BASICS

    Killing these didn’t impact the system at all when I tested:

    ... sudo apt remove snapd -y --purge
    ... sudo apt remove lxcfs -y --purge
    ... sudo apt remove policykit-1 -y --purge
    ... 
    ... sudo apt remove lvm2 -y --purge
    ... sudo apt remove at -y --purge
    ... sudo apt remove mdadm -y --purge
    ... sudo apt remove open-iscsi -y --purge
    ... sudo apt remove accountsservice -y --purge
    
  2. EXTREME

Ubuntu VPS Setup

New Ubuntu VPS Set Up

We’ve assuming we’ve created the initial droplet and that we are able to ssh as root into the box. Next steps are as follows:

Add Admin User Account

  1. SSH into the droplet as root:

    Run these commands on the server

    
    # create your admin user
    ... adduser usrnme
    # set up ssh key
    # this was the old way:
    #   ... mkdir /home/usrnme/.ssh
    #   ... chmod 700 /home/usrnme/.ssh
    #   ... cp /root/.ssh/authorized_keys /home/usrnme/.ssh
    #   ... chown -R usrnme:usrnme /home/usrnme/.ssh/authorized_keys
    #   ... chmod 600 /home/usrnme/.ssh/authorized_keys
    # this is shorter and :
    ... rsync --archive --chown=usrnme:usrnme ~/.ssh /home/usrnme
    # add user to sudo
    ... usermod -aG sudo usrnme
    
  2. Install Neovim

Histoire Setup

Install
npm -i -D histoire @histoire/plugin-vue
histoire.config.js

import { defineConfig } from "histoire"
import { HstVue } from "@histoire/plugin-vue"

export default defineConfig({
    plugins: [
        HstVue(),

    ],
    setupFile: "/src/histoire.setup.ts"
})
package.json
{
    "scripts": {
        "story:dev": "histoire dev",
        "story:build": "histoire build",
        "story:preview": "histoire preview"
    }
}
env.d.ts
/// <reference types="@histoire/plugin-vue/components" />
tsconfig.json

Make sure you have a reference to env.d.ts in tsconfig.json.

{
    "include": [
        "env.d.ts",
        "src/**/*",
        "src/**/*.vue"
    ]
}
src/histoire.setup.ts
import "./histoire.css" // import global css

file permissions

A note on file permissions.

on hugo

Where have I been with blogging to this point?

  • In 2013 I gave blogging a start and built one with my own homegrown tool. I’m guessing at the time none of the python static site generators really appealed to me for one reason or another. That and it’s an obvious programmer cliche to build it yourself, especially if its been already done numerous times elsewhere.

  • The problem with writing your own blog engine is simply software maintenance. My original blog engine was written in python 2, which is now officially defunc. I doubt I could port it to python 3 without running into poor design decisions that I would then be compelled to fix. I need to write stuff down, not get sucked into a programming rabbit hole.

On note categorization

What am I generally capturing notes on?

  • basic “how to” instructions (e.g. setting up and configuring a server).
  • cheatsheets (e.g. common commands, points I typically forget).
  • collecting my thoughts on a subject (e.g. like this post).

And what broad areas do I cover?

  • programming languages (e.g. python, go, html, css, javascript, etc.)
  • libraries (e.g. flask, hugo, pelican, etc.)
  • tools (e.g. vim, tmux, invoke, etc.)
  • experience (e.g. assessing software quality, work environments)

So, is it Categories and/or Tags?

notes on go

Note on pointers in golang.

Command Line Libraries

Python Command Line Libraries

I really don’t like any of the cli libraries out there. The one I like best is docopt and mainly because it is simple to understand and use. The problem with docopt is that it only does command line parsing. It does not handle argument type conversion or validation, nor does it do dispatching. It does leave your cli interface decoupled from your application, whereas some of these other convience libraries, such as click, couple the building of cli commands and arguments to functions and tend to make heavy use of decorators - a style I don’t find appealing. They also tend toward being application frameworks - something I don’t mind, but I’d rather have more choice over how things are implemented.

Notes on Flask

Notes from Armin Ronacher’s Flask for Fun and Profit

create_app
from flask import Flask

def create_app(config=None):
    app = Flask(__name__)
    app.config.update(config or {})
    register_blueprints(app)
    register_other_things(app)
    return app
register_blueprints
from werkzeug.utils import find_modules, import_string

def register_blueprints(app):
    for name in find_modules('myapp.blueprints'):
        mod = import_string(name)
        if hasattr(mod, 'blueprint'):
            app.register_blueprint(mod.blueprint)
Optional Contained App

The idea here is you can separate top level config and functionality that is clearly separated from internal flask related config and functionality. I.e. in the flask app this object is exposed as an attribute on the app, and visa versa.