Skip to content

Container logs

Stage container logs are at https://logs.evocase-iframe.io. Sign in with your @evo-verse.com Google account — the same Cloudflare Access wall as the admin panel and these docs. Nothing to install, no tunnel to start.

Access is by the same group as the admin panel (evocase-developers), not by email domain: a company account alone is not enough, and if you can open the admin panel you can open this. That is deliberate — see Access is credential access below.

You get every container on the stage VM: games-api, bo-api, worker, fe-backoffice, fe-embeds, postgres, redis, the storage emulator and cloudflared. Live tail, per-container regex search, and filtering by log level.

This is a live tail, not an archive

Docker keeps 30 MB of logs per container (max-size: 10m, max-file: 3) and drops the rest. For a busy api that is hours, not days. If you are looking for something from last night, it is already gone — see When you need more history.

What you can do

Follow a container live pick it from the sidebar
Search within a container / , or the search box — regex
Jump to a moment scroll up, or /container/<id>/<timestamp>
Filter by level the level chips above the stream
Several containers at once shift-click in the sidebar

Two limits worth knowing before they waste your time:

  • No cross-container search. You cannot ask "where did trace id abc123 go" across several services at once. Search each in turn.
  • Scrolling far back can skip entries. There is a known Dozzle bug where a long scroll silently jumps over multi-hour gaps that do exist on disk. Treat a gap as "unknown", not as "nothing happened".

Access is credential access

The UI reads the Docker API, and that API exposes every container's environment. On this stack that includes DOPPLER_TOKEN, which reads every secret in the project — not just one database password, as on the other stacks. Anyone who can open this page can read the stage database credentials.

That is inherent to reading container logs, not something the setup got wrong. It is why the page sits behind Access with the same policy as the admin panel, and why "give them logs access" is the same conversation as "give them the database password". It is not a lighter-weight permission.

When you need more history

For anything older than the buffer, or a search across containers, you still have a shell on the VM:

ssh deploy@evocases-iframe.taildb581b.ts.net
docker compose -f /srv/evocases-iframe/docker-compose.yml logs --since 2h api

Same Tailscale membership as Database and Redis. This reads the same 30 MB buffer, so it does not reach further back — it just lets you grep across services and pipe the result somewhere.

If "what happened last night" becomes a regular question, the fix is a log shipper to a hosted backend rather than a bigger buffer on a disk that Postgres shares. That is written up in notes/logging.md in the infra repo, with the volume estimate and current pricing.

Running it locally

cd infra
make logs-ui-up      # http://localhost:3003
make logs-ui-down

Local has no Access in front of it, so authentication is switched off entirely and there is no login — the bind to 127.0.0.1 is the only thing protecting it. Do not publish that port on a shared machine.

When it does not work

Symptom Cause
Google login loops, or "no policy" Not in the evocase-developers Access group — the same membership the admin panel needs. Ask an admin to add you there, not to this page
Page loads but the sidebar is empty The socket proxy is down; docker compose ps logs-socket-proxy on the VM
A container is missing from the list It is not running — Dozzle lists live containers, not stopped ones
Logs stop updating mid-stream The tunnel dropped the connection; reload the page
Reached the page without logging in Report this. Access is not in front of the hostname — see below

That last row is the one to take seriously. On the VM:

cd /srv/evocases-iframe && ./scripts/logs-ui-verify.sh

Nine checks: six that the UI cannot reach the Docker socket or publish a port, and three that an unauthenticated request — including one carrying a forged identity header — never reaches the origin. Run it after any change to the tunnel routes or the Access application. It exits with the number of failures, so it also works as a CI gate.