====== n8n installation with Docker Compose ====== n8n installation with Docker Compose, Let's Encrypt [[wpde>SSL]] certificate and Basic Auth. For systems that are not directly accessible on the Internet, the [[en:linux:n8n:installation|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: ===== 4. create Docker Compose file ===== /somedirectory/docker-compose.yml ==== 4.1 HTTP-01 Challenge (Standard TLS Port 443) ==== 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 [[wpde>DNS]] provider must be adapted accordingly here. 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=" - "NETCUP_API_KEY=" - "NETCUP_API_PASSWORD=" - "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