n8n-self-hosting について
Linux 仮想マシンで Docker Compose、Caddy、HTTPS を使って n8n を運用するためのガイドです。単一構成とキュー構成の選択から、セットアップ、安全対策、検証、保守まで扱います。
主な機能
- 01単一構成とキュー構成の手順
- 02Docker Compose と Caddy の設定
- 03HTTPS 証明書の確認
- 04シークレットとネットワークの保護
- 05デプロイ後のヘルスチェック
活用シーン
- 01新規 Linux 仮想マシンへの n8n 導入
- 02想定負荷に応じた構成の選択
- 03HTTPS とサービス稼働状況の確認
- 04シークレットと内部サービスの保護
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ czlonkowski/ n8n-skills --skill n8n-self-hostingインストール後、Claude Code で/n8n-self-hostingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
CREDENTIAL_OVERWRITES.mdDAY2.mdQUEUE_MODE.mdREADME.mdSECURITY.mdSINGLE_MODE.mdTASK_RUNNERS.mdassets/.env.queue.example.env.single.exampleCaddyfiledocker-compose.queue.ymldocker-compose.single.ymlinit-data.sh詳細
セルフホスト n8n のデプロイ
このスキルでは、新規の Linux VM(Ubuntu/Debian、root または sudo での SSH 接続)から、Caddy(Let's Encrypt による TLS 自動設定)の背後で動作する、HTTPS 対応の本番用 n8n を Docker Compose 経由で構築します。対象は Docker 上のセルフホスト n8n です。n8n Cloud は対象外であり、ワークフローの構築も対象外です(それはこのパックの別の項目で扱います)。
デプロイ方法は 2 つあります。アーキテクチャが異なるため、作業を始める前にモードを選択してください。
SSH 経由で、事前確認 → Docker のインストール → プロジェクトの配置 → シークレットの生成 → 起動 → TLS の検証 → 引き渡しまで、すべてを実施します。テンプレートファイルは assets/ にあり、モードごとの詳細とセキュリティに関する詳細は、以下に記載するリファレンスファイルにあります。
ルール 0 — モードを選択する(ユーザーに確認する)
推測してはいけません。確認してから、どちらか一方を選択してください。
| シングル/通常 | キュー | |
|---|---|---|
| プロセス | n8n が 1 つ | メイン + N 個のワーカー |
| 追加サービス | なし(SQLite) | Redis(キュー)+ Postgres(DB) |
| ワークフローの実行場所 | メインプロセス内 | ワーカー上で並列実行 |
| 適している用途 | 1 人のユーザー、軽度〜中程度の負荷、最もシンプルな運用 | 大量の処理、負荷の高い/長時間の実行、水平方向のスケーリング |
| Compose | assets/docker-compose.single.yml | assets/docker-compose.queue.yml |
| 詳細 | SINGLE_MODE.md | QUEUE_MODE.md |
迷った場合は、まず シングル から始めてください。最もシンプルで適切な方法であり、ほとんどのニーズに対応できます。後からキューに移行するには Compose ファイルを差し替え、SQLite から Postgres へ移行する必要があります。そのため、ユーザーがすでに本格的な処理量を見込んでいる場合は、最初から キュー を選択してください。
ルール 1 — シークレットの管理(絶対厳守)
ここで手順を誤ると、クライアントの認証情報が漏えいします。慎重に対応してください。
- すべてのシークレットを、対象マシン上で新規に生成してください。 別の n8n インスタンスから暗号化キー、DB パスワード、
.envをコピーしてはいけません。opensslコマンドについてはSECURITY.mdを参照してください。 - シークレットは
.env(モード 600)にのみ保存し、Compose から${VAR}として参照してください。シークレットをdocker-compose.yml、Caddyfile、またはコミット対象のファイルに直接記述してはいけません。 N8N_ENCRYPTION_KEYは厳重に管理してください。 保存されているすべての認証情報を暗号化します。紛失または変更すると、保存済みの認証情報を復号できなくなります。明示的に設定し、ユーザーにはマシンの外部にもバックアップするよう伝えてください。引き渡しに必要な範囲を超えて、長期保存されるログやチャット履歴に出力してはいけません。- 内部サービスを公開してはいけません。 公開するのは Caddy(80/443)のみです。n8n(5678)、Postgres(5432)、Redis(6379)はプライベートな Docker ネットワーク内にとどめてください。テンプレートでは、ホストポートのマッピングをすでに省略しています。追加してはいけません。
.envと Caddy のcaddy_dataボリューム(発行済み証明書と ACME アカウントキー)は共有する成果物ではありません。 git リポジトリ内で作業する場合は、コミットする前に.envが Git の追跡対象から除外されていることを確認してください。
事前に確認する入力情報
- SSH 接続先 —
user@hostと認証方法(鍵のパスまたは、エージェントがすでにアクセス権を持っていることのユーザー確認)。root または sudo ユーザーが必要です。 - ドメイン — n8n を稼働させる完全なホスト名。例:
n8n.example.com(→SUBDOMAIN=n8n、DOMAIN_NAME=example.com)。ユーザーが DNS を管理できる必要があります。 - TLS 用メールアドレス — Let's Encrypt 用(
SSL_EMAIL)。 - タイムゾーン — Schedule/Cron ノード用の IANA 名(例:
Europe/Warsaw)。指定がなければEtc/UTCです。 - モード — シングルまたはキュー(ルール 0)。キューの場合は、マシンに十分な RAM があることを確認します(最低でも約 4 GB。各ワーカーには約 1~2 GB が必要です)。
- オプションのモジュール — 一部の機能(現在は Agents)はバックエンドモジュールで、
N8N_ENABLED_MODULESに記載されている場合のみ有効になります。ユーザーが話題にした場合に限り確認してください。有効化する場合は、キューモードではワーカーにも到達できる必要があるため、先にQUEUE_MODE.mdのモジュールのセクションを読んでください。 - Python Code ノード/ワークフローを編集する人 — 「ワークフローで Python Code ノードを使いますか? または、あなた以外にワークフローを編集する人はいますか?」 と尋ねます。どちらか一方でも「はい」の場合、タスクランナーは 外部モード にします。
n8nio/runnersサイドカーを配置してください(キューモードではワーカーごとに 1 つ)。標準のn8nio/n8nイメージには Python 3 がないため、デフォルトの内部モードでは、すべての Python Code ノードがPython runner unavailable: Python 3 is missing from this systemというエラーで失敗します。手順 3 の前にTASK_RUNNERS.mdを読んでください。
デプロイの流れ
以下の手順を順番に進めてください。モード固有のコマンドの詳細は SINGLE_MODE.md/QUEUE_MODE.md、シークレットの生成とセキュリティ強化については SECURITY.md、更新/バックアップ/復元については DAY2.md を参照してください。
1. 事前確認(ここで検出できれば、失敗のコストを最小限に抑えられます)
- SSH で接続し、OS が Debian/Ubuntu 系であることを確認します(
. /etc/os-release)。 - DNS がすでにマシンを指している必要があります。 マシンのパブリック IP(
curl -s ifconfig.me)とdig +short <fqdn>の結果を比較します(マシン上と、できれば手元のラップトップからも実行します)。一致しない場合は、作業を止めてください。Caddy の ACME チャレンジが失敗します。ユーザーに A レコードを作成してもらい、反映を待ってから続行してください。 - ポート 80 と 443 にインターネットから到達できる必要があります。ホストのファイアウォールに加え、クラウドのセキュリティグループ/ネットワークファイアウォール(Hetzner Cloud、AWS SG など)も確認してください。これらはマシンの外部にあり、気づかないままブロックされることがよくあります。
2. Docker をインストールする(未インストールの場合)
docker --versionとdocker compose versionを確認します。インストールされていない場合は、Docker Engine と Compose プラグインをインストールします(Ubuntu/Debian では、Docker 公式のget.docker.comスクリプトを使って問題ありません)。先へ進む前に、docker compose versionを再確認してください。
3. プロジェクトを配置する
DATA_FOLDERを選びます。/opt/n8nのような絶対パスを指定してください。.envのDATA_FOLDERの値は、このディレクトリと完全に一致する必要があります(compose は${DATA_FOLDER}/caddy_config/Caddyfileをマウントし、init-data.shは相対パス./を使ってマウントします)。そのため、必ずこの場所からdocker composeを実行してください。ディレクトリを作成し、その中にcaddy_config/とlocal_files/も作成します。- テンプレートファイルをマシンに配置します。 テンプレートはこのスキルの
assets/にあり、あなたのマシン上にあります。サーバー上にはないため、各ファイルを転送してください。scpで転送するか、(ローカルコピーが不要な方法として)SSH 経由で各ファイルの内容を書き込みます。例:ssh <target> 'cat > <DATA_FOLDER>/docker-compose.yml' < assets/docker-compose.single.yml以下の名前で正確に配置してください。- 選択した compose →
<DATA_FOLDER>/docker-compose.yml(この名前に正確に変更してください) Caddyfile→<DATA_FOLDER>/caddy_config/Caddyfile- キューの場合のみ:
init-data.sh→<DATA_FOLDER>/init-data.sh。配置後、chmod +xを実行します。 - 対応する
.env.*.example→<DATA_FOLDER>/.env
- 選択した compose →
- 外部タスクランナー(Python): この時点で、ランナーの環境変数と
task-runnersサイドカーを compose に追加します(各モード用のスニペットはTASK_RUNNERS.mdにあります)。N8N_RUNNERS_AUTH_TOKENは、手順 4 で他のシークレットと一緒に生成します。
4. .env を設定し、シークレットを生成する
DATA_FOLDER、DOMAIN_NAME、SUBDOMAIN、SSL_EMAIL、GENERIC_TIMEZONEを設定します。opensslを使って、マシン上で各シークレットを生成し(コマンドはSECURITY.mdに記載されています)、該当するREPLACE_WITH_…プレースホルダーを置き換えて.envに書き込みます。N8N_ENCRYPTION_KEYを設定します。キューモードでは、さらにPOSTGRES_PASSWORDとPOSTGRES_NON_ROOT_PASSWORDも設定します。- 起動前に、未設定の項目がないことを確認します。
grep REPLACE_WITH_ .envが何も返さないことを確認してください。プレースホルダーが残っていると、その文字列がそのままパスワードになり、Postgres と n8n の接続に失敗します。 chmod 600 .envを実行します。暗号化キーを記録し、マシン外にバックアップできるようにします。
5. ファイアウォール
ufwで OpenSSH、80、443 を許可してから有効にします。5678/5432/6379 は開放しないでください。
6. 起動
cd <DATA_FOLDER> && docker compose up -dを実行します。- キューモードでは Redis、Postgres、メイン、ワーカーが起動します(ワーカーは
replicasを使用)。容量を増やすには、docker compose up -d --scale n8n-worker=Nを実行します。
7. 検証(これを確認せずに成功と判断しないでください)
docker compose psを実行し、すべてのサービスがUp/healthy であることを確認します(キューモードでは、まず postgres と redis がhealthyになっていることを確認します)。- n8n 自体の起動状態(内部):
docker compose exec n8n wget -qO- http://localhost:5678/healthz→{"status":"ok"}。これにより、「n8n が実行中」である状態と、「TLS の準備がまだできていない」状態を切り分けられます。 - 証明書の発行:
docker compose logs caddy | grep -i 'certificate obtained'を実行します。初回起動時の ACME 処理には 1〜2 分かかることがあります。完了するまでは、公開https://リクエストは TLS エラーになります。これは証明書がまだ発行待ちであることを意味し、n8n が停止しているわけではありません。 - 外部からの接続確認(再試行あり):
curl -fsS --retry 5 --retry-delay 10 https://<fqdn>/healthz→{"status":"ok"}。(/healthzで確認できるのはプロセスに接続できることだけです。/healthz/readinessでは、さらに DB の接続とマイグレーションの完了も確認できます。起動ループのデバッグ時にはこちらを使ってください。) - キューモード — メインとワーカーの設定を一致させる必要があります。 環境変数を比較します。
diff <(docker compose exec -T n8n env | sort) <(docker compose exec -T --index 1 n8n-worker env | sort)。 異なるのは公開 URL/プロキシ関連の変数だけである必要があります。それ以外に差がある場合、動作設定がメインには適用されていてもワーカーには適用されていません。ワークフローを実行するのはワーカーのため、起動時ではなく実行時に、1 つのノードで失敗します。このルールについてはQUEUE_MODE.mdを参照してください。 - 外部タスクランナー:
docker compose logs n8n | grep 'Registered runner'の結果にlauncher-javascriptとlauncher-pythonの両方が表示される必要があります(キューモードでは、すべてのワーカーを確認してください)。次に、Python Code ノードのスモークテストを実施します(TASK_RUNNERS.md→ Verify)。 https://<fqdn>を開くと、オーナー設定画面が表示されます。最初にサインアップフォームを完了した人が、そのインスタンスのオーナーになります。 オーナー未設定のインスタンスを公開すると先着争いになるため、URL を共有する前にすぐオーナーアカウントを作成してください。2FA を有効にします。(自動デプロイでは、代わりに環境変数を使ってオーナーを事前作成できます。SECURITY.mdのオーナーに関する行を参照してください。)
8. 引き継ぎ
- ユーザーに、URL、プロジェクトの保存場所、安全に保管する暗号化キー、および
DAY2.mdに記載されている Day-2 の基本事項(更新/バックアップ/復元)を伝えます。
してはいけないこと
- DNS/ポートの事前確認を省略しないでください。 A レコードの誤りやクラウドファイアウォールのポート閉鎖が、Caddy が証明書を取得できず、n8n が「壊れている」ように見える最大の原因です。
- 5678/5432/6379 をホストに公開しないでください。 Caddy はプライベートネットワーク経由で n8n に接続します。
- 別のインスタンスの暗号化キーや
.envを使い回さないでください。 サーバーごとに新しいシークレットを用意してください。 - SQLite でキューモードを実行しないでください。 キューには Postgres が必要です(テンプレートではすでに設定されています)。
- シークレットを
docker-compose.ymlや Caddyfile に記述しないでください。.envのみを使用してください。 - キューモードで、動作に影響する環境変数をメインのみに追加しないでください。 モジュール、DB、キュー、バイナリデータ、暗号化の設定は、ワーカーにも適用されるよう共有の
x-n8n-envアンカーに記述してください。メインのみに設定するのは、公開 URL/プロキシの変数だけです。QUEUE_MODE.mdを参照してください。 - むやみに
:latestを使わないでください。N8N_IMAGE_TAGを固定し、計画的に更新してください(DAY2.md)。 - 内部モードの標準イメージで Python Code ノードが使えると約束しないでください。 Python Code ノードには
n8nio/runnersサイドカーが必要です。n8n と完全に同じバージョンを使用し、インポートをランチャー設定で許可リストに登録する必要があります。デフォルトではimport jsonすら拒否されます。TASK_RUNNERS.mdを参照してください。 - ランナーが外部化された後にキューワーカーを
--scaleで増やさないでください。 サイドカーはワーカー 1 台のみを処理します。ワーカーとランナーのペアを追加してください(TASK_RUNNERS.md)。
参考ファイル
SINGLE_MODE.md— シングルインスタンスの詳細、SQLite と Postgres の比較、キューへの移行時期。QUEUE_MODE.md— キューのアーキテクチャ、ワーカー/並行処理/スケーリング、共有暗号化キー、メインとワーカー間の 環境変数の整合性ルール、任意のバックエンドモジュール(N8N_ENABLED_MODULES、Agents など)、バイナリデータ(databaseモード。キューモードではファイルシステムは未サポート。S3/Azure は Enterprise)、Webhook プロセッサー、複数メインのライセンス。SECURITY.md— シークレットの生成、暗号化キーのルール、セキュリティ強化の完全なチェックリスト(テレメトリーの無効化、環境変数へのアクセス遮断、公開 API、ファイアウォール、セキュア Cookie)。CREDENTIAL_OVERWRITES.md— OAuth の一元管理:インスタンス全体で OAuth アプリを 1 つ登録することで、ユーザーにクライアント ID/シークレットを表示せずに済みます(セルフホスト環境での「Google でログイン」)。エンドポイントと環境変数の選択、必須のエンドポイント認証トークン、親タイプからの継承、永続化、ワーカーの再読み込み。TASK_RUNNERS.md— 外部モードでのタスクランナー:Python Code ノードにn8nio/runnersサイドカーが必要な理由、シングルモード用の Compose スニペットとキューモードでのワーカーごとにサイドカー 1 台を使うパターン、/etc/n8n-task-runners.jsonを使った Python/JS モジュールの許可リスト登録、組み込みの拒否リスト、検証、障害発生時の特徴、n8n とランナーを同時にアップグレードする方法。DAY2.md— 設定(環境変数)の安全な変更、イメージの更新、バックアップ(暗号化キー+ボリューム+Postgres)、復元。assets/— テンプレート:docker-compose.single.yml、docker-compose.queue.yml、Caddyfile、.env.single.example、.env.queue.example、init-data.sh。
信頼できる公式の参考情報:公式ホスティングドキュメントは
https://docs.n8n.io/deploy/host-n8n にあります(2026 年半ばに旧 /hosting/ パスから再構成されました。こちらの URL を優先してください)。環境変数リファレンスのインデックスは
https://docs.n8n.io/deploy/host-n8n/configure-n8n/basic-configuration/use-environment-variables にあります。
この手順書と最新のドキュメントで内容が異なる場合は、ドキュメントを信頼し、ユーザーに伝えてください。