[Tutorial] Installing N8N on HestiaCP via Docker

Installing N8N on HestiaCP via Docker

Sample Installation Info:

  • HestiaCP User: mod (replace with your username)
  • N8N Domain: n8n.yourdomain.com (replace with your domain)
  • Encryption Key: xdKt8m6HzPLTJH9avNs2G7q3RbFw5Ey4 (generate your own key)

Table of Contents

  1. Part 1: Install Docker on HestiaCP
  2. Part 2: Create Nginx Templates for N8N on HestiaCP
  3. Part 3: Install and Configure N8N
  4. Part 4: Configure HestiaCP, Domain, and SSL for N8N
  5. Part 5: Test and Use N8N
  6. Part 6: Management and Maintenance
  7. Part 7: Troubleshooting

Part 1: Install Docker on HestiaCP

First, we need to install Docker and Docker Compose:

# Update the system
sudo apt update
sudo apt upgrade -y

# Install required packages
sudo apt install apt-transport-https ca-certificates curl software-properties-common -y

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

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

# Install Docker
sudo apt update
sudo apt install docker-ce -y

# Check Docker status
sudo systemctl status docker
docker ps

# Install Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# Grant execute permission to Docker Compose
sudo chmod +x /usr/local/bin/docker-compose

# Verify Docker Compose version
docker-compose --version

Part 2: Create Nginx Templates for N8N on HestiaCP

2.1 Create HTTP and HTTPS Template Files

# Navigate to the HestiaCP Nginx template directory
cd /usr/local/hestia/data/templates/web/nginx/

# Create the HTTP template (n8n.tpl)
cp default.tpl n8n.tpl

# Create the HTTPS template (n8n.stpl)
cp default.stpl n8n.stpl

2.2 Edit the n8n.stpl Template File

# Edit n8n.stpl (use nano instead of vim)
cd /usr/local/hestia/data/templates/web/nginx/
sudo nano n8n.stpl

Replace the entire content of n8n.stpl with the following:

server {
    listen      %ip%:%proxy_ssl_port% ssl;
    server_name %domain_idn% %alias_idn%;
    error_log   /var/log/%web_system%/domains/%domain%.error.log error;

    ssl_certificate      %ssl_pem%;
    ssl_certificate_key  %ssl_key%;
    ssl_stapling         on;
    ssl_stapling_verify  on;

    # TLS 1.3 0-RTT anti-replay
    if ($anti_replay = 307) { return 307 https://$host$request_uri; }
    if ($anti_replay = 425) { return 425; }

    include %home%/%user%/conf/web/%domain%/nginx.hsts.conf*;

    location ~ /\.(?!well-known\/|file) {
        deny all;
        return 404;
    }

    location / {
        proxy_pass http://%ip%:5678;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        location ~* ^.+\.(%proxy_extensions%)$ {
            try_files  $uri @fallback;

            root       %sdocroot%;
            access_log /var/log/%web_system%/domains/%domain%.log combined;
            access_log /var/log/%web_system%/domains/%domain%.bytes bytes;

            expires    max;
        }
    }

    location @fallback {
        proxy_pass http://%ip%:5678;
    }

    location /error/ {
        alias %home%/%user%/web/%domain%/document_errors/;
    }

    include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*;
}

2.3 Edit the n8n.tpl Template File

# Edit n8n.tpl (use nano instead of vim)
cd /usr/local/hestia/data/templates/web/nginx/
sudo nano n8n.tpl

Replace the entire content of n8n.tpl with the following:

server {
    listen      %ip%:%proxy_port%;
    server_name %domain_idn% %alias_idn%;
    error_log   /var/log/%web_system%/domains/%domain%.error.log error;

    include %home%/%user%/conf/web/%domain%/nginx.forcessl.conf*;

    location ~ /\.(?!well-known\/|file) {
        deny all;
        return 404;
    }

    location / {
        proxy_pass http://%ip%:5678;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        location ~* ^.+\.(%proxy_extensions%)$ {
            try_files  $uri @fallback;

            root       %docroot%;
            access_log /var/log/%web_system%/domains/%domain%.log combined;
            access_log /var/log/%web_system%/domains/%domain%.bytes bytes;

            expires    max;
        }
    }

    location @fallback {
        proxy_pass http://%ip%:5678;
    }

    location /error/ {
        alias %home%/%user%/web/%domain%/document_errors/;
    }

    include %home%/%user%/conf/web/%domain%/nginx.conf_*;
}

Part 3: Install and Configure N8N

3.1 Create Directories and Configuration Files

# Create the Docker directory for N8N (replace 'mod' with your username)
mkdir -p /home/mod/docker/n8n
cd /home/mod/docker/n8n

# Create the data directory with proper permissions
mkdir -p ./n8n_data
chmod 755 ./n8n_data
chown -R 1000:1000 ./n8n_data

# Create the docker-compose.yml file
nano docker-compose.yml

Add the following content to docker-compose.yml:

services:
  n8n:
    image: n8nio/n8n:latest
    user: "1000:1000"
    restart: always
    ports:
      - "5678:5678"
    environment:
      - N8N_HOST=n8n.yourdomain.com # Replace with your domain
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - N8N_PROXY_HOPS=1
      - WEBHOOK_URL=https://n8n.yourdomain.com/ # Replace with your domain
      - GENERIC_TIMEZONE=Asia/Ho_Chi_Minh
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
      - N8N_RUNNERS_ENABLED=true
      # Basic Auth configuration (uncomment to enable)
      # - N8N_BASIC_AUTH_ACTIVE=true
      # - N8N_BASIC_AUTH_USER=admin
      # - N8N_BASIC_AUTH_PASSWORD=your-secure-password
    env_file:
      - .env
    volumes:
      - ./n8n_data:/home/node/.n8n
    networks:
      - n8n-network

