Chạy nhiều instance n8n trên cùng VPS với Docker và subdomain riêng

Bạn có một VPS và muốn chạy nhiều instance n8n riêng biệt cho từng dự án, một cho khách hàng, một cho team nội bộ, một cho thử nghiệm? Chạy nhiều instance n8n trên cùng một VPS bằng Docker và subdomain riêng là giải pháp không cần thêm VPS nhưng vẫn đảm bảo cô lập từng môi trường.
- Kiến trúc: Mỗi instance n8n là một stack Docker Compose riêng, có database PostgreSQL, volume dữ liệu và credential riêng, expose trên một cổng nội bộ, sau đó Nginx reverse proxy với subdomain riêng.
- Bảo mật: Webhook chỉ hoạt động trên subdomain cụ thể. Có thể giới hạn IP qua Nginx.
- Không xung đột: Port, volume, network đều tách bạch.
Yêu cầu trước khi bắt đầu
- Một VPS chạy Ubuntu 24.04 LTS hoặc Debian 12, có quyền sudo root. Nếu bạn chưa có, có thể tham khảo dịch vụ thuê VPS Linux tại thueVPS với NVMe, full root và IPv4 Việt Nam.
- Docker Engine và Docker Compose v2 đã cài đặt. (xem bài cách cài Docker trên VPS Ubuntu chi tiết từ A đến Z)
- Nginx đã cài và hoạt động làm reverse proxy. (xem bài cấu hình Nginx làm reverse proxy trên Ubuntu 24.04)
- Domain trỏ về IP VPS (A record). Ví dụ:
team1.n8n.example.com,team2.n8n.example.com. - SSL certificate (dùng Certbot cho Let's Encrypt).
Vì sao nên chạy nhiều instance n8n trên cùng VPS?
Thay vì thuê thêm VPS cho từng dự án nhỏ, bạn có thể tận dụng tài nguyên còn trống trên một VPS đủ mạnh. Mỗi instance có database PostgreSQL riêng, file .env riêng, mật mã credential riêng, không sợ workflow của instance này ảnh hưởng instance kia. Điều này phù hợp cho agency, freelancer, hoặc sysadmin muốn tách staging, production, sandbox trên 1 máy.
Bước 1 - Chuẩn bị cấu trúc thư mục
Tạo thư mục gốc chứa tất cả instance, mỗi instance một thư mục con:
mkdir -p /opt/n8n-instances/team1 /opt/n8n-instances/team2
cd /opt/n8n-instances/team1
Bước 2 - Tạo file docker-compose.yml cho instance đầu tiên
Đây là template chuẩn dùng PostgreSQL làm database và lưu credential ở thư mục cục bộ. Mỗi instance dùng một cổng nội bộ khác nhau (ví dụ: team1 dùng 5678, team2 dùng 5680).
cat <<EOF > /opt/n8n-instances/team1/docker-compose.yml
version: '3.8'
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: n8n
POSTGRES_PASSWORD: <CHANGE_ME_TEAM1_DB_PASS>
POSTGRES_DB: n8n
volumes:
- ./postgres-data:/var/lib/postgresql/data
networks:
- n8n-net
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
ports:
- "127.0.0.1:5678:5678"
environment:
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_USER: n8n
DB_POSTGRESDB_PASSWORD: <CHANGE_ME_TEAM1_DB_PASS>
DB_POSTGRESDB_DATABASE: n8n
N8N_HOST: team1.n8n.example.com
N8N_PORT: 5678
N8N_PROTOCOL: https
WEBHOOK_URL: https://team1.n8n.example.com
N8N_ENCRYPTION_KEY: <CHANGE_ME_TEAM1_ENCRYPT_KEY>
N8N_METRICS: false
volumes:
- ./n8n-data:/home/node/.n8n
depends_on:
- postgres
networks:
- n8n-net
networks:
n8n-net:
driver: bridge
EOF
Giải thích:
127.0.0.1:5678:5678, Chỉ bind trên localhost, không expose ra internet. Nginx sẽ proxy qua port này.N8N_HOSTvàWEBHOOK_URL, Đặt đúng subdomain của instance đó.N8N_ENCRYPTION_KEY, Dùngopenssl rand -hex 32để sinh key riêng cho mỗi instance. Key này cực kỳ quan trọng, nếu mất, bạn không đọc được credential đã lưu.POSTGRES_PASSWORD, Mật khẩu database riêng, không dùng chung giữa các instance.
Bước 3 - Tạo instance thứ hai (team2)
Sao chép và chỉnh sửa các giá trị cho khác biệt:
mkdir -p /opt/n8n-instances/team2
cd /opt/n8n-instances/team2
# Tạo file docker-compose.yml tương tự nhưng sửa:
# - port: 127.0.0.1:5680:5678
# - N8N_HOST: team2.n8n.example.com
# - WEBHOOK_URL: https://team2.n8n.example.com
# - POSTGRES_PASSWORD: khác team1
# - N8N_ENCRYPTION_KEY: khác team1
Lặp lại bước này cho mỗi instance bạn cần. Đặt tên thư mục theo subdomain tương ứng để dễ quản lý.
Bước 4 - Khởi chạy các instance
Vào từng thư mục và chạy:
docker compose up -d
Kiểm tra trạng thái:
docker compose ps
Bạn sẽ thấy mỗi stack (team1, team2) có 2 container: postgres và n8n.
Bước 5 - Cấu hình Nginx reverse proxy cho từng subdomain
Tạo file cấu hình Nginx cho mỗi instance. Ví dụ cho team1:
cat <<EOF > /etc/nginx/sites-available/team1.n8n.example.com
server {
listen 80;
server_name team1.n8n.example.com;
return 301 https://\$server_name\$request_uri;
}
server {
listen 443 ssl http2;
server_name team1.n8n.example.com;
ssl_certificate /etc/letsencrypt/live/team1.n8n.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/team1.n8n.example.com/privkey.pem;
include snippets/ssl-params.conf; # optional
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header X-Forwarded-Host \$host;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_buffering off;
proxy_cache_bypass \$http_upgrade;
proxy_read_timeout 3600;
}
}
EOF
Tương tự cho team2, chỉ khác server_name và proxy_pass http://127.0.0.1:5680;. Sau đó enable site và kiểm tra:
ln -s /etc/nginx/sites-available/team1.n8n.example.com /etc/nginx/sites-enabled/
ln -s /etc/nginx/sites-available/team2.n8n.example.com /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
Nếu chưa có SSL, dùng Certbot để cấp chứng chỉ cho từng subdomain:
certbot --nginx -d team1.n8n.example.com -d team2.n8n.example.com
Bước 6 - Kiểm tra hoạt động
Truy cập https://team1.n8n.example.com trên trình duyệt. Bạn sẽ thấy màn hình đăng nhập n8n của instance team1. Đăng ký tài khoản admin đầu tiên. Sau đó truy cập https://team2.n8n.example.com, login riêng biệt, credential riêng. Kiểm tra port nội bộ đã khoá:
ss -tlnp | grep 5678
# Output: LISTEN 127.0.0.1:5678 (chỉ localhost, không có 0.0.0.0)
Nếu thấy 0.0.0.0:5678 thì port đang mở ra internet. Bạn cần sửa Docker Compose lại thành 127.0.0.1:5678:5678 và restart.
Câu hỏi thường gặp
Mỗi instance n8n dùng bao nhiêu RAM?
n8n cơ bản cần khoảng 200-400 MB RAM mỗi instance khi idle. PostgreSQL thêm 100-200 MB. Tổng mỗi instance tiêu tốn ~400-600 MB RAM. Với VPS 4 GB bạn có thể chạy 4-5 instance ổn định.
Có thể dùng chung một PostgreSQL cho nhiều instance không?
Được, nhưng không khuyến nghị. Mỗi instance cần database riêng trên cùng một server PostgreSQL. Bạn phải set POSTGRES_DB khác nhau (vd n8n_team1, n8n_team2) và ports chỉ expose 1 instance PostgreSQL. Nhưng cô lập kém hơn, dễ xung đột khi migrate.
N8N_ENCRYPTION_KEY có cần phải khác nhau không?
Có. Key này dùng để mã hóa credential của instance đó. Nếu dùng chung key, về mặt lý thuyết ai có quyền truy cập file n8n-data của instance này có thể giải mã credential của instance kia. Luôn sinh key riêng bằng openssl rand -hex 32.
Làm sao để cập nhật n8n cho từng instance?
Vào thư mục instance đó, chạy docker compose pull n8n && docker compose up -d. Dừng từng instance riêng lẻ, không ảnh hưởng instance khác.
Webhook có hoạt động qua subdomain không?
Có. webhook URL sẽ là https://team1.n8n.example.com/webhook/xxx. Nginx reverse proxy chuyển tiếp đến container tương ứng. Nhớ set WEBHOOK_URL đúng trong Docker Compose.
Bài viết liên quan
- Cài đặt n8n trên VPS Ubuntu 24.04 bằng Docker Compose
- Thuê VPS n8n giá rẻ cài sẵn, hướng dẫn chi tiết
- n8n Queue mode với Redis, khi nào cần tách worker
- Chọn RAM cho n8n theo số workflow chạy song song


