AI Automation

Nâng cấp n8n an toàn với pin version và cách rollback khi hỏng

Chạy n8n self-host trên VPS, việc nâng cấp lên bản mới là điều thường xuyên: vá bảo mật, tính năng mới, fix bug. Nhưng không ít lần sau docker compose pull && docker compose up -d, mọi thứ vẫn chạy, nhưng workflow lỗi, credential không verify được, hoặc webhook không còn nhận request. Nếu không có phương án dự phòng, bạn mất hàng giờ để debug hoặc mất luôn dữ liệu. Bài này sẽ chỉ bạn cách kiểm soát nâng cấp an toàn, pin version Docker image, backup đúng thứ cần backup, và rollback chính xác trong vài phút.

  • Luôn pin version image, không dùng :latest, chỉ ghi tag cụ thể
  • Backup đủ 3 thứ, database, .n8n-encryption-key, docker-compose.yml
  • Rollback có script, chạy lại compose với image cũ, restore key, restore DB
  • Kiểm tra trước khi deploy, đọc changelog, dùng stage nếu cần

Yêu cầu trước khi bắt đầu

  • VPS chạy Ubuntu 24.04 LTS hoặc Debian 12, có Docker + Docker Compose v2 đã cài (theo bài cách cài Docker trên VPS Ubuntu từ A đến Z).
  • n8n đang chạy trên Docker Compose, dùng SQLite hoặc PostgreSQL làm database chính.
  • Bạn đã có file docker-compose.yml và biết thư mục chứa volume của n8n.
  • User sudo hoặc root. Phiên bản n8n hiện tại đang chạy: kiểm tra bằng docker ps --format '{{.Image}}' | grep n8nio/n8n.

Vì sao cần pin version, câu chuyện bản latest giết workflow

Nhiều người dùng n8nio/n8n:latest trong compose. Họ nghĩ "luôn mới" là tốt. Thực tế, n8n vẫn đang phát triển nhanh, mỗi bản nhỏ (1.67.01.68.0) đều có thể thay đổi API node, cách xử lý credential, hoặc loại bỏ một node legacy nào đó. Mình từng thấy một workflow bị lỗi chỉ vì nâng từ 1.66.1 lên 1.67.0: node HTTP Request thay đổi format trả về, toàn bộ luồng chạy sai.

Pin version = chỉ định tag rõ ràng: n8nio/n8n:1.67.0. Khi muốn nâng, bạn chủ động đổi tag sau khi đọc changelog. hiếm khi nâng cấp vô thức.

Bước 1, Xác định version hiện tại và chốt lại trong compose

Đầu tiên, xem image n8n bạn đang dùng:

docker ps --format 'table {{.Names}}\t{{.Image}}' | grep n8n
# output: n8n        n8nio/n8n:latest

Nếu là :latest, bạn không biết đang ở bản nào. Kiểm tra bản thật:

docker exec n8n n8n --version
# hoặc
docker inspect n8n --format='{{.Config.Image}}' | grep -oP 'n8nio/n8n:\K.*'

Nếu hai cách trên không ra, hãy check log lúc container chạy lần đầu, thường có dòng n8n version: 1.66.2. Hoặc đơn giản nhất: pull lại :latest rồi xem log trong 5 giây, bạn sẽ thấy bản hiện tại, nhưng đừng commit bản vừa pull, hãy lấy số rồi pin ngay.

Khi đã biết số (vd 1.67.0), sửa file docker-compose.yml:

services:
  n8n:
    image: n8nio/n8n:1.67.0   # thay vì :latest
    # ... các config khác giữ nguyên

Chạy lại để chắc chắn container dùng đúng pin:

docker compose up -d
docker ps --format '{{.Image}}' | grep n8n
# mong đợi: n8nio/n8n:1.67.0

Bước 2, Backup toàn bộ trước mỗi lần nâng cấp

Trước khi nâng lên bản mới, cần backup 3 thứ. Thiếu cái nào cũng có thể mất workflow.

2a. Database

Nếu dùng SQLite (mặc định của n8n trong Docker), database nằm trong volume. Lấy đường dẫn:

