Hardening and Automating Hugo & n8n Deployment
Summary of Steps:
- Update and upgrade the system
- Install essential packages
- Harden SSH and user access
- Set up and enable the firewall
- Enable automatic security updates
- Install and configure Nginx
- Automate Hugo static site builds
- Set up n8n with Docker Compose
- Fix permissions and validate
- Ongoing maintenance
System Preparation
- Update and upgrade the system:
sudo apt update sudo apt upgrade
- 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
- Use a non-root user for all operations.
- Configure SSH for key authentication only and disable password login in
/etc/ssh/sshd_config
:PasswordAuthentication no PermitRootLogin no AllowUsers <user>
- Restart SSH:
sudo systemctl restart ssh
Firewall (UFW)
- 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
- Enable unattended-upgrades:
sudo apt install unattended-upgrades sudo dpkg-reconfigure --priority=low unattended-upgrades
Nginx Setup
- Install and enable Nginx:
sudo apt install nginx sudo systemctl enable nginx sudo systemctl start nginx
- 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; } }
- 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
- 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
- Reload and enable the service:
sudo systemctl daemon-reload sudo systemctl enable hugo-site sudo systemctl start hugo-site
n8n Docker Compose Setup
- 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
- Start n8n:
cd ~/n8n docker-compose up -d
Permissions
- Ensure all files are owned by the deploy user:
sudo chown -R <user>:<user> /home/<user>/my-progress-journal
Testing and Validation
- 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
- Use only the deploy user for builds and deploys.
- Monitor logs and security updates.
- Remove any unnecessary scripts or services.