This translation is older than the original page and might be outdated. See what has changed.

n8n installation with Docker Compose

Approved 2024/02/05 16:48 by psycore (version: 2) | Approver: psycore

n8n installation with Docker Compose

n8n installation with Docker Compose, Let's Encrypt SSL certificate and Basic Auth. For systems that are not directly accessible on the Internet, the HTTP method can also be selected (not recommended, however).

1st Docker installation (Debian)

1.1 Uninstall old versions

sudo apt-get remove docker docker-engine docker.io containerd runc

1.2 Repo installation

1.2.1 Update apt and activate HTTPS

 sudo apt-get update
 
 sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
 
sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
 

1.2.2 Add Docker GPG Key

sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

1.2.3 Repo setup

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

1.3 Install Docker Engine

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

2. install Docker Compose

sudo apt-get install docker-compose-plugin

3. DNS entry

Type: A
Name: n8n
IP address: <IP_OF_YOUR_SERVER>

4. create Docker Compose file

/somedirectory/docker-compose.yml

4.1 HTTP-01 Challenge (Standard TLS Port 443)

Zum Anzeigen hier klicken ⇲

Zum Verstecken hier klicken ⇱

version: "3"
 
services:
  traefik:
    image: "traefik"
    restart: always
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
      - "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"
      - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ${DATA_FOLDER}/letsencrypt:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro
 
  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    labels:
      - traefik.enable=true
      - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
      - traefik.http.routers.n8n.tls=true
      - traefik.http.routers.n8n.entrypoints=web,websecure
      - traefik.http.routers.n8n.tls.certresolver=mytlschallenge
      - traefik.http.middlewares.n8n.headers.SSLRedirect=true
      - traefik.http.middlewares.n8n.headers.STSSeconds=315360000
      - traefik.http.middlewares.n8n.headers.browserXSSFilter=true
      - traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
      - traefik.http.middlewares.n8n.headers.forceSTSHeader=true
      - traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
      - traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
      - traefik.http.middlewares.n8n.headers.STSPreload=true
      - traefik.http.routers.n8n.middlewares=n8n@docker
    environment:
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER
      - N8N_BASIC_AUTH_PASSWORD
      - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
      # this section reduces the database size and speed up performance, disable for debug
      - EXECUTIONS_DATA_SAVE_ON_ERROR=all
      - EXECUTIONS_DATA_SAVE_ON_SUCCESS=none
      - EXECUTIONS_DATA_SAVE_ON_PROGRESS=true
      - EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=false
      - EXECUTIONS_DATA_PRUNE=true
      - EXECUTIONS_DATA_MAX_AGE=336
      - EXECUTIONS_DATA_PRUNE_MAX_COUNT=50000
      - DB_SQLITE_VACUUM_ON_STARTUP=true
    volumes:
      - ${DATA_FOLDER}/.n8n:/home/node/.n8n

4.2 DNS-01 Challenge (Alternative TLS Ports)

The DNS provider must be adapted accordingly here.

Zum Anzeigen hier klicken ⇲

Zum Verstecken hier klicken ⇱

version: "3"
 
services:
  traefik:
    image: "traefik"
    restart: always
    command:
      #- "--log.level=DEBUG"
      - "--api=true"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--entrypoints.websecure.address=:12345"
      - "--certificatesresolvers.myresolver.acme.dnschallenge=true"
      - "--certificatesresolvers.myresolver.acme.dnschallenge.provider=netcup"
      #- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
      - "--certificatesresolvers.myresolver.acme.email=postmaster@example.com"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    ports:
      - "8081:80"
      - "12345:12345"
    environment:
      - "NETCUP_CUSTOMER_NUMBER=<CNR>"
      - "NETCUP_API_KEY=<API-KEY>"
      - "NETCUP_API_PASSWORD=<API-PASS>"
      - "NETCUP_PROPAGATION_TIMEOUT=15m"
      - "NETCUP_TTL=3600"
    volumes:
      - ${DATA_FOLDER}/letsencrypt:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro
 
  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    labels:
      - traefik.enable=true
      - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
      - traefik.http.routers.n8n.tls=true
      - traefik.http.routers.n8n.entrypoints=web,websecure
      - traefik.http.routers.n8n.tls.certresolver=myresolver
      - traefik.http.middlewares.n8n.headers.SSLRedirect=true
      - traefik.http.middlewares.n8n.headers.STSSeconds=315360000
      - traefik.http.middlewares.n8n.headers.browserXSSFilter=true
      - traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
      - traefik.http.middlewares.n8n.headers.forceSTSHeader=true
      - traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
      - traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
      - traefik.http.middlewares.n8n.headers.STSPreload=true
      - traefik.http.routers.n8n.middlewares=n8n@docker
    environment:
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER
      - N8N_BASIC_AUTH_PASSWORD
      - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}:12345/
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
      # this section reduces the database size and speed up performance, disable for debug
      - EXECUTIONS_DATA_SAVE_ON_ERROR=all
      - EXECUTIONS_DATA_SAVE_ON_SUCCESS=none
      - EXECUTIONS_DATA_SAVE_ON_PROGRESS=true
      - EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=false
      - EXECUTIONS_DATA_PRUNE=true
      - EXECUTIONS_DATA_MAX_AGE=336
      - EXECUTIONS_DATA_PRUNE_MAX_COUNT=50000
      - DB_SQLITE_VACUUM_ON_STARTUP=true
      #- N8N_LOG_LEVEL=debug
      #- N8N_LOG_OUTPUT=console
    volumes:
      - ${DATA_FOLDER}/.n8n:/home/node/.n8n

5. create .env file

/somedirectory/n8n/.env
# Folder where data should be saved
DATA_FOLDER=/root/n8n/
 
# The top level domain to serve from
DOMAIN_NAME=example.com
 
# The subdomain to serve from
SUBDOMAIN=n8n
 
# DOMAIN_NAME and SUBDOMAIN combined decide where n8n will be reachable from
# above example would result in: https://n8n.example.com
 
# The user name to use for authentication - IMPORTANT ALWAYS CHANGE!
N8N_BASIC_AUTH_USER=user
 
# The password to use for authentication - IMPORTANT ALWAYS CHANGE!
N8N_BASIC_AUTH_PASSWORD=password
 
# Optional timezone to set which gets used by Cron-Node by default
# If not set New York time will be used
GENERIC_TIMEZONE=Europe/Berlin
 
# The email address to use for the SSL certificate creation
SSL_EMAIL=user@example.com

6. create data directory

mkdir /somedirectory/n8n

7. start and stop

7.1 Start

sudo docker compose up -d

7.1.1 Start with output

sudo docker compose up

7.2 Stop

sudo docker compose stop

8 Update

8.1 Update image

docker pull n8nio/n8n

8.2 Restart

# Stop current setup
sudo docker compose stop
# Delete it (will only delete the docker-containers, data is stored separately)
sudo docker compose rm 
# Then start it again, in ingteractive mode to check for errors
sudo docker compose up

If everything runs without errors, end the process with CTRL+C and start it in daemon mode

sudo docker compose up -d
en/linux/n8n_installation_compose.txt · Last modified: 2024/02/05 16:48
CC Attribution-Noncommercial-Share Alike 4.0 International