n8nself-hostingGoogle CloudDockerDevOpsCaddy

n8n self-hosting tutorial: free deployment on Google Cloud e2-micro

Diego Hernández Herrera

As someone who values workflow efficiency, I recently discovered n8n, the open source alternative to Zapier and other automation tools. I wanted to automate some repetitive tasks in my daily life to save myself some time and avoid forgetting things.

For example, every evening I used to manually go over my git history and the notes I took on my time tracking database in Notion to draft a report of my work that day. But with n8n, I can program an automation that runs every day at 9 PM to fetch my commits from the GitLab API and my notes from Notion, feed them into Gemini and let the LLM write for me an end-of-day executive summary that gets delivered in my inbox.

And the best part is that I’m hosting my n8n instance for free in Google Cloud Compute! And because I believe this tool could be a game changer for many computer scientists, I’ll tell you how to set it up yourself.

The main limitation that arises when trying to find a platform to host n8n for free is RAM. Most LLMs and online sites recommend having at least 2-4 GB of RAM available for your instance, but that’s incredibly hard to find for free. So after tinkering for a bit, I tried to make it work on a Google e2-micro virtual machine, which is part of Google Cloud’s free tier program. It only has 1 GB of RAM, but it turns out that that’s enough if you plan to use n8n for personal automations only.

The first thing to do after logging into the Google Cloud console is to create a new virtual machine. Make sure it’s an e2-micro instance hosted in one of these US regions: us-west1, us-central1 or us-east1. The free e2-micro instance is only available in those regions, as of February 2026. You also only get for free a maximum of 30 GB of ROM within a standard persistent disk. So make sure to configure your VM’s storage using the correct type and size. Otherwise, you might get charged for it. The OS you choose doesn’t matter a lot as long as it’s free and you know your way around it; but I chose Ubuntu 22 minimal and that’s what I recommend.

Other things to consider when creating your instance: make sure you configure the firewall to enable HTTPS and HTTP traffic. And when it’s successfully created and it gets a dynamic IP assigned, reserve that IP under the Network section of your VM to get a fixed, public IP that you can use to configure the DNS for your domain.

Then, when your instance boots up and you SSH into it, we need to configure a new swapfile that the OS will use as vRAM when the actual RAM is full:

# 1. Allocate 2GB of swap (double your RAM is a safe buffer for bursts)
sudo fallocate -l 2G /swapfile

# 2. Secure the file permissions
sudo chmod 600 /swapfile

# 3. Mark it as swap space
sudo mkswap /swapfile

# 4. Enable it
sudo swapon /swapfile

# 5. Make it permanent (persist after reboot)
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Once that’s done, let’s install docker. It might be installed already depending on the OS version you chose, but on the minimal version of Ubuntu we must run these commands:

sudo apt update
sudo apt install docker.io docker-compose-v2 -y
sudo usermod -aG docker $USER
# Log out and log back in for group changes to take effect

Then, we’ll create a new folder in the Home directory to hold our n8n configuration files:

mkdir ~/n8n-hosting && cd ~/n8n-hosting

Once you’re in it, you’ll want to create a docker compose file:

nano docker-compose.yml

And paste this memory-optimized configuration into your file:

services:
  caddy:
    image: caddy:latest
    restart: unless-stopped
    ports:
      - "443:443"
    volumes:
      - caddy_data:/data
      - caddy_config:/config
      - ./Caddyfile:/etc/caddy/Caddyfile

  n8n:
    image: n8nio/n8n:latest
    restart: unless-stopped
    ports:
      - "127.0.0.1:5678:5678" # Only expose to localhost (Caddy accesses this)
    environment:
      - N8N_HOST=n8n.yourdomain.com # REPLACE THIS
      - WEBHOOK_URL=https://n8n.yourdomain.com # REPLACE THIS
      - GENERIC_TIMEZONE=America/Monterrey # Replace here too with your own time zone

      # MEMORY OPTIMIZATIONS
      - EXECUTIONS_MODE=regular # Runs executions in the main process (saves RAM)
      - N8N_DEFAULT_BINARY_DATA_MODE=filesystem # Don't hold files in RAM
      - EXECUTIONS_DATA_PRUNE=true # Auto-delete old logs
      - EXECUTIONS_DATA_MAX_AGE=72 # Keep logs for 72 hours
      - DB_SQLITE_VACUUM_ON_STARTUP=true # Shrink DB size on boot
    volumes:
      - n8n_data:/home/node/.n8n

volumes:
  caddy_data:
  caddy_config:
  n8n_data:

Caddy is a web server and proxy written in Go, and it’ll help us route requests to and from our n8n server, which is only exposed locally. Caddy is particularly useful because it handles SSL/TLS certificates on its own using Let’s Encrypt.

After you have your docker-compose.yml file ready, we now need to create a simple Caddyfile:

nano ./Caddyfile

And paste this configuration in the new file:

n8n.yourdomain.com {
    reverse_proxy n8n:5678
}

Now, the only thing left to do is running these commands:

docker compose up -d && sudo systemctl enable docker

It might take a while for the server to be available, as Caddy is going to need some minutes to get the certificates ready. But this will only happen the first time that the server boots up.

Now, you probably want to configure your DNS records to point to your VM’s fixed, public IP. And after that’s done, then congrats! You will be able to access your own personal n8n instance completely for free and without a time limit (n8n.io’s free trial only lasts 2 weeks).

This project taught me valuable lessons about infrastructure optimization, cost-effective cloud deployment, and building meaningful automations that actually save me time.