n8n

【本番運用】n8n PostgreSQL永続化の完全ガイド|Docker設定・バックアップ・移行手順

Hirokuma
25分で読める
お気に入りに登録しませんか?
【本番運用】n8n PostgreSQL永続化の完全ガイド|Docker設定・バックアップ・移行手順

n8nはデフォルトでSQLiteを使用しますが、本番運用ではPostgreSQLへの移行が推奨されます。

SQLiteはファイルベースで手軽ですが、同時接続やスケーリングに制限があります。PostgreSQLを使用することで、データの永続化、バックアップ、高可用性を実現できます。

この記事では、n8nのPostgreSQL永続化について、Docker Compose設定から環境変数、バックアップ、SQLiteからの移行まで、本番運用に必要な技術を詳しく解説します。

なぜPostgreSQLが必要か?SQLiteとの比較

SQLiteの特徴と限界

項目 SQLite PostgreSQL
アーキテクチャ ファイルベース クライアント・サーバー型
同時接続 制限あり(書き込みロック) 多数の同時接続に対応
スケーリング 単一インスタンスのみ Queue Mode / Worker対応
バックアップ ファイルコピー pg_dump / レプリケーション
高可用性 非対応 レプリケーション対応
推奨用途 開発・テスト・小規模 本番・大規模ワークフロー

PostgreSQLが必要なケース

  • Webhookを多数受け付ける
  • ワークフローの実行頻度が高い
  • 複数ワーカーでの分散処理(Queue Mode)
  • データの確実なバックアップが必要
  • 本番環境での安定運用

Docker Composeによる構築

n8nとPostgreSQLをDocker Composeで構築する方法を解説します。

ディレクトリ構成


n8n-production/
├── docker-compose.yml
├── .env
└── backups/

.envファイル


# PostgreSQL設定
POSTGRES_USER=n8n
POSTGRES_PASSWORD=your_strong_password_here
POSTGRES_DB=n8n

# n8n設定
N8N_ENCRYPTION_KEY=your_32_char_encryption_key_here
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=your_admin_password
N8N_HOST=n8n.yourdomain.com
N8N_PROTOCOL=https
WEBHOOK_URL=https://n8n.yourdomain.com/
GENERIC_TIMEZONE=Asia/Tokyo

重要:N8N_ENCRYPTION_KEYは32文字以上のランダムな文字列を設定してください。このキーは認証情報の暗号化に使用され、変更すると既存の認証情報が読めなくなります。

docker-compose.yml


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 -h localhost -U ${POSTGRES_USER}']
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設定
- 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=${N8N_HOST}
- N8N_PORT=5678
- N8N_PROTOCOL=${N8N_PROTOCOL}
- NODE_ENV=production
- WEBHOOK_URL=${WEBHOOK_URL}
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
volumes:
- n8n_data:/home/node/.n8n
networks:
- n8n-network
depends_on:
postgres:
condition: service_healthy

volumes:
postgres_data:
n8n_data:

networks:
n8n-network:
driver: bridge

起動手順


# ディレクトリ作成
mkdir -p n8n-production && cd n8n-production

# .envとdocker-compose.ymlを作成(上記内容)

# 起動
docker compose up -d

# ログ確認
docker compose logs -f n8n

環境変数の詳細解説

データベース関連

環境変数 説明 デフォルト値
DB_TYPE データベースタイプ sqlite(postgresdbに変更)
DB_POSTGRESDB_HOST PostgreSQLホスト名 localhost
DB_POSTGRESDB_PORT PostgreSQLポート 5432
DB_POSTGRESDB_DATABASE データベース名 n8n
DB_POSTGRESDB_USER ユーザー名 postgres
DB_POSTGRESDB_PASSWORD パスワード
DB_POSTGRESDB_SCHEMA スキーマ名 public

SSL接続(マネージドDB向け)

AWS RDSやCloud SQLなどのマネージドデータベースを使用する場合、SSL接続が必要です。

環境変数 説明
DB_POSTGRESDB_SSL_CA CA証明書のパス
DB_POSTGRESDB_SSL_CERT クライアント証明書のパス
DB_POSTGRESDB_SSL_KEY クライアント秘密鍵のパス
DB_POSTGRESDB_SSL_REJECT_UNAUTHORIZED 証明書検証(true/false)

