Sthora
Monitoring

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.

LiveGET /deployments/:id/live — a Server-Sent Events stream
ArchiveGET /deployments/:id/logs — read from the file, truncated from the front when the log is larger than the requested window
On the deployment rowlogByteCount, and logTail — the last DEPLOY_LOG_TAIL_BYTES (4 KB)
File capDEPLOY_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 worker

And on a machine running an agent:

docker logs -f sthora-agent

The audit log

Distinct from all of the above: the audit log records every mutating action and never records a secret's value.

On this page