A tiny self-hosted Sentry-compatible error tracking server.
2.7K
A tiny self-hosted Sentry-compatible error tracking server. One Rust binary, one SQLite file, an embedded SolidJS web UI, ~40 MB distroless image.
Crashbox accepts events from unmodified official Sentry SDKs (@sentry/node, @sentry/browser, …) by changing only the DSN. No custom SDK, no Postgres+Redis+Kafka+ClickHouse stack — just one container.
Not a full Sentry replacement: no performance traces, session replay, source maps, attachments, orgs/teams. If you need any of those, look elsewhere. If you want an error inbox for your side project tonight — this is it.
docker run -d --name crashbox \
-p 8080:8080 \
-v crashbox-data:/data \
-e [email protected] \
-e CRASHBOX_ADMIN_PASSWORD=change-me \
-e CRASHBOX_PROJECT_NAME=my-app \
-e CRASHBOX_PUBLIC_URL=http://localhost:8080 \
denyzhirkov/crashbox:1.1.0
Watch the logs once for the DSN:
INFO bootstrap: project DSN (shown once at startup)
dsn=http://<key>@localhost:8080/1
Point any Sentry SDK at it — only the DSN changes:
import * as Sentry from "@sentry/node"
Sentry.init({ dsn: "http://<key>@localhost:8080/1" })
Open http://localhost:8080, log in, your crashes are there.
| Tag | What |
|---|---|
denyzhirkov/crashbox:1.1.0 | Pinned 1.1.0 — recommended in production |
denyzhirkov/crashbox:latest | Floats to the newest release |
| Variable | Notes |
|---|---|
CRASHBOX_ADMIN_EMAIL | Bootstrapped on first boot. Required for first-run admin creation. |
CRASHBOX_ADMIN_PASSWORD | Hashed with argon2 on insert. Set strong; rotate via the CLI later if needed. |
CRASHBOX_PROJECT_NAME | Default project created on first boot. |
CRASHBOX_PUBLIC_URL | Base URL used to compose project DSNs. Set it to whatever address your SDKs will reach. |
| Variable | Default | What |
|---|---|---|
CRASHBOX_PORT | 8080 | Listen port |
CRASHBOX_RETENTION_DAYS | 30 | Events older than this are deleted (last N per issue protected) |
CRASHBOX_AUTO_RESOLVE_DAYS | 14 | Auto-resolve issues with no events for N days (auto-reopens on next event) |
CRASHBOX_MAX_EVENTS_PER_MINUTE_PER_PROJECT | 600 | Per-project ingestion cap |
CRASHBOX_GENERIC_WEBHOOK_URL | (unset) | POST notifications to a URL when new issue / re-open / spike. Telegram + Discord variants also exist. |
CRASHBOX_COOKIE_SECURE | false | Set true behind HTTPS |
Full reference: docs/configuration.md.
POST /api/:project_id/envelope[/] compatible with @sentry/node, @sentry/browser, and any SDK using the standard DSN/envelope formatdocker exec crashbox crashbox projects list, issues resolve <id>, backup /data/snap.db), Prometheus /metrics, atomic SQLite backups via VACUUM INTO/data — SQLite database, WAL file. Mount a named volume or a host path so you don't lose data on container restart.
GET /healthz — liveness · GET /readyz — readiness · GET /metrics — Prometheus
# minimal compose
services:
crashbox:
image: denyzhirkov/crashbox:1.1.0
restart: unless-stopped
ports: ["8080:8080"]
volumes: [crashbox-data:/data]
environment:
CRASHBOX_PUBLIC_URL: "http://localhost:8080"
CRASHBOX_ADMIN_EMAIL: "[email protected]"
CRASHBOX_ADMIN_PASSWORD: "change-me"
CRASHBOX_PROJECT_NAME: "my-app"
volumes:
crashbox-data:
gcr.io/distroless/cc-debian12:nonroot — glibc + ca-certificates + a non-root user, no shellnonroot:nonroot (uid 65532)/usr/local/bin/crashbox (same binary, serve is default; runs as CLI for other subcommands)MIT or Apache-2.0 at your option.
Content type
Image
Digest
sha256:6bed9e0f7…
Size
13.7 MB
Last updated
2 months ago
docker pull denyzhirkov/crashbox