Releases: jorgepb96/statainer
Release list
v0.9.20
Database moves into a data directory · repo no longer ships a database
Changed
- The database now lives in a dedicated data directory. Point configuration at a directory (
DATA_DIR, default/app/data) instead of a.dbfile — statainer manages theusers.dbfilename internally and creates it there on first start. The image pre-creates/app/dataand setsDATA_DIR=/app/data; the bundled compose already mounts./data:/app/data. USERS_DB_PATH(file or directory) is still honored for backward compatibility and takes precedence overDATA_DIR.
Migration (existing users)
- On startup, a database at the old
/app/users.dblocation is moved into the data directory automatically, so upgrading users keep their accounts and settings. The move is best-effort, idempotent and never blocks startup. - Deployments already using the bundled compose (
./data:/app/data) require no action — their database is already in the data directory.
Security
- Removed the committed
users.db(and a straytemplates/users.db) from the repository. They contained a real admin password hash and were tracked in a public repo. They are now untracked and ignored; the database is only ever created at runtime. (Docker images were never affected —.dockerignorealready excluded these files.) - Note: the old hash still exists in prior git history. Rotating the admin password is recommended if it was ever a real credential.
Tests
- Full suite: 100 passed (+5 new tests covering data-dir resolution and the legacy database migration).
Docker images
drakonis96/statainer:v0.9.20/:latestdrakonis96/dockerstats:v0.9.20/:latest
Multi-arch: linux/amd64, linux/arm64.
v0.9.19
Security hardening (login)
Defensive hardening of the authentication path. No configuration or API changes — all existing environment variables, endpoints and the external /api/v1 programmatic API behave exactly as before.
- User enumeration removed.
validate_usernow always performs a password-hash comparison (against a constant decoy hash when the username does not exist), so response timing no longer reveals which usernames are valid. - Constant-time CSRF validation. The submitted CSRF token is compared with
hmac.compare_digestinstead of==, removing a timing side-channel. - Rate limiter can no longer be a memory-exhaustion DoS. The in-memory per-IP attempt tracker purges expired buckets and caps tracked IPs (10,000), even under a flood of spoofed/rotating source IPs (e.g. attacker-controlled
X-Forwarded-For). Retry-Afterheader on rate-limited (429) responses for both page-based and Basic Auth (popup) login.- Login page marked non-cacheable (
Cache-Control: no-store) so intermediaries don't cache the form or its CSRF token.
Verified with the full test suite (95 passed, +9 new security tests).
Docker images
drakonis96/statainer:v0.9.19/:latestdrakonis96/dockerstats:v0.9.19/:latest
Multi-arch: linux/amd64, linux/arm64.
v0.9.18
v0.9.18
Patch release fixing the API access tab introduced in v0.9.17.
Fixed
- API access tab layout. The "Create key" button used the sticky action style and overlapped the scopes/keys list below it, making the panel look broken. It is now inline so the form, the one-time key reveal, and the existing-keys list flow cleanly.
- Each API scope now renders on its own full-width line (the global
.form-checkoverride is inline-block, which previously paired short scopes together inconsistently). - Restyled the Base URL hint into a subtle, self-contained box with light/dark variants.
Changed
- Added
?v=<app_version>cache-busting to the dashboard stylesheet and JS entry point so browsers and reverse proxies pick up new assets immediately after an update. This prevents a stale cachedcontext.jsfrom leaving the API access tab non-functional (form not wired, keys not listed) after upgrading.
Upgrade note: after updating, do a one-time hard refresh (Cmd/Ctrl+Shift+R) to drop any
context.jscached from v0.9.17.
Docker images
drakonis96/statainer:v0.9.18/:latestdrakonis96/dockerstats:v0.9.18/:latest
Both published for linux/amd64 and linux/arm64.
v0.9.17
v0.9.17
External programmatic API with scoped API keys
A new Settings → API access tab (admin only) exposes an optional, token-authenticated REST API for external tools.
Highlights
- Master toggle to enable/disable the whole API at runtime. While disabled, every key is rejected; keys keep their configuration.
- Named keys with granular scopes —
system:read,containers:read,stats:read,containers:start,containers:stop,containers:restart,containers:update— and an optional expiration (in days). - Reversible revocation: pause/resume a key without deleting it, or delete it to cut off access instantly.
- Tokens are shown once on creation and stored only as a SHA-256 hash — the plaintext is never persisted.
Endpoints (under /api/v1): GET /ping, GET /me, GET /system (CPU cores, max RAM, Docker info, counts), GET /containers, GET /containers/<id>, GET /stats, GET /containers/<id>/stats, and POST /containers/<id>/{start,stop,restart,update}. Authenticate with Authorization: Bearer <token>; the base URL follows however you reach the dashboard (direct IP:port or a reverse-proxy domain).
Hardening: per-key rate limiting, per-IP auth-failure throttling, audit logging of key management and write actions, optional HTTPS-only writes, and isolation from the session-auth UI routes.
New tuning env vars: EXTERNAL_API_RATE_LIMIT_MAX, EXTERNAL_API_RATE_LIMIT_WINDOW_SECONDS, EXTERNAL_API_AUTH_FAIL_MAX, EXTERNAL_API_AUTH_FAIL_WINDOW_SECONDS, EXTERNAL_API_REQUIRE_HTTPS_FOR_WRITE.
Full reference: API.md.
Docker images
drakonis96/statainer:v0.9.17/:latestdrakonis96/dockerstats:v0.9.17/:latest
Both published for linux/amd64 and linux/arm64.
v0.9.16
v0.9.16
Mobile improvements (all changes are mobile-only, desktop unaffected)
Notification panel
- Fixed notification panel not appearing when opened from sidebar
- Fixed ghost-state bug where panel CSS override kept it visible after closing
Update Manager mobile redesign
- Compact vertical layout: summary → search → sort/hide/refresh row → 2×2 tab grid → content
- Removed warning banners and subtitle on mobile
- Fixed massive vertical gaps caused by flex-grow on toolbar-actions
- Reduced toolbar spacing and margins for tighter layout
- Full-width search bar, responsive sort/filter controls
- 2-column grid for pane action buttons
Maintenance
- Updated .gitignore (added users.db, package-lock.json)
- Updated .dockerignore (added docker-compose*.yml, CHANGELOG.md, LICENSE, package.json, playwright.config.mjs)
v0.9.15
Added
- Login rate limiting: after 5 failed login attempts from the same IP, further attempts are blocked for 5 minutes (sliding window). Works for both page-based and Basic Auth (popup) login modes. Configurable via
LOGIN_RATE_LIMIT_MAX_ATTEMPTSandLOGIN_RATE_LIMIT_WINDOW_SECONDS. Set max attempts to0to disable.
Fixed
- Version footer: the Docker image now shows the actual version number instead of "dev" (the
VERSIONfile was missing from the container build).
v0.9.14
Fixed
- Login logo overflow and disproportionate sizing (consolidated styles, added max-width constraint, removed conflicting inline style block).
- Update Manager desktop button layout (toolbar/pane actions now use flex for proper wrapping).
- Sort dropdown arrow restored (CSS shorthand was removing Bootstrap background-image).
- Search icon alignment in toolbar pill.
- Checkboxes in all Update Manager tabs now clearly visible with themed styling and dark-mode support.
v0.9.13
Added
- Added Update Manager search, per-tab A-Z sorting,
Autoupdate selected, and mobile-style icon tabs that reveal labels only for the active section. - Added stricter backend deployment hardening with optional trusted-proxy support, secure session cookies, inactivity-based page-session expiry, and baseline security headers for reverse-proxy deployments.
Changed
- Unified the app version surfaces on
v0.9.13, including the UI footer, rendered pages, diagnostics payloads, SSE test fixtures, and release documentation. - Reworked the login screen so desktop and mobile now share the dashboard-style background and a simpler centered brand block.
Testing
- Expanded route and end-to-end coverage for Update Manager filtering, sorting, bulk auto-update, button sizing, version consistency, login rendering, and the new backend security headers and session policy.
v0.9.12
- Prevented Update Manager inventory rendering from falling back to live registry lookups when sampler cache details are missing, which keeps the modal responsive on slow or unreachable registries.
- Reused the already-built update candidate inventory for the auto-update tab so ready targets still appear there even when they do not currently have a pending update.
- Added a 15 second timeout to Update Manager fetches in the dashboard and surface a clearer error when Docker or registry metadata takes too long to respond.
v0.9.11
- Added a dedicated Auto-Update Management tab to the Update Manager with per-item enable and disable controls, support-aware inventory, and last update timestamps.
- Added background auto-update execution for opted-in standalone containers and Compose stacks when a newly detected update becomes available.
- Improved update notifications so they identify the updated container or stack and include the recorded version transition whenever it is available.