Self-Hosting n8n on Hetzner Cloud: Complete Docker Setup Tutorial

Workflow automation has become essential for modern businesses, but SaaS solutions can become expensive as teams grow. We’ll show you how to set up your own n8n instance on Hetzner Cloud for under €5/month, giving you unlimited workflows and complete control over your automation platform.

What You’ll Build

By the end of this tutorial, you’ll have:

  • ✅ Fully functional n8n installation with HTTPS
  • ✅ Automatic SSL certificates via Let’s Encrypt
  • ✅ Email integration for user accounts
  • ✅ Automatic startup after server restarts
  • ✅ Production-ready setup for professional use

Monthly cost: €4.51 (CX11 server) + domain costs

Prerequisites

  • Domain name pointing to your server IP
  • Basic command line knowledge
  • Hetzner Cloud account

Step 1: Server Setup

Create Hetzner Cloud Server

  1. Log into Hetzner Cloud Console
  2. Create new project
  3. Add server with these specifications:
    • Image: Ubuntu 24.04 LTS
    • Type: CX11 (1 vCPU, 4 GB RAM, 20 GB disk)
    • Location: Choose closest to your users
    • SSH Key: Add your public key

Initial Server Configuration

Connect to your server:

ssh root@YOUR_SERVER_IP

Update the system:

apt update && apt upgrade -y

Step 2: Install Docker

Install Docker and Docker Compose:

# Install dependencies
apt install apt-transport-https ca-certificates curl software-properties-common gnupg -y

# Add Docker GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Add Docker repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

# Install Docker
apt update
apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

# Create Docker network for our services
docker network create proxy

Verify Docker installation:

docker --version
docker compose version

Step 3: Configure Traefik Reverse Proxy

Create directory structure:

mkdir -p /opt/traefik/data
cd /opt/traefik

Create Traefik configuration file:

nano /opt/traefik/data/traefik.yml

Add this configuration:

api:
  dashboard: false

entryPoints:
  http:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: https
          scheme: https
  https:
    address: ":443"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false

certificatesResolvers:
  letsencrypt:
    acme:
      email: your-email@example.com  # Change this!
      storage: acme.json
      httpChallenge:
        entryPoint: http

Create acme.json file for SSL certificates:

touch /opt/traefik/data/acme.json
chmod 600 /opt/traefik/data/acme.json

Create Traefik Docker Compose file:

nano /opt/traefik/docker-compose.yml

Add this configuration:

version: '3'

services:
  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    ports:
      - "80:80"
      - "443:443"
    networks:
      - proxy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/etc/traefik/traefik.yml
      - ./data/acme.json:/acme.json
    labels:
      - "traefik.enable=true"

networks:
  proxy:
    external: true

Step 4: Set Up SMTP Relay (Optional but Recommended)

Create mailserver directory:

mkdir -p /opt/mailserver
cd /opt/mailserver

Create Docker Compose file:

nano /opt/mailserver/docker-compose.yml

Add this configuration:

version: '3'

services:
  mailserver:
    image: bytemark/smtp
    restart: always
    networks:
      - proxy
    environment:
      - RELAY_HOST=smtp.gmail.com  # Change to your SMTP provider
      - RELAY_PORT=587
      - RELAY_USERNAME=your-email@gmail.com  # Change this
      - RELAY_PASSWORD=your-app-password     # Change this
      - MAIL_DOMAIN=yourdomain.com           # Change this
    ports:
      - "25:25"

networks:
  proxy:
    external: true

Note: For Gmail, you’ll need to:

  1. Enable 2-factor authentication
  2. Generate an App Password
  3. Use the App Password (not your regular password)

Step 5: Configure n8n

Create n8n directory:

mkdir -p /opt/n8n
cd /opt/n8n

Create Docker Compose file:

nano /opt/n8n/docker-compose.yml

Add this configuration:

version: '3'

