n8n is an open-source workflow automation tool that allows you to connect and automate tasks across multiple applications and services using a drag-and-drop interface. With n8n, you can build workflows such as sending Telegram alerts when new emails arrive, syncing data between Google Sheets and your database, or automating DevOps processes.
Self-hosting n8n on your VPS brings many benefits:
- Full control over your data and security.
- Customized integrations tailored to your needs.
- No dependency on third-party hosted services.
In this guide, we’ll install n8n on a VPS running Ubuntu/Debian, using Docker + Docker Compose, configure a domain, and enable SSL with Nginx + Certbot for secure access.
Prerequisites
Before you begin, make sure you have:
- A VPS server (Ubuntu/Debian) with root or sudo privileges.
- Docker and Docker Compose are installed.
If not yet installed, check out our Docker installation guide: How to Install Docker and Portainer on Linux Ubuntu/Debian - Portainer (optional but recommended) for easier container management.
- A domain or subdomain already pointed to your VPS public IP address.
- Opened firewall ports: 5678, 80, 443.
Step 1: Check Your VPS Public IP
Run the following command to get your VPS public IP and copy it for later configuration:
curl ifconfig.me
Step 2: Create Directory for n8n Config
Create a working folder to store configuration and persistent data:
mkdir ~/n8n cd ~/n8n
Inside this directory, you will store:
- .env file with environment variables.
- docker-compose.yml file to define services.
Step 3: Configure the .env File
Create and open the file:
sudo vim .env
Example content:
# Database settings
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=postgres
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8ndb
DB_POSTGRESDB_USER=n8ndb_user
DB_POSTGRESDB_PASSWORD=n8ndb_user_PWD
# N8N Host & Port
N8N_HOST=IP-SERVER
N8N_PORT=5678
N8N_PROTOCOL=http
#WEBHOOK_URL=https://Your-Domain/
N8N_SECURE_COOKIE=false
# For saving data persistently
N8N_PERSONALIZATION_ENABLED=false
Why use .env?
It helps you manage sensitive data (like passwords) separately from the Docker Compose file, making configuration cleaner and easier to update.
Step 4: Configure docker-compose.yml
Create the file:
sudo vim docker-compose.yml
Example configuration:
version: '3.7'
services:
postgres:
container_name: n8n-postgres
image: postgres:13
restart: always
environment:
POSTGRES_USER: ${DB_POSTGRESDB_USER}
POSTGRES_PASSWORD: ${DB_POSTGRESDB_PASSWORD}
POSTGRES_DB: ${DB_POSTGRESDB_DATABASE}
volumes:
- postgres-data:/var/lib/postgresql/data
n8n:
container_name: n8n-server
image: n8nio/n8n
restart: always
ports:
- "5678:5678"
environment:
- DB_TYPE=${DB_TYPE}
- DB_POSTGRESDB_HOST=${DB_POSTGRESDB_HOST}
- DB_POSTGRESDB_PORT=${DB_POSTGRESDB_PORT}
- DB_POSTGRESDB_DATABASE=${DB_POSTGRESDB_DATABASE}
- DB_POSTGRESDB_USER=${DB_POSTGRESDB_USER}
- DB_POSTGRESDB_PASSWORD=${DB_POSTGRESDB_PASSWORD}
- N8N_BASIC_AUTH_ACTIVE=${N8N_BASIC_AUTH_ACTIVE}
- N8N_BASIC_AUTH_USER=${N8N_BASIC_AUTH_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD}
- N8N_HOST=${N8N_HOST}
- N8N_PORT=${N8N_PORT}
- N8N_PROTOCOL=${N8N_PROTOCOL}
- N8N_SECURE_COOKIE=${N8N_SECURE_COOKIE}
- N8N_PERSONALIZATION_ENABLED=${N8N_PERSONALIZATION_ENABLED}
#- WEBHOOK_URL=http://${N8N_HOST}:${N8N_PORT}
volumes:
- n8n-data:/home/node/.n8n
depends_on:
- postgres
volumes:
postgres-data:
n8n-data:
The n8n_data
folder ensures persistent storage even if the container is removed.
Step 5: Start n8n
Launch n8n in the background:
sudo docker-compose up -d
Check running containers:
sudo docker ps
You can also manage containers visually with Portainer.
Step 6: Open Firewall Port (if needed)
If you’re using UFW, allow the n8n port:
sudo ufw allow 22
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 5678
You can skip this step if you do not intend to use a firewall.
Step 7: Access n8n for the First Time
Open your browser and go to:
http://your-vps-ip:5678
On first access, you’ll be prompted to create an admin account. Once done, you’ll land on the n8n dashboard.
Step 8: Configure Domain and SSL with Nginx
To secure access and enable integrations, let’s use domain + HTTPS.
Update .env:
- Change N8N_HOST from IP to Your-domain.
- Change N8N_PROTOCOL to https.
- Uncomment and set WEBHOOK_URL to your domain (e.g., https://n8n.example.com/).
- Change N8N_SECURE_COOKIE to true
After completing the steps, your configuration file will look similar to this.
# Database settings
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=postgres
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8ndb
DB_POSTGRESDB_USER=n8ndb_user
DB_POSTGRESDB_PASSWORD=n8ndb_user_PWD
# N8N Host & Port
N8N_HOST=Your-Domain
N8N_PORT=5678
N8N_PROTOCOL=https
WEBHOOK_URL=https://Your-Domain/
N8N_SECURE_COOKIE=true
# For saving data persistently
N8N_PERSONALIZATION_ENABLED=false
Update .env:
Uncomment and set WEBHOOK_URL to your domain
... ... ...
- N8N_SECURE_COOKIE=${N8N_SECURE_COOKIE}
- N8N_PERSONALIZATION_ENABLED=${N8N_PERSONALIZATION_ENABLED}
- WEBHOOK_URL=http://${N8N_HOST}:${N8N_PORT}
volumes:
- n8n-data:/home/node/.n8n
depends_on:
- postgres
... ... ...
Install Nginx and Certbot:
sudo apt update
sudo apt install nginx certbot python3-certbot-nginx -y
Create Nginx config:
sudo vim /etc/nginx/sites-available/n8n.conf
Example configuration:
server {
listen 80;
server_name Your-Domain;
location / {
proxy_pass http://localhost:5678;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Enable config:
sudo ln -s /etc/nginx/sites-available/n8n.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Issue SSL certificate with Certbot:
sudo certbot --nginx -d n8n.example.com
If successful, you’ll see confirmation that SSL certificates were issued.
Step 9: Access n8n via HTTPS
Now visit your domain over HTTPS:
https://n8n.example.com
The connection is secure with SSL, and you can start building workflows safely.
Conclusion
- Installed n8n with Docker on Ubuntu/Debian.
- Configured a custom domain for n8n.
- Enabled SSL with Nginx and Certbot.
With this setup, you can confidently deploy automation workflows in a secure and professional environment.