How to Install n8n on a Google Cloud VM Using Docker (Step-by-Step)
- Xuebin Wei
- 15 hours ago
- 5 min read
n8n has become a highly sought-after tool because it makes complex automation accessible. It provides a visual interface for connecting APIs, services, and AI tools while still allowing custom code and advanced workflow logic.
In this tutorial, we will show you how to install n8n Docker Google Cloud environments on a Virtual Machine (VM) where our OpenClaw agent is already running. Rather than a simplified, temporary installation, we will use the official Docker deployment route to ensure a secure, structured, and scalable long-term environment.
The Deployment Architecture
Before jumping into the command line, it helps to visualize the infrastructure. We are establishing n8n as a containerized service alongside our existing applications.

Using Docker keeps the setup clean. It runs n8n in its own isolated container, making it easy to manage, update, and back up without interfering with the rest of the VM.
Step 1: Installing Docker (The Official Route)
To establish a long-term infrastructure, we will add the official Docker repository to our VM's package manager (apt).
First, update your local package list and install the necessary tools to handle secure downloads:
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-releaseNext, create a directory for the security keys and download Docker's official GPG key. This key allows your system to verify that the software packages are legitimately from Docker:
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpgNow, map the official Docker repository to your VM's sources:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(. /etc/os-release && echo $VERSION_CODENAME) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/nullFinally, update the package list again so your system recognizes the new repository, and install the Docker Engine alongside the Compose plugin:
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginVerify the installation by checking the versions:
docker --version
docker compose versionStep 2: How to install n8n Docker Google Cloud containers
With Docker installed, we can configure our n8n instance. We need two main directories: one for the deployment blueprint (n8n-compose) and one to persist our workflow data (.n8n).
Containers are temporary; if they restart or are updated, unsaved data inside them is wiped. Mapping a volume to the .n8n folder ensures your workflows are safely and permanently stored on the VM's hard drive.
Create the directories in your user folder:
mkdir ~/n8n-compose ~/.n8n
cd ~/n8n-composeCreate a .env file to securely store your security settings and passwords.
nano .envPaste the following configuration (replace the timezone and password as needed):
N8N_HOST=localhost
N8N_PORT=5678
N8N_PROTOCOL=http
GENERIC_TIMEZONE=America/New_York
TZ=America/New_York
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=YourStrongPasswordHere
N8N_SECURE_COOKIE=false
Security Check: Restrict access to this file so only the file owner can read it:
chmod 600 .envNext, create the compose.yaml blueprint:
nano compose.yamlPaste the following Docker Compose configuration. Notice how we map the persistent data volume to ~/.n8n:
services:
n8n:
image: docker.n8n.io/n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
ports:
- "5678:5678"
env_file:
- .env
volumes:
- ~/.n8n:/home/node/.n8n
Start the container in detached mode (so it runs continuously in the background):
docker compose up -d
Step 3: Secure Access via VS Code Port Forwarding
Google Cloud firewalls block outside access to port 5678 by default. Instead of opening your firewall to the entire internet, we use VS Code Remote-SSH to create a secure, encrypted tunnel from your local laptop directly to the VM.

In VS Code, open the PORTS tab at the bottom panel.
Click Forward a Port and enter 5678.
Open a browser on your local computer and navigate to http://localhost:5678.
Once you access the interface, follow the on-screen prompts to set up your n8n owner account.
(Note: For a more persistent private connection independent of VS Code, you can also configure a Tailscale Serve route using sudo tailscale serve --bg --https 8444 http://127.0.0.1:5678)
Step 4: Building a Demo Workflow (Census Data Analysis)
To see n8n in action, let's build a workflow that fetches population data from the US Census API, processes it with a custom JavaScript snippet, and visualizes the top 10 Virginia counties in a bar chart.

1. HTTP Request Node
Add an HTTP Request node to your canvas. Set the method to GET and paste this Census API URL into the URL field:
https://api.census.gov/data/2023/acs/acs5? get=NAME,B01003_001E&for=county:*&in=state:51
2. Code Node (JavaScript Analysis)
Connect a Code node. Set the language to JavaScript. This code takes the raw array data from the Census, extracts the county names and population numbers, sorts them in descending order, and prepares the labels and values for our chart.
Paste the following logic:
const rows = items.map(item => {
const value = item.json;
return Array.isArray(value) ? value : Object.values(value);
});
if (!rows || rows.length < 2) {
return [{ json: { error: 'No valid population values found', rawPreview: rows[0] || null } }];
}
const headers = rows[0];
const dataRows = rows.slice(1);
const results = dataRows.map(row => {
const obj = {};
headers.forEach((h, i) => { obj[h] = row[i]; });
return {
county: obj.NAME,
population: Number(obj.B01003_001E),
state_fips: obj.state,
county_fips: obj.county
};
}).filter(r => Number.isFinite(r.population));
const sortedDesc = [...results].sort((a, b) => b.population - a.population);
const top10 = sortedDesc.slice(0, 10);
const labels = top10.map(r => r.county.replace(', Virginia', ''));
const values = top10.map(r => r.population);
return [{ json: { labels, values, chartTitle: 'Top 10 Virginia Counties by Population' } }];

3. QuickChart Node
Finally, add a QuickChart node to generate the visualization based on our parsed data:
Chart Type: Bar Chart
Add Labels: From Array
Labels Array: ={{$json.labels}}
Data: ={{$json.values}}

Run the workflow, and you will see your generated chart displaying the data perfectly.
Conclusion
By deploying n8n via Docker on our Google Cloud VM, we now have a robust, scalable automation platform running safely behind our firewall. We successfully navigated the official installation path, secured our credentials, persisted our data with Docker volumes, and built a practical data analysis workflow.
In future tutorials here at LBSocial, we will expand on this infrastructure, integrating n8n directly with our OpenClaw agents to create fully autonomous, AI-driven workflows.