services:
  n8n:
    image: n8nio/n8n:latest
    restart: always
    environment:
      - N8N_HOST=n8n.yourdomain.com          # Change this!
      - NODE_ENV=production
      - N8N_PROTOCOL=https
      - N8N_PORT=5678
      - N8N_EDITOR_BASE_URL=https://n8n.yourdomain.com  # Change this!
      
      # Email configuration
      - N8N_EMAIL_MODE=smtp
      - N8N_SMTP_HOST=mailserver
      - N8N_SMTP_PORT=25
      - N8N_SMTP_SSL=false
      - N8N_SMTP_USER=
      - N8N_SMTP_PASS=
      - N8N_SMTP_SENDER=noreply@yourdomain.com  # Change this!
      
      # Important fixes for proxy setup
      - N8N_TRUST_PROXY_HEADER=true
      - N8N_RUNNERS_ENABLED=true
      
    volumes:
      - ./data:/home/node/.n8n
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.n8n.rule=Host(`n8n.yourdomain.com`)"  # Change this!
      - "traefik.http.routers.n8n.entrypoints=https"
      - "traefik.http.routers.n8n.tls.certresolver=letsencrypt"
      - "traefik.http.services.n8n.loadbalancer.server.port=5678"

networks:
  proxy:
    external: true

Step 6: Create Systemd Services for Auto-Start

Traefik Service

nano /etc/systemd/system/traefik-docker.service

Add this configuration:

[Unit]
Description=Traefik Docker Compose
Requires=docker.service
After=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/traefik
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down

[Install]
WantedBy=multi-user.target

Mailserver Service

nano /etc/systemd/system/mailserver-docker.service

Add this configuration:

[Unit]
Description=Mailserver Docker Compose
Requires=docker.service
After=docker.service
Before=n8n-docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/mailserver
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down

[Install]
WantedBy=multi-user.target

n8n Service

nano /etc/systemd/system/n8n-docker.service

Add this configuration:

[Unit]
Description=n8n Docker Compose
Requires=docker.service
After=docker.service traefik-docker.service mailserver-docker.service
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/n8n
ExecStartPre=/bin/bash -c 'until docker container inspect traefik > /dev/null 2>&1; do sleep 2; done'
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
Restart=on-failure
RestartSec=30
TimeoutStartSec=180

[Install]
WantedBy=multi-user.target

Enable and Start Services

# Reload systemd daemon
systemctl daemon-reload

# Enable services to start on boot
systemctl enable traefik-docker.service
systemctl enable mailserver-docker.service
systemctl enable n8n-docker.service

# Start services
systemctl start traefik-docker.service
sleep 10
systemctl start mailserver-docker.service
sleep 10
systemctl start n8n-docker.service

Step 7: DNS Configuration

Point your domain to your server:

  1. Go to your domain registrar/DNS provider
  2. Create an A record:
    • Name: n8n
    • Type: A
    • Value: YOUR_SERVER_IP
    • TTL: 300 (or minimum allowed)

Wait for DNS propagation (can take up to 24 hours, usually much faster).

Step 8: Test Your Installation

Check if services are running:

docker ps

You should see three containers running: traefik, mailserver, and n8n.

Visit your n8n instance:

https://n8n.yourdomain.com

You should see the n8n setup page with a green lock icon (HTTPS working).

Troubleshooting Common Issues

SSL Certificate Not Working

Check Traefik logs:

docker logs traefik

Common causes:

  • DNS not pointing to server
  • Firewall blocking ports 80/443
  • Wrong domain in configuration

n8n Not Accessible

Check n8n logs:

docker logs n8n-n8n-1

Common fixes:

  • Verify domain configuration matches in all files
  • Check if all containers are in the same network

Email Not Working

Check mailserver logs:

docker logs mailserver-mailserver-1

Verify SMTP credentials and settings.

Services Not Starting After Reboot

Check service status:

systemctl status traefik-docker.service
systemctl status n8n-docker.service

Restart if needed:

