docker: run as non-root, add HEALTHCHECK, document upaas deploy (closes #147)
check / check (push) Failing after 1s

The image had never been run. A trial run (fresh named volume, port 8080,
real targets, no notification endpoints) showed it exited at once: Viper
searches the working directory and, with a YAML config type, also matches an
extension-less file named dnswatcher, so the binary at /app/dnswatcher was
parsed as a config file. The binary now lives in /usr/local/bin and the
working directory is the data dir.

The runtime stage also gains an unprivileged dnswatcher user (uid 10001) that
owns /var/lib/dnswatcher, so a fresh named volume inherits writable ownership,
and a Docker HEALTHCHECK that probes /.well-known/healthcheck with busybox
wget. README gains a "Deploying with upaas" section.

Model: opus-4-8
This commit is contained in:
2026-09-21 07:56:04 +00:00
parent b351a2350c
commit df80bc1fb6
3 changed files with 53 additions and 6 deletions
+29
View File
@@ -467,6 +467,35 @@ docker run -d \
---
## Deploying with upaas
upaas builds this repo's `Dockerfile` and runs the resulting image with the
volume, port, and environment variables the operator enters. Configure:
- **Branch:** `main`. This is the recommended branch on the deployment
decision issue and is not yet confirmed by the owner.
- **Volume:** mount persistent storage at `/var/lib/dnswatcher`. The image runs
as an unprivileged user (`dnswatcher`, uid 10001) that owns this directory; a
fresh named volume inherits that ownership, and a bind-mounted host directory
must be writable by uid 10001.
- **Port:** the container listens on `8080`. Override with `PORT` if needed;
the healthcheck honours it.
- **Required environment:** `DNSWATCHER_TARGETS`, a comma-separated list of the
domains and hostnames to watch. The process refuses to start without it.
- **Recommended environment:** the notification endpoints
`DNSWATCHER_SLACK_WEBHOOK`, `DNSWATCHER_MATTERMOST_WEBHOOK`, and
`DNSWATCHER_NTFY_TOPIC` (without at least one, changes are only visible on the
dashboard); and `DNSWATCHER_METRICS_USERNAME` / `DNSWATCHER_METRICS_PASSWORD`
to enable the basic-auth-protected `/metrics` endpoint.
- **Healthcheck:** the image already declares a Docker `HEALTHCHECK` against
`/.well-known/healthcheck`; no operator configuration is needed. The same
path is available for an external probe.
The dashboard is unauthenticated and shows every watched name and recent alert;
decide deliberately whether to expose it publicly.
---
## Monitoring Lifecycle
1. **Startup**: Load state from disk. If no state file exists, start