docker inspect n8n | jq -r '.[].Mounts[] | select(.Destination == "/home/node/.n8n") | .Source'
# output: /var/lib/docker/volumes/n8n_data/_data

Backup trực tiếp:

docker exec n8n sh -c 'sqlite3 /home/node/.n8n/database.sqlite ".backup /tmp/n8n_backup.sqlite"'
docker cp n8n:/tmp/n8n_backup.sqlite /tmp/n8n_pre_upgrade_1.67.0.sqlite

Nếu dùng PostgreSQL thì backup chuẩn:

docker exec n8n-postgres pg_dump -U n8n -d n8n > /tmp/n8n_pre_upgrade.sql

2b. Encryption key

Credential của các node (API key, token...) được mã hoá bằng N8N_ENCRYPTION_KEY. File key nằm trong volume /home/node/.n8n/.n8n-encryption-key. Nếu mất key, credential bị hỏng lâu dài. Backup:

docker cp n8n:/home/node/.n8n/.n8n-encryption-key /tmp/n8n-encryption-key.backup

2c. File docker-compose.yml

Đơn giản: copy file ra ngoài lưu trữ theo tên có gắn số version:

cp docker-compose.yml /tmp/docker-compose.n8n-1.67.0.yml

Gom toàn bộ backup vào thư mục có ngày tháng để dễ rollback sau này.

Ghi chú: Nếu bạn thuê VPS từ thuê VPS Linux của thueVPS, các gói có snapshot tự động, bạn có thể snapshot luôn toàn bộ volume trước khi nâng cấp, đó là lớp bảo vệ cuối cùng nếu mọi thứ hỏng toàn bộ.

Bước 3, Nâng cấp có kiểm soát

Khi đã backup, bạn mới nâng. Cách làm:

  1. Đọc changelog tại https://github.com/n8n-io/n8n/releases. Xem có breaking change không: node bị xoá, biến môi trường đổi tên, API thay đổi.
  2. Sửa tag version trong docker-compose.yml từ 1.67.0 thành 1.68.0.
  3. Pull image mới và chạy:
docker compose pull n8n
docker compose up -d
docker compose logs n8n --tail 50

Hãy theo dõi log ít nhất 30 giây. Nếu log không có lỗi, kiểm tra web UI và chạy thử 1 workflow cơ bản. Nếu mọi thứ OK, xoá backup cũ hoặc giữ lại thêm 1 tuần. Nếu lỗi, chạy rollback ngay.

Bước 4, Rollback: Khi nâng cấp sai, quay lại ngay

Nếu phát hiện lỗi sớm (workflow lỗi, credential không verify được, page không load), rollback như sau:

Trường hợp 1: Chưa chạy migration database nặng

Thường chỉ cần đưa image cũ về và restart:

# sửa lại tag 1.67.0 trong docker-compose.yml
docker compose up -d
docker compose logs n8n --tail 30

Nếu n8n vẫn lỗi vì database đã được migration sang schema mới (không tương thích ngược), bạn sẽ thấy lỗi trong log. Chuyển sang trường hợp 2.

Trường hợp 2: Database đã migration, phải restore DB

  1. Stop container n8n:
docker compose down n8n
  1. Xoá volume chứa DB mới (chắc chắn rằng bạn đã backup step 2 trước khi nâng):
docker volume rm <tên-volume-n8n>
# Tìm tên volume: docker volume ls | grep n8n
  1. Khôi phục database từ backup:
# Tạo container tạm để copy backup vào volume
docker run --rm -v n8n_data:/target -v /tmp:/source alpine sh -c 'cp /source/n8n_pre_upgrade_1.67.0.sqlite /target/database.sqlite'
  1. Khôi phục encryption key:
docker run --rm -v n8n_data:/target -v /tmp:/source alpine sh -c 'cp /source/n8n-encryption-key.backup /target/.n8n-encryption-key'
  1. Chạy lại compose với image cũ:
docker compose up -d
docker compose logs n8n --tail 50

Nếu log hiện "Database migrated" hoặc lỗi tương tự, có thể migration key đã ăn vào file DB bạn vừa restore, lúc này bạn cần backup DB lúc rollback (bản bị lỗi) rồi restore lại bản pre-upgrade, và làm lại từ đầu chắc chắn key cũng đã được thay thế.

