Docker 28.08.2026 20 просмотров

n8n в Docker Compose: production-настройка с нуля — SSL, PostgreSQL, бэкапы

#n8n #Docker #Docker Compose #production #PostgreSQL #SSL
n8n в Docker Compose: production-настройка с нуля — SSL, PostgreSQL, бэкапы
Полный гайд по развёртыванию n8n в Docker Compose для production: nginx + SSL, PostgreSQL вместо SQLite, бэкапы и мониторинг.

Почему не просто docker run

Одна команда docker run n8nio/n8n запускает n8n, но это не production. Без nginx — нет HTTPS. Без PostgreSQL — SQLite не масштабируется. Без volume-бэкапа — потеря данных при пересоздании контейнера.

Архитектура

  • n8n — основное приложение
  • PostgreSQL 16 — база данных вместо SQLite
  • nginx — reverse proxy + SSL
  • Certbot — SSL-сертификаты Let's Encrypt

Файл .env

N8N_HOST=n8n.вашдомен.ru
N8N_PROTOCOL=https
WEBHOOK_URL=https://n8n.вашдомен.ru
N8N_ENCRYPTION_KEY=сгенерируйте-openssl-rand-hex-32
POSTGRES_DB=n8n
POSTGRES_USER=n8n_user
POSTGRES_PASSWORD=сложный-пароль
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=ещё-пароль

docker-compose.yml

version: "3.8"
services:
  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - ./data/postgres:/var/lib/postgresql/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
      interval: 10s
      retries: 5

  n8n:
    image: n8nio/n8n:latest
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
      - DB_POSTGRESDB_USER=${POSTGRES_USER}
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
      - N8N_HOST=${N8N_HOST}
      - N8N_PROTOCOL=${N8N_PROTOCOL}
      - WEBHOOK_URL=${WEBHOOK_URL}
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - N8N_BASIC_AUTH_ACTIVE=${N8N_BASIC_AUTH_ACTIVE}
      - N8N_BASIC_AUTH_USER=${N8N_BASIC_AUTH_USER}
      - N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD}
    volumes:
      - ./data/n8n:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy
    restart: unless-stopped

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/n8n.conf:/etc/nginx/conf.d/default.conf
      - /etc/letsencrypt:/etc/letsencrypt:ro
    restart: unless-stopped

nginx/n8n.conf

server {
    listen 80;
    server_name n8n.вашдомен.ru;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl;
    server_name n8n.вашдомен.ru;
    ssl_certificate /etc/letsencrypt/live/n8n.вашдомен.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/n8n.вашдомен.ru/privkey.pem;
    client_max_body_size 50M;
    location / {
        proxy_pass http://n8n:5678;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 300s;
    }
}

Получение SSL-сертификата

# Первый запуск — HTTP только
docker compose up -d nginx

# Получить сертификат
certbot certonly --webroot -w /var/www/certbot -d n8n.вашдомен.ru

# Добавить SSL в nginx.conf, перезапустить
docker compose restart nginx

# Запустить n8n
docker compose up -d

Автобэкап PostgreSQL

#!/bin/bash
# /etc/cron.daily/n8n-backup
BACKUP_DIR=/backups/n8n
mkdir -p $BACKUP_DIR
DATE=$(date +%Y%m%d_%H%M)
docker exec postgres pg_dump -U n8n_user n8n | gzip > $BACKUP_DIR/n8n_$DATE.sql.gz
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete

Часто задаваемые вопросы

Почему нужен PostgreSQL для n8n в production?

SQLite — файловая база без конкурентного доступа. При параллельных воркфлоу возникают блокировки и потеря данных. PostgreSQL обеспечивает ACID, параллельные транзакции и масштабирование. Для production обязателен.

Как обновить n8n в Docker Compose без потери данных?

Сделайте бэкап PostgreSQL. Выполните: docker compose pull n8n && docker compose up -d n8n. Данные в PostgreSQL и volume не затрагиваются при пересоздании контейнера. Проверьте логи после обновления.

Полезные материалы по теме