systemctl restart traefik-docker.service
systemctl restart n8n-docker.service

Maintenance and Updates

Regular Maintenance

Weekly checks:

# Check container status
docker ps

# Check disk space
df -h

# Check logs for errors
docker logs n8n-n8n-1 | grep -i error

Monthly updates:

# Update container images
cd /opt/n8n && docker compose pull && docker compose up -d
cd /opt/traefik && docker compose pull && docker compose up -d
cd /opt/mailserver && docker compose pull && docker compose up -d

# Clean up old images
docker system prune -f

Backup Your Data

Create backup script:

nano /opt/backup-n8n.sh

Add this content:

#!/bin/bash
mkdir -p /opt/backups
tar -czf /opt/backups/n8n-backup-$(date +%Y%m%d).tar.gz /opt/n8n/data
find /opt/backups -name "n8n-backup-*.tar.gz" -mtime +30 -delete

Make it executable and add to cron:

chmod +x /opt/backup-n8n.sh

# Add to crontab (daily backup at 2 AM)
crontab -e
# Add this line:
0 2 * * * /opt/backup-n8n.sh

Security Hardening

Configure Firewall

# Install UFW
apt install ufw

# Set defaults
ufw default deny incoming
ufw default allow outgoing

# Allow SSH
ufw allow 22

# Allow HTTP/HTTPS
ufw allow 80
ufw allow 443

# Enable firewall
ufw enable

Secure SSH

Edit SSH configuration:

nano /etc/ssh/sshd_config

Make these changes:

PermitRootLogin prohibit-password
PasswordAuthentication no
PubkeyAuthentication yes

Restart SSH:

systemctl restart ssh

Set Up Fail2Ban

apt install fail2ban

# Copy default configuration
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

# Enable and start
systemctl enable fail2ban
systemctl start fail2ban

Cost Breakdown

Monthly costs:

  • Hetzner CX11 server: €4.51
  • Domain (yearly, varies): ~€10-15/year
  • Total: ~€5-6/month

Compare to n8n Cloud:

  • n8n Starter: $20/month
  • n8n Pro: $50/month
  • Savings: $180-540/year

Scaling Your Setup

Multiple n8n Instances

You can run multiple isolated n8n instances for different teams:

Create /opt/n8n-team2/docker-compose.yml:

version: '3'
services:
  n8n-team2:
    image: n8nio/n8n:latest
    restart: always
    environment:
      - N8N_HOST=team2.yourdomain.com
      # ... rest of configuration
    volumes:
      - ./data:/home/node/.n8n
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.n8n-team2.rule=Host(`team2.yourdomain.com`)"
      - "traefik.http.routers.n8n-team2.entrypoints=https"
      - "traefik.http.routers.n8n-team2.tls.certresolver=letsencrypt"
      - "traefik.http.services.n8n-team2.loadbalancer.server.port=5678"

networks:
  proxy:
    external: true

Upgrade Server Resources

If you need more power, upgrade your Hetzner server:

  • CX21: 2 vCPU, 8 GB RAM (€8.46/month)
  • CX31: 2 vCPU, 16 GB RAM (€16.07/month)

Conclusion

You now have a production-ready n8n installation that costs a fraction of hosted solutions while giving you complete control. The setup includes automatic HTTPS, email functionality, and robust service management.

Key benefits of this approach:

  • Cost-effective: Save hundreds of dollars annually
  • Full control: No usage limits or restrictions
  • Privacy: Your data stays on your infrastructure
  • Customizable: Modify and extend as needed

This configuration has been tested in production environments and provides enterprise-grade reliability at a fraction of the cost.

About tva

tva ensures comprehensive infrastructure management of database systems, cloud environments, and global supply chains. Our methodical approach combines rigorous security protocols with performance optimization, while strategic advisory services enable precise coordination of both digital capabilities and physical assets – maintaining the highest standards of operational excellence and compliance throughout all engagements.

Visit tva.sg for more information about our services.

Scroll to Top