Backup và update Supabase self-host an toàn

Chia sẻ bài viết

Mục lục
Backup và update Supabase self-host an toàn

Trả lời nhanh: Backup Supabase = hai thứ: database (pg_dump qua container db, cron hằng đêm) và file storage (thư mục volumes/storage). Bản sao phải rời khỏi máy, rsync qua tailnet sang VPS/máy khác. Update: backup trước, đọc changelog, git pull + docker compose pull rồi up -d: và luôn thử restore định kỳ, backup chưa từng restore thử là backup trên niềm tin.

Bản cloud của Supabase backup hộ bạn mỗi ngày; bản self-host thì đêm đầu tiên bạn quên là đêm rủi ro bắt đầu. Bài này dựng bộ ba: backup tự động hằng đêm, bản sao rời máy qua tailnet, và quy trình update stack, thứ đáng sợ hơn người ta tưởng vì một lần compose pull kéo theo cả chục service đổi phiên bản. Toàn bộ bằng script dán được, theo phong cách quen của blog.

Tóm tắt nhanh
  • Hai tài sản phải giữ: Postgres (pg_dump) và volumes/storage (file người dùng upload)
  • Cron 2 giờ sáng: dump nén + xoay vòng 7 ngày, script sẵn trong bài
  • Quy tắc 3-2-1 rút gọn cho VPS: bản tại chỗ + bản offsite qua tailnet
  • Update: backup → changelog → pull → up, đừng bao giờ pull mù
  • Mỗi quý một lần restore thử vào stack tạm, backup phải được chứng minh, không phải được tin

Backup database: pg_dump qua container

#!/bin/bash
# /root/backup-supabase.sh
set -e
D=/root/backups/supabase
mkdir -p $D
docker exec supabase-db pg_dumpall -U postgres | gzip > $D/db-$(date +%F).sql.gz
# xoay vong 7 ngay:
find $D -name "db-*.sql.gz" -mtime +7 -delete
chmod +x /root/backup-supabase.sh
crontab -e   # them dong:
0 2 * * * /root/backup-supabase.sh >> /var/log/backup-supabase.log 2>&1

(Tên container db xem bằng docker compose ps: tùy phiên bản compose có thể khác đôi chút.) pg_dumpall ôm cả roles và mọi database, hợp khẩu vị khôi phục toàn phần; kho lớn muốn dump từng db riêng thì đổi sang pg_dump có chọn lọc. Nguyên lý dump vs PITR đã mổ ở bài backup database, với đa số app trên Supabase self-host, dump hằng đêm là điểm cân đúng.

Đừng quên nửa còn lại: storage và cấu hình

Ảnh đại diện, tài liệu người dùng upload không nằm trong Postgres, chúng nằm ở docker/volumes/storage. Cộng thêm hai file cấu hình quyết định sống còn: .env (mất là mất JWT_SECRET, mọi token, mọi key phải sinh lại) và các file compose đã tùy chỉnh. Gộp vào script:

tar czf $D/storage-$(date +%F).tar.gz -C /duong-dan/supabase/docker volumes/storage
cp /duong-dan/supabase/docker/.env $D/env-$(date +%F).bak

Ghi chú riêng cho .env: file này là chùm chìa khóa, thư mục backup phải chỉ root đọc được (chmod 700), và khi đẩy offsite thì đường truyền phải kín (phần kế).

Bản sao rời máy: rsync qua tailnet

Backup nằm cùng VPS với dữ liệu chỉ chống được lỗi phần mềm, không chống được mất máy. Đẩy sang một điểm thứ hai (VPS khác, NAS ở nhà) qua tailnet là không mở port nào mà đường đi mã hóa sẵn:

# them vao cuoi script backup:
rsync -az --delete /root/backups/supabase/ [email protected]:/backup/supabase/

Mô hình này chính là chiều ngược của bài backup NAS lên VPS, hạ tầng tailnet dựng một lần, chảy được cả hai chiều. Muốn bài bản hơn rsync: restic (mã hóa + dedup + giữ nhiều mốc) cùng công thức đích qua IP tailnet.

Update stack không làm chết dữ liệu

Stack chục service nghĩa là update có bề mặt rộng, kỷ luật bốn bước:

1. /root/backup-supabase.sh          # backup tay ngay truoc khi dong
2. Doc changelog/release notes       # dac biet cac major cua db va auth
3. cd supabase && git pull
   cd docker && docker compose pull
4. docker compose up -d && docker compose ps   # cho healthy het

Dữ liệu nằm trong volumes nên up -d bình thường không đụng, rủi ro thật nằm ở migration ngầm khi image db/auth nhảy phiên bản lớn: đó là lý do bước 1 và 2 không được cắt. Có bản backup tươi trong tay, tình huống xấu nhất cũng chỉ là dựng lại stack cũ và restore, phiền, nhưng không mất gì.

Restore thử: nghi thức mỗi quý

