Tự Host n8n Workflow Automation Trên VPS 2026 — 5 Triệu/Năm Tiết Kiệm So Với Zapier, Nhưng Có 4 Cái Bẫy Trước Khi Bắt Đầu

📅 01/07/2026 · ⏱ 14 phút đọc · 🏷 Automation · DevOps · VPS

1. Tôi Trả Zapier $79/Tháng Trong 2 Năm Trước Khi Nhận Ra Mình Ngu

Giữa năm 2024, tôi setup automation cho một hệ thống nhỏ: khi khách điền form Google Form → gửi email welcome → thêm vào Google Sheets → gửi tin Telegram cho team. Trên Zapier, workflow này chỉ 4 bước. Nhưng bạn biết Zapier tính tiền thế nào không? Gói Starter $19.99/tháng (thời đó) chỉ cho 750 tasks. Cái workflow 4 bước của tôi mỗi lần chạy đếm 4 tasks. Một tháng 200 leads = 800 tasks. Vượt quota. Phải lên gói Professional $49/tháng. Rồi sang năm thứ hai, tôi thêm 3 workflow nữa — $79/tháng.

Tôi nhìn lại: $79 × 24 tháng = $1,896 (~47 triệu VNĐ). Cho một thứ mà về bản chất chỉ là "nếu A thì B thì C".

Đầu năm 2026, tôi chuyển toàn bộ sang n8n tự host trên một con VPS 4GB RAM giá 197.000đ/tháng (~$8/tháng). Kết quả: tiết kiệm hơn 90% chi phí, workflow chạy nhanh gấp 3 lần, không giới hạn số bước, không lo data rò rỉ ra bên thứ ba. Bài viết này là toàn bộ những gì tôi học được — bao gồm những cái bẫy suýt làm tôi mất hết workflow database.

2. n8n Là Gì Và Tại Sao Nó Hơn Zapier/Make Trong Năm 2026

n8n (đọc là "n-eight-n", viết tắt của "nodemation") là nền tảng workflow automation mã nguồn mở, phát hành dưới license Sustainable Use License (fair-code). Không giống Zapier hay Make (trước là Integromat) — cả hai đều là SaaS đóng, bạn không thấy code, không kiểm soát dữ liệu — n8n cho phép bạn cài lên server của chính mình, toàn quyền kiểm soát, audit code bất kỳ lúc nào.

Tiêu chín8n (Self-hosted)ZapierMake (Integromat)
Giấy phépMã nguồn mở (fair-code)Độc quyền SaaSĐộc quyền SaaS
Giá (team nhỏ)~$8/tháng (VPS) — miễn phí vĩnh viễn$19.99-$69/tháng$9-$34/tháng
Giới hạn stepsKhông giới hạn100 steps/zap (Professional)Không giới hạn
Số lượng tích hợp400+ nodes7,000+ apps2,000+ apps
Custom codeJavaScript/Python trong workflowCode step (Python/JS)JS/Python modules
Dữ liệu ở đâuServer của bạnMỹ (AWS us-east-1)EU (Đức/CH Czech)
Delay tối đaKhông giới hạn (queue mode)5 phút (delay step)Không giới hạn
Webhook custom domainCó (cùng domain bạn)không (zapier.com)hook.make.com
Branch/merge logicCó (IF, Switch, SplitInBatches)Có (Paths)Có (Router)
Execution historyGiữ bao lâu tùy bạn2 tuần (Starter)30 ngày
Multi-tenantCó (nhiều user, project)Team plan ($69+/user)Teams ($34+/user)

Điểm tôi thích nhất ở n8n không phải là giá rẻ — mà là không ai khác động vào dữ liệu của tôi. Khi bạn chạy workflow trên Zapier, API keys, nội dung email, dữ liệu khách hàng đều đi qua server của Zapier ở Mỹ. Với n8n tự host, tất cả nằm trên VPS của bạn. Điều này đặc biệt quan trọng nếu bạn làm việc với dữ liệu khách hàng Việt Nam hoặc ngành y tế/tài chính.

