1. Prepare the application
Add the labels and shared diagnostics volume before an incident. Docker cannot add them to an existing container, and recreating a failing application during an investigation can change the evidence.
services:
api:
environment:
DOTNET_EnableDiagnostics: "1"
volumes:
- api-dotnet-tmp:/tmp
labels:
tracebag.enabled: "true"
tracebag.environment: "production"
tracebag.displayName: "My API"
tracebag.logs.persist: "true"
tracebag.logs.parser: "auto"
tracebag.logs.retentionDays: "7"
tracebag.kind: "dotnet"
tracebag.dotnet.runtime: "8"
tracebag.dotnet.tmpVolume: "my_api_dotnet_tmp"
volumes:
api-dotnet-tmp:
name: my_api_dotnet_tmptracebag.enabled=true allows discovery and live logs. Searchable logs require the separate tracebag.logs.persist=true opt-in. The .NET labels and named /tmp volume enable counters and captures.
The value of tracebag.dotnet.tmpVolume must be the actual Docker volume name. The explicit name above prevents Compose from adding a project prefix.
2. Set up Tracebag on the host
This is a one-time setup. Download a pinned release and keep this directory on the server for later sessions.
mkdir tracebag && cd tracebag
export TRACEBAG_VERSION=0.1.3
curl -fsSLo compose.yaml \
https://raw.githubusercontent.com/poodlelab/tracebag/v${TRACEBAG_VERSION}/deploy/compose.release.yaml
curl -fsSLo compose.resident.yaml \
https://raw.githubusercontent.com/poodlelab/tracebag/v${TRACEBAG_VERSION}/deploy/compose.resident.yaml
curl -fsSLo .env.example \
https://raw.githubusercontent.com/poodlelab/tracebag/v${TRACEBAG_VERSION}/deploy/.env.release.example
cp .env.example .envGenerate a database secret and an administrator password hash. The password itself is not stored in .env.
postgres_password=$(openssl rand -hex 32)
sed -i.bak "s|^TRACEBAG_POSTGRES_PASSWORD=.*|TRACEBAG_POSTGRES_PASSWORD=${postgres_password}|" .env
read -rsp "Tracebag admin password: " admin_password; echo
password_hash=$(printf '%s\n' "${admin_password}" | \
docker run --rm -i ghcr.io/poodlelab/tracebag:${TRACEBAG_VERSION} hash-password admin)
unset admin_password
sed -i.bak "s|^TRACEBAG_ADMIN_PASSWORD_HASH=.*|TRACEBAG_ADMIN_PASSWORD_HASH=${password_hash}|" .env
rm -f .env.bak
chmod 600 .envSet TRACEBAG_ENVIRONMENT_LABEL in .env to the exact environment label on the prepared targets. This prevents another Compose project on the same host from appearing accidentally.
3. Give the session an HTTPS address
On a remote server, keep Tracebag on 127.0.0.1:9090 and route an existing HTTPS reverse proxy to it. Set the external address in .env:
TRACEBAG_BIND_ADDRESS=127.0.0.1
TRACEBAG_PORT=9090
TRACEBAG_PUBLIC_URL=https://tracebag.example.comThe proxy route can stay configured. It has no backend while Tracebag is stopped and becomes available when the session starts. Copy-ready Caddy, Nginx, and Traefik configurations are in the reverse-proxy guide.
For Tracebag running on your own computer, keep the defaults and use http://localhost:9090. An SSH port forward remains an optional fallback, not a requirement.
4. Start the session
docker compose --env-file .env -f compose.yaml pull tracebag-postgres tracebag
docker compose --env-file .env -f compose.yaml up -d --waitOpen TRACEBAG_PUBLIC_URL and sign in as admin. The first diagnostic for a declared .NET runtime takes longer because Tracebag downloads that runner image on demand.
5. Understand the available history
| Evidence | When a session starts |
|---|---|
| Live logs | Available while Tracebag runs. |
| Searchable logs | Tracebag ingests entries Docker still retains when persistence is enabled. Rotated logs cannot be recovered. |
| Counters and recordings | Collected from session start onward. |
| Stacks, traces, and dumps | Captured only when requested during the session. |
| Docker events | Collected from session start onward. |
6. End the session
docker compose --env-file .env -f compose.yaml downTracebag, PostgreSQL, and the Compose network are removed. The running backend no longer has Docker access. Named volumes retain the database, keys, logs, incidents, and artifacts for the next session.
--volumes deletes Tracebag's database, authentication keys, and collected evidence. Do this only when that data is no longer needed.Need continuous history?
Resident mode keeps Tracebag and PostgreSQL running after reboots. Use it when uninterrupted log ingestion or Docker-event history matters more than limiting the time Docker access is active.
docker compose --env-file .env \
-f compose.yaml -f compose.resident.yaml \
up -d --wait