Environment Variables
All configuration options for the Rustrak server. None is needed to start it
except SESSION_SECRET_KEY in production: the defaults run SQLite, serve the
dashboard and listen on 8080.
Server
| Variable | Default | Description |
|---|---|---|
HOST | 0.0.0.0 | TCP bind address |
PORT | 8080 | Server port, for the API and the dashboard |
RUST_LOG | info | Log level (trace, debug, info, warn, error) |
RUSTRAK_LOG_TIMEZONE | UTC | IANA timezone name for log timestamp display (e.g. Asia/Shanghai) |
PUBLIC_URL | (none) | Public-facing URL used in DSN strings and alert links |
HOST
The network interface the server listens on. The default (0.0.0.0) means “all interfaces” and is correct for Docker, so you don’t need to set it.
Only change this if you want to restrict access to a specific interface:
HOST=127.0.0.1 # loopback only, e.g. for local dev behind a local proxyDocker note: If you set
HOST=127.0.0.1inside a container, the port mapping won’t work and the server will be unreachable.
PUBLIC_URL
The address your SDKs and your team reach the server on. Rustrak writes it into every DSN and, unless DASHBOARD_URL says otherwise, into the issue links in alert notifications. Must include the scheme (http:// or https://). Trailing slashes are stripped automatically.
# Production (behind reverse proxy)
PUBLIC_URL=https://rustrak.example.com
# Self-hosted with custom port
PUBLIC_URL=http://192.168.1.10:9090Why this matters: HOST=0.0.0.0 is the TCP bind address. It means “listen on all interfaces” and is not a routable address. Without PUBLIC_URL, the DSN shown in the dashboard contains http://0.0.0.0:8080/..., which your SDK cannot reach. Set it even locally, e.g. PUBLIC_URL=http://localhost:8080.
RUSTRAK_LOG_TIMEZONE
Converts the timestamps in the server’s process logs (stdout: HTTP requests, background workers, event digestion, everything under RUST_LOG) to a specific IANA timezone for easier correlation with logs from other systems.
RUSTRAK_LOG_TIMEZONE=Asia/ShanghaiUse an IANA zone name (e.g. Asia/Shanghai, America/New_York, Europe/Madrid), not a fixed UTC offset, so daylight saving time is handled correctly. If unset, or set to a name that isn’t a recognized IANA zone, logs fall back to UTC and the server still starts normally (a warning is logged when the value is invalid).
Scope: this only affects how log lines are displayed. Event and issue timestamps are always stored and returned as UTC.
Dashboard
The dashboard is on by default, served from / on the same port and origin as the API. Nothing here needs setting for that.
| Variable | Default | Description |
|---|---|---|
RUSTRAK_DASHBOARD | on | Whether to serve the dashboard at all. off keeps the server API-only |
DASHBOARD_URL | PUBLIC_URL | Base URL for the issue links in notifications |
RUSTRAK_DASHBOARD_DIR | ./static | Where the compiled dashboard lives, relative to the working directory or absolute |
RUSTRAK_DASHBOARD
off keeps the dashboard unmounted even though the image carries a build. Use it for a server that should answer the API only, or when the dashboard runs from another host.
RUSTRAK_DASHBOARD=offon, off, true, false, 1 and 0 are accepted. Anything else refuses to start, deliberately: a typo that silently left the dashboard on would expose a UI you meant to keep off the box.
DASHBOARD_URL
The issue links in alert notifications follow PUBLIC_URL, because the server serves the dashboard itself. Set DASHBOARD_URL only when people open the dashboard on a different host than PUBLIC_URL: a separate ingestion hostname, or a rustrak-ui container. With neither set, the links use the server’s bind address.
RUSTRAK_DASHBOARD_DIR
The image already puts the dashboard at /app/static, which is what the default resolves to, so you do not normally set this. The dashboard is mounted when the directory holds an index.html and skipped when it does not.
# Serve a dashboard you built and mounted yourself
RUSTRAK_DASHBOARD_DIR=/srv/rustrak-dashboardRUSTRAK_API_URL is not a server variable. It belongs to the optional rustrak/rustrak-ui image, for a dashboard on its own host, and names the server that image proxies the API to.
The update check
The dashboard compares the running server’s version against the release feed published on GitHub Pages, and shows a notice when a newer one exists. The request is made by each reader’s browser. Nothing about the instance is sent: it is a plain GET for a public JSON file, and a blocked or unreachable feed simply means no notice appears.
Security
| Variable | Default | Description |
|---|---|---|
SSL_PROXY | false | Set to true when behind HTTPS proxy (nginx, Cloudflare) |
SESSION_SECRET_KEY | (random) | 64-character key for session encryption |
SSL_PROXY
Set to true when running behind a reverse proxy that terminates SSL (nginx, Cloudflare, etc.). This enables secure cookies.
SSL_PROXY=trueWhen SSL_PROXY=true:
- Cookies are sent only over HTTPS (
Secureflag enabled) SESSION_SECRET_KEYbecomes required
SESSION_SECRET_KEY
Generate with:
openssl rand -hex 32- Development: Optional (a random key is used, sessions don’t persist across restarts)
- Production with
SSL_PROXY=true: Required
The key must be at least 64 characters, which is what openssl rand -hex 32 produces: the cookie key is a 256-bit signing key followed by a 256-bit encryption key. Anything shorter is refused at startup with the length it received, so openssl rand -base64 32 (44 characters) will not do. Changing the key invalidates every existing session.
OpenID Connect SSO
Optional sign-in through Pocket ID, Authentik, Keycloak, Google or any other
OpenID Connect provider. SSO is off unless OIDC_ISSUER_URL is set. See
Single Sign-On for how it works, a step-by-step setup
and troubleshooting.
| Variable | Default | Description |
|---|---|---|
OIDC_ISSUER_URL | (disabled) | Provider issuer URL used for discovery |
OIDC_CLIENT_ID | (required) | Client ID issued to Rustrak |
OIDC_CLIENT_SECRET | (required) | Client secret issued to Rustrak |
OIDC_REDIRECT_URL | (required) | Exact callback URL, ending in /auth/sso/callback |
OIDC_PROVIDER_NAME | SSO | Label on the login button |
OIDC_SCOPES | openid email profile | Space-separated scopes |
OIDC_AUTO_PROVISION | false | Create an account for someone whose email has none |
OIDC_LINK_EXISTING_ACCOUNTS | false | Link to an existing account without asking for its password |
OIDC_REQUIRE_EMAIL_VERIFIED | true | Refuse identities whose email the provider has not verified |
OIDC_ALLOWED_DOMAINS | (all) | Comma-separated email domains allowed to use SSO |
Database
| Variable | Default | Description |
|---|---|---|
DATABASE_URL | sqlite:///data/rustrak.db | Database connection string. Required only for PostgreSQL |
DATABASE_MAX_CONNECTIONS | 10 | Maximum pool connections |
DATABASE_MIN_CONNECTIONS | 1 | Minimum pool connections |
DATABASE_URL
The backend is chosen by the image: latest is SQLite, postgres is PostgreSQL. See Database backends.
SQLite (optional, the default above is right for Docker):
# Absolute path
DATABASE_URL=sqlite:///var/lib/rustrak/rustrak.db
# In-memory (for testing only, data lost on restart)
DATABASE_URL=sqlite::memory:PostgreSQL (required with the postgres image):
# Format
postgres://username:password@host:port/database
# Examples
DATABASE_URL=postgres://rustrak:rustrak@postgres:5432/rustrak # Docker
DATABASE_URL=postgres://user:pass@host:5432/rustrak?sslmode=require # With SSLRate Limiting
| Variable | Default | Description |
|---|---|---|
MAX_EVENTS_PER_MINUTE | 60000 | Max events/minute (global) |
MAX_EVENTS_PER_HOUR | 1000000 | Max events/hour (global) |
MAX_EVENTS_PER_PROJECT_PER_MINUTE | 20000 | Max events/minute per project |
MAX_EVENTS_PER_PROJECT_PER_HOUR | 300000 | Max events/hour per project |
The defaults are a brake for a runaway loop that would fill the disk, not a cap
on ordinary spikes. Windows are fixed minutes and hours, and the limit is
exact: once a window is full, ingest answers 429 with Retry-After and
X-Sentry-Rate-Limits, and the SDK waits before sending again. An event that
was already accepted when its window filled is dropped rather than stored, and
counted in the project’s rate_limited_event_count.
Storage
| Variable | Default | Description |
|---|---|---|
INGEST_DIR | /tmp/rustrak/ingest | Temporary event storage |
SOURCEMAP_STORAGE_PATH | /data/sourcemaps | Directory for source map chunk storage |
SOURCEMAP_CACHE_MB | 64 | Memory kept for parsed source maps across events |
SOURCEMAP_STORAGE_PATH
Where Rustrak stores source map chunks uploaded by Sentry SDKs. The default is inside the /data volume, so with -v rustrak_data:/data they persist with no setting. Chunks are stored in a content-addressable layout: a SHA-1 hash like abc123... is written to {SOURCEMAP_STORAGE_PATH}/ab/c123....map.
SOURCEMAP_STORAGE_PATH=/var/lib/rustrak/sourcemapsStorage sizing: Each source map chunk is typically around 2MB. Multiply by the number of distinct source files across all your deployments. A typical JavaScript app with 50 source files uses around 100MB.
Multi-server deployments: All server instances must read and write from the same SOURCEMAP_STORAGE_PATH. Mount a shared volume (NFS, EFS, a network filesystem) and point every instance at it. Without this, chunks uploaded to one instance won’t be visible to others during bundle assembly.
SOURCEMAP_CACHE_MB
Once a source map has been read and parsed for one event, Rustrak keeps the parsed form in memory so the next event that hits the same file skips both steps. This budget caps that memory, measured as the size of the source map files it holds, and the least recently used map is dropped first. A map larger than the whole budget is never kept.
SOURCEMAP_CACHE_MB=64The cache only saves the file read and the parse. Which file a debug_id points to is looked up in the database on every event, so a deleted or re-uploaded source map takes effect immediately. Size it to hold the maps your errors actually hit: a handful of large Next.js server bundles is usually enough, and the default covers a 15 MB map four times over.
Email Alerts (SMTP)
Global SMTP settings for email notifications. Channels can override these.
| Variable | Default | Description |
|---|---|---|
SMTP_HOST | - | SMTP server hostname |
SMTP_PORT | 587 | SMTP port (587 for STARTTLS, 465 for SSL) |
SMTP_USERNAME | - | SMTP username |
SMTP_PASSWORD | - | SMTP password |
SMTP_FROM | alerts@rustrak.local | Default sender address |
Bootstrap
| Variable | Description |
|---|---|
CREATE_SUPERUSER | Create admin user on startup (email:password) |
CREATE_SUPERUSER="admin@example.com:secure-password"Only creates the user if the database has no users yet. After that it is ignored.
Prometheus metrics
RUSTRAK_METRICS=on enables GET /metrics on the server’s existing port. It is off by default (the route returns 404); only on and off are accepted. This is independent of anonymous telemetry and does not send data anywhere.
The scrape reports ingest totals and latency, digest outcomes, 5xx responses by matched route, and failed alerts by provider. It also reports the pending spool (count, bytes and oldest-file age) and database size, read at most once every 15 seconds. Counters reset on restart, not when anonymous telemetry sends a report. Labels never contain project IDs, user details or event contents.
/metrics has no application authentication. Keep it on a trusted network or restrict it at the reverse proxy. The standalone dashboard image does not forward it, so point Prometheus at the server.
RUSTRAK_METRICS=on
curl http://localhost:8080/metricsTelemetry
| Variable | Default | Description |
|---|---|---|
RUSTRAK_TELEMETRY | on | Anonymous usage report every 6 hours. off sends nothing |
DO_NOT_TRACK | unset | 1 sends nothing either; the cross-tool convention |
Either variable on its own is enough to turn it off. What the report contains, field by field, is on the Telemetry page.
Complete Example
SQLite (image tag latest)
SESSION_SECRET_KEY=generate-your-own-with-openssl-rand-hex-32
PUBLIC_URL=https://rustrak.example.com
SSL_PROXY=trueThat is the whole configuration. The database defaults to /data/rustrak.db and the dashboard is served from /.
PostgreSQL (image tag postgres)
DATABASE_URL=postgres://rustrak:password@postgres:5432/rustrak
# Security (required behind an HTTPS proxy)
SSL_PROXY=true
SESSION_SECRET_KEY=generate-your-own-with-openssl-rand-hex-32
# Server: SDKs, the dashboard and alert links all use this address
PUBLIC_URL=https://rustrak.example.com
RUST_LOG=info
# Database Pool
DATABASE_MAX_CONNECTIONS=20
# Rate Limiting (only to lower the defaults on small hardware)
MAX_EVENTS_PER_MINUTE=10000
MAX_EVENTS_PER_HOUR=200000
# Email Alerts (optional, can also be set per channel)
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USERNAME=alerts@example.com
SMTP_PASSWORD=your-smtp-password
SMTP_FROM=alerts@example.com