Những workflow nên có cho sysadmin trên VPS

Vấn đề: VPS chạy ổn, nhưng bạn có đang ngủ ngon?
Bạn vừa SSH vào một VPS mới, cài xong Nginx, MariaDB, PHP 8.3, Docker và fail2ban. Mọi thứ chạy ngon lành. Nhưng ba tháng sau, ổ đầy log, service chết lúc 2h sáng, database bị corrup, và bạn phải restore từ bản backup… nếu có. Với một thuê VPS chạy production, việc thiết lập những workflow tự động hóa ngay từ đầu là khác biệt giữa “hệ thống vận hành” và “hệ thống tự vận hành”. Bài viết này dành cho sysadmin đã có kiến thức cơ bản, muốn xây dựng bộ 7 workflow thiết yếu: backup, monitor, cảnh báo, deploy, log rotate, bảo mật và DNS động. Mỗi workflow đều có lệnh chạy được trên Ubuntu 24.04 LTS.
Yêu cầu trước khi bắt đầu
- Một VPS chạy Ubuntu 24.04 LTS, user sudo non-root.
- Domain trỏ về IP VPS (cho Coolify và monitor).
- Tài khoản Telegram Bot + token (cho cảnh báo).
- Tài khoản S3-compatible (Backblaze B2, MinIO hoặc AWS S3) cho backup.
- Kiến thức cơ bản về systemd, crontab và Docker.
Workflow 1: Backup tự động lên S3 bằng Restic
Restic là công cụ backup mã nguồn mở, hỗ trợ snapshot dedup và mã hóa. Cài đặt:
sudo apt update && sudo apt install restic -y
restic version
# restic 0.16.4
Khởi tạo repository trên S3 (ví dụ Backblaze B2):
export RESTIC_REPOSITORY="s3:https://s3.us-west-004.backblazeb2.com/my-bucket/vps-backup"
export RESTIC_PASSWORD="your-strong-password-here"
restic init
Tạo script backup tại /usr/local/bin/backup-vps.sh:
#!/bin/bash
export RESTIC_REPOSITORY="s3:https://s3.us-west-004.backblazeb2.com/my-bucket/vps-backup"
export RESTIC_PASSWORD="your-strong-password-here"
restic backup /etc /var/www /var/lib/mysql --tag auto-$(date +%Y%m%d)
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 3 --prune
sudo chmod +x /usr/local/bin/backup-vps.sh
Thêm cron job chạy hàng ngày lúc 2h sáng:
sudo crontab -e
# Thêm dòng:
0 2 * * * /usr/local/bin/backup-vps.sh >> /var/log/backup.log 2>&1
Verify: Kiểm tra log và snapshot:
sudo cat /var/log/backup.log
restic snapshots
Nếu không có S3, bạn có thể dùng rclone backup lên Google Drive. Xem hướng dẫn chi tiết tại bài dùng rclone backup VPS lên Google Drive.
Workflow 2: Giám sát hệ thống với Prometheus + Grafana
Prometheus thu thập metric từ node_exporter, Grafana vẽ dashboard. Dùng Docker Compose để triển khai nhanh:
mkdir ~/monitoring && cd ~/monitoring
nano docker-compose.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:v2.53.0
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=30d'
ports:
- "9090:9090"
restart: unless-stopped
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=strongpassword
volumes:
- grafana-data:/var/lib/grafana
restart: unless-stopped
node_exporter:
image: prom/node-exporter:latest
command:
- '--path.rootfs=/host'
pid: host
volumes:
- /:/host:ro,rslave
restart: unless-stopped
volumes:
prometheus-data:
grafana-data:
docker compose up -d
Tạo file prometheus.yml:
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['node_exporter:9100']
Verify: Mở http://<VPS-IP>:9090/targets, node_exporter status UP. Grafana tại http://<VPS-IP>:3000, import dashboard ID 1860 (Node Exporter Full). Nếu cần kỹ thuật chuyên sâu hơn, xem bài giám sát VPS với Prometheus và Grafana từ host.
Workflow 3: Cảnh báo Telegram khi service chết hoặc tài nguyên cạn
Bot Telegram gửi thông báo nếu service down hoặc disk/ram cao. Tạo script /usr/local/bin/alert-telegram.sh:
#!/bin/bash
BOT_TOKEN="your-bot-token-here"
CHAT_ID="your-chat-id-here"
MESSAGE="$1"
curl -s -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendMessage" \
-d "chat_id=$CHAT_ID" \
-d "text=$MESSAGE"
sudo chmod +x /usr/local/bin/alert-telegram.sh
Tạo systemd service check: /etc/systemd/system/check-nginx.service
[Unit]
Description=Check Nginx and alert
[Service]
Type=oneshot
ExecStart=/bin/bash -c 'if ! systemctl is-active --quiet nginx; then /usr/local/bin/alert-telegram.sh "Nginx died on $(hostname)"; fi'
Kích hoạt timer: /etc/systemd/system/check-nginx.timer
[Unit]
Description=Check Nginx every 5 minutes
[Timer]
OnCalendar=*:0/5
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now check-nginx.timer
Verify: Dừng Nginx tạm thời, đợi 5 phút, kiểm tra Telegram có tin nhắn không. sudo journalctl -u check-nginx.service -f xem log. Tham khảo bài gửi cảnh báo hệ thống VPS qua Telegram bot bằng script Bash để mở rộng.
Workflow 4: Deploy ứng dụng tự động với Coolify
Coolify là PaaS tự host (thay thế Heroku), cho phép deploy từ Git repository với một click. Cài đặt nhanh:
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
Quá trình cài tự động kéo Docker images và chạy trên port 8000. Truy cập http://<VPS-IP>:8000, tạo tài khoản admin. Thêm server của bạn (localhost) và deploy một ứng dụng Node.js hoặc PHP từ GitHub bằng webhook tự động. Mỗi lần push code, Coolify tự build và redeploy. Hướng dẫn chi tiết tại bài tự host PaaS kiểu Heroku trên VPS bằng Coolify.
Lưu ý: Coolify chiếm khoảng 1-2 GB RAM. Dùng VPS Linux tối thiểu 2GB RAM, hàng đầu 4GB. Nếu xài thuê VPS giá rẻ 2GB RAM, chỉ deploy 1-2 ứng dụng nhẹ.
Workflow 5: Log rotate tự động, không để ổ đầy
Mặc định Ubuntu có logrotate chạy hàng ngày, nhưng cần cấu hình cho ứng dụng custom. Tạo file /etc/logrotate.d/custom-apps:
/var/log/myapp/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 www-data adm
postrotate
systemctl reload myapp > /dev/null 2>&1 || true
endscript
}
Kiểm tra cấu hình:
sudo logrotate -d /etc/logrotate.d/custom-apps
Verify: Chạy thử logrotate force:
sudo logrotate -f /etc/logrotate.d/custom-apps
ls -la /var/log/myapp/
File cũ nén thành .gz. Xem thêm bài cấu hình logrotate quản lý log trên VPS Ubuntu.
Workflow 6: Bảo mật tự động, Fail2ban + SSH key + firewall
Fail2ban giám sát log và block IP brute-force. Cài đặt:
sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban
Tạo file /etc/fail2ban/jail.local:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 1h
findtime = 10m
Khoá SSH password, chỉ dùng key:
sudo nano /etc/ssh/sshd_config
# PasswordAuthentication no
# PermitRootLogin prohibit-password
sudo systemctl restart sshd
Firewall UFW chỉ mở port cần:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80,443/tcp
sudo ufw enable
Verify: sudo fail2ban-client status sshd, hiện số IP bị ban. sudo ufw status verbose, hiện rules. Bài chi tiết: hướng dẫn cấu hình UFW firewall cơ bản trên Ubuntu VPS.
Workflow 7: DNS động cho VPS, hết IPv4 cố định vẫn truy cập
Nếu VPS dùng IP động (ví dụ mạng gia đình), dùng DNS động để luôn truy cập bằng domain. Dùng DuckDNS (miễn phí). Tạo script /usr/local/bin/duckdns-update.sh:
#!/bin/bash
DOMAIN="your-domain"
TOKEN="your-duckdns-token"
curl -s "https://www.duckdns.org/update?domains=$DOMAIN&token=$TOKEN&ip=" > /dev/null
sudo chmod +x /usr/local/bin/duckdns-update.sh
Thêm cron job chạy mỗi 5 phút:
*/5 * * * * /usr/local/bin/duckdns-update.sh >> /var/log/duckdns.log 2>&1
Verify: cat /var/log/duckdns.log, kiểm tra response "OK". Ping domain thử xem trùng IP VPS không. Workflow này hữu ích khi bạn thuê VPS Ubuntu có IPv4 tĩnh sẵn, nhưng nếu cần dự phòng, hãy thiết lập DNS động.
Xử lý lỗi thường gặp
Lỗi: Restic không kết nối được S3
Kiểm tra endpoint và credentials. Dùng lệnh: restic check. Thêm biến môi trường RESTIC_REPOSITORY chính xác. Nếu dùng Backblaze B2, đảm bảo bucket đã public? không, B2 private là được, Restic dùng key riêng.
Lỗi: Coolify không deploy được, báo lỗi "no space left"
Docker chiếm nhiều disk. Chạy docker system prune -a -f để dọn images cũ. Kiểm tra dung lượng: df -h. Nếu VPS dùng NVMe dung lượng nhỏ, hãy dọn thường xuyên.
Lỗi: Fail2ban không ban IP dù log có brute-force
Kiểm tra logpath có đúng không: sudo fail2ban-client status sshd. Xem filter: sudo fail2ban-client get sshd filter. Sửa jail.local: thêm logpath = /var/log/auth.log cho Ubuntu.
Câu hỏi thường gặp
Có cần thiết lập tất cả 7 workflow cùng lúc không?
Không. Ưu tiên workflow 1 (backup) và 6 (bảo mật) trước, vì đó là những thứ bảo vệ dữ liệu và hệ thống. Sau đó thêm workflow 2 và 3 (giám sát + cảnh báo) khi hệ thống có service production.
Coolify có thay thế được CI/CD như GitLab CI không?
Coolify phù hợp deploy ứng dụng nhỏ- vừa (Node.js, PHP, static site). Nếu cần CI/CD mạnh với test tự động, GitLab CI hoặc GitHub Actions vẫn tốt hơn. Coolify làm việc deploy nhanh, không làm pipeline phức tạp.
Logrotate có cần cấu hình cho Docker container không?
Có. Docker container log có thể làm đầy disk nhanh. Thêm flag khi chạy container: --log-opt max-size=10m --log-opt max-file=3 hoặc cấu hình trong daemon.json.
Dùng VPS giá rẻ có đủ chạy Prometheus + Grafana không?
VPS 2GB RAM chạy được. Prometheus + node_exporter dùng ~300MB, Grafana ~200MB. Nhưng nếu VPS đã chạy database và web, nên dùng bảng giá VPS để chọn gói 4GB RAM hoặc thuê máy chủ riêng nếu cần.
Telegram bot alert có gửi được cảnh báo disk đầy không?
Có. Thêm đoạn kiểm tra disk trong cron: df -h | awk '{if ($5+0 > 90) system("/usr/local/bin/alert-telegram.sh \"Disk full on $HOSTNAME\")"}'.
Bài viết liên quan
- Dùng rclone backup VPS lên Google Drive
- Giám sát VPS với Prometheus và Grafana từ host
- Gửi cảnh báo hệ thống VPS qua Telegram bot bằng script Bash
- Tự host PaaS kiểu Heroku trên VPS bằng Coolify


