タグ: Docker Compose

  • n8n Dockerインストール完全ガイド|docker-composeで本番環境を構築する手順

    n8n Dockerインストール完全ガイド|docker-composeで本番環境を構築する手順

    n8nをDockerでセルフホストすれば、実行回数無制限で月額コストを大幅に削減できます。この記事では、ローカル開発環境から本番環境まで、Docker/Docker Composeを使ったn8nのインストール手順を解説します。

    前提条件

    必要な環境

    • Docker Engine 20.10以上
    • Docker Compose v2以上
    • メモリ:最低2GB(推奨4GB以上)
    • ストレージ:10GB以上の空き容量

    Dockerのインストール確認

    以下のコマンドでDockerがインストールされているか確認します。

    
    docker –version
    docker compose version
    

    バージョン情報が表示されればOKです。未インストールの場合は、Docker公式サイトからDocker Desktopをインストールしてください。

    方法1:docker runで手軽に起動(ローカル開発向け)

    最もシンプルな方法です。ローカルでn8nを試したい場合に最適です。

    基本の起動コマンド

    
    docker run -it –rm 
      –name n8n 
      -p 5678:5678 
      -v n8n_data:/home/node/.n8n 
      n8nio/n8n
    

    起動後、ブラウザで http://localhost:5678 にアクセスするとn8nの画面が表示されます。

    コマンドの解説

    オプション 説明
    -it 対話モード(ログをターミナルに表示)
    –rm コンテナ停止時に自動削除
    –name n8n コンテナ名を指定
    -p 5678:5678 ポートマッピング
    -v n8n_data:/home/node/.n8n データ永続化(名前付きボリューム)

    バックグラウンドで起動

    ターミナルを閉じてもn8nを動かし続けたい場合は、-dオプションを使用します。

    
    docker run -d 
      –name n8n 
      -p 5678:5678 
      -v n8n_data:/home/node/.n8n 
      –restart unless-stopped 
      n8nio/n8n
    

    –restart unless-stopped により、PCを再起動してもn8nが自動起動します。

    方法2:Docker Compose(推奨)

    設定をファイルで管理できるDocker Composeを使う方法です。環境変数やデータベース連携が簡単に設定でき、本番運用にも対応できます。

    ディレクトリ構成

    
    n8n/
    ├── docker-compose.yml
    ├── .env
    └── n8n_data/          # データ永続化用(自動作成)
    

    基本のdocker-compose.yml

    まずはシンプルな構成から始めましょう。

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

    .envファイル

    環境変数は.envファイルで管理すると便利です。

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

    起動コマンド

    
    # 起動
    docker compose up -d
    
    # ログ確認
    docker compose logs -f n8n
    
    # 停止
    docker compose down
    
    # 停止(ボリューム削除も含む)
    docker compose down -v
    

    方法3:PostgreSQL連携(本番環境向け)

    本番環境では、デフォルトのSQLiteではなくPostgreSQLを使用することを推奨します。データの信頼性とパフォーマンスが向上します。

    docker-compose.yml(PostgreSQL版)

    
    services:
      n8n:
        image: n8nio/n8n
        container_name: n8n
        ports:
          - “5678:5678″
        environment:
          - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
          - TZ=${TZ}
          - 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_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
        volumes:
          - n8n_data:/home/node/.n8n
        depends_on:
          postgres:
            condition: service_healthy
        restart: unless-stopped
    
      postgres:
        image: postgres:15
        container_name: n8n-postgres
        environment:
          - POSTGRES_USER=${POSTGRES_USER}
          - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
          - POSTGRES_DB=${POSTGRES_DB}
        volumes:
          - postgres_data:/var/lib/postgresql/data
        healthcheck:
          test: [“CMD-SHELL”, “pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}”]
          interval: 5s
          timeout: 5s
          retries: 10
        restart: unless-stopped
    
    volumes:
      n8n_data:
      postgres_data:
    

    .env(PostgreSQL版)

    
    # タイムゾーン
    GENERIC_TIMEZONE=Asia/Tokyo
    TZ=Asia/Tokyo
    
    # PostgreSQL設定
    POSTGRES_USER=n8n
    POSTGRES_PASSWORD=your_secure_password_here
    POSTGRES_DB=n8n
    
    # n8n暗号化キー(認証情報の暗号化に使用)
    # 以下のコマンドで生成: openssl rand -hex 32
    N8N_ENCRYPTION_KEY=your_32_char_encryption_key_here
    

    暗号化キーの生成

    N8N_ENCRYPTION_KEYは認証情報の暗号化に使用される重要なキーです。以下のコマンドで生成してください。

    
    openssl rand -hex 32
    

    重要:このキーは変更するとすべての認証情報が復号できなくなります。必ずバックアップしてください。

    方法4:HTTPS対応(外部公開向け)

    n8nを外部に公開する場合は、HTTPSが必要です。TraefikまたはCaddyをリバースプロキシとして使用します。

    docker-compose.yml(Traefik版)

    
    services:
      traefik:
        image: traefik:v2.10
        container_name: traefik
        command:
          - “–api.insecure=false”
          - “–providers.docker=true”
          - “–providers.docker.exposedbydefault=false”
          - “–entrypoints.web.address=:80″
          - “–entrypoints.websecure.address=:443″
          - “–certificatesresolvers.letsencrypt.acme.tlschallenge=true”
          - “–certificatesresolvers.letsencrypt.acme.email=${SSL_EMAIL}”
          - “–certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json”
          - “–entrypoints.web.http.redirections.entrypoint.to=websecure”
        ports:
          - “80:80″
          - “443:443″
        volumes:
          - traefik_data:/letsencrypt
          - /var/run/docker.sock:/var/run/docker.sock:ro
        restart: unless-stopped
    
      n8n:
        image: n8nio/n8n
        container_name: n8n
        environment:
          - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
          - N8N_HOST=${N8N_HOST}
          - N8N_PORT=5678
          - N8N_PROTOCOL=https
          - WEBHOOK_URL=<a href="https://${N8N_HOST}/" target="_blank" rel="noopener">https://${N8N_HOST}/</a>
          - 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_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
        volumes:
          - n8n_data:/home/node/.n8n
        labels:
          - “traefik.enable=true”
          - “traefik.http.routers.n8n.rule=Host(<code>${N8N_HOST}</code>)”
          - “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
        restart: unless-stopped
    
      postgres:
        image: postgres:15
        container_name: n8n-postgres
        environment:
          - POSTGRES_USER=${POSTGRES_USER}
          - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
          - POSTGRES_DB=${POSTGRES_DB}
        volumes:
          - postgres_data:/var/lib/postgresql/data
        healthcheck:
          test: [“CMD-SHELL”, “pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}”]
          interval: 5s
          timeout: 5s
          retries: 10
        restart: unless-stopped
    
    volumes:
      n8n_data:
      postgres_data:
      traefik_data:
    

    .env(HTTPS版)

    
    # ドメイン設定
    N8N_HOST=n8n.example.com
    SSL_EMAIL=admin@example.com
    
    # タイムゾーン
    GENERIC_TIMEZONE=Asia/Tokyo
    TZ=Asia/Tokyo
    
    # PostgreSQL設定
    POSTGRES_USER=n8n
    POSTGRES_PASSWORD=your_secure_password_here
    POSTGRES_DB=n8n
    
    # n8n暗号化キー
    N8N_ENCRYPTION_KEY=your_32_char_encryption_key_here
    

    初期設定

    オーナーアカウントの作成

    n8nに初めてアクセスすると、オーナーアカウントの作成画面が表示されます。

    1. メールアドレスを入力
    2. 名前を入力
    3. パスワードを設定
    4. 「Next」または「Set up」をクリック

    このアカウントがn8nの管理者アカウントになります。

    タイムゾーンの確認

    設定画面でタイムゾーンが「Asia/Tokyo」になっていることを確認してください。スケジュール実行の時刻に影響します。

    n8nのアップデート

    Docker Composeの場合

    
    # 最新イメージを取得
    docker compose pull
    
    # コンテナを再作成(データは保持)
    docker compose up -d
    

    特定バージョンを指定

    docker-compose.ymlのimageを変更してバージョンを固定できます。

    
    services:
      n8n:
        image: n8nio/n8n:1.70.0  # バージョン指定
    

    バージョン確認

    n8nの画面左下に現在のバージョンが表示されます。また、以下のコマンドでも確認できます。

    
    docker exec n8n n8n –version
    

    バックアップと復元

    データのバックアップ

    PostgreSQL使用時

    
    # データベースのバックアップ
    docker exec n8n-postgres pg_dump -U n8n n8n > backup_$(date +%Y%m%d).sql
    

    SQLite使用時(デフォルト)

    
    # ボリュームのバックアップ
    docker run –rm -v n8n_data:/data -v $(pwd):/backup alpine tar cvf /backup/n8n_backup.tar /data
    

    ワークフローのエクスポート

    n8nのUI上からもワークフローをJSONファイルとしてエクスポートできます。

    1. ワークフロー一覧画面を開く
    2. エクスポートしたいワークフローを選択
    3. 「…」メニューから「Download」を選択

    トラブルシューティング

    コンテナが起動しない

    
    # ログを確認
    docker compose logs n8n
    
    # コンテナの状態を確認
    docker compose ps
    

    ポートが使用中

    5678ポートが他のアプリケーションで使用されている場合は、docker-compose.ymlのポートマッピングを変更します。

    
    ports:
      - “15678:5678″  # ホスト側を15678に変更
    

    パーミッションエラー

    n8nはUID 1000で動作します。ボリュームマウント時に権限エラーが出る場合は、以下を実行します。

    
    sudo chown -R 1000:1000 ./n8n_data
    

    PostgreSQLに接続できない

    • depends_onでpostgresの起動を待っているか確認
    • healthcheckが正常に動作しているか確認
    • .envファイルの認証情報が正しいか確認
    
    # PostgreSQLの状態確認
    docker compose exec postgres pg_isready -U n8n
    

    主要な環境変数

    環境変数 説明 デフォルト値
    GENERIC_TIMEZONE タイムゾーン UTC
    N8N_HOST ホスト名 localhost
    N8N_PORT ポート番号 5678
    N8N_PROTOCOL プロトコル(http/https) http
    WEBHOOK_URL Webhook用のベースURL
    N8N_ENCRYPTION_KEY 認証情報の暗号化キー
    DB_TYPE データベースタイプ sqlite
    NODE_FUNCTION_ALLOW_EXTERNAL Functionノードで許可する外部パッケージ
    EXECUTIONS_DATA_PRUNE 実行履歴の自動削除 true
    EXECUTIONS_DATA_MAX_AGE 実行履歴の保持期間(時間) 336

    セキュリティのベストプラクティス

    • N8N_ENCRYPTION_KEYを必ず設定:認証情報を暗号化
    • PostgreSQLを外部に公開しない:Dockerネットワーク内のみでアクセス
    • HTTPSを使用:外部公開時は必須
    • 強力なパスワード:オーナーアカウントとDB認証
    • 定期的なバックアップ:データとワークフローを保護
    • 最新バージョンを維持:セキュリティパッチの適用

    まとめ

    n8nをDockerでインストールする方法を解説しました。

    方法 用途 難易度
    docker run お試し・ローカル開発 簡単
    Docker Compose(基本) ローカル開発・小規模運用 簡単
    Docker Compose + PostgreSQL 本番環境 中程度
    Docker Compose + PostgreSQL + HTTPS 外部公開・本番環境 やや複雑

    ローカルで試すなら「docker run」、本番運用なら「PostgreSQL + HTTPS」構成がおすすめです。

    n8nの基本的な使い方は、セルフホストの詳細についてはも参考にしてください。

  • n8nセルフホスト構築ガイド|Docker Composeで本番環境を構築する方法

    n8nセルフホスト構築ガイド|Docker Composeで本番環境を構築する方法

    n8nのセルフホストは、Cloud版と比べてコストを大幅に抑えながら、実行回数無制限・完全なデータ管理を実現できる運用方法です。この記事では、Docker Composeを使ったセルフホスト環境の構築から、本番運用に必要なHTTPS化、バックアップ、アップデートまでを解説します。

    セルフホストとCloud版の比較

    n8nには大きく3つの利用形態があります。

    項目 Cloud版 セルフホスト(VPS) ローカル(Docker Desktop)
    月額コスト €20〜50 ¥700〜2,000(サーバー代) 無料
    実行回数 2,500〜10,000/月 無制限 無制限
    外部連携(Webhook) △(トンネル必要)
    24時間稼働 ×(PC起動時のみ)
    運用・保守 不要 自己責任 自己責任
    データ管理 n8n社 自社管理 自社管理

    セルフホストが向いているケース

    • ワークフローの実行回数が多く、Cloud版の上限を超える
    • 機密データを外部サービスに預けたくない
    • 月額コストを最小限に抑えたい
    • サーバー運用の知識がある(または学ぶ意欲がある)

    セルフホストの選択肢

    セルフホストの構築先として、主に以下の選択肢があります。

    サービス 月額目安 特徴
    Hostinger VPS ¥780〜1,200 1クリックでn8nインストール可能、初心者向け
    XServer VPS ¥830〜1,150 国内サーバー、日本語サポート充実
    シン・VPS ¥620〜900 国内最安クラス
    DigitalOcean $6〜12 1クリックでn8nインストール可能、海外サーバー
    Railway $5〜(従量課金) PaaS型、使用量に応じて課金
    GCP Compute Engine 無料枠あり e2-micro無料枠で運用可能

    この記事では、汎用的なVPS環境を想定し、Docker Composeを使った構築方法を解説します。

    前提条件

    • VPS(Ubuntu 22.04/24.04 推奨、メモリ2GB以上)
    • SSH接続環境
    • 独自ドメイン(HTTPS化する場合)
    • 基本的なLinuxコマンドの知識

    ステップ1:Dockerのインストール

    まずVPSにSSH接続し、Dockerをインストールします。

    1-1. システムの更新

    
    sudo apt update && sudo apt upgrade -y
    

    1-2. Dockerのインストール

    公式のインストールスクリプトを使用します。

    
    curl -fsSL <a href="https://get.docker.com" target="_blank" rel="noopener">https://get.docker.com</a> | sh
    

    1-3. 現在のユーザーをdockerグループに追加

    
    sudo usermod -aG docker $USER
    

    一度ログアウトして再ログインするか、以下を実行します。

    
    newgrp docker
    

    1-4. インストール確認

    
    docker –version
    docker compose version
    

    バージョン情報が表示されれば成功です。

    ステップ2:n8n用のディレクトリとファイルを作成

    2-1. 作業ディレクトリの作成

    
    mkdir -p ~/n8n
    cd ~/n8n
    

    2-2. docker-compose.ymlの作成

    本番運用を想定し、PostgreSQLをデータベースとして使用する構成です。

    
    nano docker-compose.yml
    

    以下の内容を貼り付けます。

    
    version: ‘3.8’
    
    services:
      postgres:
        image: postgres:16
        restart: always
        environment:
          POSTGRES_USER: ${POSTGRES_USER}
          POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
          POSTGRES_DB: ${POSTGRES_DB}
        volumes:
          - postgres_data:/var/lib/postgresql/data
        healthcheck:
          test: [“CMD-SHELL”, “pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}”]
          interval: 10s
          timeout: 5s
          retries: 5
    
      n8n:
        image: n8nio/n8n:latest
        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_HOST=${N8N_HOST}
          - N8N_PORT=5678
          - N8N_PROTOCOL=${N8N_PROTOCOL}
          - WEBHOOK_URL=${WEBHOOK_URL}
          - GENERIC_TIMEZONE=Asia/Tokyo
          - TZ=Asia/Tokyo
        volumes:
          - n8n_data:/home/node/.n8n
        depends_on:
          postgres:
            condition: service_healthy
    
    volumes:
      postgres_data:
      n8n_data:
    

    Ctrl + XYEnter で保存します。

    2-3. 環境変数ファイルの作成

    
    nano .env
    

    以下の内容を記述します。パスワードは必ず変更してください。

    
    # PostgreSQL設定
    POSTGRES_USER=n8n_user
    POSTGRES_PASSWORD=your_secure_password_here
    POSTGRES_DB=n8n
    
    # n8n設定
    N8N_HOST=localhost
    N8N_PROTOCOL=http
    WEBHOOK_URL=<a href="http://localhost:5678/" target="_blank" rel="noopener">http://localhost:5678/</a>
    

    パスワードの生成例

    
    openssl rand -base64 24
    

    ステップ3:n8nの起動と初期設定

    3-1. コンテナの起動

    
    docker compose up -d
    

    初回はイメージのダウンロードに数分かかります。

    3-2. 起動確認

    
    docker compose ps
    

    両方のコンテナが「running」になっていれば成功です。

    
    docker compose logs -f n8n
    

    ログを確認し、エラーがないことを確認します(Ctrl + Cで終了)。

    3-3. ブラウザでアクセス

    http://サーバーのIPアドレス:5678

    にアクセスします。初回はオーナーアカウントの作成画面が表示されます。

    1. メールアドレス、パスワード、名前を入力
    2. 「Next」をクリック
    3. アンケートに回答(スキップ可)
    4. ライセンス登録画面でメールアドレスを入力し、無料ライセンスキーを取得

    ステップ4:HTTPS化(本番運用向け)

    本番環境ではHTTPS化が必須です。ここではCaddyをリバースプロキシとして使用する方法を紹介します。

    4-1. ドメインのDNS設定

    お使いのドメインのDNS設定で、AレコードをVPSのIPアドレスに向けます。

    例:n8n.example.com203.0.113.1

    4-2. docker-compose.ymlの修正

    Caddyを追加した構成に変更します。

    
    version: ‘3.8’
    
    services:
      caddy:
        image: caddy:2
        restart: always
        ports:
          - “80:80″
          - “443:443″
        volumes:
          - ./Caddyfile:/etc/caddy/Caddyfile
          - caddy_data:/data
          - caddy_config:/config
        depends_on:
          - n8n
    
      postgres:
        image: postgres:16
        restart: always
        environment:
          POSTGRES_USER: ${POSTGRES_USER}
          POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
          POSTGRES_DB: ${POSTGRES_DB}
        volumes:
          - postgres_data:/var/lib/postgresql/data
        healthcheck:
          test: [“CMD-SHELL”, “pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}”]
          interval: 10s
          timeout: 5s
          retries: 5
    
      n8n:
        image: n8nio/n8n:latest
        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_HOST=${N8N_HOST}
          - N8N_PORT=5678
          - N8N_PROTOCOL=https
          - WEBHOOK_URL=<a href="https://${N8N_HOST}/" target="_blank" rel="noopener">https://${N8N_HOST}/</a>
          - GENERIC_TIMEZONE=Asia/Tokyo
          - TZ=Asia/Tokyo
        volumes:
          - n8n_data:/home/node/.n8n
        depends_on:
          postgres:
            condition: service_healthy
    
    volumes:
      postgres_data:
      n8n_data:
      caddy_data:
      caddy_config:
    

    n8nのportsを削除し、Caddyからのみアクセスさせる構成にしています。

    4-3. Caddyfileの作成

    
    nano Caddyfile
    
    
    n8n.example.com {
        reverse_proxy n8n:5678
    }
    

    n8n.example.comを実際のドメインに置き換えてください。CaddyはLet’s Encryptから自動でSSL証明書を取得します。

    4-4. .envファイルの更新

    
    # PostgreSQL設定
    POSTGRES_USER=n8n_user
    POSTGRES_PASSWORD=your_secure_password_here
    POSTGRES_DB=n8n
    
    # n8n設定
    N8N_HOST=n8n.example.com
    

    4-5. 再起動

    
    docker compose down
    docker compose up -d
    

    https://n8n.example.comでアクセスできれば完了です。

    ステップ5:運用・保守

    n8nのアップデート

    n8nは頻繁にアップデートされます。以下のコマンドで最新版に更新できます。

    
    cd ~/n8n
    docker compose pull
    docker compose up -d
    

    現在のバージョン確認:

    
    docker exec -it n8n-n8n-1 n8n -v
    

    バックアップ

    定期的なバックアップを推奨します。

    データベースのバックアップ

    
    docker exec n8n-postgres-1 pg_dump -U n8n_user n8n > backup_$(date +%Y%m%d).sql
    

    ボリュームごとバックアップ

    
    docker compose down
    sudo tar -czvf n8n_backup_$(date +%Y%m%d).tar.gz 
      /var/lib/docker/volumes/n8n_postgres_data 
      /var/lib/docker/volumes/n8n_n8n_data
    docker compose up -d
    

    ログの確認

    
    # n8nのログ
    docker compose logs -f n8n
    
    # PostgreSQLのログ
    docker compose logs -f postgres
    
    # 直近100行
    docker compose logs –tail=100 n8n
    

    コンテナの再起動

    
    docker compose restart
    

    トラブルシューティング

    コンテナが起動しない

    
    docker compose logs
    

    でエラー内容を確認します。よくある原因:

    • ポート5678が他のプロセスで使用中
    • .envファイルの記述ミス
    • PostgreSQLの接続エラー

    Webhookが動作しない

    • WEBHOOK_URLが正しく設定されているか確認
    • ファイアウォールでポート80/443が開いているか確認
    • ドメインのDNS設定が正しいか確認

    セキュアクッキーのエラー

    HTTPでアクセスしている場合に発生します。本番環境ではHTTPS化してください。ローカルテスト時は以下の環境変数を追加することで回避できます(非推奨)。

    
    environment:
      - N8N_SECURE_COOKIE=false
    

    メモリ不足

    VPSのメモリが1GB未満の場合、n8nの動作が不安定になることがあります。スワップファイルを追加するか、メモリを増設してください。

    
    # スワップファイルの追加(2GB)
    sudo fallocate -l 2G /swapfile
    sudo chmod 600 /swapfile
    sudo mkswap /swapfile
    sudo swapon /swapfile
    echo ‘/swapfile none swap sw 0 0’ | sudo tee -a /etc/fstab
    

    ライセンスについて

    n8nは「Sustainable Use License」を採用しています。

    • 無料で利用可能:社内業務、非商用、個人利用
    • 商用利用可能:自社の業務自動化に使用する場合
    • 有料ライセンス必要:n8nをホスティングサービスとして第三者に提供する場合、ホワイトラベル提供する場合

    自社の業務自動化目的であれば、セルフホストは完全無料で利用できます。

    よくある質問

    Q. Cloud版からセルフホストに移行できますか?

    A. はい、可能です。Cloud版のn8nからワークフローをエクスポート(JSON形式)し、セルフホスト環境にインポートできます。ただし、認証情報(Credentials)は再設定が必要です。

    Q. 複数人で使えますか?

    A. はい、セルフホスト版でも複数ユーザーを作成できます。ユーザー管理機能は無料で利用可能です。

    Q. PostgreSQLの代わりにSQLiteでも動きますか?

    A. はい、環境変数でDB_TYPE=sqliteを指定すれば動作します。ただし、本番環境ではPostgreSQLを推奨します。SQLiteはパフォーマンスや同時接続数に制限があります。

    Q. どのくらいのスペックが必要ですか?

    A. 最低要件としてCPU 1コア、メモリ1GBで動作しますが、安定運用には2コア、2GB以上を推奨します。ワークフローの複雑さや実行頻度に応じてスケールアップを検討してください。

    Q. 自動バックアップは設定できますか?

    A. cronを使って定期バックアップを設定できます。以下は毎日午前3時にバックアップを実行する例です。

    
    crontab -e
    # 以下を追加
    0 3 * * * cd ~/n8n && docker exec n8n-postgres-1 pg_dump -U n8n_user n8n > ~/backups/n8n_$(date +%Y%m%d).sql
    

    まとめ

    n8nのセルフホストは、初期設定の手間はかかりますが、一度構築すれば低コストで実行回数無制限の自動化環境を手に入れられます。

    この記事で解説した内容

    • Docker Composeを使ったn8n環境の構築
    • PostgreSQLをデータベースとして使用する本番構成
    • CaddyによるHTTPS化
    • アップデート、バックアップなどの運用方法

    まずはCloud版の14日間無料トライアルでn8nの使い方を学び、本格運用の段階でセルフホストに移行するのがおすすめの流れです。

    n8nの基本的な使い方については、料金プランの詳細はも参考にしてください。

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

    【エンジニア向け】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の安定運用が実現できます。