Git push → running container, on your hardware
WatchTower deploys apps to servers you own over SSH. No proxies, no third-party build cloud, no per-deploy fees. Here's the full lifecycle.
The deploy pipeline
Trigger
GitHub webhook, manual button, scheduled cron, or CLI. WatchTower verifies the HMAC signature, dedupes replays, and enqueues a build.
Queue
If Redis is configured the build goes to RQ; otherwise it falls back to in-process BackgroundTasks. Builds survive API restarts on the Redis path.
Build
Worker clones the repo into $WATCHTOWER_BUILD_DIR, runs the build command, and packages the artifact. Build env detected via Nixpacks or your custom command.
Ship
rsync over SSH (via fabric) to each OrgNode registered to the project. SSH keys are encrypted at rest with Fernet.
Reload
Each node runs its configured reload command — systemd unit restart, container swap, nginx reload, whatever you set. WatchTower waits for healthy.
Observe
Deployment.status updates live in the dashboard. Failed deploys auto-rollback if the previous artifact is still on the node.
What's inside the WatchTower process
One FastAPI app at watchtower.api:app. Same process serves the React SPA from web/dist in production — no separate frontend server.
API + auth
Routers under /api/*. Auth via signed user-session token (GitHub OAuth or Device Flow) or a static WATCHTOWER_API_TOKEN for CI.
Database
SQLite by default at ~/.watchtower/watchtower.db. Postgres-capable via DATABASE_URL. Migrations are Alembic-driven.
Build queue
RQ + Redis when configured; FastAPI BackgroundTasks otherwise. Probe failure cached for the process lifetime so a missing broker doesn't add 2s to every webhook.
Builder
Clone → build → package → rsync → SSH reload. Per-deploy isolation in $WATCHTOWER_BUILD_DIR. Audit log records every mutation.
Container watcher
Optional watchtower start daemon polls running Podman containers, pulls newer images, and restarts on a schedule. Configured via config/watchtower.yml.
LLM agent
Provider-agnostic — speaks any OpenAI-compatible endpoint (Ollama, LM Studio, OpenAI, OpenRouter). Tools run under the caller's identity, no privilege escalation.
Your machines form a private mesh
Every computer you add — a laptop, a Mac mini, a Raspberry Pi, even a cloud box — joins one encrypted Tailscale network. They all see each other; the internet sees nothing until you say so.
Try it in 60 seconds
# 1. clone and run
git clone https://github.com/sinhaankur/WatchTower.git
cd WatchTower
./run.sh
# 2. open http://127.0.0.1:8000
# 3. (optional) connect a remote host via SSH from the dashboard,
# register a project, push to its git repo to trigger a deploy