You don't need another theory-heavy guide — you need a single clean flow that just works if followed once, start to finish. Below is exactly that: no branching, no confusion, every command verbatim.
End result: https://n8n.eugenesamuel.uno loading the n8n owner-setup screen over real HTTPS — in about 15 minutes.
Create the VM (Google Cloud)
Go to Compute Engine → Create Instance and use:
- Name:
n8n - OS: Ubuntu 22.04 LTS
- Machine type:
e2-micro(free tier)
Tick:
- ✅ Allow HTTP traffic
- ✅ Allow HTTPS traffic
Click Create. Wait 1–2 minutes for the VM to boot.
Connect & prepare
Click SSH from the VM list to open a browser terminal, then run:
sudo apt update && sudo apt upgrade -y
sudo apt install -y ca-certificates curl gnupg nanoInstall Docker
Add Docker's GPG key:
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpgAdd the Docker apt repo:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/nullInstall Docker + Compose plugin:
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginEnable and start the service:
sudo systemctl enable docker
sudo systemctl start dockersudo usermod -aG docker $USER
newgrp dockerTest (should NOT show a permission error):
docker psSet up n8n (the most important part)
mkdir ~/n8n
cd ~/n8n
nano docker-compose.ymlPaste exactly this into Nano. Notice the n8n_data named volume at the bottom — this is Docker-managed storage, which is why you never need to chown anything and 502 errors never appear:
services:
n8n:
image: n8nio/n8n
restart: always
ports:
- "5678:5678"
environment:
- N8N_HOST=n8n.eugenesamuel.uno
- N8N_PORT=5678
- WEBHOOK_URL=https://n8n.eugenesamuel.uno/
- GENERIC_TIMEZONE=Asia/Kolkata
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:Save: Ctrl + X → Y → Enter
Start n8n
docker compose up -dWait 20 seconds, then check:
docker psThe STATUS column must show Up 20 seconds (and growing). Now smoke-test from the VM itself:
curl http://localhost:5678You should get back HTML (the n8n login/setup page source). If you do, the container is healthy — we just need to put Nginx + HTTPS in front.
Domain setup
In your domain DNS, add:
| Type | Name | Value |
|---|---|---|
| A | n8n | YOUR_VM_IP |
Wait 2–5 minutes for DNS to propagate.
Install Nginx
sudo apt install -y nginx
sudo rm /etc/nginx/sites-enabled/defaultConfigure Nginx
sudo nano /etc/nginx/sites-available/n8nPaste:
server {
listen 80;
server_name n8n.eugenesamuel.uno;
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
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;
}
}Save (Ctrl + X → Y → Enter). Enable and reload:
sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginxHTTPS (final)
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d n8n.eugenesamuel.unoWhen prompted, choose Redirect to HTTPS. Certbot writes the TLS block + 80→443 redirect into your Nginx config automatically.
🎉 Done
Open:
https://n8n.eugenesamuel.unoThe n8n owner-setup screen loads over real HTTPS. Create your account and you're in.
Rules — do NOT do these again
- ❌ Don'tuse a
~/.n8nbind-mount volume - ❌ Don'tadd
N8N_PROTOCOL=https(Nginx terminates TLS, not n8n) - ❌ Don'trun
dockerwithoutnewgrp dockerfirst - ❌ Don'tskip the Docker restart after changing compose
- ❌ Don'tmix HTTP and HTTPS inside the container
Already have a broken install? Clean reset
If you followed an older guide that used ~/.n8n as a bind-mount and are now stuck in a 502 / crash-loop, this is the safe reset path. From the ~/n8n folder:
cd ~/n8n
docker compose down
sudo rm -rf ~/.n8nThen edit docker-compose.yml to match Step 4 above (named volume, no N8N_PROTOCOL). Start fresh:
docker compose up -dRe-test locally, then bounce Nginx so it picks up the healthy upstream:
curl http://localhost:5678
sudo systemctl restart nginxOpen https://n8n.eugenesamuel.uno — 502 is gone.
✅ Final result
- ✅ Docker n8n running
- ✅ Domain connected
- ✅ HTTPS working
- ✅ No 502
- ✅ No permission errors
If anything breaks (rare now)
Paste the output of these two commands:
docker ps
docker logs n8n-n8n-1 --tail=30…and I'll fix it. Or, if you want to skip the surgery entirely, I'll set this up for you end-to-end — VM, domain, SSL, monitoring — in one sitting.