Published on

Cloud Run × Neonでつくる低コストn8n環境

Authors
  • avatar
    Name
    Nomad Dev Life
    Twitter
2025-10-05-img5

VPSに構築したn8nが落ちる

個人開発のマーケティングの自動化のために、n8nを使っています。これまでVPSにデプロイしていましたが、メモリ不足で他のコンテナが落ち始めたため、GCPへ移行することにしました。

この記事では、Cloud環境でなるべくコストをかけずにn8nを安定稼働させることを目的にした構成を紹介します。

  • Cloud Run: 必要なときだけ起動
  • DBはNeon(PostgreSQL): 無料枠でスタート可能
    • Cloud Storage + SQLite も検討したが、準備が面倒で動きも複雑なので却下
  • Gemini Flash: 低コストなLLM
  • Cloud Scheduler: n8n側を常時起動させないので、トリガーをn8nの外に設ける

GCPにn8n環境を構築する

1. NeonでPostgreSQLのインスタンスを用意

Neon公式サイトでアカウントを作成し、PostgreSQLインスタンスを作成。無料プランで始められ、SSL対応もデフォルトで有効です。

無料プランの一番のネックはストレージ(0.5GB)だと思います。構築後、Reddit検索 -> LLMによる評価 -> Discord送信というWorkflowを1つ作成してみたところ、消費されたストレージは0.04GBでした。

Workflowの中でDBに何を保存するかによって変わってくるので一概には言えませんが、Nodeが明示的にDBにデータを保存しないのであれば、無料プランでも運用できそうです。

2025-10-05-img7

2. GCPのSecret Managerにsecretsを登録

n8nが利用するDB接続情報や暗号鍵をSecret Managerに登録します。 Secret名は好きに付けて問題ありません。今回はn8nのPostgreSQLの環境変数に_N8N_REDDITを付けました。

Secret名用途
DB_N8N_REDDIT_POSTGRESDB_HOSTNeonのホスト名
DB_N8N_REDDIT_POSTGRESDB_PORTNeonのポート番号(通常は5432)
DB_N8N_REDDIT_POSTGRESDB_DATABASENeonのDB名
DB_N8N_REDDIT_POSTGRESDB_USERNeonのDBユーザー名
DB_N8N_REDDIT_POSTGRESDB_PASSWORDNeonのDBパスワード
N8N_REDDIT_ENCRYPTION_KEYn8nの暗号鍵

N8N_REDDIT_ENCRYPTION_KEYは、以下のコマンドで生成しました。

openssl rand -hex 16

3. Cloud Runにn8nのコンテナをデプロイ

使用するイメージは公式の n8nio/n8n:(version)。なるべく新しいversionを指定しましょう。

Cloud Runを起動する際に、このイメージ名を指定します。

環境変数設定

環境変数の設定は以下のとおりです。

環境変数
WEBHOOK_URL(Cloud RunのエンドポイントURL)
N8N_HOST0.0.0.0
N8N_PORT5678
N8N_PROTOCOLhttps
DB_TYPEpostgresdb
DB_POSTGRESDB_SSL_ENABLEDtrue
EXECUTIONS_PROCESSmain
EXECUTIONS_MODEregular

WEBHOOK_URLは、Cloud RunのServiceを作成した際に発行される、https://...run.appというURLを指定します。これによって、n8n側でこのURLをベースにしてWebhookのend-pointを生成します。

2025-10-05-img6

Secret Managerで登録した値を各DB関連の環境変数にマッピングします。

環境変数Secret名
DB_POSTGRESDB_HOSTDB_N8N_REDDIT_POSTGRESDB_HOST
DB_POSTGRESDB_PORTDB_N8N_REDDIT_POSTGRESDB_PORT
DB_POSTGRESDB_DATABASEDB_N8N_REDDIT_POSTGRESDB_DATABASE
DB_POSTGRESDB_USERDB_N8N_REDDIT_POSTGRESDB_USER
DB_POSTGRESDB_PASSWORDDB_N8N_REDDIT_POSTGRESDB_PASSWORD
N8N_ENCRYPTION_KEYN8N_REDDIT_ENCRYPTION_KEY

起動設定

  • Startup probe

    • Initial delay: 120s
      → これを入れないと、デプロイ後に 404 Not Found になることがあります。
  • Minimum number of instances

    • 0 に設定
      → アクセスがないときはコンテナが停止し、コストを最小化できます。
  • Startup CPU boost

    • ✅ チェックを入れる
      → コンテナ起動がスムーズになります。これを外すと同様に 404 が発生しやすいです。
2025-10-05-img8
2025-10-05-img9

4. n8nのフロー例

実際のワークフロー例は以下の記事で紹介しています:

上記の記事では、n8n内のCron Nodeを使ってWorkflowをトリガーしていました。

しかし、Cloud Runで最小インスタンス数を0にしている場合、待機中はコンテナが落ちているため、n8n側のスケジュールは動きません。

ですので、それをWebhook Nodeに置き換え、外部からWebhook URLにアクセスしてWorkflowをトリガーします。

2025-10-05-img5

Webhook NodeはTest/Prodの2つのWebhook URLを発行します。このうち、TestのWebhook URLはテストをすることができます。

2025-10-05-img5

Listen for test eventをクリックすると、TestのWebhook URLにアクセスが来るのを待ち始めます。 アクセスが来ると、画面右側にリクエストの内容が表示されるようになっています。この仕組みを使って、TestのWebhook URLを受け付けられるか確認します。

5. 定期実行(Cloud Scheduler + Webhook)

一つ前の"n8nのフロー例"のセクションで用意したWebhook URLを使って、n8nのWorkflowを起動します。

今回はCloud Schedulerを使い、定時にこのWebhook URLにリクエストします。

設定方法

Cloud Schedulerのジョブは、以下のように設定します。

項目
ターゲットHTTP
URLn8nのWebhook URL
HTTPメソッドGET
スケジュールcron形式で設定

Cloud Schedulerで定時にジョブを実行する | Nomad Dev LifeではCloud Tasksを使ってRetryを実行するようにしていました。

ただ、Cloud Scheduler単体でもRetryできます。Cloud Tasksと比べるとReliabilityは落ちますが、今回はユーザー向けの機能ではないので、Cloud Tasksを入れずにCloud Schedulerの再実行機能を使うことにしました。

Cloud Runのmin-instances=0では、Webhook呼び出し時にコンテナ起動待ち時間が発生します。この間にHTTPリクエストがタイムアウトしても、 Cloud SchedulerのRetry Configで数十秒後に再送してくれるため、結果的にトリガーを発火させることができます。

2025-10-05-img4

おわりに

Cloud Runの 「インスタンス0」+Cloud Schedulerリトライ の組み合わせにより、
ほぼ無料で堅牢な自動化環境を構築しました。

n8nのWorkflowの実行頻度によって料金は変わります。私の場合は、Gemini Flashが¥30-50/dayで一番コストがかかっており、GCPの部分は¥100/月くらいです。

この機会に、自分のn8n環境を構築してみませんか?