暗号化キー


N8N_ENCRYPTION_KEY=your_32_char_encryption_key_here

重要なポイント

  • 認証情報(Credentials)の暗号化に使用
  • 設定しないと起動時に自動生成される
  • キーを変更すると既存の認証情報が復号できなくなる
  • 必ず安全な場所にバックアップすること

キーの生成方法


# OpenSSLでランダムな32文字を生成
openssl rand -hex 16

.n8nディレクトリの永続化

PostgreSQLを使用しても、.n8nディレクトリの永続化は引き続き必要です。

.n8nディレクトリに保存されるデータ

  • 暗号化キー(N8N_ENCRYPTION_KEYを設定しない場合)
  • インスタンスログ
  • Source Control機能のアセット
  • 一時ファイル

ボリュームマッピング


volumes:
- n8n_data:/home/node/.n8n

または、ホストディレクトリにマッピング:


volumes:
- ./n8n-data:/home/node/.n8n

バックアップ戦略

本番運用では、定期的なバックアップが必須です。

PostgreSQLのバックアップ

手動バックアップ(pg_dump)


# バックアップ実行
docker exec n8n-postgres pg_dump -U n8n -d n8n > backup_$(date +%Y%m%d_%H%M%S).sql

# 圧縮してバックアップ
docker exec n8n-postgres pg_dump -U n8n -d n8n | gzip > backup_$(date +%Y%m%d).sql.gz

自動バックアップスクリプト


#!/bin/bash
# backup.sh

BACKUP_DIR="/path/to/backups"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7

# PostgreSQLバックアップ
docker exec n8n-postgres pg_dump -U n8n -d n8n | gzip > ${BACKUP_DIR}/n8n_db_${DATE}.sql.gz

# n8n_dataボリュームのバックアップ
docker run --rm -v n8n_data:/data -v ${BACKUP_DIR}:/backup alpine
tar czf /backup/n8n_data_${DATE}.tar.gz -C /data .

# 古いバックアップの削除
find ${BACKUP_DIR} -name "*.gz" -mtime +${RETENTION_DAYS} -delete

echo "Backup completed: ${DATE}"

cronで自動実行


# 毎日午前3時にバックアップ
0 3 * * * /path/to/backup.sh >> /var/log/n8n-backup.log 2>&1

リストア手順

PostgreSQLのリストア


# 圧縮ファイルからリストア
gunzip -c backup_20250101.sql.gz | docker exec -i n8n-postgres psql -U n8n -d n8n

# 非圧縮ファイルからリストア
cat backup.sql | docker exec -i n8n-postgres psql -U n8n -d n8n

n8n_dataボリュームのリストア


# 既存ボリュームを削除(注意)
docker volume rm n8n_data

# 新しいボリュームを作成してリストア
docker run --rm -v n8n_data:/data -v /path/to/backups:/backup alpine
tar xzf /backup/n8n_data_20250101.tar.gz -C /data

SQLiteからPostgreSQLへの移行

既存のSQLite環境からPostgreSQLに移行する手順です。

移行方法の選択肢

方法 メリット デメリット
ワークフローのエクスポート/インポート 確実、クリーン 実行履歴は移行されない
SQLダンプの変換 データ完全移行 スキーマ差異の調整が必要
新規構築 シンプル 再設定が必要

推奨:ワークフローのエクスポート/インポート

Step 1:ワークフローのエクスポート

  1. n8nの管理画面にログイン
  2. 各ワークフローを開いて「Export」→ JSONファイルを保存
  3. または、CLIでエクスポート:


# 全ワークフローをエクスポート
docker exec n8n n8n export:workflow --all --output=/home/node/.n8n/workflows.json

Step 2:認証情報のエクスポート


# 認証情報をエクスポート(暗号化されたまま)
docker exec n8n n8n export:credentials --all --output=/home/node/.n8n/credentials.json

Step 3:PostgreSQL環境の構築

上記のdocker-compose.ymlを使用して新しい環境を構築します。

重要:N8N_ENCRYPTION_KEYは元の環境と同じ値を使用してください。

Step 4:データのインポート


# ワークフローのインポート
docker exec n8n n8n import:workflow --input=/home/node/.n8n/workflows.json

# 認証情報のインポート
docker exec n8n n8n import:credentials --input=/home/node/.n8n/credentials.json

