n8nをDockerでセルフホストする手順|CaddyでHTTPS公開とバックアップまで

PRこの記事にはアフィリエイト広告が含まれます。紹介したサービスに申し込まれると、運営者が報酬を受け取ることがあります。評価や順位は報酬で変えていません。広告表記について

n8n は、ノードをつないで業務の自動化を組めるツールです。クラウド版もありますが、セルフホストすれば実行回数を気にせずに使えます。この記事では、n8n を Docker Compose で VPS に置き、Caddy で HTTPS 公開するまでを解説します。

手順は 2026年10月21日 時点の安定版である n8n 2.44.5 で確かめました。

必要なメモリ:アイドル時は約400MiB

この記事の構成(n8n と Caddy)を起動し、オーナーアカウントを作ってから10分待って測った値です。

n8n 2.44.5 と Caddy のメモリ使用量(初期設定の直後、アイドル時)合計 396 MiB。半分以上の余裕が残るのは 1GB のプランからです。OS や Docker 自体が使う分は含みません。
n8n 本体: 376 MiBリバースプロキシ(Caddy): 20 MiB1GB 余裕61%合計 396 MiB
  • n8n 本体376 MiB
  • リバースプロキシ(Caddy)20 MiB
コンテナ別の内訳を表で見る
グループコンテナメモリ
n8n 本体n8n376 MiB
リバースプロキシ(Caddy)caddy20 MiB

測定日 。macOS 上の Docker(OrbStack、arm64、割り当て 16GB)。docker stats で5回(60秒間隔)取得した中央値。このサイトの構成(n8n は既定の SQLite、前段に Caddy)で起動し、オーナーアカウントを作成してから10分待って測定。

起動しただけの状態なら、1GB のプランでも動きます。ただし、n8n 公式ドキュメントは、メモリの使用量が次の要素で増えると説明しています。

  • 扱う JSON データの量と、バイナリデータ(ファイル)の大きさ
  • ワークフローのノードの数
  • 同時に動いているワークフローの数

特に Code ノードと、エディターからの手動実行は、メモリを多く使うと明記されています。大きなファイルを扱う予定がある場合や、AI エージェントのように長いデータをやり取りするワークフローを組む場合は、2GB 以上のプランを選んでおくと安心です。

構成

公式ドキュメントの例は、リバースプロキシに Traefik を使っています。この記事では、設定がより短い Caddy を使います。環境変数は公式の例に合わせています。

インターネット ──(443)──> Caddy ──(内部ネットワーク)──> n8n:5678

n8n の 5678番ポートは外に出しません。公式の例では 127.0.0.1:5678:5678 としてサーバー内に限定していますが、この記事の構成では Caddy からしか使わないため、expose: にしてサーバーにも公開しません。

手順1:VPS に Docker を入れ、DNS を設定する

Docker のインストール、ファイアウォール、DNS の設定は、VPSにDocker ComposeでアプリをHTTPS公開する基本手順と同じです。n8n 用のサブドメイン(例:n8n.example.com)の A レコードを、VPS の IP アドレスに向けておきます。

手順2:ファイルを作る

作業用のディレクトリ(例:~/n8n)を作り、次の3つのファイルを置きます。

compose.yaml:

services:
  caddy:
    image: caddy:2.11.7
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    environment:
      - N8N_DOMAIN=${N8N_DOMAIN}
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config

  n8n:
    image: docker.n8n.io/n8nio/n8n:2.44.5
    restart: unless-stopped
    # 外には公開せず、Caddy からだけ届くようにする
    expose:
      - "5678"
    environment:
      - N8N_HOST=${N8N_DOMAIN}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - N8N_WEBHOOK_URL=https://${N8N_DOMAIN}/
      - NODE_ENV=production
      - GENERIC_TIMEZONE=Asia/Tokyo
      - TZ=Asia/Tokyo
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
      - N8N_RESTRICT_FILE_ACCESS_TO=/files
    volumes:
      - n8n_data:/home/node/.n8n
      - ./local-files:/files

volumes:
  caddy_data:
  caddy_config:
  n8n_data:

Caddyfile:

{$N8N_DOMAIN} {
	reverse_proxy n8n:5678
}

.env:

N8N_DOMAIN=n8n.example.com

設定のポイントは次のとおりです。

設定 理由
image に 2.44.5 を指定 公式の例はタグなし(最新版)です。再起動のたびに版が変わらないよう固定し、更新は自分のタイミングで行います
N8N_WEBHOOK_URL Webhook の URL を外から見える HTTPS の URL にします。公式ドキュメントによると、この名前は n8n 2.30.0 から使えます。それより前の版は WEBHOOK_URL です
GENERIC_TIMEZONE と TZ スケジュール実行の時刻の基準です。設定しないと、公式の既定はニューヨーク時間になります
N8N_RESTRICT_FILE_ACCESS_TO=/files ワークフローから読み書きできるファイルを /files(ホストの ./local-files)に限定します

