n8n is a powerful automation tool that lets you connect various services and build automated workflows without writing code. It supports over 300 integrations and makes it easy to create data processing pipelines, send notifications, integrate with APIs, and much more.
If you want full control over your n8n setup, the best option is to self-host it on your own server. This guide walks you through installing n8n on a VPS using Docker.
Requirements
Before you begin, make sure you have:
- A VPS running Linux (e.g. Ubuntu 22.04)
- A user with sudo privileges
- At least 1 GB of RAM (2 GB recommended)
We'll install Docker and Docker Compose in the next section.
Step 1. Install Docker and Docker Compose
Connect to your server via SSH and run the following commands:
# 1. Update the package index
sudo apt update
# 2. Install required dependencies
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
# 3. Add the Docker GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o
/usr/share/keyrings/docker-archive-keyring.gpg
# 4. Add the Docker repository
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 5. Update the package index again
sudo apt update
# 6. Install Docker Engine
sudo apt install -y docker-ce docker-ce-cli containerd.io
# 7. Install Docker Compose V2 (as a plugin)
sudo apt install -y docker-compose-plugin
Verify that everything is installed correctly:
docker --version
docker compose version To run Docker commands without sudo, add your user to the Docker group:
sudo usermod -aG docker $USER ⚠️ You'll need to log out and back into your SSH session (or reboot the server) for this change to take effect.
Step 2. Launch n8n — Choose Your Method
There are two ways to run n8n. Pick one — you don't need to run both.
Option A. Manual launch with docker run (quick start / testing)
Use this if you want to get n8n up and running quickly without extra configuration.
Create a volume to store n8n data:
docker volume create n8n_data Start n8n:
docker run -it --rm --name n8n -p 5678:5678 -v n8n_data:/home/node/.n8n docker.n8n.io/n8nio/n8n
```
n8n will be available at:
```
http://<YOUR_VPS_IP>:5678 ⚠️ The --rm flag means the container will be removed after it stops. Your data will remain in the n8n_data volume, but for production use we recommend Option B.
Option B. Launch with Docker Compose (recommended)
This method is better suited for long-term use: n8n will automatically restart after server reboots, and all configuration lives in a single file.
Create a docker-compose.yml file:
nano docker-compose.yml Paste the following content:
services:
n8n:
image: docker.n8n.io/n8nio/n8n
restart: always
ports:
- "5678:5678"
environment:
- GENERIC_TIMEZONE=Europe/London
- N8N_SECURE_COOKIE=false
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data: Press Ctrl + O, then Enter (to save) and Ctrl + X (to exit).
Start n8n:
docker compose up -d
```
n8n will be available at:
```
http://<YOUR_VPS_IP>:5678 To stop n8n:
docker compose down Step 3. [Optional] Connect PostgreSQL
By default, n8n stores data in a built-in SQLite database. This is fine for testing, but not suitable for production: SQLite struggles under high load and doesn't support concurrent access.
For reliable and scalable operation, we recommend using PostgreSQL.
Start PostgreSQL in Docker:
docker run --name postgres \
-e POSTGRES_USER=n8n_user \
-e POSTGRES_PASSWORD=supersecret \
-e POSTGRES_DB=n8n \
-p 5432:5432 \
-d postgres Where:
n8n_user— database username (choose your own)supersecret— user password (use a strong one)n8n— database name
Then connect PostgreSQL to n8n by adding the environment variables. If you're using Docker Compose, add them to the environment section:
environment:
- GENERIC_TIMEZONE=Europe/London
- N8N_SECURE_COOKIE=false
- DB_TYPE=postgresdb
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_HOST=localhost
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_USER=n8n_user
- DB_POSTGRESDB_PASSWORD=supersecret If you're using the manual launch (docker run), pass the same variables using -e flags:
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-e DB_TYPE=postgresdb \
-e DB_POSTGRESDB_DATABASE=n8n \
-e DB_POSTGRESDB_HOST=localhost \
-e DB_POSTGRESDB_PORT=5432 \
-e DB_POSTGRESDB_USER=n8n_user \
-e DB_POSTGRESDB_PASSWORD=supersecret \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n ⚠️ Make sure PostgreSQL is reachable from the n8n container. If the database is on a different server, specify its IP in DB_POSTGRESDB_HOST and configure your firewall accordingly.
Updating n8n
Applies only when using Docker Compose (Option B):
# 1. Pull the latest images
docker compose pull
# 2. Stop the current containers
docker compose down
# 3. Start again
docker compose up -d Tunnel Mode (for testing)
Tunnel mode temporarily exposes your server to the internet via a secure tunnel — useful when you want to test incoming webhooks (e.g. from Telegram or Stripe) but don't yet have a domain or HTTPS set up.
Example: you're building an automation that responds to incoming Telegram messages. Telegram can't reach your server without a public address. In this case, run n8n in tunnel mode, get a temporary HTTPS URL, and use it in your Telegram settings.
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n \
start --tunnel ⚠️ Tunnel mode is for testing and debugging only. Do not use it in production.
Conclusion
You now know how to install and run n8n on a VPS using Docker — quickly, flexibly, and with minimal effort. You can use built-in triggers, connect Telegram, Google Sheets, Slack, and hundreds of other services to build powerful automations without writing a single line of code.
Server Solution Ready for n8n
Want to launch n8n without the hassle? We offer reliable VPS and dedicated servers optimised for n8n, round-the-clock technical support, and transparent pricing.
Get in touch — and start automating your workflows with n8n today!
Comments