n8n webhook から Postgres へ: Lizard でのデプロイ例
n8n webhook は 1 つのワークフローで JSON を Postgres に書き込み、保存された行を返せます。 この例では Lizard 上で n8n を実行し、ヘッダー認証情報で webhook を保護し、送信側が再試行したときに重複行を避けるために request ID を使います。
公開リポジトリには、固定されたイメージ、ワークフロー、テーブル定義、確認スクリプトが含まれています。この記事では、単一の n8n インスタンスと JSON リクエストを扱います。より広いホスティング構成については、Lizard での n8n ホスティングから始めてください。
この例で実行するもの
n8n サービスと、それ専用の Managed Postgres は同じリージョンで実行されます。Postgres には、n8n 自身のワークフローと認証情報レコード、およびこの例の webhook_events テーブルの両方が保存されます。アプリケーションは 1 つのインスタンスを使用します。この例では Redis キューも分離ワーカーもありません。
このリポジトリでは n8n 2.38.5 と公式イメージの digest を固定しています。digest を固定することで、イメージの選択を再現可能にできます。固定を変更する前に、後続の n8n リリースを確認し、アップグレードをテストしてください。
ワークフローには 3 つのノードがあります:
- Webhook は
X-Example-Keyヘッダー付きの本番 POST リクエストを受け付けます。 - Store event はパラメータ化された Postgres クエリを実行します。
- Respond は保存された request ID、JSON body、作成時刻を返します。
データベース、オーナー、公開 URL を設定する
リポジトリからサービスを作成し、同じ Lizard プロジェクト内に別の Managed Postgres を作成します。リポジトリの手順に、コマンドと環境変数が記載されています。
DB_TYPE=postgresdb を設定し、データベースのホスト、ポート、名前、ユーザー、パスワードをアドオンの変数にバインドしてください。n8n の横でデータベースを動かすだけでは不十分です。n8n がそれらの値を受け取り、正常に接続できなければなりません。n8n の Postgres 設定を参照してください。
最初の起動前に、別の N8N_ENCRYPTION_KEY を生成して保持してください。n8n はこれを使って、データベースに保存された認証情報を保護します。デプロイのたびに新しいランダムキーを使うと、n8n は古い認証情報を読めなくなります。キーはリポジトリの外で、復旧記録と一緒に保管してください。
この例では、n8n が到達可能になる前にオーナーも設定します。N8N_INSTANCE_OWNER_MANAGED_BY_ENV と bcrypt パスワードハッシュを使い、n8n のオーナー設定に従います。ログインパスワードと webhook キーは別々のシークレットです。
N8N_HOST には、スキームやパスを含まないサービスの公開ホスト名を設定してください。起動スクリプトは、そのホスト名から HTTPS の WEBHOOK_URL とエディタ URL を組み立てます。ポート 5678 を使ってください。Lizard の前に別のプロキシを追加する場合は、proxy-hop 設定を確認してください。
ワークフローをインポートして公開する
リポジトリ内の SQL ファイルを使って webhook_events を作成してください。Postgres とヘッダーの認証情報を n8n にインポートし、その後ワークフローをインポートします。認証情報準備スクリプトは、サービス環境からシークレット値を読み取り、非公開の一時インポートファイルを書き出します。公開ワークフローには認証情報 ID と名前だけが含まれます。
n8n エディタを使ってワークフローを公開するか、n8n publish:workflow --id=lizardPostgresExample を使ってください。CLI での公開はデータベースを変更します。実行中の n8n プロセスは、その変更を登録するために再起動が必要です。この挙動は n8n CLI ガイドに記載されています。
リクエスト送信前に /healthz/readiness を確認してください。本番 URL は /webhook/lizard-postgres-example を使います。/webhook-test/ URL はエディタのテストセッション用であり、公開済みワークフローの代わりにはなりません。
リクエストを送信して再試行をテストする
公開 URL と webhook キーを環境変数に設定したうえで:
curl --fail-with-body "$N8N_URL/webhook/lizard-postgres-example" \
-H 'Content-Type: application/json' \
-H "X-Example-Key: $EXAMPLE_WEBHOOK_TOKEN" \
--data '{"requestId":"example-001","message":"hello"}'SQL クエリは request ID と JSON body を値としてバインドします。ユーザー入力をクエリテキストに連結して SQL を組み立てることはありません。引用符やネストされた JSON もデータのままです。
テーブルの主キーは request_id です。競合時には、クエリは最初に保存された行を返します。同じ ID を別のメッセージで送っても、元の payload は変更されません。これがこの例の再試行ポリシーです。アプリケーションで更新や競合エラーが必要な場合は、別のポリシーを選んでください。
イベントごとに新しい request ID を使ってください。新しいイベントを表すためにテスト ID を再利用して、2 行目が作られることを期待しないでください。
デプロイ確認
2026 年 9 月 9 日に、eu-west-lim-a で n8n 2.38.5 と Postgres 18.6 を実行しました。同じ 7 つの確認項目が、n8n サービスの再起動前後の両方で成功しました。
| 確認 | Before restart | After restart |
|---|---|---|
| Health endpoint | 200 | 200 |
| Database readiness | 200 | 200 |
| 正しいキーでのリクエスト | 200; 格納済みの本文を返す | 200; 格納済みの本文を返す |
| 変更されたボディを持つ同じリクエスト ID | 返された元の行 | 返された元の行 |
| Missing key | 403 | 403 |
| Wrong key | 403 | 403 |
| 不明な Webhook パス | 404 | 404 |
データベースには、両方の実行後も 1 件のイベントが保存されていました。JSON body と作成時刻は、再起動をまたいでも一致しました。テスト body には引用符とネストされた JSON が含まれていました。オーナーもサインインし、エディタ内でインポート済みワークフローを確認できました。
デプロイ記録と生の結果を確認してください。記録には、テストしたコードコミット名が含まれています。自分のワークフローに使う前に、リポジトリの確認スクリプトを自分のデプロイに対して実行してください。
これらの確認でカバーしないもの
この例では、負荷、稼働時間、コールドスタート遅延、または完全な月額請求はテストしません。また、キューモード、データベースバックアップ、ファイルアップロード、データベース消失からの復旧もセットアップしません。
サービス再起動の確認によって、このデプロイが再起動後に保存済みワークフローと認証情報を読み取れることは確認できます。これは災害復旧を証明するものではありません。そのためには、データベースバックアップを取得し、暗号化キーを保持し、別環境に復元して、ワークフローを再実行してください。
この JSON ワークフローには永続的なローカルファイルシステムは不要です。ローカルファイルを読み書きするワークフローには、適切なストレージと独自の永続性テストが必要です。そのワークロードを追加する前に、Persistent Volumes と n8n のストレージ要件を確認してください。
FAQ
n8n に Postgres は必要ですか? いいえ。セルフホスト版 n8n は SQLite を使えます。この例では、ワークフロー、認証情報、実行レコードをアプリケーションコンテナの外に保持し、データベース書き込みワークフローを実演するために Postgres を使っています。
エディタでは webhook が動くのに、他では 404 が返るのはなぜですか? ワークフローが公開されていることと、送信側が本番の /webhook/ パスを使っていることを確認してください。CLI で公開した場合も、実行中の n8n プロセスの再起動が必要です。
再デプロイ後も同じでなければならないものは何ですか? データベース接続は意図したデータベースを指している必要があり、暗号化キーは引き続き認証情報を復号できなければなりません。公開 webhook URL と認証の取り決めは、呼び出し元に対して安定したまま維持してください。
これは本番向けの完全な n8n セットアップですか? これは確認済みの単一インスタンス例です。本番自動化で依存する前に、ワークロードに合わせたバックアップ、監視、ストレージ、容量計画を追加してください。
AI で構築。Lizard で公開。
本番公開にプラットフォームチームは必要ありません。クラウド全体が、1 つの CLI コマンドですぐ使えます。
- ワークスペース
- —
- サービス
- —
- アドオン
- —
- デプロイ
- —