Open-source project
datawranglerai/self-host-n8n-on-gcr avatar
datawranglerai/self-host-n8n-on-gcr

Self-host-n8n-on-gcr: Terraform for n8n on Cloud Run with Cloud SQL and Queue Mode

Self-host n8n on Google Cloud without the subscription fees or server headaches - because your automation workflows shouldn't cost more than your coffee budget

617 stars132 forksHCLMIT

At a glance

What is it?
An HCL-first repository that deploys n8n to Google Cloud Run behind Cloud SQL PostgreSQL, with a queue mode variant added in v3.1.0. The Terraform path is the supported one; the README's manual walkthrough exists mainly to explain what the modules create.
Who is it for?
Adopt this if you want n8n on Cloud Run and are willing to keep a Terraform state file for it; the queue mode variant added in v3.1.0 is the version to start from if you expect concurrent executions. Do not adopt it if you have no appetite for Cloud SQL, since the repository treats PostgreSQL as the persistence layer rather than offering a SQLite fallback.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 126 days ago.
What is it written in?
Mainly HCL, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The bill and the server, not the workflow editor

n8n itself is not the problem this repository addresses. The problem is where the process lives. Running n8n on a VM means patching an operating system, sizing a disk, and paying for idle hours. Running it on n8n's hosted offering means a recurring subscription and execution accounting you do not control. The README frames the target as the middle: Cloud Run for hosting with per-use pricing, Cloud SQL PostgreSQL for persistence, and Google Auth Platform for OAuth against Sheets and Drive. The stated audience is someone with a Google Cloud account, the gcloud CLI, and enough Docker and command line familiarity to read a Dockerfile. That is a narrower audience than the repository topics suggest. The topics list agentic-ai, ai-agents and ai-agent-framework, but nothing in the supplied material describes agent orchestration. What it describes is infrastructure: a database, a container, a service account, and a port.

What Terraform actually creates, and the startup race it works around

The repository is HCL, and the README's own framing is that the step-by-step guide is there to explain what is happening under the hood while Terraform handles the deployment. So the manual path is documentation of the mechanism, not the recommended path. The mechanism has one non-obvious part. n8n needs a delay before it talks to an external database, otherwise it races the database during initialisation. The README attributes this pattern to n8n's own Kubernetes deployment manifest, where the container command sleeps before starting. On Cloud Run the same trick is applied through a command override, which is why Option A needs no extra files. Option B replaces the override with a custom image built from docker.n8n.io/n8nio/n8n:latest, copying a startup.sh that sleeps five seconds, maps Cloud Run's injected PORT onto N8N_PORT, echoes the database environment variables, and then execs /docker-entrypoint.sh. The port mapping is the part worth reading twice. Cloud Run assigns a port and injects PORT; n8n listens on N8N_PORT. If you deploy without setting the port explicitly, the two disagree and the container fails with nothing useful in the logs. Option A sidesteps this by setting everything through command-line flags at deploy time, which is also why it is the shorter path.

Prerequisites and the API enablement step people skip

The README lists a Google Cloud account, gcloud CLI installed and configured, basic Docker and command line familiarity, Docker itself only for the custom image path, and an optional domain name that it recommends for production. The first concrete commands are environment setup and API enablement: export PROJECT_ID and REGION, run gcloud auth login, gcloud config set project $PROJECT_ID, then enable artifactregistry.googleapis.com, run.googleapis.com, sqladmin.googleapis.com and secretmanager.googleapis.com. The README's justification for doing all four at once is to avoid enable-this-API-first failures partway through a deployment. Secret Manager being in that list tells you where credentials are expected to live rather than in plain environment variables on the service. Region selection is left to you, with europe-west2 as the example value. None of this is unusual for Cloud Run, but the ordering matters: enabling APIs after Terraform has already started creating resources is the failure mode the README is trying to prevent.

Queue mode, and why v3.1.0 is the version that matters

The release notes show v3.1.0, dated 2026-03-25, titled Queue Mode support for n8n on Cloud Run. The README's table of contents includes a Queue Mode Deployment section described as scaling n8n for production, and the repository topics include queue-workers and redis. That combination is the substantive difference between this repository's early versions and its current one. Queue mode separates the process that accepts work from the workers that execute it, which is the standard answer to a single n8n instance becoming the bottleneck under concurrent executions. The trade is that you now operate more than one Cloud Run service plus a Redis instance, and the cost estimate in the README stops being a simple function of one service's request volume. If your workloads are a handful of scheduled jobs, queue mode is overhead you are choosing to carry. If they are bursty or long-running, the single-service deployment is the wrong shape and the README says so by putting queue mode under a production heading.

