Tại sao Crontab truyền thống là “cơn ác mộng” với Docker?
Nếu bạn từng phải SSH vào VPS chỉ để sửa một dòng backup trong file crontab của hệ thống, bạn sẽ hiểu nó phiền toái thế nào. Cách làm cũ thường là viết các câu lệnh kiểu docker exec -t my_container script.sh trực tiếp vào host. Cách này không chỉ thủ công mà còn tiềm ẩn nhiều rủi ro vận hành.
Dự án càng lớn, việc quản lý crontab càng trở nên khó kiểm soát. Bạn rất khó theo dõi log để biết task thành hay bại. Tệ nhất là khi container đổi tên hoặc restart, các câu lệnh crontab cũ sẽ hỏng hoàn toàn vì không tìm thấy ID container. Đó là lý do mình chuyển sang dùng Ofelia — một scheduler viết bằng Go, chiếm chưa đến 20MB RAM nhưng cực kỳ mạnh mẽ.
Ofelia: “Quản gia” thực thụ cho môi trường Docker
Thay vì là một bộ hẹn giờ đơn giản, Ofelia đóng vai trò như một container điều khiển. Nó giao tiếp trực tiếp với Docker Engine API để quản lý các tác vụ. Thay vì sửa file hệ thống, bạn chỉ cần khai báo labels ngay trong file docker-compose.yml của ứng dụng.
Những điểm “ăn tiền” khiến Ofelia vượt trội hơn hẳn:
- Cấu hình tập trung: Mọi thiết lập nằm gọn trong file Compose, đi theo ứng dụng từ môi trường Dev đến Prod.
- Cơ chế Docker-native: Ofelia tự nhận diện container qua tên hoặc label, không lo bị lỗi khi container thay đổi ID.
- Linh hoạt: Hỗ trợ nhảy vào container đang chạy (exec), tạo container tạm thời (run), hoặc chạy lệnh trên máy host (local).
- Gom log thông minh: Bạn không cần lục tìm log ở khắp nơi, Ofelia sẽ tập trung tất cả về một đầu mối duy nhất.
Bắt tay vào cài đặt và cấu hình
Cách tốt nhất để triển khai Ofelia là thông qua Docker Compose. Phương pháp này giúp bạn kiểm soát hạ tầng một cách minh bạch và dễ dàng bảo trì.
1. Khởi tạo dịch vụ Ofelia
Chúng ta cần một container Ofelia chạy ngầm để giám sát. Điểm mấu chốt là mount file /var/run/docker.sock ở chế độ ro (read-only) để Ofelia có quyền đọc thông tin các container khác mà vẫn đảm bảo an toàn.
version: '3.8'
services:
ofelia:
image: mcuadros/ofelia:latest
container_name: ofelia
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
command: daemon --docker
restart: always
2. Chạy Cron Job cho một Container cụ thể (Job-exec)
Hãy tưởng tượng bạn có một database MariaDB cần backup vào 2 giờ sáng mỗi ngày. Thay vì viết script bên ngoài, hãy thêm trực tiếp các label này vào service MariaDB của bạn:
services:
mariadb:
image: mariadb:10.6
labels:
ofelia.enabled: "true"
ofelia.job-exec.db-backup.schedule: "0 0 2 * * *"
ofelia.job-exec.db-backup.command: "sh -c 'mysqldump -u root -p$MYSQL_ROOT_PASSWORD --all-databases > /backups/db_$(date +%F).sql'"
Lưu ý: Ofelia sử dụng định dạng cron 6 trường (giây, phút, giờ, ngày, tháng, thứ). Trong ví dụ trên, lệnh backup sẽ thực hiện đúng vào giây thứ 0 của phút thứ 0, giờ thứ 2 sáng sớm.
3. Chạy task bằng Container tạm thời (Job-run)
Có những task bạn không muốn cài trực tiếp vào container chính để giữ nó gọn nhẹ, ví dụ như quét virus hoặc tối ưu hóa ảnh. Ofelia hỗ trợ job-run để khởi tạo một container mới, chạy xong tác vụ rồi tự động tiêu hủy.
labels:
ofelia.enabled: "true"
ofelia.job-run.cleanup.schedule: "@midnight"
ofelia.job-run.cleanup.image: "alpine"
ofelia.job-run.cleanup.command: "rm -rf /data/temp/*"
Sử dụng các alias như @midnight hay @every 12h giúp file cấu hình của bạn trông sạch sẽ và dễ đọc hơn rất nhiều.
Mẹo debug và tối ưu quy trình
Lỗi phổ biến nhất khi mới dùng Ofelia là viết sai cú pháp trong label. Khi job không chạy như ý, việc đầu tiên bạn nên làm là kiểm tra log của chính Ofelia:
docker logs -f ofelia
Nếu bạn tích hợp Ofelia với hệ thống logging tập trung hoặc cần kiểm tra dữ liệu JSON trả về từ Docker API, hãy cẩn thận với các đoạn text rối mắt. Để nhìn rõ cấu trúc log phức tạp, mình thường paste nhanh vào JSON Formatter tại toolcraft.app — giúp tiết kiệm đáng kể thời gian so với việc mở VS Code chỉ để format log.
Nâng cấp: Nhận thông báo ngay khi Job lỗi
Trong thực tế, việc một backup task bị fail mà không ai biết là điều cực kỳ nguy hiểm. Ofelia cho phép gửi thông báo qua Slack ngay lập tức nếu lệnh trả về mã lỗi khác 0.
[job-exec "critical-task"]
schedule = 0 */5 * * * *
container = web_app
command = php artisan monitor:health
slack-webhook = https://hooks.slack.com/services/T000/B000/XXX
slack-only-on-error = true
Tính năng này giúp bạn chủ động xử lý sự cố trước khi người dùng kịp phàn nàn. Bạn có thể dùng file config.ini thay cho label nếu số lượng job vượt quá con số 10 để dễ quản lý hơn.
Lời kết
Chuyển từ Crontab sang Ofelia giống như việc nâng cấp từ công cụ thủ công lên dây chuyền tự động. Nó giúp hạ tầng Docker của bạn chuyên nghiệp, dễ bảo trì và tin cậy hơn. Chỉ với vài dòng label, bạn đã giải quyết xong bài toán lập lịch tác vụ vốn cực kỳ đau đầu trên môi trường container.
Nếu bạn đang vận hành các hệ thống thực tế, hãy thử áp dụng Ofelia ngay. Sự an tâm khi biết mọi task đều được giám sát chặt chẽ là phần thưởng xứng đáng nhất cho nỗ lực tối ưu của bạn.

