n8n

【エンジニア向け】n8n Docker Compose設定完全ガイド|環境変数・PostgreSQL・Queue Mode・Traefik連携

Hirokuma
37分で読める
お気に入りに登録しませんか?
【エンジニア向け】n8n Docker Compose設定完全ガイド|環境変数・PostgreSQL・Queue Mode・Traefik連携

n8nをDockerで運用するエンジニアにとって、Docker Composeの設定は最も重要な基盤です。

環境変数の設定ミス、ボリュームの永続化忘れ、ネットワーク設定の誤りなど、多くのトラブルはdocker-compose.ymlの設定に起因します。

この記事では、n8nのDocker Compose設定について、環境変数の完全リファレンス、本番向け構成パターン、Queue Mode設定、Traefik連携まで、エンジニアが知っておくべき技術を網羅的に解説します。

基本構成:最小限のdocker-compose.yml

まず、ローカル開発用の最小構成を確認します。

最小構成(SQLite + HTTP)


version: "3.8"

services:
n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
ports:
- "5678:5678"
environment:
- GENERIC_TIMEZONE=Asia/Tokyo
- TZ=Asia/Tokyo
volumes:
- n8n_data:/home/node/.n8n

volumes:
n8n_data:

この構成の特徴:

  • データベース:SQLite(デフォルト)
  • プロトコル:HTTP(ローカル開発向け)
  • ボリューム:Docker Named Volume

起動コマンド


# 起動
docker compose up -d

# ログ確認
docker compose logs -f n8n

# 停止
docker compose down

# ボリューム含めて削除
docker compose down -v

環境変数リファレンス

n8nの挙動は環境変数で制御します。カテゴリ別に主要な環境変数を解説します。

基本設定

環境変数説明デフォルト
N8N_HOSTn8nのホスト名localhostn8n.example.com
N8N_PORTリッスンポート56785678
N8N_PROTOCOLプロトコルhttphttps
WEBHOOK_URLWebhook用外部URLhttps://n8n.example.com/
N8N_EDITOR_BASE_URLエディタのベースURLhttps://n8n.example.com/
GENERIC_TIMEZONEタイムゾーンAmerica/New_YorkAsia/Tokyo
TZシステムタイムゾーンUTCAsia/Tokyo

認証・セキュリティ

環境変数説明デフォルト
N8N_BASIC_AUTH_ACTIVEBasic認証の有効化false
N8N_BASIC_AUTH_USERBasic認証ユーザー名
N8N_BASIC_AUTH_PASSWORDBasic認証パスワード
N8N_ENCRYPTION_KEY認証情報暗号化キー自動生成
N8N_SECURE_COOKIESecure Cookieの有効化true
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS設定ファイル権限チェックfalse

N8N_ENCRYPTION_KEYの重要性


# 32バイト(64文字の16進数)を生成
openssl rand -hex 32

このキーは認証情報(Credentials)の暗号化に使用されます。設定しないと起動時に自動生成されますが、コンテナを再作成すると既存の認証情報が復号できなくなります。必ず明示的に設定し、安全にバックアップしてください。

データベース設定

環境変数説明デフォルト
DB_TYPEデータベースタイプsqlite
DB_POSTGRESDB_HOSTPostgreSQLホストlocalhost
DB_POSTGRESDB_PORTPostgreSQLポート5432
DB_POSTGRESDB_DATABASEデータベース名n8n
DB_POSTGRESDB_USERユーザー名postgres
DB_POSTGRESDB_PASSWORDパスワード
DB_POSTGRESDB_SCHEMAスキーマ名public

実行履歴(Executions)

環境変数説明デフォルト
EXECUTIONS_DATA_PRUNE実行履歴の自動削除true
EXECUTIONS_DATA_MAX_AGE保持期間(時間)336(14日)
EXECUTIONS_DATA_PRUNE_MAX_COUNT最大保持件数10000
EXECUTIONS_DATA_SAVE_ON_ERRORエラー時の保存all
EXECUTIONS_DATA_SAVE_ON_SUCCESS成功時の保存all
EXECUTIONS_DATA_SAVE_ON_PROGRESS進行中の保存false
EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS手動実行の保存true

