Watchdog uses a two-tier monitoring architecture:
/proc, Docker socket, running processes.Every check type declares its runner mode: DashboardOnly, AgentOnly, or Both.
Before starting an agent container, create an agent record in the Watchdog dashboard:
host-server or customer-acme)Each monitored server gets its own agent entry and token.
The watchdog compose files (compose.yml, compose.stage.yml) already include an agent service. It uses the same Docker image as the app but runs the agent process — no separate image needed.
Add WATCHDOG_AGENT_TOKEN to your environment file:
# .env.stage or .env.local
WATCHDOG_AGENT_TOKEN=your-token-here
# Stage
docker compose -f compose.stage.yml up -d agent
# Dev
docker compose up -d agent
The agent connects to the app container via the internal Docker network (http://app:80) — no external URL needed.
The Docker socket is commented out by default. Uncomment it in the compose file to enable Docker Container Health and Docker Exec checks:
# compose.stage.yml
agent:
volumes:
- /:/host/root:ro
- /var/run/docker.sock:/var/run/docker.sock:ro # uncomment this line
agent:
# Uses the same image as the app — no separate pull needed
image: watchdog-stage
environment:
WATCHDOG_DASHBOARD_URL: http://app:80 # Internal Docker network URL
WATCHDOG_AGENT_TOKEN: your-token # From Settings > Agents
HOST_ROOT: /host/root # Maps config paths to mounted host FS
TZ: Europe/Berlin
pid: host # Required for ProcessCheck
volumes:
- /:/host/root:ro # Required for disk/file/log checks
# - /var/run/docker.sock:/var/run/docker.sock:ro # Uncomment for Docker checks
restart: unless-stopped
To monitor a separate server (e.g. a customer server), deploy the standalone agent image there:
docker pull ghcr.io/markus-michalski/watchdog/agent:latest
Use docker-compose.agent.yml from the repository as a template:
# docker-compose.agent.yml
services:
watchdog-agent:
image: ghcr.io/markus-michalski/watchdog/agent:latest
restart: unless-stopped
environment:
WATCHDOG_DASHBOARD_URL: https://watchdog.yourdomain.com
WATCHDOG_AGENT_TOKEN: your-agent-token-here
HOST_ROOT: /host/root
TZ: Europe/Berlin
pid: host # Required for ProcessCheck
volumes:
- /:/host/root:ro # Required for disk/file/log checks
# - /var/run/docker.sock:/var/run/docker.sock:ro # Uncomment for Docker checks
Copy and adapt on the remote server:
# On the remote server
curl -O https://raw.githubusercontent.com/markus-michalski/watchdog/main/docker-compose.agent.yml
# Edit WATCHDOG_DASHBOARD_URL and WATCHDOG_AGENT_TOKEN
docker compose -f docker-compose.agent.yml up -d
The remote server must be able to reach the watchdog dashboard URL over HTTPS (or HTTP on private networks).
| Variable | Required | Description |
|---|---|---|
WATCHDOG_DASHBOARD_URL |
Yes | Base URL of the watchdog dashboard, no trailing slash. Use http://app:80 for host agents via Docker network, or https://watchdog.yourdomain.com for remote agents. |
WATCHDOG_AGENT_TOKEN |
Yes | Bearer token generated in the dashboard under Settings → Agents. |
HOST_ROOT |
For file/disk/log checks | Path prefix prepended to configured file paths. Set to /host/root when the host filesystem is mounted at that path. Without this, the check reads paths inside the container. |
TZ |
Recommended | Timezone for log timestamps (e.g. Europe/Berlin). |
| Check type | Volume/setting needed |
|---|---|
| Disk Space, File Age, File Size, Log File | - /:/host/root:ro + HOST_ROOT=/host/root |
| Process Running | pid: host |
| Docker Container Health, Docker Exec | - /var/run/docker.sock:/var/run/docker.sock:ro |
| HTTP, SSL, TCP, DNS, Redis, Database (Both mode) | No special mounts |
/api/v1/agent/config.run_now flags (triggered via "Run now" in the UI) and runs any checks that are due according to their configured interval./api/v1/agent/results in a single batch after each tick.Signal handling: the agent shuts down gracefully on SIGTERM and SIGINT.
Agent shows as offline in the dashboard
Check the agent container logs:
docker logs watchdog-stage-agent
Common causes:
WATCHDOG_AGENT_TOKEN not set or incorrectWATCHDOG_DASHBOARD_URL unreachable from the agent containerDisk/file checks return "Path not found"
The HOST_ROOT environment variable is not set, or the host filesystem is not mounted. Verify:
- /:/host/root:ro is in the volumes listHOST_ROOT: /host/root is set in the environmentProcessCheck always returns Fail
The pid: host option is missing from the agent service definition. Without it, the agent only sees its own container processes.