本番運用のベストプラクティス

ヘルスチェックの設定


healthcheck:
test: ['CMD-SHELL', 'pg_isready -h localhost -U ${POSTGRES_USER}']
interval: 10s
timeout: 5s
retries: 5

PostgreSQLの準備が完了してからn8nを起動することで、接続エラーを防ぎます。

リスタートポリシー


restart: always

コンテナが停止した場合に自動的に再起動します。

リソース制限


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

ログ管理


services:
n8n:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

リバースプロキシとSSL

本番環境では、Nginx / TraefikなどのリバースプロキシでSSL終端を行います。

Nginxの設定例


server {
listen 443 ssl http2;
server_name n8n.yourdomain.com;

ssl_certificate /etc/letsencrypt/live/n8n.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/n8n.yourdomain.com/privkey.pem;

location / {
proxy_pass http://localhost: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-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
}
}

Queue Modeでのスケーリング

大規模なワークフロー処理には、Queue Mode + Redisを使用します。

Queue Mode構成


version: '3.8'

services:
postgres:
# ... 上記と同じ

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:
# ... 基本設定に以下を追加
environment:
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_BULL_REDIS_PORT=6379

n8n-worker:
image: n8nio/n8n:latest
container_name: n8n-worker
restart: always
command: worker
environment:
# n8nと同じDB設定
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
# ... その他の設定
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_BULL_REDIS_PORT=6379
depends_on:
- postgres
- redis

volumes:
postgres_data:
redis_data:
n8n_data:

トラブルシューティング

よくある問題と解決方法

問題 原因 解決方法
DB接続エラー PostgreSQLが起動していない healthcheckとdepends_onを設定
認証情報が読めない 暗号化キーが異なる N8N_ENCRYPTION_KEYを確認
SQLiteにフォールバック DB_TYPE未設定 環境変数を確認
Permission denied ボリュームの権限問題 UID/GID設定またはchown
起動時にハング マイグレーション中 初回起動時は時間がかかる

ログの確認方法


# n8nのログ
docker compose logs -f n8n

# PostgreSQLのログ
docker compose logs -f postgres

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

データベース接続の確認


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

# テーブル一覧を確認
dt

# ワークフロー数を確認
SELECT COUNT(*) FROM workflow_entity;

よくある質問(FAQ)

Q. SQLiteからPostgreSQLへの移行は必須ですか?

A. 必須ではありませんが、本番運用では強く推奨されます。SQLiteは同時書き込みに制限があり、Webhookを多数受け付けるような使い方では問題が発生する可能性があります。

Q. マネージドPostgreSQL(RDS、Cloud SQL)は使えますか?

A. はい、使用できます。接続情報を環境変数で設定し、必要に応じてSSL接続を設定してください。

Q. N8N_ENCRYPTION_KEYを忘れた場合はどうなりますか?

A. 既存の認証情報が復号できなくなります。ワークフロー自体は残りますが、認証情報は再設定が必要です。キーは必ずバックアップしてください。

Q. PostgreSQLのバージョンは何を使うべきですか?

A. PostgreSQL 13以上が推奨です。2025年現在、PostgreSQL 15または16が安定しており推奨されます。

Q. 実行履歴(Executions)はどこに保存されますか?

A. PostgreSQLのexecution_entityテーブルに保存されます。実行履歴が増えるとディスク容量を消費するため、定期的なクリーンアップまたは保持期間の設定を検討してください。

まとめ

この記事では、n8nのPostgreSQL永続化について解説しました。

本番運用のための必須設定

  • DB_TYPE=postgresdb で PostgreSQLを指定
  • N8N_ENCRYPTION_KEY を固定値で設定
  • .n8nディレクトリのボリューム永続化
  • PostgreSQLデータのボリューム永続化

運用のポイント

  • healthcheckでPostgreSQLの準備完了を待つ
  • 定期的なバックアップ(pg_dump + ボリューム)
  • 暗号化キーの安全な管理
  • リバースプロキシでSSL終端

スケーリング時の追加設定

  • Queue Mode + Redis
  • n8n-workerの追加

PostgreSQLを使用することで、n8nの安定性と信頼性が大きく向上します。本番環境では必ずPostgreSQLを使用し、適切なバックアップ戦略を実装してください。