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

Self-hosting n8n on Cloud Run turns on a 5-second sleep

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

619 stars133 forksHCLMIT

At a glance

What is it?
self-host-n8n-on-gcr is a Terraform-first walkthrough for running n8n on Google Cloud Run with Cloud SQL for persistence and Google Auth Platform for OAuth, and its most useful detail is unglamorous: n8n needs a five-second delay before it touches the database, and Cloud Run injects a PORT variable that n8n does not read.
Who is it for?
This guide fits someone who wants n8n under their own control without running a server, and who is willing to read a deployment document rather than paste one command. It does not fit someone who needs an existing production automation estate migrated.
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 146 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 October 5, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Terraform first, the manual guide second

The repository presents two routes and does not pretend they are equal. There is a quick start that jumps straight to the Terraform deployment for anyone who wants to skip manual setup, and a step-by-step guide underneath it that the README argues is still worth reading, on the grounds that it explains what is happening while Terraform handles the heavy lifting.

The release history shows which route the project has been pushing. Version 2.0.0, in August 2025, brought the Terraform automation together with better documentation. Version 3.0.0, in October 2025, simplified the deployment and improved reliability. Version 3.1.0, in March 2026, added Queue Mode support for n8n on Cloud Run.

The repository itself is small and matches that shape: a README, a Dockerfile, a startup script, a deployment script and a Terraform directory, plus the usual changelog and licence files. The primary language is recorded as HCL, which is the Terraform configuration, not the shell script that starts the container.

The last push to main is dated May 13, 2026.

The 5-second sleep before the database

The first real obstacle is a race condition, and the fix is a delay rather than a retry loop.

n8n needs a small startup delay when connecting to an external database, because during initialisation it can reach the database before it is ready. On a container platform where every cold start goes through that same sequence, the race is not occasional, it is structural.

There are two ways to handle it. Option A, the recommended one, uses n8n's official Docker image with a command override that adds a five-second delay at deploy time. No extra files are needed, because the delay lives in the deploy command rather than in an image. The pattern is not invented here: the README traces it to n8n's own Kubernetes deployments.

Option B builds a custom image instead, and the guide frames that as the advanced choice, for when you need custom startup logic or want detailed debugging output. It gives you more control and obliges you to build and maintain an image.

The difference in cost is what matters in practice. Option A is a flag on a deploy command. Option B is a Dockerfile, a shell script, and a rebuild whenever n8n moves.

Cloud Run injects PORT, n8n reads N8N_PORT

The second obstacle is the one the community video walkthrough is built around, and it is described as the port configuration fix that trips up most people.

Cloud Run assigns ports dynamically. If someone deploys without explicitly setting the port, Cloud Run injects a PORT variable into the container. n8n does not read PORT. It reads N8N_PORT, and falls back to 5678 when that is unset. So a deployment that omits the port flag arrives at a container listening on the wrong interface, and the symptom is a failed container with no useful error.

The startup script resolves it in three steps: if PORT is set, export N8N_PORT from it; otherwise keep an explicitly set N8N_PORT; otherwise default to 5678. After that it prints the database type and host, the database port and the resulting n8n port for debugging, then replaces itself with n8n's original entrypoint so the container still starts normally.

The guide gives three reasons to prefer that logic over hardcoding: Cloud Run auto-assigns ports, the mapping survives a change in how Cloud Run handles them, and the same image then works on Cloud Run, Cloud Run Jobs and other container platforms. Option A needs none of it because it sets everything explicitly through command-line flags.

The custom image switches to a shell entrypoint

The Dockerfile in the repository is the Option B image, and one line in it explains itself: the entrypoint uses shell form to help avoid exec format issues.

The base is the official n8n image at its latest tag. The startup script is copied to the root of the image, the user is switched to root so the script can be made executable, and then switched back to the node user. Port 5678 is exposed, and the entrypoint runs the script through a shell rather than executing it directly.

That last choice is the interesting one. When a script is copied into an image built from another image, the interpreter line, the line endings and the target architecture all have to agree, and a mismatch produces a failure at exec time with nothing useful in the logs. Handing the work to a shell moves that class of failure earlier and makes it visible.

The effect, according to the guide, is that debugging output exists at all. Without this setup you get a container that failed, with no explanation of whether the problem was the port, the database or the entrypoint.

Cloud Run, Cloud SQL, and an OAuth handshake

