Logs
Build logs, container logs, and where each one actually lives.
Build logs
Every chunk of docker compose build output is published to a Redis pub/sub channel for the
live view and appended to a size-capped file on the server.
| Live | GET /deployments/:id/live — a Server-Sent Events stream |
| Archive | GET /deployments/:id/logs — read from the file, truncated from the front when the log is larger than the requested window |
| On the deployment row | logByteCount, and logTail — the last DEPLOY_LOG_TAIL_BYTES (4 KB) |
| File cap | DEPLOY_LOG_MAX_BYTES (16 MB) |
Log lines never reach PostgreSQL
Beyond the 4 KB tail on the row. A chatty build would otherwise bloat the database, and the database is the thing every other feature depends on.
Each chunk carries which stream it came from: stdout, stderr, or system — the last being
the platform's own commentary, such as a blue/green deployment saying it fell back to
recreate.
Secret scrubbing
Every line passes through one point on its way out, and that is where environment-variable values are removed. A build that echoes its environment does not publish it.
Container logs
Runtime logs are read from Docker on demand and are never persisted by the platform. What you see is what the Docker daemon is holding.
That is capped, deliberately, in two places:
/etc/docker/daemon.json, written by the installer:json-file, 10 MB across 3 files, as the daemon default.- The compose renderer, which writes the same caps into every service it renders
(
DEPLOY_CONTAINER_LOG_MAX_SIZE_MB,DEPLOY_CONTAINER_LOG_MAX_FILES).
An unbounded log file filling / is the single most common way a cheap VPS
dies. Both caps exist because either one alone can be bypassed — the daemon
default by a compose file that sets its own driver, and the per-service
setting by a container the platform did not render.
Platform logs
docker compose -p sthora logs -f api
docker compose -p sthora logs -f workerAnd on a machine running an agent:
docker logs -f sthora-agentThe audit log
Distinct from all of the above: the audit log records every mutating action and never records a secret's value.