Ngoài ra, n8n hỗ trợ Code node cho phép bạn viết JavaScript/Python trực tiếp trong workflow. Cần parse JSON lồng nhau 4 cấp? Cần gọi một API không có sẵn connector? Chỉ cần 5 dòng code. Zapier cũng có Code step nhưng bị giới hạn runtime 10 giây và 6MB memory trên gói thấp — trong khi n8n trên VPS của bạn chạy với toàn bộ RAM máy.

⚠️ Bẫy #1: Bạn phải tự bảo trì. Khi tự host, bạn chịu trách nhiệm backup database, cập nhật bảo mật, monitor uptime. Nếu không làm, một ngày đẹp trời VPS sập → toàn bộ automation chết. Tôi sẽ chỉ bạn cách setup backup tự động ở phần sau.

3. Cài n8n Trên VPS Bằng Docker Compose — Dưới 10 Phút

n8n chạy tốt nhất trên VPS tối thiểu 2GB RAM, 2 vCPU, 20GB SSD. Với workload nhẹ (dưới 50 workflow, dưới 1000 execution/ngày), con VPS 4GB RAM của Netihot giá 137.000đ/tháng là dư sức. Tôi khuyên dùng Ubuntu 24.04 LTS.

3.1. Cài Docker + Docker Compose

# Cập nhật hệ thống
sudo apt update && sudo apt upgrade -y

# Cài Docker
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER

# Cài Docker Compose plugin
sudo apt install -y docker-compose-plugin

# Kiểm tra
docker --version
docker compose version

Sau đó logout/login lại để quyền docker có hiệu lực (hoặc chạy newgrp docker).

3.2. File docker-compose.yml cho n8n

Tạo thư mục cho n8n:

mkdir -p ~/n8n && cd ~/n8n

Tạo file docker-compose.yml:

nano docker-compose.yml
version: '3.8'

services:
  postgres:
    image: postgres:16-alpine
    container_name: n8n-postgres
    restart: unless-stopped
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=thay_bang_mat_khau_manh
      - POSTGRES_DB=n8n
    volumes:
      - ./pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n"]
      interval: 10s
      timeout: 5s
      retries: 5

  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    restart: unless-stopped
    ports:
      - "127.0.0.1:5678:5678"
    environment:
      - N8N_HOST=your-domain.com
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - WEBHOOK_URL=https://your-domain.com
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=thay_bang_mat_khau_manh
      - N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)
      - N8N_USER_MANAGEMENT_DISABLED=false
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=admin
      - N8N_BASIC_AUTH_PASSWORD=thay_bang_mat_khau_manh_2
    volumes:
      - ./n8n_data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy
    links:
      - postgres

  # Tùy chọn: reverse proxy tự động HTTPS
  caddy:
    image: caddy:2-alpine
    container_name: n8n-caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./caddy_data:/data

File Caddyfile (cùng thư mục):

your-domain.com {
    reverse_proxy n8n:5678
}
⚠️ Bẫy #2: ENCRYPTION_KEY là mất là mất hết credential. Biến N8N_ENCRYPTION_KEY dùng để mã hóa tất cả credential (API keys, passwords) trong database. Nếu bạn đổi key này, tất cả credential cũ không decrypt được nữa — phải nhập lại từng cái một. Lưu key này vào password manager (Bitwarden, 1Password), đừng chỉ để trong docker-compose.

Khởi động:

docker compose up -d

Kiểm tra:

docker compose ps
# Phải thấy 3 container: postgres (healthy), n8n (up), caddy (up)

docker compose logs n8n | tail -20
# Tìm dòng: "n8n ready on ::, port 5678"

Lúc này truy cập https://your-domain.com — bạn sẽ thấy màn hình login n8n với basic auth.

4. Workflow Đầu Tiên: Tự Động Báo Telegram Khi Có Khách Điền Form

Đây là workflow "hello world" của automation — tôi dùng nó hàng ngày cho trang landing page. Khi khách điền Google Form → gửi tin nhắn Telegram cho team kèm nội dung form → lưu vào Google Sheets.

4.1. Tạo Webhook Trigger

Trong n8n dashboard, click "Add Workflow" → thêm node "Webhook":

# Cấu hình Webhook node:
HTTP Method: POST
Path: form-submit
Response Mode: Last Node
# n8n sẽ sinh webhook URL: https://your-domain.com/webhook/form-submit

4.2. Thêm Google Sheets Node

