Monitoring, Logging & Backup
Health checks, logging strategies, backup/restore cho PostgreSQL và Redis
Health Checks
Health checks cho Docker biết container có đang hoạt động bình thường không. Nếu health check fail, Docker có thể tự restart container:
Health check trong docker-compose.yml
# ── ASP.NET API ── backend: healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s # Kiểm tra mỗi 30 giây timeout: 10s # Timeout sau 10 giây retries: 3 # Sau 3 lần fail → unhealthy start_period: 40s # Chờ 40s khi khởi động (warm-up) # ── PostgreSQL ── postgres: healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 10s timeout: 5s retries: 5 # ── Redis ── redis: healthcheck: test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"] interval: 10s timeout: 5s retries: 5
ASP.NET Health Endpoint
// Program.cs var builder = WebApplication.CreateBuilder(args); // Đăng ký health checks builder.Services.AddHealthChecks() .AddNpgSql( builder.Configuration.GetConnectionString("DefaultConnection")!, name: "postgresql", tags: new[] { "db", "ready" }) .AddRedis( builder.Configuration["Redis:ConnectionString"]!, name: "redis", tags: new[] { "cache", "ready" }); var app = builder.Build(); // Map health endpoint app.MapHealthChecks("/health", new HealthCheckOptions { // Trả về chi tiết từng dependency ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse }); // Endpoint đơn giản chỉ check app alive app.MapHealthChecks("/health/live", new HealthCheckOptions { Predicate = _ => false // Không check dependencies });
/health (readiness — bao gồm database, cache) và /health/live (liveness
— chỉ check app sống). Docker health check nên dùng /health. Load balancer dùng
/health/live để tránh false negative khi database tạm chậm.
Logging
Docker tự capture stdout/stderr của mỗi container. Các lệnh xem logs:
# Xem logs tất cả services docker compose logs # Follow logs real-time docker compose logs -f # Logs của một service cụ thể, 100 dòng cuối docker compose logs -f --tail=100 backend # Logs với timestamp docker compose logs -t backend # Logs trong khoảng thời gian docker compose logs --since="2024-01-15T10:00:00" backend docker compose logs --since="1h" backend # 1 giờ gần nhất
Cấu hình Log Rotation
Mặc định Docker không giới hạn log size — logs có thể chiếm hết disk space:
# docker-compose.yml — Thêm vào mỗi service backend: logging: driver: "json-file" options: max-size: "10m" # Max 10 MB per log file max-file: "3" # Giữ tối đa 3 files (30 MB total)
max-size và max-file cho production.
Hoặc cấu hình global cho toàn bộ Docker daemon:
// /etc/docker/daemon.json { "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }
ASP.NET Logging cho Production
Cấu hình logging level phù hợp cho production (giảm noise, giữ thông tin quan trọng):
// appsettings.Production.json { "Logging": { "LogLevel": { "Default": "Warning", "Microsoft.AspNetCore": "Warning", "Microsoft.EntityFrameworkCore": "Error", "MyApp": "Information" }, "Console": { "FormatterName": "json" } } }
MyApp giữ ở Information để log
business logic, framework giữ ở Warning để giảm noise.
Backup & Restore
PostgreSQL Backup
# ── Manual backup ── docker compose exec postgres pg_dump \ -U myapp_user \ -d myapp_db \ --format=custom \ --compress=9 \ > backup_$(date +%Y%m%d_%H%M%S).dump # ── Restore từ backup ── docker compose exec -T postgres pg_restore \ -U myapp_user \ -d myapp_db \ --clean --if-exists \ < backup_20240115_100000.dump # ── Automated daily backup (cron) ── cat > /home/$USER/backup-db.sh << 'EOF' #!/bin/bash BACKUP_DIR="/home/$USER/backups" KEEP_DAYS=7 mkdir -p $BACKUP_DIR cd /home/$USER/my-app # Tạo backup docker compose exec -T postgres pg_dump \ -U myapp_user -d myapp_db \ --format=custom --compress=9 \ > "$BACKUP_DIR/db_$(date +%Y%m%d_%H%M%S).dump" # Xóa backup cũ hơn 7 ngày find $BACKUP_DIR -name "db_*.dump" -mtime +$KEEP_DAYS -delete echo "[$(date)] Backup completed" EOF chmod +x /home/$USER/backup-db.sh # Chạy mỗi ngày lúc 2:00 AM (crontab -l; echo "0 2 * * * /home/$USER/backup-db.sh >> /var/log/db-backup.log 2>&1") | crontab -
Redis Backup
Redis tự tạo RDB snapshot theo interval mặc định (sau 3600 giây nếu có ít nhất 1 thay đổi).
Backup: Copy file dump.rdb từ volume:
# Trigger save thủ công docker compose exec redis redis-cli -a $REDIS_PASSWORD BGSAVE # Copy RDB file ra ngoài docker cp $(docker compose ps -q redis):/data/dump.rdb ./backups/redis_backup.rdb
Restore: Stop Redis, copy dump.rdb vào volume, start lại.
AOF log mọi write operation, cho phép khôi phục gần như 100% dữ liệu:
redis: command: > redis-server --requirepass ${REDIS_PASSWORD} --appendonly yes --appendfsync everysec
--appendfsync everysec sync mỗi giây — cân bằng giữa durability và performance. Tối đa
mất 1 giây dữ liệu khi crash.
Monitoring cơ bản
Các lệnh giám sát tài nguyên của Docker containers:
# Real-time resource usage (CPU, Memory, Network I/O) docker stats # Resource usage của compose stack docker compose stats # Disk usage tổng quan docker system df # Chi tiết disk usage docker system df -v # Xem health status docker compose ps # Output: NAME STATUS PORTS # backend Up 2 hours (healthy) 8080/tcp # postgres Up 2 hours (healthy) 5432/tcp
docker-compose.yml.
Uptime Check đơn giản
Script kiểm tra hệ thống còn hoạt động và gửi alert nếu down:
cat > /home/$USER/check-health.sh << 'EOF' #!/bin/bash URL="https://app.example.com/api/health" WEBHOOK="https://hooks.slack.com/services/YOUR/WEBHOOK/URL" HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 $URL) if [ "$HTTP_CODE" != "200" ]; then curl -s -X POST $WEBHOOK \ -H "Content-Type: application/json" \ -d "{\"text\": \":red_circle: App DOWN! Health check returned $HTTP_CODE\"}" fi EOF chmod +x /home/$USER/check-health.sh # Chạy mỗi 5 phút (crontab -l; echo "*/5 * * * * /home/$USER/check-health.sh") | crontab -