The custom image path is a maintenance commitment, not a convenience

Option A is recommended and needs no files. Option B requires you to own a Dockerfile pinned to the latest tag and a startup.sh you will have to revisit whenever n8n changes its entrypoint or Cloud Run changes how it injects ports. The README is honest that Option B exists for custom startup logic and detailed debugging output, and that its script prints DB_TYPE, DB_POSTGRESDB_HOST, DB_POSTGRESDB_PORT and N8N_PORT before starting. That output is genuinely useful when a container exits immediately, which is the failure the README describes for the no-custom-image case. But the FROM line uses latest, which means your image is only as reproducible as the upstream tag is stable. Nothing in the supplied material describes a pinning policy or an automated rebuild. If you take Option B, treat the Dockerfile as code you maintain, because that is what it is. The README also notes the shell-form ENTRYPOINT is used to avoid exec format issues, a detail that suggests the maintainers hit that problem themselves.

Where this is the wrong tool

PostgreSQL is not optional here. The README treats Cloud SQL as the persistence layer because workflows should survive restarts, and every deployment path in the supplied material assumes a database connection with a startup delay to reach it. If you want a single container with a SQLite file and a mounted volume, this repository is not that, and the startup sleep becomes pointless complexity. The second boundary is Cloud Run's execution model. Queue mode exists precisely because long-running work does not fit a request-scoped service cleanly, so if your workflows include multi-minute jobs, you are committing to the queue architecture and its Redis dependency rather than avoiding it. The third boundary is Terraform state. The README's own v2.0.0 release note describes Terraform automation as a major UX improvement, which means the intended workflow is apply-driven. That implies a state file you must store and protect. Nothing in the supplied material describes a remote backend configuration, so where that state lives is a decision you make, not one the repository makes for you.

Alternatives and the real difference in approach

The obvious comparison is n8n's own Kubernetes deployment, which the README cites as the source of the sleep-before-start pattern. The difference is not the container. It is what you operate. Kubernetes gives you a Deployment manifest, a persistent volume claim, and a cluster you patch and pay for whether or not workflows run. This repository gives you a Cloud Run service that scales to zero between requests and a managed database. The trade runs the other way too: Kubernetes lets you run a stateful n8n with local storage and no external database, while Cloud Run pushes you toward Cloud SQL and the startup delay that comes with it. If you already run a cluster, the Kubernetes manifest is less new infrastructure. If you do not, adopting a cluster to host one automation tool is a large commitment relative to a Terraform apply. The second alternative is n8n's hosted product, which removes the database and the port configuration entirely at the cost of the subscription the README opens by objecting to.

Licence, maintenance cost, and what to check first

The repository is MIT licensed. That covers the HCL and any scripts in it. It does not cover n8n itself, which is a separate project with its own licence terms, and it does not cover the container image you pull from docker.n8n.io. If you redistribute a built image, the licence of the software inside it is the one that governs, not the MIT licence on this repository. That is a factual boundary, not legal advice, and it is worth confirming with whoever handles licensing in your organisation before you bake an image into a pipeline. On maintenance: the release cadence shown is three tagged releases across roughly ten months, with a major version bump at v3.0.0 and queue mode arriving at v3.1.0. That is a project still changing shape. Upgrades mean re-running Terraform and, for Option B, rebuilding an image pinned to latest. The README's own Updates and Maintenance section exists because running year-old software is the default outcome if you do not schedule the work. The cheapest thing to verify before committing is the port contract: confirm that the port your Cloud Run service is configured with matches the N8N_PORT the container ends up using, because that mismatch produces an empty log and a failed revision rather than a clear error.

Editorial conclusion

Adopt this if you want n8n on Cloud Run and are willing to keep a Terraform state file for it; the queue mode variant added in v3.1.0 is the version to start from if you expect concurrent executions. Do not adopt it if you have no appetite for Cloud SQL, since the repository treats PostgreSQL as the persistence layer rather than offering a SQLite fallback. Before applying, verify three things in your own project: that the four APIs named in Step 1 are enabled, that your Cloud Run service port matches the container's N8N_PORT, and that your Terraform state is stored somewhere you control rather than locally.

Official sources

  1. datawranglerai/self-host-n8n-on-gcr on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Community notes

Community notes