タグ: 本番運用

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

    【本番運用】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を使用し、適切なバックアップ戦略を実装してください。