Backup chưa từng restore là hy vọng, không phải kế hoạch. Mỗi quý một lần, 30 phút: dựng stack Supabase tạm (thư mục khác, cổng khác, hoặc VPS test theo giờ), nạp bản dump mới nhất:

gunzip -c db-2026-09-18.sql.gz | docker exec -i supabase-db-test psql -U postgres

rồi mở Studio tạm kiểm vài bảng, thử một lượt đăng nhập. Ghi lại thời gian restore thực tế, con số đó là RTO thật của bạn khi có biến, và là con số đáng biết trước ngày cần đến. Xong nghi thức, hạ stack tạm, yên tâm ba tháng.

Bộ lệnh sao lưu đầy đủ, ba phần

# 1. Co so du lieu
docker compose exec -T db pg_dump -U postgres -Fc postgres \
  > /root/sao-luu/db-$(date +%F).dump

# 2. Kho tep, phan khong nam trong dump
tar czf /root/sao-luu/storage-$(date +%F).tar.gz ./volumes/storage

# 3. Cau hinh va khoa bi mat
tar czf /root/sao-luu/cauhinh-$(date +%F).tar.gz .env docker-compose.yml ./volumes/api

# 4. Day ra may khac, khong de cung mot cho
rsync -avz /root/sao-luu/ may-luu-tru:/kho/supabase/

# 5. Xoa ban cu hon 30 ngay de khong day o
find /root/sao-luu -name "*.dump" -mtime +30 -delete

Phần hai và ba là phần hay bị bỏ sót. Sao lưu mỗi cơ sở dữ liệu thì khôi phục xong sẽ có người dùng nhưng mất hết tệp họ tải lên, và các thành phần không nói chuyện được với nhau vì khóa đã khác.

Diễn tập khôi phục, việc quyết định mọi thứ

ViệcTần suấtCái cần ghi lại
Kiểm tệp sao lưu có tồn tại và đúng kích thướcHằng tuần, tự độngCảnh báo khi tệp nhỏ bất thường
Nạp thử bản sao vào một máy khácMỗi quýThời gian nạp, và bao nhiêu phần trăm dữ liệu đúng
Diễn tập đầy đủ: dựng lại toàn bộ stack từ ba tệpMỗi nửa nămTổng thời gian ngừng thật, ghi thành số

Bản sao chưa từng khôi phục thử không phải bản sao, chỉ là một tệp làm mình yên tâm. Con số duy nhất đáng tin là thời gian bạn đo được trong lần diễn tập gần nhất.

Cập nhật stack mà không mất dữ liệu

  1. Chạy đủ ba lệnh sao lưu ở trên, và kiểm tệp đã tạo xong.
  2. Đọc ghi chú phát hành, chú ý phần thay đổi có phá vỡ tương thích.
  3. Cập nhật trên một bản dựng thử trước, không cập nhật thẳng bản đang chạy.
  4. Cập nhật bản thật vào khung giờ ít người dùng, và giữ bản sao trong tầm tay.
  5. Sau khi cập nhật, chạy lại bộ lệnh kiểm tra: các thành phần có sống, đăng nhập có được, tệp có tải lên được.

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

Backup lúc 2h sáng có cần dừng stack không?

Không, pg_dump chụp ảnh nhất quán trong lúc database vẫn phục vụ. Chọn giờ thấp điểm chỉ để giảm cạnh tranh I/O, không phải vì bắt buộc.

Dump của self-host có nạp lên Supabase cloud được không (và ngược lại)?

Được về cơ bản vì cùng là Postgres, đây chính là đường di cư hai chiều (bài migrate của cụm nói kỹ chiều cloud về VPS). Lưu ý các schema hệ thống (auth, storage) cần xử lý theo hướng dẫn di cư thay vì nạp mù toàn bộ.

Volume storage lớn quá, tar mỗi đêm nặng nề thì sao?

Chuyển sang rsync/restic tăng dần (incremental) cho storage, chỉ đồng bộ file thay đổi; giữ tar trọn gói cho mốc tuần. Database vẫn dump trọn hằng đêm vì đó là phần đổi liên tục và nén tốt.

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

Khung phổ biến: 7 bản ngày + 4 bản tuần + vài bản tháng, cân giữa dung lượng và độ sâu lịch sử. Sự cố phát hiện muộn (dữ liệu hỏng âm thầm) là lý do cần bản tuần/tháng chứ không chỉ 7 ngày gần nhất.

Hạ tầng VPS tại Việt Nam của TND
Cloud VPS linh hoạt và VPS NVMe xung cao, IP công cộng riêng, đặt tại Việt Nam
Backup nhanh hay chậm là chuyện của ổ đĩa: dump + nén + rsync trên VPS NVMe TND xong trong lúc ổ thường còn đang đọc. Cần điểm offsite? Thêm một Cloud VPS làm đích nhận qua tailnet, cả cặp đều đặt tại Việt Nam, bàn giao trong 5 phút.
Dùng thử VPS NVMe, bàn giao trong 5 phútNhu cầu nhẹ hơn? Xem VPS giá rẻ từ 129K

Bài viết liên quan