Queue Mode(Redis)

環境変数説明デフォルト
EXECUTIONS_MODE実行モードregular
QUEUE_BULL_REDIS_HOSTRedisホストlocalhost
QUEUE_BULL_REDIS_PORTRedisポート6379
QUEUE_BULL_REDIS_PASSWORDRedisパスワード
QUEUE_BULL_REDIS_DBRedisDB番号0
QUEUE_HEALTH_CHECK_ACTIVEヘルスチェックfalse

本番向け構成:PostgreSQL + HTTPS

本番環境向けの推奨構成です。

.envファイル


# ドメイン設定
DOMAIN_NAME=example.com
SUBDOMAIN=n8n
SSL_EMAIL=admin@example.com

# PostgreSQL
POSTGRES_USER=n8n
POSTGRES_PASSWORD=your_strong_db_password
POSTGRES_DB=n8n

# n8n
N8N_ENCRYPTION_KEY=your_64_char_hex_key_here
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=your_admin_password

# タイムゾーン
GENERIC_TIMEZONE=Asia/Tokyo

docker-compose.yml(PostgreSQL + Nginx)


version: "3.8"

services:
postgres:
image: postgres:15-alpine
container_name: n8n-postgres
restart: always
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- n8n-network
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}']
interval: 10s
timeout: 5s
retries: 5

