Guide • Automation Infrastructure
Self-Hosting n8n on Google Cloud (Free Tier)
Practical, production-ready deployment guide for running your own n8n instance on Google Cloud with Docker, Nginx, and Let's Encrypt.
29.12.2025 · ~20 min read
Running your own automation platform gives you full control over data, workflows, and scalability. In this guide, we'll walk through a real-world, production-ready setup of n8n on Google Cloud, using Docker for isolation, Nginx as a reverse proxy, and Let's Encrypt for HTTPS.
This guide is written from hands-on experience, including the most common pitfalls you will hit when setting this up for real- and how to solve them correctly.
Who this setup is for
This setup is ideal if you want:
- A private n8n instance
- A custom domain or subdomain (e.g.
n8n.your-domain.com) - HTTPS out of the box
- A solution that is easy to update and maintain
- No vendor lock-in
Architecture overview
The stack we'll build looks like this:
Internet → HTTPS (Let's Encrypt) → Nginx (Reverse Proxy) → n8n (Docker container) → Persistent volume (~/.n8n)
Components:
- Google Cloud VM (Ubuntu, Free Tier–compatible)
- Docker – runs n8n in isolation
- Nginx – reverse proxy + SSL termination
- Certbot – automatic HTTPS certificates
- Persistent volume – keeps workflows safe during updates
Table of Contents
- Install and enable Docker
- Run n8n in Docker (correctly for production)
- Install Nginx
- Configure Nginx as a reverse proxy
- Enable HTTPS with Certbot
- Restart n8n correctly for HTTPS
- Updating n8n safely
- Updating Docker without data loss
- Troubleshooting: real problems & real fixes
- Is it really free!?
Step 1: Install and start Docker
Update your VM and install Docker:
Install Docker
sudo apt update
sudo apt install docker.io -yStart Docker and enable it on boot:
Enable Docker service
sudo systemctl start docker
sudo systemctl enable dockerVerify installation:
Verify Docker
docker --versionStep 2: Run n8n in Docker (production-correct)
This step is critical. n8n must be started with the final domain and protocol in mind.
Using a subdomain (recommended)
Example: n8n.your-domain.com
Run n8n container
docker run -d --restart unless-stopped \
--name n8n \
-p 5678:5678 \
-e N8N_HOST="n8n.your-domain.com" \
-e N8N_PROTOCOL="https" \
-e WEBHOOK_URL="https://n8n.your-domain.com/" \
-e NODE_ENV="production" \
-v ~/.n8n:/root/.n8n \
n8nio/n8nWhy this matters
N8N_HOSTandWEBHOOK_URLmust match the final HTTPS URL- Secure cookies depend on HTTPS
- Webhooks will silently fail if URLs are wrong
- These values cannot be changed by restarting- only by recreating the container
At this stage, n8n is reachable internally at:
http://localhost:5678
We will not expose this publicly.
Step 3: Install Nginx
Nginx will forward external traffic to n8n and handle HTTPS.
Install Nginx
sudo apt install nginx -yStep 4: Configure Nginx reverse proxy
Create a new site configuration:
Create Nginx site config
sudo nano /etc/nginx/sites-available/n8n.confPaste:
Nginx config for n8n
server {
listen 80;
server_name n8n.your-domain.com;
location / {
proxy_pass http://localhost:5678;
proxy_http_version 1.1;
proxy_buffering off;
proxy_cache off;
chunked_transfer_encoding off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400;
}
}Enable the site and reload Nginx:
Enable Nginx site
sudo ln -s /etc/nginx/sites-available/n8n.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginxAt this point, http://n8n.your-domain.com should load n8n (without HTTPS yet).
Step 5: Enable HTTPS with Certbot
Install Certbot and the Nginx plugin:
Install Certbot
sudo apt install certbot python3-certbot-nginx -yRequest a certificate:
Request HTTPS certificate
sudo certbot --nginx -d n8n.your-domain.comCertbot will verify DNS, perform the HTTP challenge, install the certificate, enable HTTP → HTTPS redirect, and schedule automatic renewal.
If successful, you'll see:
Congratulations! You have successfully enabled HTTPS
Step 6: Restart n8n correctly (important)
After HTTPS is live, restart the container (not Docker itself):
Restart n8n
docker restart n8nNow open:
https://n8n.your-domain.com
You should see:
- 🔒 Valid HTTPS
- No “secure cookie” error
- n8n setup screen
Updating n8n (without losing data)
Your workflows and credentials live in ~/.n8n, so updates are safe.
Update n8n container
docker stop n8n
docker rm n8n
docker pull n8nio/n8n:latestThen re-run the same docker run command you used originally (with all -e flags).
Updating Docker itself
Updating Docker is independent from n8n.
Update Docker
docker stop $(docker ps -aq)
sudo apt update
sudo apt upgrade docker.io -y
sudo rebootAfter reboot:
Start n8n after reboot
docker start n8nTroubleshooting (real problems we faced & solved)
❌ DNS_PROBE_FINISHED_NXDOMAIN
Cause: DNS records added in the wrong place (e.g. cPanel while domain uses Cloudflare).
Fix:
Check authoritative nameservers
dig your-domain.com NSAdd DNS records only in the active DNS provider (e.g. Cloudflare) and verify with:
Verify DNS
dig n8n.your-domain.com @8.8.8.8❌ Certbot returns NXDOMAIN
Cause: DNS exists in the dashboard but is not globally resolvable yet.
Fix:
Confirm Cloudflare answers
dig n8n.your-domain.com @nelly.ns.cloudflare.comThen wait for negative DNS cache to expire (typically 15–60 minutes).
❌ “Secure cookie” error in n8n
Cause: n8n is configured for HTTPS but accessed via HTTP.
Fix:
- Enable HTTPS properly
- Do not disable secure cookies
- Restart container after HTTPS is active
❌ 502 Bad Gateway from Nginx
Cause: Nginx cannot reach n8n on localhost:5678.
Most common reasons:
- Container not running
- Container started without correct env vars
- Container was restarted instead of recreated
Fix:
Recreate n8n container
docker stop n8n
docker rm n8n
# then recreate with correct docker run command❌ “Why didn't restarting Docker fix it?”
Because:
docker restartdoes not change environment variables- Docker containers are immutable
- Any change to
-eflags requires container recreation
Final notes
This setup gives you:
- Full control over automation infrastructure
- Secure HTTPS webhooks
- Predictable updates
- Zero vendor lock-in
- A solid foundation for internal or client-facing automation
Once you understand DNS authority, container immutability, and the correct order of enabling HTTPS, n8n becomes extremely reliable in production.
Is it really free!?
Here is the breakdown of what is all free and what you need to pay attention to not to break rate limit of the free tier!
⚠️ The ONE thing that can cost money (watch this carefully)
🌐 Outbound traffic (egress)
Google Free Tier includes:
- 1 GB/month outbound traffic (approx.)
What counts as outbound traffic:
- Webhooks from n8n to external APIs
- HTTP requests to:
- Slack
- OpenAI
- Google APIs
- Web services
- File downloads/uploads triggered by workflows
Typical cost:
- Very small at first
- A few cents per GB
- But can grow with heavy automation
💡 Example:
- Personal automations → effectively free
- Client automations, heavy workflows → a few € per month
Final verdict (clear and honest)
✔ YES - Your n8n setup is:
- Technically correct
- Production-capable
- Secure
- Free Tier–compatible
✔ It will remain free as long as:
- You stay on e2-micro
- Disk stays ≤ 30 GB
- Outbound traffic stays low/moderate
Practical recommendation
For:
- Personal use
- Internal automations
- Learning / MVP
- Light client usage
This setup can run for months or years at $0
For:
- Heavy workflows
- Large file processing
- Many external API calls
Expect small, predictable costs, not surprises.