Three Google services do the work. Cloud Run hosts the application and charges only while it runs. Cloud SQL for PostgreSQL provides persistence, on the stated grounds that your workflows should survive restarts. The Google Auth Platform handles connecting n8n to Google services such as Sheets and Drive.

The setup step is short enough to reproduce. You set a project ID and a region, log in with the gcloud command line tool, set the active project, and enable four services up front: Artifact Registry, Cloud Run, the SQL admin API and Secret Manager. Enabling them all at the start is deliberate, since the alternative is discovering the missing API from an error partway through.

bash
gcloud services enable artifactregistry.googleapis.com
gcloud services enable run.googleapis.com
gcloud services enable sqladmin.googleapis.com
gcloud services enable secretmanager.googleapis.com

The case for self-hosting is made in terms of control rather than cost alone: complete control over workflows and data, no arbitrary execution limits, and no uncertainty about where sensitive data is stored. With Cloud Run underneath, the pitch is that you get the control of self-hosting without managing actual servers.

Prerequisites are a Google Cloud account, which the guide says comes with a generous free tier for new accounts, the gcloud command line tool configured, and enough familiarity with Docker and the command line to follow the steps. Docker itself is only needed for the custom image route.

A domain is optional and only matters in production

One prerequisite is qualified rather than required: a domain name, described as optional but recommended for production use.

That qualifier matters for how you read the rest of the setup. Cloud Run gives you a generated service URL, so nothing in the quick start needs a hostname. A domain becomes necessary when OAuth callbacks are involved, because the redirect URI a Google service sends back to has to match something the provider will accept, and an ephemeral-looking generated URL is awkward to register as an authorized origin.

The guide also has sections beyond deployment itself, listed in its table of contents: configuring n8n for OAuth with Google services, a queue mode deployment section framed around scaling n8n for production, an updates and maintenance section whose heading is a warning about not running year-old software, a cost estimates section, and troubleshooting.

For people who prefer to watch, there is a community video walkthrough credited to Terra Femme, covering the full Terraform deployment through the Cloud Shell Editor, including the port configuration step that causes most of the trouble.

Editorial conclusion

This guide fits someone who wants n8n under their own control without running a server, and who is willing to read a deployment document rather than paste one command. It does not fit someone who needs an existing production automation estate migrated. Before you start, decide which of the two deployment paths you want, because the custom image in Option B is only needed for debugging or custom startup logic and otherwise costs you an image to build and keep up to date, and expect the port configuration to be the step that fails first if you deploy without reading the port section.

Frequently asked questions

Can you still self-host n8n?

Yes, and this repository is a guide to doing it: n8n on Google Cloud Run, with Cloud SQL for PostgreSQL persistence and the Google Auth Platform for OAuth to services such as Sheets and Drive. The guide is MIT licensed and its latest release adds Queue Mode support.

Is there a free way to deploy n8n?

The guide's premise is avoiding n8n subscription fees: Cloud Run charges only while a container runs, and Google Cloud is described as offering a generous free tier for new accounts. A domain name is optional and only recommended for production use.

What does the n8n startup delay fix?

n8n needs a small delay when connecting to an external database, to avoid a race condition during initialisation. The recommended path adds a five-second delay through a command override on the official image, while the custom image does it with a sleep of five seconds in its startup script.

Why does the custom image map PORT to N8N_PORT?

Cloud Run injects a PORT variable when a service is deployed without an explicit port, while n8n reads N8N_PORT and defaults to 5678. The startup script maps PORT when it is set, preserves an explicitly set N8N_PORT, and falls back to 5678 otherwise, printing the values for debugging first.

What has changed across the releases of this n8n guide?

Version 2.0.0 in August 2025 brought Terraform automation and better documentation, version 3.0.0 in October 2025 simplified the deployment with reliability improvements, and version 3.1.0 in March 2026 added Queue Mode support for n8n on Cloud Run.

What does Queue Mode add to an n8n deployment on Cloud Run?

Queue Mode support arrived in version 3.1.0, and the guide includes a dedicated section on queue mode deployment framed around scaling n8n for production use rather than running a single instance.

Official sources

  1. datawranglerai/self-host-n8n-on-gcr on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/datawranglerai-self-host-n8n-on-gcr.svg)](https://hysenlabs.com/projects/datawranglerai-self-host-n8n-on-gcr)