Trong bộ này có gì
Ba script bash nhỏ, một helper cảnh báo dùng chung và các file config để nối chúng lại. Đọc hết mất mười phút, và ngoài các tool mà script gọi, bạn không phải cài thêm gì.
| File | Làm gì |
|---|---|
deploy.sh | Clone một release, build, health check, và rollback nếu lỗi. Có hai chế độ: restart (đổi symlink rồi restart pm2) và bluegreen (không rớt request nào trong bài đo bên dưới). Ở chế độ blue/green, deploy.sh rollback đổi ngược về bản trước. |
backup.sh | Dump database SQLite và Postgres đúng cách, rồi backup bằng restic (mặc định giữ 7 bản theo ngày, 4 theo tuần, 6 theo tháng) và kiểm tra repository. Gặp bản dump hỏng thì script dừng trước khi tạo snapshot. |
restore-test.sh | Restore snapshot mới nhất vào một thư mục tạm, kiểm tra các bản dump database, chạy lệnh kiểm tra riêng của bạn (không bắt buộc) và đọc thử một mẫu dữ liệu. |
notify.sh | Gửi tin Telegram hoặc POST tới webhook khi có script nào lỗi. Chạy ổn thì không báo gì. |
| Config | kit.env.example, Caddyfile.example, ecosystem.config.js, cron.example |
Deploy không downtime, có số đo
Ở chế độ bluegreen, release mới khởi động trên port đang rảnh và được health check trực tiếp. Sau đó Caddy chuyển sang nó bằng graceful reload, rồi release cũ mới dừng. Release không khỏe thì không bao giờ nhận traffic.
Cách đo: container Debian 12, Caddy 2.6.2 cài từ apt, pm2, một app Node cần 1.5 giây để khởi động. Tải là 20 request mỗi giây qua Caddy suốt lần deploy (cứ năm request thì có một request vào endpoint chậm 300 ms). Request bị tính là lỗi nếu gặp lỗi kết nối, timeout quá 3 giây, hoặc trả status khác 200.
| Kịch bản | Request | Lỗi | Thời gian deploy |
|---|---|---|---|
Chế độ restart, release tốt | 116 | 32 (toàn HTTP 502) | 2.4 s |
Chế độ restart, release lỗi (đã rollback) | 380 | 67 (toàn HTTP 502) | 16.8 s |
bluegreen, release tốt | 211 | 0 | 7.6 s |
bluegreen, release lỗi (health trả 500) | 373 | 0 | 16.6 s |
bluegreen, release chết ngay khi khởi động | 371 | 0 | 16.5 s |
bluegreen, rollback | 208 | 0 | 7.5 s |
Ở lần chạy blue/green tốt, tải đi qua cả hai phiên bản (115 phản hồi từ v1, rồi 96 từ v2), nên traffic có chuyển thật. Qua nhiều lần chạy, chế độ restart lỗi 31 đến 35 request, còn blue/green không lỗi request nào.
Backup mà bạn đã restore được
- Database được dump đúng cách. SQLite dùng online backup và kiểm tra tính toàn vẹn. Postgres dùng
pg_dump -Fcvàpg_restore -l. Copy thẳng file database đang chạy là cách nhanh nhất để có một bản backup hỏng. - Dump hỏng thì dừng. Trong test, một file SQLite bị làm hỏng khiến backup dừng mà không tạo snapshot nào.
- Dump cũ không lọt vào. Database đã bị bạn xóa khỏi config sẽ không lẻn vào các snapshot mới.
restore-test.shchứng minh điều đó. Nó restore, kiểm tra các bản dump và chạyrestic checktrên một mẫu. Cho nó chạy hằng tuần từ cron.- Repository từ xa. Repository
sftp:chạy được với cả hai script (đã test với một server OpenSSH cục bộ).
Cảnh báo khi lỗi
Đặt TELEGRAM_BOT_TOKEN và TELEGRAM_CHAT_ID, hoặc NOTIFY_WEBHOOK_URL. Khi deploy, backup hay restore test lỗi, mỗi kênh nhận đúng một tin. Chạy ổn thì không gửi gì. Token được đưa cho curl qua stdin và không bao giờ in ra, còn nếu API thông báo không với tới được thì exit code của script vẫn giữ nguyên.
Cài đặt trong năm bước
- Cài
restic,git,curlvàpm2(thêmcaddynếu dùng blue/green,sqlite3hoặcpostgresql-clienttùy database bạn có). - Copy thư mục lên server, chạy
cp kit.env.example kit.envrồi sửa file này. - Để mật khẩu repository trong một file có quyền 600.
- Chạy
./backup.sh,./restore-test.sh, rồi./deploy.sh. - Thêm các dòng cron trong
cron.example.
Đã test thế nào
59 phép kiểm chạy trong một container Debian 12 sạch (Node 22, restic, PostgreSQL 15, Caddy 2.6.2 và OpenSSH cài từ apt, pm2). Chúng gồm: backup thư mục, SQLite và Postgres, restore rồi so sánh từng dòng, sai repository, database hỏng, thiếu bản dump, deploy và rollback ở cả hai chế độ dưới tải, cảnh báo gửi tới một API giả chạy cục bộ, và restic qua SFTP.
Dành cho ai
Dành cho dev làm một mình hoặc nhóm nhỏ, chạy một hai app Node hoặc Go trên một VPS Linux, muốn deploy và backup đáng tin mà không phải chuyển sang Kubernetes.
Yêu cầu
Linux, bash, pm2, restic, và Caddy nếu dùng blue/green. App của bạn đọc port từ biến PORT. Blue/green chạy hai release song song trong vài giây, nên migration database phải tương thích ngược.
Câu hỏi hay gặp
Muốn deploy không downtime thì có cần mua bộ này không?
Không. Kỹ thuật này được mô tả trong bài viết này cùng các lệnh cốt lõi. Bộ này đóng gói nó lại, kèm health check, rollback, quản lý trạng thái, cảnh báo và bộ test.
Nó giả định stack nào?
Linux, bash, pm2, Caddy cho blue/green, restic cho backup, và app đọc port từ biến môi trường PORT.
Có chạy với Postgres và SQLite không?
Có, cả hai đều được dump và kiểm tra.
Dùng cho nhiều app được không?
Mỗi app một file kit.env, rồi đặt KIT_CONF để chọn file.
Giấy phép thế nào?
Dùng trên server của bạn. Không bán lại các file.
Lịch sử thay đổi
- 0.3.0: deploy blue/green kèm rollback, cảnh báo khi lỗi (Telegram và webhook), đã test repository SFTP, mọi thông báo bằng tiếng Anh.
- 0.2.0: dump SQLite và Postgres trong
backup.sh, kiểm tra bản dump trongrestore-test.sh. - 0.1.0: bản đầu tiên.
Bài liên quan
- Zero-downtime deploys on one VPS with Caddy and pm2 (tiếng Anh)
- restic forget and prune: how the keep flags decide (tiếng Anh)
- A restic backup recipe for SQLite and Postgres on one VPS (tiếng Anh)
- Monitoring backups so that silence never means success (tiếng Anh)
- The 3-2-1 backup rule applied to a single VPS (tiếng Anh)
Mua sản phẩm này
Polar lo thanh toán, thuế và hóa đơn (họ là merchant of record). Thanh toán xong bạn nhận link tải ngay.