Thêm node "Google Sheets" → Operation: Append → chọn spreadsheet và sheet đích. Map dữ liệu từ webhook body vào các cột.

Cần tạo OAuth2 credential trong n8n: vào Settings → Credentials → Google Sheets OAuth2 API. n8n tự host cần bạn tạo app trên Google Cloud Console (miễn phí). Khác với Zapier — Zapier làm sẵn OAuth cho bạn, cái này là trade-off của tự host.

4.3. Thêm Telegram Node

Thêm node "Telegram" → Resource: Send Message → chọn chat ID (có thể là group hoặc channel). Format message với dữ liệu từ form:

🔔 Có lead mới từ Landing Page!

👤 Họ tên: {{ $json.ho_ten }}
📧 Email: {{ $json.email }}
📱 SĐT: {{ $json.so_dien_thoai }}
📝 Ghi chú: {{ $json.ghi_chu }}

⏰ {{ $now.format('DD/MM/YYYY HH:mm') }}

4.4. Thêm IF Node Phân Loại Lead

Bạn có thể thêm logic phân loại: nếu khách chọn "Quan tâm VPS" → tag là "hot lead", gửi riêng vào group VIP. n8n dùng node IF để rẽ nhánh — mỗi nhánh có thể có Telegram node riêng với chat ID khác nhau.

IF node:
  Condition: {{ $json.quan_tam }} contains "VPS"
  True → Telegram (group VIP)
  False → Telegram (group chung)

Sau khi nối xong tất cả node, click "Execute Workflow" để test. n8n hiển thị execution log chi tiết từng node — dữ liệu JSON đi qua mỗi bước, thời gian chạy, lỗi nếu có. Giao diện debug này tốt hơn Zapier rất nhiều, đặc biệt khi workflow phức tạp 20+ bước.

💡 Mẹo: Dùng Node "Set" để biến đổi dữ liệu. Nếu Google Form trả về timestamp dạng ISO 8601 (2026-07-01T09:00:00Z), bạn có thể dùng Set node để format lại thành "09:00 01/07/2026" trước khi đưa vào Telegram. n8n có sẵn hàm moment.js trong expression — cực kỳ tiện cho xử lý datetime.

5. Những Workflow Thực Tế Tôi Đang Chạy Hằng Ngày

Để bạn có ý tưởng về sức mạnh của n8n, đây là những workflow tôi đang chạy production:

5.1. Monitoring VPS + Cảnh Báo Qua Telegram

Workflow này chạy cron mỗi 5 phút: SSH vào VPS qua node SSH → chạy lệnh free -m && df -h → parse output → nếu RAM > 80% hoặc disk > 90% → gửi cảnh báo Telegram. Tiết kiệm được ít nhất 3 lần VPS hết disk mà tôi không biết.

Schedule Trigger (Cron: */5 * * * *)
  → SSH Execute ("free -m | grep Mem | awk '{print $3/$2*100}'")
  → IF (mem_percent > 80)
    → Telegram Alert: "🚨 VPS XXX: RAM {mem_percent}%"

5.2. Tổng Hợp Tin Tức Hằng Ngày

Mỗi sáng 7:00, workflow gọi RSS feed của VnExpress, Tuổi Trẻ (node RSS Read) → OpenAI node tóm tắt 5 tin nổi bật → Telegram. Không cần đọc báo sáng, chỉ cần đọc 1 tin nhắn là nắm được tình hình.

5.3. Tự Động Deploy Web Khi Push Git

Webhook từ GitHub → clone repo → chạy build script → copy file vào web root. Thay thế hoàn toàn GitHub Actions cho project nhỏ — nhanh hơn, log ngay trên n8n dashboard.

5.4. Đồng Bộ Đơn Hàng Shopee → Google Sheets

Dùng HTTP Request node gọi Shopee API (cần partner ID) → parse JSON → append vào Google Sheets → tính tổng doanh thu → Telegram báo cáo cuối ngày. Một workflow thay thế phần mềm quản lý bán hàng giá vài triệu/năm.

6. Bảo Mật n8n Trên VPS: 6 Lớp Phòng Thủ

Khi bạn mở n8n ra internet, bạn đang mở một công cụ có quyền truy cập tất cả API keys và credential. Bảo mật không phải là option — là bắt buộc.

