Yes, running multiple Docker containers alongside n8n on KVM 2 works fine, and it's what most people self-hosting n8n end up doing. Hostinger's KVM 2 plan gives you 2 vCPU cores, 8 GB of RAM, 100 GB of NVMe storage and 8 TB of monthly bandwidth, and n8n itself sits at a few hundred megabytes of RAM when it's idle. That leaves plenty of headroom for the usual supporting cast: PostgreSQL, Redis, a reverse proxy, Portainer, maybe Uptime Kuma and a self-hosted database tool.
The real limit isn't RAM, it's those 2 CPU cores, so the number that matters is how many containers are actually busy at the same time rather than how many exist. Set memory limits per container, keep local AI models off the box, and a KVM 2 will happily run a stack of eight to ten light services with n8n in the middle of it.
KVM 2 hands you 8 GB of RAM and 2 vCPU, which is a comfortable middle ground for a container stack
Here's what you're working with on Hostinger's second VPS tier, and how it stacks up against the plans either side of it:
| Plan | vCPU | RAM | NVMe storage | Bandwidth |
|---|---|---|---|---|
| KVM 1 | 1 | 4 GB | 50 GB | 4 TB |
| KVM 2 | 2 | 8 GB | 100 GB | 8 TB |
| KVM 4 | 4 | 16 GB | 200 GB | 16 TB |
| KVM 8 | 8 | 32 GB | 400 GB | 32 TB |
Allocations do get adjusted from time to time, so confirm the current numbers on the VPS plan page before you buy.
KVM 1 runs n8n on its own without complaint. Add Postgres, a proxy and two or three side services and 4 GB starts feeling tight fast, especially the moment a workflow pulls a large API response into memory. KVM 2 is the first tier where you stop doing arithmetic every time you want to add a container.
The 100 GB of NVMe matters more than people expect. Docker images pile up quietly. A Postgres image, an n8n image, a proxy, Portainer, plus a few pulled-and-abandoned tags, and you can burn 15 GB before you've stored a single workflow execution.
Add n8n's execution history and binary data on top of that. Storage discipline is the same story as picking sensible upload limits on shared hosting: the ceiling is generous until you ignore it.
If you're still on shared hosting and wondering whether any of this applies to you, it doesn't. Docker needs root and a real kernel, which shared plans don't give you. Our notes on when a shared plan stops being enough cover that jump in more detail.
n8n's own footprint is small, but your workflows decide the real number
An idle n8n container typically sits somewhere in the 200 to 400 MB range. That's the boring part. What moves the needle is what your nodes do.
Three things push n8n's memory and CPU use up hard:
Big payloads in memory. n8n holds item data between nodes. Pull 50,000 rows from an API and map them through a Code node, and that whole set lives in RAM during the run. A single greedy workflow can chew through a gigabyte or two.
Binary data. PDFs, images, CSV exports. By default this goes through memory. Setting N8N_DEFAULT_BINARY_DATA_MODE=filesystem writes it to disk instead, which trades a bit of I/O for a much calmer RAM graph.
On a 2-core box that trade is worth making.
Browser-based nodes and anything Chromium-shaped. Puppeteer-style community nodes spawn a headless browser per run. That's the single fastest way to saturate both cores at once. If your automations depend on scraping, plan for it deliberately rather than discovering it during an outage.
Note: n8n's default SQLite database is fine for testing and genuinely poor for a production stack. The official n8n documentation recommends PostgreSQL for anything you rely on, and switching later means exporting and re-importing credentials and workflows. Start with Postgres and skip the migration.
Concurrency is the other lever. n8n runs workflow executions in the main process unless you enable queue mode, which adds Redis and one or more worker containers. Queue mode is the right answer for heavy parallel loads, but each worker is another process fighting for those two cores. On KVM 2 I'd cap it at two workers and watch the load average before adding a third.
How many containers can you realistically run alongside n8n on KVM 2?
Between eight and twelve light containers, in practice. RAM runs out later than CPU does, so let me split those two.
Rough planning figures for idle containers on a fresh install (yours will differ by image version and config, so treat these as ballpark, not spec):
| Container | Typical idle RAM | CPU appetite |
|---|---|---|
| n8n | 200–400 MB | Spiky, follows your workflows |
| PostgreSQL 16 | 100–200 MB | Low until queries get ugly |
| Redis | 20–50 MB | Very low |
| Caddy or Traefik | 30–80 MB | Very low |
| Nginx Proxy Manager | 100–150 MB | Very low |
| Portainer | 50–100 MB | Negligible |
| Uptime Kuma | 100–200 MB | Low, periodic |
| NocoDB or Baserow | 300–600 MB | Moderate |
| n8n worker (queue mode) | 200–400 MB each | Spiky |
Add that up and a full stack lands somewhere around 1.5 to 2.5 GB at rest. On 8 GB, that's a lot of slack, which is exactly the point: the slack absorbs your workflow spikes.
Two cores is where you have to be honest. Two containers doing real work at the same moment will already have them both busy. Three is contention.
So the question worth asking isn't "how many containers," it's "how many of these will ever run flat out simultaneously?" A proxy, a database and a monitoring dashboard are almost always idle. Two n8n workers running Chromium are not.
What you shouldn't try to squeeze on here
Local large language models. Running Ollama with a 7B model alongside n8n on KVM 2 is going to disappoint you. Those models want serious RAM and ideally a GPU, and CPU inference on two cores is slow enough to time out your workflow nodes.
Call a hosted API from n8n instead, or move the model to its own bigger box.
Same caution for Elasticsearch, a full Supabase stack, or anything that assumes it owns the machine. Those aren't KVM 2 workloads.
Setting it up: Docker, one compose file, and everything behind a reverse proxy
Time: 45 to 90 minutes for a first-timer. Difficulty: intermediate. You need basic SSH comfort and a domain or subdomain you control.
Choose your OS template in hPanel. Hostinger's VPS templates include Ubuntu with Docker preinstalled, plus a one-click n8n template if you'd rather not touch a compose file at all. For a multi-container stack, take plain Ubuntu with Docker and build the stack yourself. You'll want that control later.
SSH in and update everything. Run
apt update && apt upgrade -y. Reboot if the kernel updated. Do this before you install anything else, not after.Confirm Docker and Compose are there.
docker --versionanddocker compose version. If Compose is missing, install the plugin from Docker's official documentation rather than grabbing an old standalonedocker-composebinary. The v2 plugin syntax isdocker compose, no hyphen.Create a swap file. On an 8 GB box, 2 GB of swap is cheap insurance against an OOM kill during a bad workflow run.
fallocate -l 2G /swapfile, thenchmod 600,mkswap,swapon, and add the line to/etc/fstabso it survives a reboot. Warning: swap is a safety net, not extra RAM. If your stack lives in swap, performance will crater and you need a bigger plan.Point a subdomain at the VPS IP. Create an A record like
n8n.yourdomain.compointing to the server's IPv4 address. Timing note: this usually resolves within a few minutes, but DNS can take a couple of hours to settle worldwide. Do it now so it's ready when you start the proxy.Make a project directory and an
.envfile. Something like/opt/stack. Inside.env, setSUBDOMAIN,POSTGRES_PASSWORD, andN8N_ENCRYPTION_KEY(a long random string). Warning: back up that encryption key somewhere outside the server. Lose it and every stored credential in n8n becomes unreadable.Write the compose file. This is the core of the whole thing:
services:
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
mem_limit: 256m
n8n:
image: docker.n8n.io/n8nio/n8n
restart: unless-stopped
environment:
- N8N_HOST=${SUBDOMAIN}
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://${SUBDOMAIN}/
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- GENERIC_TIMEZONE=America/New_York
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
- N8N_DEFAULT_BINARY_DATA_MODE=filesystem
volumes:
- n8n_data:/home/node/.n8n
depends_on:
postgres:
condition: service_healthy
mem_limit: 2g
postgres:
image: postgres:16
restart: unless-stopped
environment:
- POSTGRES_DB=n8n
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- pg_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n"]
interval: 10s
retries: 5
mem_limit: 1g
volumes:
n8n_data:
pg_data:
caddy_data:
- Write the Caddyfile. Three lines in the same folder:
n8n.yourdomain.com {
reverse_proxy n8n:5678
}
Caddy requests and renews a Let's Encrypt certificate on its own, as long as ports 80 and 443 reach it and DNS already resolves.
Start the stack.
docker compose up -d. First run pulls a few hundred megabytes of images, so give it a minute or two on a fresh box.Watch the logs before you celebrate.
docker compose logs -f caddyshows the certificate being issued.docker compose logs -f n8nshows the database connection and the editor coming up. Then openhttps://n8n.yourdomain.comand create the owner account.Lock down the firewall. Allow 22, 80 and 443 with
ufw, and nothing else. Notice that n8n's port 5678 is never published to the host in that compose file. Containers on the same Docker network reach each other by service name, so the proxy talks ton8n:5678internally while the outside world can't. That single detail prevents the most common self-hosted n8n mistake: an unauthenticated editor sitting wide open on a public IP.Add your next container to the same file. Uptime Kuma, Portainer, NocoDB, whatever you need. Give each one a
mem_limit, arestart: unless-stopped, and a block in the Caddyfile if it needs a public URL. Thendocker compose up -dagain. Compose only touches what changed.
Note: if you use Hostinger's one-click n8n template instead of this, it installs its own Docker setup. Bolting a hand-written compose stack on top of that can create port conflicts on 80 and 443. Pick one approach per server.
Should you use Portainer, Coolify or plain Compose?
Plain Compose is the least fragile option and the easiest to move to another host, because your entire stack is one text file you can commit to Git. Portainer sits on top of it and gives you a web UI for logs, stats and restarts, which is genuinely handy at 2 a.m. on your phone. Coolify and CapRover go further and manage deployments for you, at the cost of a few hundred megabytes of overhead and another moving part.
On KVM 2, I'd run Compose as the source of truth and add Portainer purely for visibility.
Memory limits are what stop one bad workflow from killing the whole server
Without limits, Docker lets any container use all available RAM. So a runaway n8n execution can starve Postgres, Postgres gets OOM-killed, and now your automation platform has no database. I've watched it happen.
Setting mem_limit per service caps the damage. If n8n hits its 2 GB ceiling, that container dies and restarts, while Postgres and the proxy carry on. One service down beats the whole box down.
Restart policies matter alongside that. restart: unless-stopped brings containers back after a crash or a reboot without fighting you when you deliberately stop something. Add healthchecks to anything other services depend on, and use depends_on with condition: service_healthy so n8n doesn't start hammering a Postgres that isn't accepting connections yet.
For CPU, Compose supports cpus: "1.5" to stop a single container monopolising both cores. I'd only reach for this if you have one known-greedy service. On a two-core box, over-restricting CPU tends to cause more timeouts than it prevents.
Keep an eye on things with docker stats, which shows live per-container CPU and memory. Run it after a typical busy hour, not right after boot. Boot-time numbers tell you nothing about your actual load.
Backups matter more than uptime once your credentials live in n8n
Three things need protecting: the Postgres data, the n8n volume at /home/node/.n8n, and your encryption key.
A pg_dump from inside the Postgres container, written to a dated file and pushed off-server, covers the database. The n8n volume holds the encryption key file and binary data on filesystem mode. Copy both nightly with a cron job and you can rebuild the whole stack from a fresh VPS in under an hour.
Hostinger's VPS plans also include automatic backups plus manual snapshots you can trigger from hPanel before a risky change. A snapshot taken before you upgrade the n8n image has saved me more than once. Check the current schedule on the plan page, since how long automatic copies are kept varies by plan level, and a server-level snapshot is not a substitute for a database dump you can restore selectively.
While you're setting up domains for each container, the way additional hostnames get pointed is worth understanding, because most people end up running four or five subdomains off one VPS. Caddy and Traefik both handle certificates automatically, so you rarely need to buy anything, though it's still worth knowing where paid certificates fit if a client insists on one.
One more habit that pays off: write down what's running and why. Even a plain README next to your compose file, in whichever format you keep your notes in, beats trying to remember six months later what that fourth container was for.
Things people get wrong about running Docker containers alongside n8n on KVM 2
Mix-up: More containers means more RAM used, so 8 GB is the constraint to plan around.
Reality: Idle containers cost very little. Two vCPU cores are the tighter constraint, and CPU contention shows up as slow, timing-out workflows rather than a clean out-of-memory error, which makes it harder to diagnose.
Mix-up: n8n needs its own server, separate from anything else.
Reality: n8n is a normal Node application in a container. It coexists fine with databases, dashboards and small web apps. What it doesn't coexist well with is anything that wants sustained full CPU, like video encoding or local AI inference.
Mix-up: If the editor loads at your domain, webhooks will work.
Reality: Webhooks use the WEBHOOK_URL value, not the address in your browser. Get it wrong and n8n hands external services a URL they can't reach, so Stripe, GitHub and Telegram triggers silently fail while manual test runs work perfectly.
Mix-up: Publishing port 5678 to the host is needed for the proxy to reach n8n.
Reality: Containers on a shared Docker network reach each other by service name. Publishing 5678 to the host exposes the editor directly to the internet and bypasses your proxy's protections.
When things break, it's usually one of these four
Problem: A container keeps restarting and the logs cut off mid-startup with exit code 137.
Fix: That's an out-of-memory kill. Raise that service's mem_limit, or lower another container's, and check free -h to see whether the host itself is out of headroom.
Problem: Caddy or Traefik can't issue a certificate.
Fix: Nine times out of ten, DNS isn't resolving yet or something else already holds port 80. Run ss -tulpn | grep :80 to find the squatter, usually a stray Apache or Nginx from an OS template, and stop it.
Problem: Webhook triggers return 404 to the calling service.
Fix: Confirm WEBHOOK_URL uses your full public HTTPS address with a trailing slash, then recreate the container. Environment variable changes need docker compose up -d, not a plain restart.
Problem: docker compose up fails with a permission error on a bind-mounted folder.
Fix: The n8n image runs as the node user, not root. Named volumes avoid this entirely, which is why the example above uses n8n_data instead of a host path.
What this means for your setup, and what to do next
If you're weighing KVM 1 against KVM 2 for a container stack, the deciding question is whether n8n will be the only thing on the box. Alone, with SQLite, KVM 1 is enough. The moment you add Postgres, a proxy and a second app, KVM 2's extra core and 4 GB stop you from rebuilding the whole thing three months later.
Migrating a live n8n instance is a chore nobody enjoys.
Go up to KVM 4 if any of these apply: you need queue mode with two or more workers, your workflows regularly move large files, or you're hosting client automations where a slow run costs money. Sixteen gigabytes and four cores gives you room to be careless, which is worth paying for once real work depends on it.
Whatever tier you land on, build the stack with named volumes, per-container memory limits and a compose file you keep in version control. That's what turns a rebuild into a twenty-minute job instead of a lost weekend.
If you're ready to spin one up, Hostinger's KVM 2 VPS is the plan this whole guide is built around, and the code hHostCouponHub applies the current site discount at checkout. Longer terms carry the deepest advertised savings, so check the price on the plan page before you pick a billing cycle.
Frequently asked questions
Is KVM 2 enough to run n8n in queue mode with Redis?
Yes, with one or two workers. Redis is light, and each worker adds a few hundred megabytes of RAM. The limit is CPU: two workers running simultaneously on 2 vCPU will contend, so move to KVM 4 if you need three or more.
How much RAM does self-hosted n8n use in Docker?
Roughly 200 to 400 MB idle, and considerably more during execution depending on your data volume. Workflows handling tens of thousands of items or large binary files can spike past 1 GB, which is why a 2 GB mem_limit on the n8n container is a sensible starting cap.
Can I run other websites on the same VPS as n8n?
Yes. Add them as containers on the same Docker network and route each to its own subdomain in your reverse proxy config. WordPress with its own MySQL container fits comfortably next to n8n on 8 GB, though a busy WordPress site and heavy automations will compete for those two cores.
Should I use Hostinger's one-click n8n template or install Docker myself?
Use the template if you want n8n running in a few minutes and nothing else on the server. Install Docker yourself if you plan on running multiple Docker containers alongside n8n on KVM 2, because a hand-written compose file gives you control over networks, volumes and resource limits that the template setup doesn't expose.
Get the VPS first, then build the stack one container at a time and check docker stats after each addition. That's the whole method. When you're ready, grab KVM 2 with the coupon applied and you can have n8n answering webhooks on your own domain the same afternoon.
This page contains affiliate links. If you purchase through the links on this page, we may earn a commission, at no extra cost to you.




