A monitoring tool that uses Telegram's scheduled messages to detect server downtime.
The bot continuously reschedules a message to be sent in the future for each monitored user. If the server goes down, it will stop rescheduling, and the message will be sent to the specified Telegram users, effectively alerting them about the server downtime.
This approach provides a reliable "dead man's switch" mechanism:
- While the server is running: The bot continuously reschedule the message
- If server fails: The message gets delivered, indicating system failure
- No false positives: Only triggers when the server actually stops working
The configuration is read from config.json at runtime. The binary looks for it in this order: the WATCHTOWER_CONFIG environment variable, the current working directory, then next to the executable.
- Create
config.jsonnext to the binary (or pointWATCHTOWER_CONFIGat it):
{
"api_id": your_api_id,
"api_hash": "your_api_hash",
"session_file": "watchtower.session",
"schedule_interval": 15,
"sleep_interval": 10,
"recipients": ["user1", "user2"]
}schedule_interval must be greater than sleep_interval, otherwise the alert fires while the server is still alive (validated on startup). recipients is optional and is used when --users is not passed. checks is optional; see Health checks.
- Get your API credentials from https://my.telegram.org/apps and update the config
For Linux (static binary):
# Install MUSL and build
sudo apt install musl-tools
rustup target add x86_64-unknown-linux-musl
cargo build --release --target x86_64-unknown-linux-muslFor Windows:
# Install MinGW and build
sudo apt install mingw-w64
rustup target add x86_64-pc-windows-gnu
cargo build --release --target x86_64-pc-windows-gnuPass recipients with --users, or omit it to use recipients from config.json:
Linux
$ ./watchtower-linux-x64 --users=user1,user2Windows
watchtower-win-x64.exe --users=user1,user2To run this program in the background in Linux you can use systemd, screen, nohup command & etc.
To run this program in the background using nohup command &, follow these steps:
- Run the binary for your platform for the first time. You will need to enter your phone number and the code received in Telegram. The program will create the watchtower.session file with information about the session. Then stop the program.
Linux:
$ ./watchtower-linux-x64 --users=user1,user2
Enter the phone number:
+123456789
Enter the code received in Telegram:
12345
Successfully singed in!
Saving session
# stop programm here- Now you can run this program in the background using nohup bash command.
Linux:
$ nohup ./watchtower-linux-x64 --users=user1,user2 &This command starts a process that will ignore the HUP signal and will not stop after the user logs off.
After the session file is created (see above), install the unit from deploy/:
$ sudo mkdir -p /opt/watchtower
$ sudo cp watchtower-linux-x64 /opt/watchtower/watchtower
$ sudo cp config.json watchtower.session /opt/watchtower/
$ sudo cp deploy/watchtower.service /etc/systemd/system/
$ sudo systemctl enable --now watchtowerRecipients come from config.json, so the service needs no arguments.
$ docker build -t watchtower .
$ docker run -d --name watchtower \
-v "$PWD/config.json:/app/config.json:ro" \
-v "$PWD/watchtower.session:/app/watchtower.session" \
watchtowerThe session file must be writable so the first interactive login can be reused.
Besides the dead man's switch, watchtower can actively probe targets. Add a checks list to config.json:
"checks": [
{ "type": "tcp", "name": "db", "addr": "127.0.0.1:5432", "timeout_secs": 5 },
{ "type": "http", "name": "api", "url": "https://example.com/health", "expected_status": 200, "body_contains": "ok" }
]Run them once (concurrently) and exit non-zero if any target is down:
$ watchtower checkThis is handy from cron or another monitor. Supported check types:
tcp— connect toaddrwithintimeout_secs.http— GETurland verifyexpected_status(default 200) and the optionalbody_containssubstring.
- Install Rust
- Clone repository
- Create and fill
config.jsonwith your credentials - Run
cargo build
The config is loaded at runtime, so cargo build no longer needs config.json to be present.
MIT