Hardening and Automating Hugo & n8n Deployment

Summary of Steps:

  1. Update and upgrade the system
  2. Install essential packages
  3. Harden SSH and user access
  4. Set up and enable the firewall
  5. Enable automatic security updates
  6. Install and configure Nginx
  7. Automate Hugo static site builds
  8. Set up n8n with Docker Compose
  9. Fix permissions and validate
  10. Ongoing maintenance

System Preparation

  1. Update and upgrade the system:
    sudo apt update
    sudo apt upgrade
    
  2. Install essential packages:
    sudo apt install ufw
    sudo apt install unattended-upgrades
    sudo apt install docker.io
    sudo apt install docker-compose
    sudo apt install nginx
    sudo apt install python3-pip
    

User and SSH Security

  1. Use a non-root user for all operations.
  2. Configure SSH for key authentication only and disable password login in /etc/ssh/sshd_config:
    PasswordAuthentication no
    PermitRootLogin no
    AllowUsers <user>
    
  3. Restart SSH:
    sudo systemctl restart ssh
    

Firewall (UFW)

  1. Allow only necessary services:
    sudo ufw allow OpenSSH
    sudo ufw allow <web-service>
    sudo ufw allow <secure-web-service>
    sudo ufw enable
    

Automatic Security Updates

  1. Enable unattended-upgrades:
    sudo apt install unattended-upgrades
    sudo dpkg-reconfigure --priority=low unattended-upgrades
    

Nginx Setup

  1. Install and enable Nginx:
    sudo apt install nginx
    sudo systemctl enable nginx
    sudo systemctl start nginx
    
  2. Configure Nginx as a static file server for Hugo:
    server {
        listen <web-service>;
        server_name <your-domain>;
        root /home/<user>/my-progress-journal/public;
        index index.html;
        location / {
            try_files $uri $uri/ =404;
        }
    }
    
  3. Enable the site and reload Nginx:
    sudo ln -s /etc/nginx/sites-available/<your-site> /etc/nginx/sites-enabled/
    sudo nginx -t
    sudo systemctl reload nginx
    

Hugo Static Site Automation

  1. Create a systemd service /etc/systemd/system/hugo-site.service:
    [Unit]
    Description=Hugo Static Site Builder
    After=network.target
    
    [Service]
    Type=oneshot
    User=<user>
    WorkingDirectory=/home/<user>/my-progress-journal
    ExecStartPre=/usr/bin/sudo /usr/bin/chown -R <user>:<user> /home/<user>/my-progress-journal/public
    ExecStart=/usr/local/bin/hugo --baseURL https://<your-domain>
    RemainAfterExit=true
    
    [Install]
    WantedBy=multi-user.target
    
  2. Reload and enable the service:
    sudo systemctl daemon-reload
    sudo systemctl enable hugo-site
    sudo systemctl start hugo-site
    

n8n Docker Compose Setup

  1. Example docker-compose.yml in ~/n8n:
    version: "3"
    services:
      n8n:
        container_name: n8n
        image: n8nio/n8n
        restart: always
        environment:
          - N8N_BASIC_AUTH_ACTIVE=true
          - N8N_BASIC_AUTH_USER=<user>
          - N8N_BASIC_AUTH_PASSWORD=<password>
          - N8N_HOST=<n8n-domain>
          - N8N_PORT=<port>
          - N8N_PROTOCOL=http
        volumes:
          - /home/<user>/.n8n:/home/node/.n8n
        ports:
          - "<port>:<port>"
        networks:
          - n8n_internal
    networks:
      n8n_internal:
        external: true
    
  2. Start n8n:
    cd ~/n8n
    docker-compose up -d
    

Permissions

  1. Ensure all files are owned by the deploy user:
    sudo chown -R <user>:<user> /home/<user>/my-progress-journal
    

Testing and Validation

  1. Reboot the server and confirm:
    • Nginx, Hugo, and n8n all start automatically.
    • The site is served correctly via Nginx.
    • n8n is accessible via its domain (if proxied).

Ongoing Maintenance