6.1. Basic Auth (Đã làm ở trên)

Đây là lớp đầu tiên: username/password trước khi vào được n8n UI. Đừng dùng admin/admin — tôi từng scan Shodan và thấy hàng trăm n8n instance không đổi mật khẩu mặc định.

6.2. Firewall + Chỉ Mở Port Cần Thiết

# UFW: chỉ mở 22, 80, 443
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Port 5678 của n8n chỉ nên bind vào 127.0.0.1 (đã cấu hình trong docker-compose). Traffic qua Caddy reverse proxy mới tới được n8n.

6.3. Rate Limiting Qua Caddy

your-domain.com {
    rate_limit {
        zone dynamic {
            key {remote_host}
            events 20
            window 10s
        }
    }
    reverse_proxy n8n:5678
}

20 requests/10 giây — đủ cho người dùng bình thường, chặn brute force.

6.4. Tường Lửa Ứng Dụng — CrowdSec

Cài CrowdSec + Caddy plugin để tự động block IP có hành vi tấn công:

curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
sudo apt install -y crowdsec
sudo apt install -y crowdsec-caddy-bouncer
sudo systemctl enable crowdsec

6.5. Backup PostgreSQL Tự Động

Đây là thứ quan trọng nhất. Không có backup = một ngày database hỏng = mất hết workflow.

# Script backup: /root/backup-n8n.sh
#!/bin/bash
BACKUP_DIR="/root/backups/n8n"
mkdir -p $BACKUP_DIR
DATE=$(date +%Y%m%d_%H%M%S)
docker exec n8n-postgres pg_dump -U n8n n8n > "$BACKUP_DIR/n8n_$DATE.sql"
# Giữ 7 ngày backup
find $BACKUP_DIR -name "*.sql" -mtime +7 -delete

Cron:

0 3 * * * /root/backup-n8n.sh

Nâng cao hơn: dùng restic + Backblaze B2 để backup offsite, đảm bảo kể cả VPS cháy vẫn khôi phục được.

⚠️ Bẫy #3: n8n lưu execution history không giới hạn → database phình to. Mặc định n8n lưu mọi execution log vĩnh viễn trong PostgreSQL. Sau vài tháng chạy workflow mỗi 5 phút, database của tôi lên tới 2GB. Cấu hình dọn dẹp: Settings → Workflow Settings → "Save Manual Executions" = 30 ngày, "Save Production Executions" = 7 ngày. Hoặc dùng environment variable: EXECUTIONS_DATA_PRUNE=trueEXECUTIONS_DATA_MAX_AGE=168 (giờ).

7. n8n Cloud vs Self-Hosted: Khi Nào Nên Dùng Gói Trả Phí

n8n cũng có cloud plan với giá từ €20/tháng (khoảng 525.000đ). Khi nào nên dùng cloud thay vì tự host?

Tình huốngSelf-hostedn8n Cloud
Ngân sách hạn chế✅ Tối ưu (VPS 137K/tháng)❌ €20+/tháng
Cần kiểm soát dữ liệu tuyệt đối✅ Dữ liệu nằm trên server bạn❌ Dữ liệu qua server n8n
Không muốn lo bảo trì server❌ Bạn phải tự làm✅ n8n lo hết
Cần SLA 99.9% uptime⚠️ Tùy VPS bạn chọn✅ Cam kết SLA
Team lớn, nhiều user⚠️ Tự quản lý user✅ SSO, RBAC tích hợp
Cần hỗ trợ kỹ thuật❌ Community forum✅ Email support ưu tiên
Workflow dùng AI node✅ AI node miễn phí (bạn trả API key)✅ AI node miễn phí

Lời khuyên của tôi: bắt đầu với self-hosted. Nếu sau 3 tháng bạn thấy việc bảo trì quá phiền, hoặc workflow quan trọng tới mức cần SLA, hãy migrate lên cloud. Migrate từ self-hosted lên cloud rất dễ: chỉ cần export workflow ra JSON rồi import vào cloud instance.

8. So Sánh Hiệu Năng: n8n Trên VPS 2GB vs VPS 8GB