n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: always
ports:
- "5678:5678"
environment:
# データベース
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
- DB_POSTGRESDB_USER=${POSTGRES_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
# 認証
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=${N8N_BASIC_AUTH_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
# ホスト設定
- N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
- N8N_SECURE_COOKIE=true
# タイムゾーン
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
- TZ=${GENERIC_TIMEZONE}
# 実行履歴
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=168
- EXECUTIONS_DATA_PRUNE_MAX_COUNT=10000
# その他
- NODE_ENV=production
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
volumes:
- n8n_data:/home/node/.n8n
- ./local-files:/files
networks:
- n8n-network
depends_on:
postgres:
condition: service_healthy

volumes:
postgres_data:
n8n_data:

networks:
n8n-network:
driver: bridge

Traefik連携:自動SSL証明書

Traefikを使用すると、Let’s EncryptのSSL証明書を自動取得・更新できます。

docker-compose.yml(Traefik版)


version: "3.8"

services:
traefik:
image: traefik:v2.10
container_name: traefik
restart: always
command:
- "--api.dashboard=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.letsencrypt.acme.tlschallenge=true"
- "--certificatesresolvers.letsencrypt.acme.email=${SSL_EMAIL}"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- ./traefik_data:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- n8n-network

postgres:
image: postgres:15-alpine
container_name: n8n-postgres
restart: always
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- n8n-network
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER}']
interval: 10s
timeout: 5s
retries: 5

n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: always
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
- DB_POSTGRESDB_USER=${POSTGRES_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=${N8N_BASIC_AUTH_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
- N8N_SECURE_COOKIE=true
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
- TZ=${GENERIC_TIMEZONE}
- NODE_ENV=production
volumes:
- n8n_data:/home/node/.n8n
- ./local-files:/files
networks:
- n8n-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.n8n.rule=Host(${SUBDOMAIN}.${DOMAIN_NAME})"
- "traefik.http.routers.n8n.entrypoints=websecure"
- "traefik.http.routers.n8n.tls.certresolver=letsencrypt"
- "traefik.http.services.n8n.loadbalancer.server.port=5678"
depends_on:
postgres:
condition: service_healthy

volumes:
postgres_data:
n8n_data:

networks:
n8n-network:
driver: bridge

Traefik用ディレクトリ準備


mkdir -p traefik_data local-files
touch traefik_data/acme.json
chmod 600 traefik_data/acme.json

Queue Mode構成:Redis + Worker

大規模なワークフロー処理には、Queue Modeを使用してワーカーを分離します。

Queue Modeのアーキテクチャ

  • Main(n8n):UI、API、Webhookを処理し、ジョブをRedisに投入
  • Redis:ジョブキューとして機能
  • Worker:Redisからジョブを取得して実行
  • PostgreSQL:ワークフロー定義、認証情報、実行結果を保存

docker-compose.yml(Queue Mode)


version: "3.8"

services:
postgres:
image: postgres:15-alpine
container_name: n8n-postgres
restart: always
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- n8n-network
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER}']
interval: 10s
timeout: 5s
retries: 5

redis:
image: redis:7-alpine
container_name: n8n-redis
restart: always
volumes:
- redis_data:/data
networks:
- n8n-network
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
interval: 10s
timeout: 5s
retries: 5

n8n:
image: n8nio/n8n:latest
container_name: n8n-main
restart: always
ports:
- "5678:5678"
environment:
# データベース
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
- DB_POSTGRESDB_USER=${POSTGRES_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
# Queue Mode
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_BULL_REDIS_PORT=6379
- QUEUE_HEALTH_CHECK_ACTIVE=true
# 認証・セキュリティ
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=${N8N_BASIC_AUTH_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD}
# ホスト設定
- N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
- N8N_SECURE_COOKIE=true
# タイムゾーン
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
- TZ=${GENERIC_TIMEZONE}
- NODE_ENV=production
volumes:
- n8n_data:/home/node/.n8n
networks:
- n8n-network
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy

n8n-worker:
image: n8nio/n8n:latest
container_name: n8n-worker
restart: always
command: worker
environment:
# データベース(Mainと同じ設定)
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
- DB_POSTGRESDB_USER=${POSTGRES_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
# Queue Mode
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_BULL_REDIS_PORT=6379
# 暗号化キー(Mainと同じ)
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
# タイムゾーン
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
- TZ=${GENERIC_TIMEZONE}
- NODE_ENV=production
volumes:
- n8n_data:/home/node/.n8n
networks:
- n8n-network
depends_on:
- n8n
- redis

volumes:
postgres_data:
redis_data:
n8n_data:

networks:
n8n-network:
driver: bridge

Workerのスケーリング


# Worker数を増やす
docker compose up -d --scale n8n-worker=3

ボリュームとパーミッション

Named Volume vs Bind Mount

方式メリットデメリット
Named VolumeDockerが管理、移植性が高い直接アクセスしにくい
Bind Mount直接アクセス可能、バックアップ容易パーミッション管理が必要

Bind Mountを使用する場合


volumes:
- ./n8n_data:/home/node/.n8n
- ./postgres_data:/var/lib/postgresql/data

パーミッション設定


# n8nデータ(コンテナ内はnode:node = 1000:1000)
sudo mkdir -p n8n_data
sudo chown -R 1000:1000 n8n_data

# PostgreSQLデータ(コンテナ内はpostgres = 999:999)
sudo mkdir -p postgres_data
sudo chown -R 999:999 postgres_data

機密情報の管理(_FILE接尾辞)

環境変数に直接パスワードを記載する代わりに、ファイルから読み込むことができます。

Docker Secretsの使用


# シークレットファイルを作成
echo "your_db_password" > ./secrets/db_password.txt
echo "your_encryption_key" > ./secrets/encryption_key.txt
chmod 600 ./secrets/*


services:
n8n:
environment:
- DB_POSTGRESDB_PASSWORD_FILE=/run/secrets/db_password
- N8N_ENCRYPTION_KEY_FILE=/run/secrets/encryption_key
secrets:
- db_password
- encryption_key

secrets:
db_password:
file: ./secrets/db_password.txt
encryption_key:
file: ./secrets/encryption_key.txt

ヘルスチェックとリソース制限

ヘルスチェック設定


services:
n8n:
healthcheck:
test: ['CMD-SHELL', 'wget -q --spider http://localhost:5678/healthz || exit 1']
interval: 30s
timeout: 10s
retries: 3
start_period: 30s

リソース制限


services:
n8n:
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M

アップデート手順

イメージの更新

# 最新イメージをプル docker compose pull # コンテナを再作成 docker compose up -d

# 古いイメージを削除
docker image prune -f

バージョン固定(推奨)

本番環境では、latestではなくバージョンを固定することを推奨します。


services:
n8n:
image: n8nio/n8n:1.70.0

トラブルシューティング

よくある問題と解決方法

問題原因解決方法
認証情報が読めないN8N_ENCRYPTION_KEYの変更元のキーを復元
PostgreSQLに接続できない起動順序の問題depends_on + healthcheckを設定
SQLiteにフォールバックDB_TYPE未設定DB_TYPE=postgresdbを確認
Webhookが動作しないWEBHOOK_URL未設定外部アクセス可能なURLを設定
SSL証明書エラーDNS未反映Aレコードの設定を確認
Permission deniedボリュームの権限UID/GIDを確認してchown

ログ確認コマンド


# 全サービスのログ
docker compose logs -f

# 特定サービスのログ
docker compose logs -f n8n

# 最新100行のみ
docker compose logs --tail 100 n8n

# タイムスタンプ付き
docker compose logs -t n8n

コンテナ内でのデバッグ


# n8nコンテナに入る
docker exec -it n8n /bin/sh

# PostgreSQLに接続
docker exec -it n8n-postgres psql -U n8n -d n8n

# Redisに接続
docker exec -it n8n-redis redis-cli

よくある質問(FAQ)

Q. latestタグを使っても大丈夫ですか?

A. 開発環境では問題ありませんが、本番環境ではバージョンを固定することを強く推奨します。n8nは週次でリリースがあり、破壊的変更が含まれる可能性があります。

Q. Named VolumeとBind Mountはどちらが良いですか?

A. 一般的にはNamed Volumeが推奨されます。ただし、バックアップを容易にしたい場合やファイルに直接アクセスしたい場合はBind Mountが便利です。

Q. Queue ModeではRedisは必須ですか?

A. はい、Queue ModeではRedisが必須です。Redisがジョブキューとして機能し、MainプロセスとWorkerプロセス間の通信を仲介します。

Q. Workerは何台必要ですか?

A. ワークフローの実行頻度と複雑さによります。小〜中規模であれば1〜2台、大規模であれば3台以上を検討してください。CPUコア数に応じてスケールするのが目安です。

Q. docker compose v1とv2の違いは?

A. v2は「docker compose」(ハイフンなし)で実行し、v1は「docker-compose」(ハイフンあり)です。現在はv2が推奨されており、v1は非推奨です。

まとめ

この記事では、n8nのDocker Compose設定について詳しく解説しました。

構成パターン

  • 最小構成:SQLite + HTTP(ローカル開発向け)
  • 本番構成:PostgreSQL + HTTPS(Nginx or Traefik)
  • スケール構成:Queue Mode + Redis + Worker

重要な環境変数

  • N8N_ENCRYPTION_KEY:認証情報の暗号化(必ず固定・バックアップ)
  • DB_TYPE:データベースタイプ(本番はpostgresdb)
  • WEBHOOK_URL:Webhook用外部URL(HTTPS推奨)
  • EXECUTIONS_MODE:実行モード(スケール時はqueue)

本番運用のポイント

  • バージョンを固定(latestは避ける)
  • healthcheckでサービス依存関係を管理
  • リソース制限でメモリ枯渇を防止
  • 機密情報は_FILE接尾辞でファイルから読み込み

Docker Composeの設定を正しく理解することで、n8nの安定運用が実現できます。