Back to blog

How to install n8n on FastPanel

6/22/2025 · 1 min · FastPanel

Share

The n8n is an open source workflow automation platform that allows integrating systems, APIs, and services with low implementation complexity.

Requirements

Updating the system

redhat/derivatives

sudo dnf --refresh update
sudo dnf upgrade

Debian/derivatives

sudo apt update
sudo apt upgrade

Enabling Docker repository

redhat/derivatives

sudo dnf install yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

Debian/derivatives

sudo apt install -y ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/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/$(. /etc/os-release; echo "$ID") $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Installing Podman

dnf install podman podman-compose
podman -v

Expected output (example):

podman version 4.9.4-rhel

Installing Docker

dnf install docker
apt install docker

Enabling service

sudo systemctl enable podman
sudo systemctl start podman

Directory structure

mkdir -p /opt/n8n_stack
cd /opt/n8n_stack
mkdir -p n8n_storage redis_storage db_storage
touch docker-compose.yml .env init-data.sh healthcheck.js

docker-compose.yml

Link: https://github.com/sr00t3d/fastpanel-n8n-docker/blob/main/docker-compose.yml
version: '3.8'

x-shared: &shared
  restart: always
  image: docker.n8n.io/n8nio/n8n:1.91.3
  env_file: .env
  user: "1000:1000"
  volumes:
    - /opt/n8n_stack/n8n_storage:/home/node/.n8n
    - ./healthcheck.js:/healthcheck.js
  depends_on:
    redis:
      condition: service_healthy
    postgres:
      condition: service_healthy

services:
  postgres:
    image: postgres:11
    restart: always
    env_file: .env
    ports:
      - "127.0.0.1:5433:5432"
    volumes:
      - /opt/n8n_stack/db_storage:/var/lib/postgresql/data
      - ./init-data.sh:/docker-entrypoint-initdb.d/init-data.sh
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}']
      interval: 10s
      timeout: 10s
      retries: 30
      start_period: 60s

  redis:
    image: redis:6-alpine
    restart: always
    volumes:
      - /opt/n8n_stack/redis_storage:/data
    healthcheck:
      test: ['CMD', 'redis-cli', 'ping']
      interval: 5s
      timeout: 5s
      retries: 10

  n8n:
    <<: *shared
    ports:
      - "127.0.0.1:5678:5678"
    healthcheck:
      test: ["CMD", "node", "/healthcheck.js"]
      interval: 10s
      timeout: 10s
      retries: 20
      start_period: 60s

  n8n-worker:
    <<: *shared
    command: worker
    depends_on:
      - n8n
    healthcheck:
      test: ["CMD-SHELL", "node -e 'process.exit(0)'"]
      interval: 30s
      timeout: 5s
      retries: 3

.env

Link: https://github.com/sr00t3d/fastpanel-n8n-docker/blob/main/.env
Warning: generate strong keys and passwords.
openssl rand -hex 32
N8N_HOST=domain.com
N8N_PORT=5678
N8N_PROTOCOL=https
WEBHOOK_URL=https://domain.com/
N8N_ENCRYPTION_KEY=STRONG_32BIT_KEY
GENERIC_TIMEZONE=America/Sao_Paulo
TZ=America/Sao_Paulo

DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=postgres
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8n_prod_db
DB_POSTGRESDB_USER=n8n_prod_user
DB_POSTGRESDB_PASSWORD=STRONG_DB_PASSWORD

N8N_EMAIL_MODE=smtp
N8N_SMTP_HOST=email@domain.com
N8N_SMTP_PORT=465
N8N_SMTP_USER=your_email@domain.com
N8N_SMTP_PASS=EMAIL_PASSWORD
N8N_SMTP_SENDER=your_email@domain.com
N8N_SMTP_SSL=true

POSTGRES_DB=n8n_prod_db
POSTGRES_USER=postgres
POSTGRES_PASSWORD=STRONG_POSTGRES_PASSWORD

POSTGRES_NON_ROOT_USER=n8n_prod_user
POSTGRES_NON_ROOT_PASSWORD=STRONG_NON_ROOT_PASSWORD

QUEUE_BULL_REDIS_HOST=redis
QUEUE_BULL_REDIS_PORT=6379
QUEUE_BULL_REDIS_DB=0

N8N_RUNNERS_ENABLED=true
OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true

init-data.sh

Link: https://github.com/sr00t3d/fastpanel-n8n-docker/blob/main/init-data.sh
#!/bin/bash
set -e

if [ -n "${POSTGRES_NON_ROOT_USER:-}" ] && [ -n "${POSTGRES_NON_ROOT_PASSWORD:-}" ]; then
  psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
    CREATE EXTENSION IF NOT EXISTS "pgcrypto";
    CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
    DO
    \$do\$
    BEGIN
      IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = '${POSTGRES_NON_ROOT_USER}') THEN
        CREATE USER "${POSTGRES_NON_ROOT_USER}" WITH PASSWORD '${POSTGRES_NON_ROOT_PASSWORD}';
      ELSE
        ALTER USER "${POSTGRES_NON_ROOT_USER}" WITH PASSWORD '${POSTGRES_NON_ROOT_PASSWORD}';
      END IF;
    END
    \$do\$;
    GRANT ALL PRIVILEGES ON DATABASE "${POSTGRES_DB}" TO "${POSTGRES_NON_ROOT_USER}";
EOSQL
else
  echo "SETUP INFO: POSTGRES_NON_ROOT_USER or POSTGRES_NON_ROOT_PASSWORD not defined."
fi
chmod +x init-data.sh

healthcheck.js

Link: https://github.com/sr00t3d/fastpanel-n8n-docker/blob/main/healthcheck.js
var http = require('http');

var options = {
  host: '127.0.0.1',
  port: 5678,
  path: '/healthz',
  method: 'GET'
};

var req = http.request(options, function(res) {
  console.log('STATUS: ' + res.statusCode);
  process.exit(res.statusCode === 200 ? 0 : 1);
});

req.on('error', function(e) {
  console.log('ERROR: ' + e.message);
  process.exit(1);
});

req.end();

Permissions

sudo chown -R 1000:1000 /opt/n8n_stack/*

Starting the containers

docker compose up -d
docker ps

Check if the services are running/healthy.

For debugging:

docker compose logs -f n8n

Enabling stack on boot (systemd)

Link: https://github.com/sr00t3d/fastpanel-n8n-docker/blob/main/n8n_stack.service

Create /etc/systemd/system/n8n_stack.service:

[Unit]
Description=n8n Stack
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/n8n_stack
ExecStart=/usr/bin/podman-compose -f docker-compose.yml up -d
ExecStop=/usr/bin/podman-compose -f docker-compose.yml down
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target

Enable:

sudo systemctl enable n8n_stack.service

Configuring in FastPanel (reverse proxy)

In the n8n domain/subdomain:

  1. Create site manually.

  1. Uncheck database and FTP.
  2. Go to Backend (PHP, Reverse proxy, etc).
  3. Add proxy:

Try connection:

http://yourdomain.tld:5678

Fixing “Connection lost” error

This error usually indicates a misconfigured websocket in NGINX.

In the location / block, add:

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

Reload NGINX:

sudo nginx -t
sudo systemctl restart nginx

After this, n8n should stabilize without connection loss.

CC BY-NC

This post is licensed under CC BY-NC.

Comments

Join the discussion below.