Tôi đã test cùng một workflow 15 node (Webhook → HTTP Request → IF → Code JS → Google Sheets × 2 → Telegram × 2 → Wait → HTTP Request → Slack) trên 2 cấu hình VPS khác nhau tại Netihot:

Cấu hình VPSThời gian chạy (15-node workflow)Execution/giờ (stress test)CPU usageRAM usage
2 vCPU, 2GB RAM (77K/tháng)2.8 giây~60045-70%1.1GB
4 vCPU, 4GB RAM (137K/tháng)1.4 giây~1,40030-50%1.5GB
4 vCPU, 8GB RAM (197K/tháng)1.1 giây~2,20020-35%2.1GB

Kết luận: Với hầu hết use case cá nhân/team nhỏ, VPS 2GB RAM là đủ. Chỉ cần lên 4GB nếu bạn chạy >50 workflow hoặc workflow dùng nhiều AI/HTTP Request tốn memory. RAM được dùng chủ yếu bởi PostgreSQL (cache), Docker runtime, và chính n8n process — không phải bởi workflow execution.

🔧 Tối ưu PostgreSQL cho VPS RAM thấp: Thêm vào docker-compose Postgres section: command: postgres -c shared_buffers=256MB -c effective_cache_size=768MB. Mặc định Postgres chiếm shared_buffers = 25% RAM hệ thống — trên VPS 2GB, 512MB đã là quá nhiều cho riêng Postgres.

9. Các Lỗi Thường Gặp Và Cách Fix

9.1. Webhook không nhận request từ bên ngoài

Kiểm tra: WEBHOOK_URL environment variable phải khớp với domain thực tế. Nếu bạn truy cập n8n qua https://n8n.yourdomain.com nhưng WEBHOOK_URL để http://localhost:5678 → webhook URL sinh ra sai → external service không gọi được.

9.2. "Cannot connect to database" sau khi khởi động lại

PostgreSQL trong Docker cần vài giây để ready. Nếu n8n container khởi động trước Postgres → lỗi. Đã fix bằng depends_on: postgres condition: service_healthy ở trên. Nếu vẫn lỗi: docker compose restart n8n.

9.3. Workflow chạy chậm sau vài tuần

Nguyên nhân thường là execution history không được dọn. Vào Settings → Usage → check số lượng saved executions. Nếu >100,000 → bật auto-prune.

9.4. Credential OAuth2 hết hạn

Google OAuth2 token hết hạn sau 1 giờ và refresh token có thể bị revoke nếu không dùng 6 tháng. n8n tự refresh — nhưng nếu workflow không chạy trong 6 tháng, bạn phải re-authorize credential trong Settings.

⚠️ Bẫy #4: Update n8n Docker image không đọc changelog. n8n cập nhật rất nhanh — mỗi tuần có bản mới. Đôi khi có breaking change trong node config hoặc credential format. Trước khi docker compose pull && docker compose up -d, LUÔN đọc GitHub releases. Tôi từng update mù và mất 3 cái Google Sheets credential vì thay đổi OAuth scope — mất nửa buổi sáng config lại.

10. Kết Luận: n8n + VPS = Bộ Não Tự Động Hóa Riêng Cho Bạn

Sau 6 tháng dùng n8n tự host, tôi không còn nghĩ đến Zapier nữa. Chi phí từ $79/tháng xuống còn 197.000đ/tháng (~$8) — tiết kiệm 90%. Nhưng quan trọng hơn: tôi có toàn quyền kiểm soát. Tôi biết dữ liệu của mình ở đâu. Tôi có thể debug từng mili giây của workflow. Tôi có thể viết code tùy chỉnh mà không bị giới hạn runtime.

Nếu bạn đang trả tiền cho Zapier, Make, hay bất kỳ automation SaaS nào — hãy thử cài n8n lên VPS cuối tuần này. Mất 10 phút cài đặt, 30 phút làm workflow đầu tiên, và bạn sẽ tự hỏi tại sao không làm sớm hơn.

🚀 Cần một con VPS mạnh mẽ, ổn định để chạy n8n 24/7?

Netihot cung cấp VPS Việt Nam từ 47.000đ/tháng — cài Docker, chạy n8n, uptime 99.9%, hỗ trợ 24/7.

Thuê VPS Ngay — Từ 47K/Tháng