Xử lý lỗi thường gặp khi nâng cấp và rollback

LỗiNguyên nhânCách xử lý
Credential không verify sau nâng cấpEncryption key không khớp hoặc credential format thay đổiRollback DB + key như Bước 4. Nếu vẫn lỗi, test với image cũ hơn 1 bản
Database migration lỗi: Cannot migrateSchema cũ không tương thích với bản mớiRollback DB và pin version cũ. Chờ bản fix hoặc đọc changelog để biết cách migration thủ công
Workflow chạy sai format outputNode API thay đổi (VD: HTTP Request)Kiểm tra changelog, sửa workflow node, hoặc rollback nếu chưa kịp sửa workflow nhiều
n8n không start sau rollbackKey cũ không khớp với DB cũ do copy sai thứ tựChạy log: docker compose logs n8n. Nếu lỗi liên quan credential key, restore lại cả DB + key cùng lúc từ cùng bản backup

Chạy journalctl -u docker hoặc docker compose logs ngay khi gặp lỗi để có thông tin chẩn đoán.

Tự động hoá quy trình backup trước upgrade

Thay vì làm thủ công mỗi lần, viết script /usr/local/bin/backup-n8n-pre-upgrade.sh:

#!/bin/bash
# Backup n8n trước khi nâng cấp
BACKUP_DIR="/root/n8n_backups/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"

# Backup database
docker exec n8n sh -c 'sqlite3 /home/node/.n8n/database.sqlite ".backup /tmp/db_$$.sqlite"'
docker cp n8n:/tmp/db_$$.sqlite "$BACKUP_DIR/database.sqlite"

# Backup encryption key
docker cp n8n:/home/node/.n8n/.n8n-encryption-key "$BACKUP_DIR/"

# Backup compose
cp docker-compose.yml "$BACKUP_DIR/"

# Ghi version hiện tại
docker exec n8n n8n --version > "$BACKUP_DIR/version.txt" 2>/dev/null || true

echo "Backup hoàn tất tại $BACKUP_DIR"

Mỗi lần upgrade, chạy script này trước. Khi cần rollback, bạn sẽ biết chính xác file nào restore vào đâu.

Câu hỏi thường gặp

Có cần pin tất cả service trong compose không?

Chỉ cần pin n8n và database (nếu dùng PostgreSQL). Các service phụ như Redis, postgres cũng nên pin version để tránh lỗi tương thích: redis:7-alpine, postgres:16.

Mất encryption key có khôi phục được credential không?

Không. Nếu mất .n8n-encryption-key mà không có backup, bạn mất toàn bộ credential đã lưu trong n8n. Workflow vẫn còn nhưng không thể xác thực với bất kỳ service nào. Đây là lý do backup file này là bắt buộc.

Nên giữ bao nhiêu bản backup?

Giữ 2-3 bản backup gần nhất, tương ứng với các lần upgrade gần đây. Cũ hơn nữa có thể xoá. Tuy nhiên, giữ lại .n8n-encryption-key và compose file của từng lần upgrade riêng để biết phiên bản nào đi với config nào.

Tôi dùng n8n cloud, có cần quan tâm?

Nếu dùng VPS n8n bản cloud (n8n Start/Pro/Max) của thueVPS, việc nâng cấp do đơn vị cung cấp quản lý. Bạn không cần làm các bước trên. Còn nếu bạn tự host n8n trên VPS riêng, quy trình này là bắt buộc.

Kiểm tra n8n có lỗi sau upgrade thế nào nhanh nhất?

Mở web UI, chạy workflow quan trọng nhất bằng tay. Nếu credential bị đỏ (không verify), đó là dấu hiệu đầu tiên. Kiểm tra log: docker compose logs n8n | grep -i error. Nếu không thấy workflow nào báo lỗi trong 5 phút, khả năng cao upgrade thành công.

Bài viết liên quan

Lưu ý: Bài viết mang tính tham khảo, tổng hợp kiến thức chung. Mỗi hệ thống, hạ tầng và nhu cầu có đặc thù riêng, nên kiểm thử trong môi trường an toàn và tham vấn kỹ sư trước khi triển khai thực tế.