networks:
  n8n-network:
    driver: bridge

3.2 Create the .env File

# Generate a random Encryption key:
openssl rand -base64 24

# Create the .env file
cd /home/mod/docker/n8n
nano .env

Add the following content to the .env file:

# Replace xdKt8m6HzPLTJH9avNs2G7q3RbFw5Ey4 with your own key
N8N_ENCRYPTION_KEY=xdKt8m6HzPLTJH9avNs2G7q3RbFw5Ey4

3.3 Install N8N with Docker Compose

# Start N8N using Docker Compose
docker-compose up -d

# Check container status
docker ps

:warning: Warning: Keep your N8N_ENCRYPTION_KEY secure! If this key is lost, you will be unable to access sensitive information that has been encrypted in N8N, such as connection passwords, API tokens, etc.


Part 4: Configure HestiaCP, Domain, and SSL for N8N

4.1 Set Up Firewall for Port 5678

To ensure N8N can communicate via port 5678, you need to open this port in the HestiaCP firewall.

Via the web interface:

  1. Log in to HestiaCP.
  2. Go to the FIREWALL tab.
  3. Click the + ADD RULE button.
  4. Fill in the details as follows:
    • Action: ACCEPT
    • Protocol: TCP
    • Port: 5678
    • IP Address: 127.0.0.1 (if you only want localhost access)
    • Comment: N8N
  5. Click Add to save the rule.

Via the command line:

# Open port 5678 in HestiaCP firewall (localhost only)
v-add-firewall-rule ACCEPT 127.0.0.1 5678 TCP N8N

# Or open port 5678 for all IPs if needed
# v-add-firewall-rule ACCEPT 0.0.0.0/0 5678 TCP N8N

# Restart the firewall
v-update-firewall

:warning: Warning: It is recommended to only open port 5678 for localhost (127.0.0.1) because N8N will be accessed through the Nginx reverse proxy. Opening it for all IPs (0.0.0.0/0) should only be done if there is a specific reason.

4.2 Create a Domain on HestiaCP

  1. Log in to HestiaCP via the web interface at https://IP-server:8083 or your admin domain.
  2. Select the WEB tab.
  3. Click the + ADD WEB DOMAIN button.
  4. Enter the domain n8n.yourdomain.com (replace with your domain).
  5. Leave the other options at their defaults and click Add.

4.3 Configure Domain and SSL

  1. In the domain list, click Edit for the domain n8n.yourdomain.com.
  2. Select the Advanced options tab.
  3. In the Proxy Template section, select n8n from the dropdown list.
  4. Click Save to apply the changes.
  5. Return to the domain list to install Let’s Encrypt SSL.

Alternatively, use the command line to install SSL via Let’s Encrypt:

# Install SSL via Let's Encrypt (replace 'mod' and the domain with your own)
v-add-letsencrypt-domain mod n8n.yourdomain.com

4.4 Apply Template and Restart Nginx

# Rebuild web domains for the user (replace 'mod' with your username)
v-rebuild-web-domains mod

# Restart Nginx
sudo systemctl restart nginx

Part 5: Test and Use N8N

  1. Open your web browser and navigate to https://n8n.yourdomain.com (replace with your domain).
  2. If Basic Auth has been enabled, log in using the credentials you configured.
  3. Set up your first N8N admin account when prompted.

Congratulations! You have successfully installed N8N on HestiaCP using Docker with an Nginx reverse proxy.


Part 6: Management and Maintenance

6.1 Monitor Logs

# View N8N container logs
docker logs -f n8n-n8n-1

# View Nginx error logs for the domain
tail -f /var/log/nginx/domains/n8n.yourdomain.com.error.log

6.2 Update N8N

To check the current versions of N8N, Node.js, and npm, access the N8N container and run the following commands:

# Access the container after identifying NAMES using [docker ps]
docker ps
docker exec -it n8n-n8n-1 sh

# Or use this one-liner to auto-detect the container name
docker exec -it "$(docker ps --filter "ancestor=n8nio/n8n" --format "{{.Names}}")" sh

# Check N8N version
n8n -v

# Check Node.js version
node -v

# Check npm version
npm -v

# Or run all checks in a single command
docker exec -it "$(docker ps --filter "ancestor=n8nio/n8n" --format "{{.Names}}")" sh -c 'echo "n8n version:"; n8n -v; echo "node version:"; node -v; echo "npm version:"; npm -v; exec sh'

# Exit the container (exit or Ctrl + D)
exit

To update N8N to the latest version:

cd /home/mod/docker/n8n
docker-compose pull
docker-compose down
docker-compose up -d

6.3 Backup Data

# Backup the data directory
cp -r /home/mod/docker/n8n/n8n_data /backup/n8n_data_$(date +%Y%m%d)

6.4 Restart the Service

# Restart N8N
cd /home/mod/docker/n8n
docker-compose restart

Part 7: Troubleshooting

N8N Not Starting

Check the logs to identify the cause:

cd /home/mod/docker/n8n
docker logs n8n-n8n-1

Domain Connection Issues

Verify the Nginx configuration and proxy status:

sudo nginx -t
sudo systemctl status nginx

Permission Issues

Ensure correct permissions on the N8N data directory:

sudo chown -R 1000:1000 /home/mod/docker/n8n/n8n_data
sudo chmod -R 755 /home/mod/docker/n8n/n8n_data

Port 5678 Not Working

Check the firewall status and rules for port 5678:

v-list-firewall
sudo ufw status
3 Likes

Thanks. I was able to get it setup following your instructions.