Vấn đề với monitoring truyền thống
Prometheus + Grafana rất mạnh cho metrics server, nhưng khi chỉ cần biết “website có đang lên không?” hay “API có trả về 200 không?” — dựng cả một stack như vậy là quá tốn công. Trước khi dùng Gatus, mình SSH vào từng server kiểm tra thủ công. Bây giờ mở dashboard là thấy hết — trạng thái từng endpoint, lịch sử uptime, response time.
Gatus giải quyết đúng một bài toán: health check endpoint đơn giản, có Status Page đẹp, gửi cảnh báo Telegram khi có sự cố. Không cần database, không cần agent cài trên server, toàn bộ cấu hình là một file YAML.
Gatus là gì và tại sao chọn nó?
Về mặt kỹ thuật, Gatus là một binary Go duy nhất — deploy xong là chạy ngay, không cần runtime hay dependency nào thêm. Footprint cực nhẹ: RAM tiêu thụ thường dưới 20MB, startup dưới 1 giây. Tool hỗ trợ bốn loại check:
- HTTP/HTTPS — kiểm tra status code, body, response time
- TCP — kiểm tra port có mở không (database, Redis, v.v.)
- DNS — kiểm tra domain có resolve đúng không
- ICMP (ping) — kiểm tra host có reachable không
So với Zabbix hay Netdata, Gatus không giám sát CPU/RAM/disk — đó là việc của các tool khác. Gatus tập trung hoàn toàn vào “dịch vụ này có hoạt động đúng không?” — một góc nhìn bổ sung, không thay thế, cho hệ thống monitoring đã có.
Thứ mình thích nhất ở Gatus: Status Page tích hợp sẵn, không cần cài thêm plugin hay dịch vụ nào. Khách hàng hỏi “website bị gì vậy?” — share link status page là xong, không phải giải thích dài dòng qua chat.
Cài đặt Gatus bằng Docker Compose
Docker là cách nhanh nhất để bắt đầu. Tạo thư mục làm việc:
mkdir -p ~/gatus && cd ~/gatus
touch config.yaml docker-compose.yml
Nội dung file docker-compose.yml:
version: "3.8"
services:
gatus:
image: twinproduction/gatus:stable
container_name: gatus
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- ./config.yaml:/config/config.yaml
environment:
- GATUS_CONFIG_PATH=/config/config.yaml
Khởi động container:
docker compose up -d
docker compose logs -f gatus
Nếu không dùng Docker, build từ source cũng được:
git clone https://github.com/TwiN/gatus.git
cd gatus
go build -o gatus .
./gatus --config config.yaml
Cấu hình chi tiết
Cấu trúc cơ bản của config.yaml
web:
port: 8080
# Tùy chọn: đặt base-path nếu dùng reverse proxy subdirectory
# base-path: /status
storage:
type: sqlite # Lưu lịch sử uptime vào SQLite (thư mục /data)
path: /data/gatus.db
alerting:
telegram:
token: "1234567890:ABCdef..." # Bot token từ @BotFather
id: "-100123456789" # Chat ID (group dùng số âm)
default-alert:
enabled: true
failure-threshold: 3 # Cảnh báo sau 3 lần check liên tiếp thất bại
success-threshold: 2 # Thông báo recovered sau 2 lần check thành công
send-on-resolved: true # Gửi tin khi dịch vụ phục hồi
endpoints:
- name: "Website itfromzero.com"
url: "https://itfromzero.com"
interval: 5m
conditions:
- "[STATUS] == 200"
- "[RESPONSE_TIME] < 3000" # Response time < 3 giây
alerts:
- type: telegram
Giám sát nhiều loại endpoint
endpoints:
# HTTP endpoint với kiểm tra body
- name: "API Health Check"
url: "https://api.example.com/health"
interval: 2m
conditions:
- "[STATUS] == 200"
- "[BODY] == {\"status\":\"ok\"}" # Body phải chứa JSON này
- "[RESPONSE_TIME] < 1000"
alerts:
- type: telegram
failure-threshold: 2 # Override: cảnh báo sau 2 lần thất bại
# TCP — kiểm tra port database
- name: "PostgreSQL Port"
url: "tcp://db.internal:5432"
interval: 1m
conditions:
- "[CONNECTED] == true"
alerts:
- type: telegram
# TCP — Redis
- name: "Redis Cache"
url: "tcp://redis.internal:6379"
interval: 1m
conditions:
- "[CONNECTED] == true"
alerts:
- type: telegram
# DNS check — domain resolve đúng IP không
- name: "DNS itfromzero.com"
url: "dns://1.1.1.1"
dns:
query-name: "itfromzero.com"
query-type: "A"
interval: 10m
conditions:
- "[DNS_RCODE] == NOERROR"
# ICMP ping — server có reachable không
- name: "VPS Singapore"
url: "icmp://103.x.x.x"
interval: 5m
conditions:
- "[CONNECTED] == true"
Lấy Bot Token và Chat ID cho Telegram
Vào Telegram, nhắn tin cho @BotFather — gõ /newbot, đặt tên bot, rồi lưu lại token dạng 1234567890:ABCdef... mà BotFather trả về.
Để lấy Chat ID của group hoặc kênh:
# Thêm bot vào group, sau đó gọi API:
curl "https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates"
# Tìm "chat":{"id":-100xxxxxxxxx} trong response
Dùng biến môi trường cho thông tin nhạy cảm
Không nên hardcode token trong config. Gatus hỗ trợ env variable theo cú pháp ${VAR_NAME}:
alerting:
telegram:
token: "${TELEGRAM_BOT_TOKEN}"
id: "${TELEGRAM_CHAT_ID}"
Cập nhật docker-compose.yml để truyền biến:
services:
gatus:
image: twinproduction/gatus:stable
container_name: gatus
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- ./config.yaml:/config/config.yaml
- gatus_data:/data
env_file:
- .env
volumes:
gatus_data:
File .env:
TELEGRAM_BOT_TOKEN=1234567890:ABCdef...
TELEGRAM_CHAT_ID=-100123456789
Kiểm tra và sử dụng Monitoring Dashboard
Truy cập Status Page
Gatus chạy xong, mở http://your-server-ip:8080 là thấy ngay dashboard. Mỗi endpoint hiển thị trạng thái hiện tại (xanh/đỏ), response time trung bình, và uptime 7 ngày cùng 24 giờ gần nhất theo dạng block timeline — nhìn là biết ngay có vấn đề gì không.
Nếu muốn expose ra internet qua Nginx:
server {
listen 80;
server_name status.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Kiểm tra cảnh báo Telegram hoạt động
Thêm một endpoint test với điều kiện chắc chắn thất bại, sau đó xóa đi:
endpoints:
- name: "Test Alert"
url: "https://httpstat.us/503" # Luôn trả về 503
interval: 30s
conditions:
- "[STATUS] == 200" # Sẽ fail
alerts:
- type: telegram
failure-threshold: 1 # Cảnh báo ngay lần đầu
Restart Gatus và đợi 30 giây — nếu cấu hình đúng, Telegram sẽ nhận được tin nhắn cảnh báo với thông tin endpoint và lý do thất bại.
Xem log và debug
# Xem log realtime
docker compose logs -f gatus
# Kiểm tra config có parse đúng không
docker compose exec gatus cat /config/config.yaml
# Restart sau khi sửa config
docker compose restart gatus
Vài lưu ý thực tế khi vận hành
- failure-threshold nên đặt >= 2 để tránh cảnh báo nhầm do network hiccup tạm thời
- Endpoint production quan trọng thì
interval: 1m; endpoint ít quan trọng hơn thì5mlà đủ — tránh tạo quá nhiều request không cần thiết - Mount volume
/datara ngoài để lịch sử uptime không mất khi restart container - Nếu Gatus chạy trên cùng server với service cần monitor, thêm external check từ server khác để tránh false positive khi cả server down
Với setup này, mình không còn phải lo ngại việc website down mà không hay biết. Toàn bộ monitoring endpoint chỉ tốn một file YAML và một container — đơn giản hơn nhiều so với việc dựng Prometheus exporter cho từng dịch vụ.

