Commit Graph
8 Commits
Author SHA1 Message Date
clawbot b305942e5e Refuse invalid settings at start, health check follows PORT (closes #31)
check / check (push) Successful in 2m49s
PORT (1 to 65535) and XDG_DATA_HOME (an absolute path) are now checked in
the config package, which is built before the database opens, so a bad
value stops the start with an error and a non-zero exit instead of leaving
the daemon running without HTTP or putting the database somewhere else.
entrypoint.sh refuses a MALLOC_ARENA_MAX that is not a positive whole
number, since glibc ignores a bad one silently. The HEALTHCHECK probes the
port PORT names. The README corrects the Linux state directory, lists
XDG_DATA_HOME, and adds a "Running under upaas" section.

Model: opus-5-5
2026-09-28 17:05:36 +00:00
clawbot 08f060045b Cap glibc malloc arenas to keep non-Go RSS bounded (closes #23)
check / check (push) Successful in 3m44s
After the earlier memory work, SQLite's live heap is bounded but process
RSS still climbed about 70 MiB/min, nearly all anonymous and outside the
Go runtime and outside SQLite's own accounting, without any SQLITE_NOMEM.
The cause is glibc: the SQLite C library allocates and frees millions of
small page-cache chunks from many threads, and glibc keeps each arena's
freed chunks resident. With arenas uncapped it creates up to eight per
core, so on a large host RSS grows with the core count.

Set MALLOC_ARENA_MAX=2 in the image to bound the retained memory. Writes
are already serialized, so the two-arena cap costs no throughput. Update
the README Memory section.

Model: opus-4-8
2026-09-21 19:29:31 +02:00
clawbot 658aadbb81 Set GOMEMLIMIT in the image and document the memory budget (closes #13)
check / check (push) Failing after 1s
Add ENV GOMEMLIMIT=1536MiB to the runtime stage so the Go runtime keeps a
1.5 GiB soft heap limit. runuser preserves it the way it already does
XDG_DATA_HOME, so the routewatch process inherits it.

Add a Memory section to the README describing the budget (Go 1.5 GiB soft,
SQLite 640 MiB pool cache and 1.5 GiB hard heap, ~0.2 GiB other), the
required 5 GiB container limit, how to override GOMEMLIMIT, what happens at
each limit, and the DEBUG=routewatch System stats line. Every sentence
matches the behaviour already merged to next.

Model: opus-4-8
2026-09-21 17:29:29 +02:00
clawbot 54014c88c8 Run make check inside the Docker build with a pinned lint stage (closes #5)
REPO_POLICIES.md requires the container build to run the checks; the
Dockerfile only compiled the binary, so script/cibuild checked nothing. A
new lint stage on the golangci-lint v2.7.2 image runs make fmt-check and
make lint, and the build stage waits for it and then runs make test, so
make docker now fails when formatting, lint or a test fails. All three base
images are pinned by digest with their versions unchanged. The final image
and how it starts are unchanged.

make docker is now the gate to use on hosts where the installed linter is
older than the Go toolchain and make lint cannot run directly.

Model: opus-4-8 (implementation, review); fable-5-1 (summary)
2026-09-21 09:35:16 +02:00
sneak c6fa2b0fbd Fix container to run app as routewatch user
Use runuser to drop privileges and execute the app as the routewatch
user (uid 1000). Fix data directory permissions at runtime since host
mounts may have incorrect ownership.
2025-12-31 16:17:59 -08:00
sneak f788a0dbf9 set state dir properly in container 2025-12-31 16:08:17 -08:00
sneak 0ae89c33db Fix Dockerfile: vendor dependencies after copying source 2025-12-30 13:16:35 +07:00
sneak 8e79b8c074 Add Dockerfile with multi-stage build and source archive
- Builder stage: vendor dependencies, build binary, create source archive
- Source archive (.tar.zst) includes all code and vendored dependencies
- Runtime stage: minimal Debian image with binary and source archive
- Health check via curl to /.well-known/healthcheck.json
- Runs as non-root user (routewatch:1000)
2025-12-29 16:07:11 +07:00