手順3:起動してオーナーを登録する

mkdir -p local-files
docker compose up -d
docker compose logs -f n8n

ログに Editor is now accessible via: と出たら、ブラウザで https://n8n.example.com を開きます。最初に表示される画面でオーナーアカウントを作れば完了です。

手元での検証結果は次のとおりです(ドメインの代わりに n8n.localhost と Caddy の内部証明書を使用)。

確認したこと 結果
Caddy 経由の HTTPS でエディターが開くか 開いた(ステータス 200)
ヘルスチェック /healthz {"status":"ok"}
ホストから 5678番に直接アクセスできないか 接続できなかった(公開されていない)

起動時に出る「非推奨」の表示について

n8n 2.44.5 を起動すると、ログに設定の非推奨(deprecation)に関する案内が5件出ました。エラーではなく、起動も正常に終わります。主なものは次の2つです。

  • N8N_RUNNERS_MODE:コードを実行するタスクランナーの「内部モード」は、将来のバージョンで削除される予定です。公式は、ランナーを別のプロセスとして動かす external モードを案内しています。
  • N8N_RUNNERS_TASK_TIMEOUT など:いくつかの上限値の既定が、将来小さくなる予定です(タスクのタイムアウトが300秒から60秒に、など)。今の動きを保ちたい場合は、値を明示的に設定します。

今すぐ対応しなくても動きますが、アップデートの前にはリリースノートを確認するようにしてください。

手順4:暗号鍵ごとバックアップする

n8n に登録した API キーなどの認証情報は、暗号化してデータベースに保存されます。その暗号鍵は、ボリューム内の config というファイルにあります(手元では /home/node/.n8n/config に encryptionKey が保存されていました)。

この鍵をなくすと、データベースが残っていても認証情報を復号できません。 データベースだけでなく、ボリュームを丸ごとバックアップします。

# n8n を止めてから、ボリュームを丸ごと固める
docker compose stop n8n
docker run --rm \
  -v n8n_n8n_data:/data:ro \
  -v "$PWD":/backup \
  alpine:3.22 tar czf /backup/n8n_data.tar.gz -C /data .
docker compose start n8n

ボリューム名は「ディレクトリ名_n8n_data」になります。docker volume ls で確認して、自分の環境の名前に置き換えてください。データベースは書き込み中にコピーすると壊れることがあるため、止めてから取ります。

復元するときは、先に Compose で起動してボリュームを作り、n8n を止めてから中身を入れ替えます。最後に、n8n の実行ユーザー(UID 1000)に所有者を戻します。

docker compose up -d
docker compose stop n8n
docker run --rm \
  -v n8n_n8n_data:/data \
  -v "$PWD":/backup:ro \
  alpine:3.22 sh -c 'rm -rf /data/* && tar xzf /backup/n8n_data.tar.gz -C /data && chown -R 1000:1000 /data'
docker compose start n8n

docker volume create で先にボリュームを作る方法もありますが、Compose の管理外のボリュームになり、起動のたびに警告が出ます。上の順序なら警告は出ません。

手元では、取ったバックアップを別の Compose プロジェクトにこの手順で復元しました。初期設定の画面は出ず、オーナーアカウントがそのまま引き継がれていることを確認しました。

バックアップはサーバーの外に置く

バックアップファイルを VPS の中に置いたままでは、サーバーが壊れたときに一緒に失われます。手元の PC やオブジェクトストレージなど、別の場所にコピーしてください。ファイルには暗号鍵が含まれるため、置き場所の権限にも注意が必要です。

よくあるつまずき

  • Webhook の URL が http://localhost:5678 になる:N8N_WEBHOOK_URL(2.30.0 より前は WEBHOOK_URL)を設定していないと、外部サービスに登録する URL が正しくなりません。
  • 5678番ポートを ports: で公開してしまう:Docker で公開したポートは ufw のルールを素通りします。詳しくは基本手順の記事の注意を参照してください。
  • 証明書が取れない:DNS の A レコードが VPS を向いているか、80番と443番が外から届くかを確認します。VPS の管理画面側のファイアウォールも見落としやすい箇所です。

アップデートするときは

n8n は新しい版が頻繁に出て、脆弱性の修正も多いため、月に1回以上の更新を勧めます。更新の手順と、1.x から 2.x への移行で動かなくなるものは、n8n のアップデート手順と脆弱性対策で解説しています。

出典

  1. Docker Compose(n8n 公式ドキュメント)(に確認)
  2. Memory-related errors(n8n 公式ドキュメント)(に確認)
  3. n8n のリリース一覧(GitHub)(に確認)
  4. Automatic HTTPS(Caddy 公式)(に確認)