v1.0.0 · released 5 November 2026
Changelog
Release notes from 1.0.0 onward. The full history lives in the repository.
All notable changes to Rivetr are documented here. The format follows Keep a Changelog and Semantic Versioning. The full history is in the repository.
[1.0.0] - 2026-11-05
First stable release. Everything below the highlights was previously listed as unreleased.
Highlights
- New dashboard shell: grouped sidebar with submenus, a contextual sidebar inside apps, databases, services and servers, a top bar with breadcrumb switchers (team, project, environment, resource), a status pill and the primary action. Shared page components (page header, framed section cards, form grid, data table with pagination, empty states, skeletons).
- Clear page structure and URLs: every page sits in one place and has breadcrumbs. Instance settings under
/settings, personal pages under/account, team under/team, integrations under/integrations, credentials under/keys, monitoring under/monitoring. App, database and service sections use the same names (/build,/domains,/environment,/storage,/healthcheck,/resources,/advanced,/rollback,/operations,/danger). Duplicate tabs (two Network, two Security, a Settings tab with its own tab strip) are gone. Old URLs redirect. Seedocs/planning/ui-information-architecture.md. - Projects canvas: zoomable canvas of projects, environments and resources with live status, a side panel, filters and resource links; list, grid or canvas view on the dashboard and projects page.
- Theme customisation per user: light, dark or system mode, accent colour (presets or custom hex), neutral base, corner radius, density, font and size, sidebar style, reduced motion and high contrast, with a live preview. Saved to the account (migration 129), applied before first paint; admins set the instance default under Settings > Branding.
- Remembered UI state: sidebar collapse and open groups, view toggles, canvas viewport and filters, table page size and filters, log viewer options, terminal font size, metric time ranges, in-page tabs and command palette recents are kept per browser (
rivetr:ui:*). - Instance settings: editable update channel and schedules, Advanced page (registration, API access with IP allowlist, MCP toggle, two-step destructive confirmation, DNS validation with custom resolvers, outbound target policy, passkeys), public IPv4/IPv6 detection, transactional email (SMTP or Resend) with a test send (migration 123).
- Server operations: images page with reclaimable space, Docker cleanup schedule with per-category options and run history, OS patching with automatic security updates, maintenance window and reboot detection, patch status on the servers list (migration 124). Non-root SSH users with passwordless sudo, and Tailscale connectivity per server (migration 131).
- App configuration: structured healthcheck (HTTP or command, expected code and body, timing), per-domain internal port, search indexing and DNS status, an unsaved-changes bar, a container file browser for apps, databases and services, and clone to another server, project or environment with optional volume data (migration 125).
- Tags (migration 126), passkey sign-in (migration 127) and traffic analytics per app, server and team with optional GeoIP (migration 128).
- AI-generated Docker Compose from a description, advanced Swarm service spec (migration 130), and 30 new service templates (365 total).
Breaking
- Dashboard URLs changed (old ones redirect). API paths are unchanged.
- The MCP server can now be turned off; existing installs keep it on.
smtp_tls = trueinrivetr.tomlnow means STARTTLS, or implicit TLS on port 465.- Swarm services are created through the Docker API instead of the
docker service createCLI.
Added
-
Deployments for Docker Compose services: a Deploy button pulls (or builds) the images and runs
docker compose up -d, recreating only changed containers. Each run is recorded with who started it, the trigger, duration, live and stored logs, and the image digest per compose service before and after (migration 120). Optional build from source per service (migration 121): a git repo + branch or a path on the server, images built in order, tagged with the revision andlatestand pushed (a localregistry:2works), with auto deploy on push for git sources. Pre- and post-deploy hooks run in a one-off container of a compose service (docker compose run --rm --no-deps); a failed pre-deploy hook leaves the running containers, the compose file and thelatesttags as they were. Rollback redeploys a previous deployment's images pinned by digest. New Containers tab (state, health, usage, restart one container, logs, terminal) and Environment tab: encrypted env vars (migration 122) written to a managed.envthe compose file can use, with.envimport. Services without a build source keep deploying by pulling. Seedocs/reference/service-deployments.md. -
Storage usage for apps and services: the Storage tile that databases already had now shows on app and Docker Compose service pages too. It counts the container's writable layer plus its mounted volumes; a service counts a volume its containers share only once. Sizes are measured at most once a minute per container, so polling stays cheap. Docker only for now; on Podman the tile stays hidden.
-
Rollback with data (pre-deploy database snapshots): new per-app
snapshot_before_deploysetting (default off; Settings > Deployment > Rollback with Data, orPUT /api/apps/:id). When on, every deployment snapshots each linked PostgreSQL, MySQL, MariaDB, MongoDB, Redis and KeyDB database right before the new container starts, reusing the managed database backup code (backup typepre_deploy, linked via the newdeployment_db_snapshotstable, migration 115). A failed or skipped snapshot is logged in the deployment log and never blocks the deploy.POST /api/deployments/:id/rollbackacceptsrestore_data: trueto restore the snapshots taken while the target deployment was running, after the rollback container is healthy and the old container is retired; it returns 400 before doing anything if the target has no usable snapshot. Before overwriting a database a safety backup of its current data is taken (the database is skipped if that fails). Data written after the snapshot is lost on restore. Per engine: PostgreSQL replays the dump in one transaction after dropping thepublicschema; MySQL and MariaDB drop every table and view in the database, then replay the dump (exact rollback, but not transactional: a dump that fails midway leaves a partial database, which the safety backup covers); MongoDB takes amongodump --archive, validates it withmongorestore --dryRunbefore touching anything, then drops the app database and restores the archive (exact rollback;admin,localandconfigare never dropped); Redis and KeyDB take an RDB withredis-cli --rdb(AUTH is used only when the server asks for it) and restore by stopping the database container, replacingdump.rdbin its data volume and starting it again, which means a few seconds of downtime for that database. Redis/KeyDB restore needs the data volume on the Rivetr host and no AOF persistence; this is checked before the rollback starts (the rollback returns 400, and a deploy logs that the snapshot was skipped). DragonflyDB and ClickHouse are not snapshotted. MongoDB, Redis and KeyDB backups (including manual and scheduled ones) are now binary safe: they are copied out of the container through base64 and length-checked, where they were previously corrupted by the text-only copy.GET /api/deployments/:id/snapshotslists the snapshots a rollback to that deployment would restore, and the rollback dialog shows an "Also restore database data" checkbox when there are any. New[data_retention] deployment_snapshots_keep(default3;0disables pruning) keeps snapshots for the N most recent deployments per app; the daily cleaner removes older dump files and rows in batches. -
CPU Steal tile on Monitoring, surfaces the host's CPU "steal" (the since-boot share of cycles the hypervisor took from this VM for other tenants), read from
/proc/stat. Explains why an in-guest CPU reading can look low while a hosting provider's host-side graph reads high: persistent steal means the node is oversubscribed. The tile is muted under 5%, amber 5-25%, red above 25%.GET /api/system/statsgainedcpu_steal_percent. -
Per-app proxy access logging toggle: new
access_loggingapp setting (Configuration > Network, orPUT /api/apps/:id). When off, the proxy skips building log metadata and writing that app's requests toproxy_logs, which saves CPU and DB writes on high-traffic apps. Existing apps stay on (migration 114, default 1); new apps default to the new[proxy] access_log_defaultconfig value (defaulttrue) unless the create request sets it. Takes effect immediately.
Changed
- New Rivetr logo and favicon: an indigo R tile now shows in the sidebar, on the login, setup, forgot and reset password and invitation pages, as the browser and touch icon, and at the top of the README. A white-label logo, app name or favicon still overrides it, and clearing a custom favicon restores the default. Source and usage notes are in
docs/branding/. - App detail page tabs consolidated from 12 to 6: Overview, Deployments (Deployments, Previews), Jobs, Logs & Monitoring (Logs, Monitoring, Log Drains, Terminal), Configuration (Env Vars, Network, Settings) and Security. Groups with more than one page show a pill row under the tab strip. No routes changed: every
/apps/:id/...URL still opens the same page and highlights its group. - Deploys and rollbacks drain the old container before stopping it: after the proxy swaps routes, Rivetr now waits for in-flight HTTP requests on the old container to finish (up to the new
proxy.drain_timeout_secs, default 30,0disables) before stopping it, instead of stopping it immediately. WebSocket tunnels are not waited for. Apps without a healthcheck now wait up to 30s for their port to accept connections before routes are swapped (a timeout logs a warning and continues, as before). - Dashboard and Monitoring redesigned: the dashboard opens with one metric strip (running, CPU, memory, disk, uptime, each with a utilisation meter and a skeleton while loading instead of "..."), then the resource chart and a running-services list that share one height and scroll inside the card, then cost and recent events. Monitoring drops the nine-card grid, the two duplicated memory and disk sections and the radial gauges: it shows four utilisation meters (CPU, memory, disk, load average), the history chart, a compact Host card (uptime, CPU steal, free memory, swap, free disk, database and runtime state) and a Health checks list with an "N of N passing" summary. Status is always text plus a dot, never colour alone. The chart no longer re-animates on every poll and its legend shows the live values.
- Usage panels unified across apps, databases and services: the shared resource panel is now a metric strip (CPU and memory with utilisation meters, network, and storage for databases). App Overview leads with live usage and merges Configuration and Details into one list; database and service General pages show read-only facts as a list instead of disabled inputs; per-app uptime stats use the same strip with a Healthy, Degraded or Unreliable label; the service Stats tab reuses the shared panel. The app Logs tab is a single card with a taller, neutral console. Service and project pages now show the project name in the breadcrumb.
- Projects page redesigned: the header shows project, app and database counts; a search box matches project names, descriptions and the names of the apps, databases and services inside them; a sort menu defaults to problems first. Each card has a health pill (Healthy, Needs attention, Building or Empty), links straight to every app, database and service, lists failing resources first so they are never hidden behind "+N more", and keeps its footer pinned so cards in a row line up. Status dots carry a screen-reader label.
- axum upgraded to 0.8: all routes use the
/{param}path syntax and the two custom extractors no longer needasync_trait. Prometheus/metricspath labels now read/api/apps/{id}instead of/api/apps/:id. Handlers whose JSON body is optional (delete app, deploy, rollback, reject deployment, clone app) use a new lenientOptionalJsonextractor: axum 0.8 started answering 400 to an empty body that still carriesContent-Type: application/json, which is what the dashboard sends. The unusedaxum-extradependency was removed. - bollard (Docker client) upgraded to 0.21: container, network, image, exec, stats and log calls moved to the new request builders and models. Checked against a real Docker daemon: deploy from an image and from an uploaded Dockerfile, container limits, restart policy, ports, env vars and network aliases as created by Docker, stats, log stream, terminal exec with resize, scheduled-job exec with exit codes, live resource-limit updates, stop, start, restart and a rolling redeploy. One known limit: the new client library sends build memory limits as a 32-bit number, so a build memory limit above 2147483647 bytes (just under 2 GiB) is capped there and a warning appears in the build log. The 2g default is unaffected in practice.
- sqlx upgraded to 0.9: the new release refuses any SQL string that is not a literal unless the code explicitly marks it as audited. The 23 places that build SQL at runtime (log search, proxy and audit log filters, webhook events, database settings update, retention cleanup, key-file checks and the migration runner) were each reviewed: they only assemble static fragments, fixed table and column names and
?placeholders, and every value is bound as a parameter. The retention cleanup helper now only accepts&'static strtable and column names, so the compiler enforces that no runtime text can reach its SQL. Existing databases open unchanged. Checked with injection strings on every filtered endpoint (they return nothing and leave the tables intact). - New command
rivetr db encrypt-secrets: enabling an encryption key only protected values written afterwards, so an existing install kept every earlier secret in plaintext. The command (dry run by default,--executeto apply) creates the key and salt files if needed and encrypts env vars, SSH keys and passwords, S3 keys, TOTP secrets and GitHub App secrets in one transaction. Each value is decrypted back and compared before it is written, and running it again changes nothing. The startup warning for installs without a key now points at it. - Typography: the dashboard now uses Geist (UI) and Geist Mono (numbers, paths, code) instead of Figtree with the system monospace font.
- Dependencies upgraded to current stable releases: frontend React 19.3, React Router 8, Vite 8, TypeScript 7, Tailwind 4.3, lucide-react 1, TanStack Query, Radix and the rest of the in-range updates; the build no longer needs
vite-tsconfig-paths(Vite resolves tsconfig paths itself) and lucide's removed GitHub icon is replaced by a local component. Backend:zip9,rand0.10,totp-rs6,argon20.6,sha20.11,hmac0.13,aes-gcm0.11,jsonwebtoken11 (with theaws_lc_rsbackend),reqwest0.13 (bundled root certificates kept),git20.21,x509-parser0.18,rcgen0.14,tower-http0.7,toml1,cron0.17,parking_lot0.13,base640.23,pem4,ratatui0.30, plus all semver-compatible updates. Stored data is unaffected: existing Argon2 password hashes, encrypted secrets and enrolled authenticator apps keep working (covered by new tests against a reference Argon2 vector, the RFC 6238 SHA1 vector and the existing legacy-format AES-GCM vector). The minimum supported Rust version is now 1.95.axum0.8,bollard0.21 andsqlx0.9 are intentionally not included yet: each is a breaking migration of a core subsystem and needs its own end-to-end test pass.
Fixed
- Deleting a database left its data on disk: the container was removed but the data directory under
<data_dir>/databases(and the named volume of an adopted database) stayed, even though the dialog said all data would be deleted. Delete now removes both. Files written by the database's own user are removed from a short-livedalpinecontainer when Rivetr cannot delete them itself. Data another database still points at is kept, and nothing outside<data_dir>/databasesis touched. Backups are not affected. - A failed deploy no longer marks a working app red: the Projects page used the latest deployment's status, so one failed or cancelled deploy turned the app's dot red although the previous deployment was still serving.
GET /api/apps/statusesnow reportsrunningwhile any deployment of the app is running; the failure is still listed under Deployments. - Docker Compose service domains never got HTTPS: the TLS certificate only listed app domains, so a service with a domain was routed but served the instance certificate, and browsers refused it. Service domains are now added to the certificate at startup and picked up by the renewal loop within a minute of being set. Startup and the renewal loop now share one domain collector (
proxy::acme::collect_cert_domains), so they no longer disagree: startup also reads the older plain-stringdomainsformat, and the renewal loop also skips.sslip.ioand.traefik.mehelper hosts. - Images from a registry with a port were rejected:
localhost:5000/appandregistry.example.com:443/team/app:1.2failed with "Invalid character in docker image tag" because the reference was split at the first:. The tag is now read after the last/, and only the registry host may carry a numeric port. - Managed PostgreSQL 18 databases crash-looped on start: the 18 image refuses a data volume mounted at
/var/lib/postgresql/dataand expects one at/var/lib/postgresql, with the cluster in a version subdirectory. Rivetr now mounts the right path for the version (18 and later, and non-numeric tags such aslatest); 12 to 17 are unchanged. Installing TimescaleDB follows$PGDATAinstead of a fixed path. An existing 18 database never started, so nothing needs migrating. - Pale status badges and the service status pill turned white on the dark theme: the database log and network badges, the team permission allow and deny badges, the GitHub connected badge and the service status pill now have dark variants.
- A failed image pull now says why: the deployment log shows the registry's answer (for example "pull access denied" or "repository does not exist"). Before, it only said "Failed to pull image from registry". A failed Dockerfile build step keeps showing the daemon's reason (for example "returned a non-zero code: 7") with the new Docker client.
- Docker networks are no longer duplicated on older engines: Rivetr now checks that the
rivetrand per-app networks exist before creating them, instead of relying on a duplicate check that engines older than Docker 25 apply only when asked. - ZIP uploads over 2MB always failed: the upload routes (
/api/apps/:id/deploy/upload,/api/projects/:id/apps/upload,/api/build/detect) inherited axum's 2MB default body limit, so any realistic project archive was rejected with "Error parsing multipart/form-data request". They now accept up to 100MB, matching the cap on extracted contents. Every other route keeps the 2MB limit. - Pages scrolled sideways on phones and tablets: the main column could grow past the screen when any child was wide, and the app header, cost toolbar and Settings sub-navigation did not wrap. Checked on 20 pages at widths from 360 to 1280px. The Settings sub-navigation now stays a dropdown until there is room beside the sidebar (1024px).
- Dashboard metric strip left an empty cell on phones next to Disk.
- Resource chart gridlines and ticks, and the monitoring gauges, rendered with invalid colours: they used
hsl(var(--border))on oklch theme tokens. - Every restart reset most app settings: the migration 066 check (
sqlite_autoindex_apps%) matched the apps table's own text primary key, so the table was rebuilt on every startup and every column added after it (snapshot_before_deploy,access_logging,restart_policy,privileged,cap_add,devices,shm_size,init_process, the Docker options, ...) went back to its default. The check now looks only for a UNIQUE constraint onname. - Cloning an app or an environment dropped
snapshot_before_deployandaccess_logging:POST /api/apps/:id/cloneandPOST /api/projects/:project_id/environments/:env_id/clonenow carry both settings over. - SSO/OIDC login had no browser binding on its CSRF state:
GET /auth/sso/:provider_id/loginnow also sets anHttpOnly; SameSite=Laxcookierivetr_sso_state(path/auth/sso,Secureover HTTPS) and the callback requires thestateto match it, so an attacker-minted state cannot be replayed into a victim's browser. The state is consumed atomically (single use) and expires after 10 minutes (previously only cleaned up lazily, never checked). The cookie helpers are shared with social login (api/state_cookie.rs). - Cloudflare tunnels, GitHub Apps, Docker Swarm and SSH keys were not team scoped: tunnels get a nullable
team_id(migration 117; existing tunnels stay global) andPOST /api/tunnelsaccepts one the caller belongs to.GET /api/tunnels,GET /api/github-apps,GET /api/github-apps/installationsandGET /api/ssh-keysonly return the caller's teams' rows plus legacy team-less ones (system-wide GitHub Apps stay visible to all, SSH keys follow their app).resource_authz_middlewarenow covers/api/tunnels/:id/...,/api/github-apps/:id/...and/api/github-apps/installations/:id/...(previously any signed-in user could list a team's repos through its installation token or stop its tunnel) and requires the developer role for writes. App-bound SSH keys, tunnel routes and swarm services now require write access to the app they reference. Swarm init/leave/nodes and swarm services with no app are admin-only. Instance admins and team-less legacy rows behave as before. - Global SSH keys, the GitHub App manifest callback and system-wide GitHub Apps were open to any signed-in user: SSH keys now record their creator (migration 119); a global key (no app) can be edited or deleted only by that user or an instance admin, and keys created before this change are admin-only to modify. The GitHub App registration state moved from an unsigned, client-supplied blob to a server-side single-use table (
github_manifest_states, migration 118, 30 minute expiry): the callback rejects a missing, forged or replayedstate, takes the team and scope from the row written by the authorized caller, and records that user ascreated_by.POST /api/github-appswithis_system_wide: trueis admin-only. The dashboard's "Create GitHub App" flow now passes the state to GitHub (it never did, so the team and scope were dropped) and only asks for a system-wide app when the user is an instance admin. - Notification channels created through
POST /api/notification-channelshad no team: they were visible to every signed-in user, including their webhook URLs and bot tokens. The request now takes an optionalteam_id(default: the caller's first team) and needs the team admin role, likePOST /api/teams/:id/notification-channels. Only instance admins can still create a global channel, by leaving the team out. Existing team-less channels are unchanged. - Resource authorization middleware never ran, and team roles were not enforced:
resource_authz_middlewarematched on/api/...but the router is mounted with.nest("/api", ..), which strips the prefix, so almost every/api/apps/:id/...route (deployments, stats, status, commits, volumes, basic-auth, snapshots, ...) answered 200 to members of other teams. It now matches on the original URI. It also now requires thedeveloperteam role (or higher) for any mutating request on apps, deployments, volumes, previews, databases, services, projects and servers, so aviewercan no longer edit or deploy an app, and a team that only holds a view-only app share cannot write. Instance admins and the admin API token are unaffected, and team-less (legacy) resources stay open to every signed-in user. - Social login (GitHub/Google/GitLab/Azure/Bitbucket) failed with a 500: the CSRF state was stored in
sessionsunder a fakeoauth_stateuser id, which violates thesessions.user_idforeign key. States now live in their ownoauth_login_statestable (migration 116). - Redeploying an app with replicas dropped its extra replicas: old replica containers kept their canonical name (
rivetr-<app>-<n>), so creating the new replica failed with a Docker 409 and the app ended up with one container. Old replicas are now renamed to-prevbefore the new ones start, like the primary container, and drained and retired after the route swap. - Manual rollback dropped HTTP Basic Auth from the app's proxy route: the route rebuilt after a rollback only carried the strip prefix, so an app protected by Basic Auth became publicly reachable until its next deploy (it also lost its healthcheck path and access-logging flag). The rollback route now keeps all three. The "Rollback to this" button on the deployment detail page now rolls back to that deployment instead of the most recent other one.
- Dashboard and Monitoring stats took 30s+ to load:
GET /api/system/statsqueried Docker stats for each container one after another (about 1-2s each, 36s with 16 apps). It now collects container IDs first, queries them concurrently (32 at a time, 5s timeout each) and caches the aggregate for 10s. - Dashboard "Running Services" card fired one stats request per app and database every 15s: added
GET /api/system/resources, which returns CPU and memory for every running app and database in one call (containers queried concurrently, cached 10s,team_idscoping as in/api/system/stats). The card uses it. - Projects page fired one
/apps/:id/statusrequest per app: addedGET /api/apps/statuses(sameteam_idscoping and visibility asGET /api/apps) returning every app's latest deployment status in one query, and the projects page uses it. - Unbounded growth of
proxy_logs,webhook_events, audit logs,scheduled_job_runsand expired sessions: the daily log cleaner now prunes these in bounded 10,000-row batches. New[data_retention]config (defaults:proxy_logs_days = 14,webhook_events_days = 30,audit_logs_days = 90,scheduled_job_runs_keep = 100;0disables an item); sessions expired for over a day (including OAuth state rows) are always removed. Behavior change: existing rows older than these windows are deleted on the first daily run (about 5 minutes after start). - Proxy access log write amplification: the proxy no longer spawns a task plus an INSERT per request. Entries go through a bounded queue (10,000, dropped and counted when full) to a single writer that batch-inserts every second or 200 entries, and log metadata is only built when logging is enabled. Redirect-rule regexes are compiled once and cached instead of per request.
- Proxy logs page full-table
COUNT(*):GET /api/proxy/logsnow counts at most 10,000 matching rows;totalis capped and a newtotal_cappedfield flags it. - Monitoring CPU usage was wrong (showed e.g. 129.7%), the "CPU Usage" card and the utilization chart summed each container's Docker CPU% (where 100% = one core), so the figure was noisy and could exceed 100%, never reflecting real host load. Both the live
GET /api/system/statsendpoint and the history collector now read true host CPU utilization from/proc/stat(sampling the cumulative counters over a 200 ms window), reported as a 0-100% aggregate across all cores. Falls back to the old container sum on non-Linux dev machines. - Notification channel "Send test" reported a JSON error, the test endpoint returned an empty
200 OK, but the dashboard parses the response as JSON, so the button failed with "Unexpected end of JSON input" even though the test was actually sent. The endpoint now returns a small JSON body. - Subscribing to "Container Crashed" / "Container Restarted" failed, these event types exist in the backend enum and the UI, but the
notification_subscriptions.event_typeCHECK constraint (from migration 016) never listed them, so the insert hit a CHECK violation. Migration 110 rebuilds the table with the full event-type set. - Dashboard Disk Usage card overlapped its icon: long values like "76.61 GB / 95.82 GB" now wrap inside the card instead of running under the icon.
- API failures showed fake zeros and empty states: the dashboard, Monitoring, Projects, Services, Templates, Running Services, Cost Overview, Recent Events and several settings lists (API tokens, SSH keys, destinations, teams, tunnels, audit log, webhook events, proxy logs) now show an inline error with a Retry button when the request fails, instead of
0%or "No items". - Accessibility: icon-only buttons (delete, edit, copy, back, refresh, row menus) and unlabelled inputs now have accessible names, and the ZIP and database dump drop zones can be activated from the keyboard.
- Removed unused legacy route files
routes/apps/$id.tsxandroutes/services/$id.tsx.
Security
- Dependency updates for Dependabot alerts: Rust
quinn-proto,rustls-webpki,aws-lc-sys,lettreand the AWS SDK crates (which also movesaws-smithy-jsonpast its recursion advisory) are on patched versions inCargo.lock; the frontend movedreact-routerand the@react-router/*packages from 7.10.1 to 7.18.4 and took the non-breakingnpm audit fixupdates. 6 npm advisories remain, all one build-time chain (bracesthrough theshadcnCLI) with no patched release; nothing in it ships in the dashboard. - SSH host keys are now pinned for servers and build servers: every SSH, scp and rsync call used
StrictHostKeyChecking=no, so a man-in-the-middle could impersonate a managed server. Connections now useaccept-newagainst<data_dir>/ssh/known_hosts: the key is trusted on first use and a later key change is refused by OpenSSH. After legitimately rebuilding a server, clear its pin withDELETE /api/servers/:id/host-key(or/api/build-servers/:id/host-key). Behavior change: the first connection to each server after upgrading pins whatever key it presents. Git clone connections are unchanged. - Encryption at rest no longer silently off on fresh installs (SEC-M10): when
[auth] encryption_keyis unset, Rivetr loads<data_dir>/.encryption_keyif present; on a fresh install (no users, env vars, servers or git providers) it generates one (random 256-bit, mode 0600, created atomically, never overwritten) and logs a notice to back it up with the database. Existing installs without a key keep running unchanged but log a prominent warning with the exact line to add. Legacy plaintext values stay readable once a key is enabled. KDF hardening (per-install salt, Argon2id) remains a follow-up needing a versioned ciphertext format. - Client IP spoofing and brute force (SEC-H3, SEC-L4, SEC-M4): rate limiting and audit logs now use the TCP peer address and honor
X-Forwarded-For/X-Real-IPonly from trusted proxies (newrate_limit.trusted_proxieslist of IPs/CIDRs; loopback is always trusted;X-Forwarded-Foris read right to left). Behavior change: if Rivetr sits behind a proxy on another host or a Docker bridge, add that proxy totrusted_proxies, otherwise all clients share the proxy's rate-limit bucket. Added per-account lockout for/api/auth/loginand/api/auth/2fa/validate(5 failures in 15 min, exponential backoff up to 15 min,429while locked, cleared on success). Unknown emails now run a dummy Argon2 verify so login timing no longer reveals whether an account exists. The admin token check inget_current_useris constant time. - Content-Security-Policy and HSTS (SEC-M6, SEC-L3): the dashboard is served with a CSP (
default-src 'self',script-src 'self'plus sha256 hashes of the inline scripts in the embedded HTML computed at serve time,style-src 'self' 'unsafe-inline'for white-label CSS, same-hostws:/wss:forconnect-src,img-src 'self' data: blob: https:,frame-ancestors 'none',object-src 'none',base-uri 'self'). Non-HTML responses getdefault-src 'none'; frame-ancestors 'none'.Strict-Transport-Security: max-age=31536000is sent when the request arrived over HTTPS (X-Forwarded-Proto). Behavior change: a custom frontend build that adds external scripts, fonts or API origins will be blocked. - OAuth login hardening (SEC-M3): the callback now rejects a missing, unknown or expired
statewith 400 and consumes it atomically (single use). A new OAuth identity is linked to an existing local account by email only when the provider vouches for the address (GitHub/user/emailsverified flag, Googleverified_email, GitLabconfirmed_at, Bitbucketis_confirmed, Azure single-tenant only); otherwise sign-in is refused with an explanatory error. Existing connections are unaffected. - Login
returnUrlvalidation (SEC-M7): the post-login redirect read fromlocalStoragemust be a same-origin path (single leading/, no//, backslash or control characters), otherwise it falls back to/. - Authorization tail (SEC-C3): the per-resource authorization middleware now also covers build servers, notification channels and subscriptions, destinations, CA certificates, S3 configs and backups, volumes, previews, project environments and app-bound SSH keys. Behavior change: build servers are team scoped like servers (members of the owning team and instance admins only; build servers with no team stay visible to everyone), and the lists of build servers, notification channels, destinations, CA certificates, S3 configs/backups and previews only return rows of the caller's teams plus team-less rows. Creating a resource with a
team_idthe caller is not a member of now returns 403 (apps, servers, databases, services, projects, build servers, destinations, CA certificates, S3 configs), as does assigning an app to an inaccessible project. Git provider connections (get, delete, list repos) are limited to their owner or an instance admin. Bulk start/stop/restart/deploy skip apps the caller cannot access. Admin token and instance admins are unchanged. - OAuth state bound to the browser (SEC-M3): the OAuth login redirect sets a short-lived
rivetr_oauth_statecookie (HttpOnly,SameSite=Lax, 10 min,Securebehind HTTPS) and the callback requires thestateto match it in addition to the stored row, then clears it. Behavior change: start the sign-in and finish it on the same host name (the one inexternal_url); a login started on one address and redirected back to another now fails with a 400 asking to restart. - Versioned encryption with per-install salt (SEC-M10, SEC-L8): new secrets are written as
ENC2:(AES-256-GCM with an HKDF-SHA256 subkey derived from the key and a random per-install salt in<data_dir>/.encryption_salt, mode 0600, created on first use whenever an encryption key is in use). ExistingENC:values and legacy plaintext keep decrypting and are upgraded lazily the next time their row is written. Behavior change: back up.encryption_salttogether with the key and the database; without itENC2:values cannot be read, and an older Rivetr binary cannot readENC2:values (no downgrade after new secrets are saved).
0.11.0 - 2026-06-09
Added
- Competitive-parity sweep (Coolify v4.1.0 / Dokploy v0.29.x), Closed five gaps surfaced by a fresh re-research of both competitors. See
docs/research/competitive-gap-analysis.md(§ "Re-research 2026-05-27").[skip ci]/[skip cd]commit markers, A push whose tip commit message contains[skip ci],[ci skip],[skip cd],[cd skip],[skip deploy], or[no deploy](case-insensitive) no longer triggers a deployment. Honored across the GitHub, GitLab, Gitea, and Bitbucket webhook handlers via the sharedcommit_skips_deploy()helper.- Configurable stop grace period, New per-app
stop_grace_period(seconds) controls how long a container gets to shut down gracefully (SIGTERM) before SIGKILL on stop/replace. NULL/empty uses the runtime default (Docker's 10s). NewContainerRuntime::stop_timeout()(DockerStopContainerOptions.t, Podman--time); editable in the app's Docker Options settings. Migration 107. - PostgreSQL 17 & 18, Added to the managed-Postgres version list (pgvector already supported); default bumped 16 → 17 to match the dashboard.
- LibSQL managed database, New
DatabaseType::Libsql(Turso's server-side SQLitesqld,ghcr.io/tursodatabase/libsql-server). Auth-less HTTP/HRANA API on port 8080;http://connection string; appears in the new-database picker. - Expanded MCP tool surface, The
/mcpendpoint grew from 4 tools to 9: addedlist_deployments,get_deployment_status,list_services,list_databases,list_projects, andrestart_app(database credentials are masked inlist_databases).
- Move resources between projects from their settings page, Each app, database, and service settings page now has a "Project" card to reassign (or unassign) the resource to any project, complementing the existing project-centric add/remove flow.
update_databasenow acceptsproject_id(empty string clears the assignment). - Per-service resource limits, Services now have
cpu_limit/memory_limitfields (Service settings → "Resource Limits"). Rivetr injects them as the top-levelcpus/mem_limitcompose keys (honored bydocker compose up, unlike swarm-onlydeploy.resources.limits) on every service at deploy time, a service that already sets a key keeps its own value, so Docker enforces the caps via cgroups, bringing services in line with apps and managed databases. Applied across the start and both restart paths. The service stats page shows the configured caps alongside live usage. Migration 108. - Database storage usage in stats, the database stats endpoint now reports
storage_bytes, the actual on-disk size of the data directory (measured withdu -sbinside the container, using the engine's volume root so it covers adopted layouts too). Surfaced as a "Storage Used" tile in the resource monitor. - Configurable deployment concurrency, caps how many deployments build at once via a shared semaphore in the deploy engine; additional deploys queue until a slot frees. Previously every triggered deployment spawned immediately with no bound, so a monorepo push (one repo → several apps) or a burst of webhooks could start many simultaneous Docker builds and exhaust host CPU/RAM. Configurable from Settings → "Max concurrent deployments" (saved instance setting, applied live with no restart) or
runtime.max_concurrent_deploymentsinrivetr.toml. Default 2. - Host metrics on the Monitoring page, the page now shows true host RAM (used / available / total + %), swap, load average (1/5/15m + per-core), CPU core count, and host uptime alongside the existing CPU and disk views (previously it showed no memory at all).
GET /api/system/statswas extended to read host memory/swap/load from/proc, no new crates. - Sendry email notifications, new "Sendry" notification channel (a Resend-compatible HTTP email API,
https://docs.sendry.online). Configure an API key + from/to addresses in Settings → Notifications; delivered viareqwestlike the other providers (no new crate). Migration 109 extends thenotification_channelstype constraint. - Dashboard polish, System Overview stat values no longer wrap to two lines; the CPU / Memory / Disk cards link to
/monitoring; the Running Services list shows a per-service health dot and links to each resource; Recent Events use meaning-coded dots (success / failure / info) with tooltips and link to the relevant app or deployment; added a live "updated N ago" indicator.
Fixed
- Long log lines widened the whole page, on the logs tab a single very long line (URL, base64, stack trace) stretched the layout horizontally instead of staying inside the log box. The log container is now width-constrained (
min-w-0/max-w-full) and long lines wrap/scroll within it. - Repeated sections across resource detail tabs, the same control or info was rendered in multiple tabs of an app/database/service (restart policy in both General and Docker settings; the domain editor in both the Network tab and Settings → Network; database resource-limits and metadata in both Overview and Settings; service exposed-ports in both Overview and Network). Each is now shown in a single canonical tab.
- Queued deployments showed a running clock and inflated duration, a deployment's
started_atwas stamped when it was created (queued), so a deploy waiting behind the concurrent-deployment limit displayed a growing timer and, once it finally built, a total duration that included the queue wait (looking as long as the deploy ahead of it, easily mistaken for the cap not working).started_atis now reset to the real build start when a slot frees, and pending deployments render as "Queued" instead of a running timer. The concurrency cap itself was already correct. - App update ignored
github_app_installation_id,PUT /api/apps/:idaccepted the field but never wrote it, so an existing app couldn't have a GitHub App installation attached or changed (e.g. converting an app from a registry image to a private git source left it with no clone auth). It's now merged and persisted like the other fields, so switching an app to a git source works entirely via the API/UI. - Database CPU/memory limits couldn't be changed after creation, the DB settings "Resource Limits" card was read-only ("delete and recreate to change limits"), and
update_databaseignored limit changes for the running container. The card is now editable with a Save button, and a limit change is applied live to the running container viadocker update(cgroups), no restart needed. - Database overview showed fake resource-limit placeholders, when a database had no CPU/memory limit set, the overview rendered hardcoded
512mb/0.5defaults, implying a cap that wasn't actually applied (e.g. a DB using 2.4 GB displaying a "512mb" limit). It now shows the configured value or "No limit". - Live memory-limit update failed on containers started without a cap,
update_container_limits(apps' apply-limits and the new DB path) setmemorywithoutmemory_swap, which Docker rejects with "Memory limit should be smaller than already set memoryswap limit" whenever the container had unlimited swap. It now setsmemory_swap == memoryso the update is accepted and the cap is hard. - Service restart didn't apply config changes,
restart_servicerandocker compose restart, which only restarts the existing container processes and never re-reads the compose file, so changes made since the last start (resource limits, env, domain/port, compose edits) silently didn't take effect on a restart. It now runsdocker compose up -d --force-recreate, rebuilding the containers from the current compose. - Reverse proxy always sent
X-Forwarded-Proto: http, Even on the HTTPS listener (:443) the proxy hard-codedX-Forwarded-Proto: http, so upstream apps that build absolute URLs from the forwarded scheme (Laravel, Rails, Django, …) emitted insecurehttp://asset and redirect URLs that browsers block as mixed content (symptom: pages render unstyled because the CSS request is blocked). The HTTPS listener now reportshttps, the HTTP listener still reportshttp; applies to both request and WebSocket forwarding. - Migration 107 (
stop_grace_period) was never wired intorun_migrations(), The migration file and theApp.stop_grace_periodfield shipped, but the matchingexecute_sqlcall was missing, so fresh installs never created the column and everyPOST /api/appsfailed withno column found for name: stop_grace_period. Now wired with an idempotentpragma_table_infoguard.
Removed
- Template suggestion / submission features, removed the "My Suggestions", "Submit a template", and "Suggest a template" actions from
/templatestogether with their pages, API-client methods, and backend endpoints/handlers/models (template_suggestionsandcommunity_template_submissionscode paths). The core template catalog and one-click deploy are unchanged.
Tests
- +5 unit tests: commit skip-marker detection (case-insensitivity + non-matches), LibSQL config / no-credential-env, and Postgres 17/18 availability. Suite now 251 passing.
0.10.23 - 2026-05-27
Added
- Host-protection resource defaults: every container now inherits configurable safety defaults (memory limit, PID limit, OOM score bias) when it sets none, so a runaway container can no longer exhaust host RAM. Per-resource limits still override; set
default_memory_limit = ""to opt out. - Container log rotation + critical-disk auto-reclaim: containers now get log rotation defaults, and the disk monitor automatically prunes images and build cache when usage crosses the critical threshold, closing the disk host-hang vector.
- Database integrity check on startup: self-check runs a SQLite
PRAGMA quick_checkand surfaces corruption loudly in the startup report. Non-critical; the server still starts. - Tooling & reference docs: added
rustfmt.toml, a[lints]table inCargo.toml, and configuration/API reference docs covering everyrivetr.tomlfield and REST endpoint.
Tests
- Expanded unit coverage for build-type auto-detection and API input validation (+33 tests covering precedence, framework detection, and injection/path-traversal blocking). Suite now 246 passing.
0.10.22 - 2026-05-27
Fixed
- Panic isolation: switched the release profile from
panic = "abort"topanic = "unwind"so a panic in one of the ~79 Tokio tasks unwinds only that task instead of killing the whole process. A newguarded()helper wraps all 16 background loops incatch_unwind, and the 8 reverse-proxy hot-pathunwrap()calls now fall back to a header-less response on untrusted-input errors.
Changed
- Release builds now unwind on panic (slightly larger binary, negligible runtime cost) for process-level resilience.
0.10.21 - 2026-05-02
Added
- Database-to-app linking with auto env injection: a new "Linked Databases" section lets users connect a managed database to an app with one click, auto-injecting connection env vars (
DATABASE_URL,HOST,PORT, etc., orREDIS_URL/MONGODB_URL) on the next deploy. An optional prefix avoids key collisions; user-defined env vars always win. - Inline credentials display on the project DB list: each database card now has a "Show credentials" toggle that expands the connection string, username, and password inline with copy buttons.
Fixed
- MySQL 8 connection broken via published connection string: managed MySQL containers now start with
--skip-sslso clients can connect without TLS errors, reverting the prior query-string workaround. - Audit
ip_addresswas always null: theClientIpextractor is now wired into all 30+ audit-emitting handlers, recording socket IP (orX-Forwarded-Forfor proxied requests). - Disk-stats path inconsistency: backend now canonicalizes
data_dirso the Dashboard and Monitoring pages report the same number.
UX
- Sidebar user menu: clearer spacing, hover/focus states, and a rotating chevron make the user pill obviously interactive.
- Deploy menu commit/tag and ZIP-file modals: both menu items now open their dialogs (fixed a Radix dropdown-to-dialog focus race).
- Template page category anchors: category sections have anchors and "View all N" links that smooth-scroll and expand inline.
- Resource Limits live-apply: saving limits now applies them immediately to a running container via
docker update, with helper text that adapts to running/stopped state.
Removed
- The prior
?ssl-mode=DISABLEDMySQL connection-string workaround, replaced by the--skip-sslserver-side fix.
0.10.20 - 2026-05-02
Added
- Coolify-style deploy log side panel: a dockable panel opens automatically on Deploy/Start/Restart (apps, services, databases) and streams image-pull and container-start activity in real time, via new per-resource WebSocket/REST routes.
- MariaDB as a managed database type: MariaDB joins the catalogue (versions 11 default, 10.11, 10.6, 10.5) with the correct
mariadb://scheme, data mount, andmariadb-dumpbackups. scripts/deploy-vm.sh: local Parallels Ubuntu ARM64 VM deploy mirror for faster iteration on Apple Silicon.
Fixed
- Container monitor service health check broken since v0.10.18: the health-check query omitted columns added by a later migration, silently disabling crash detection for all Compose services. Now selects the full column set.
/api/apps/:id/insightsreturned 503 when AI not configured: now returns 404, eliminating misleading console 503s and log spam.- Docker network "endpoint already exists" warnings on restart: the connect helper now treats the
403 + "already exists"pair as an idempotent no-op. - MariaDB/MySQL post-start user-provisioning warning silenced when the entrypoint already created the user.
- Audit log now records the full set of mutating actions (token, app, service, database, deployment, env-var, and domain operations) that were previously missing.
/api/audit?limit=Nalias accepted, matching the Coolify/Dokploy convention.- POST/DELETE endpoints accept empty body / no
Content-Type: delete-app, rollback, and cancel no longer return 415 without a body. - Cancel deployment in non-cancellable state returns 409 (was 404), reflecting that the deployment exists but isn't cancellable.
- Rollback
commit_messagereferences the correct deployment id (the path-param target). - Old running deployment marked
replacednotfailedafter rollback, since no build error occurred. - Stable internal hostname surfaced in App model:
GET /api/apps/:idnow exposes a derivedinternal_hostnameso the Network tab connection example stays correct across restarts. - Templates list endpoint compressed + slim: responses now gzip-compress and return a slim field set (was ~500 KB plain, now ~86 KB gzipped); full bodies live at
GET /api/templates/:id. - Database SQL backup downloads use
application/sqlContent-Type so browsers can display rather than save-as. - Compose service auto-domain fallback: services with no domain now auto-assign
<service-name>.localso they're reachable via the proxy.
Frontend bug fixes (VM sweep)
- Setup form placeholder and validator now agree on a 12-character minimum.
- App General tab hides the "Dockerfile path" field unless build type is
dockerfile. - Network tab shows the actual network name
"rivetr"(was"rivetr-network"). - Templates page first paint capped to 6 cards per category with a "View all N" link (was ~1300 cards).
/monitoringchart wrapper now has an explicit min-height, ending the rechartswidth(-1)warning.- Setup auto-logs-in when the API returns a session token, falling back to
/loginotherwise. - Deployment detail label shows "Deployed at" instead of "Finished" while still running.
- Project page no longer double-renders empty-state CTA buttons.
- Added form
autocompleteattributes so password managers and iOS strong-password generation work. - Login submit button is disabled when email or password is empty.
- Project page hides the Healthy/Issues/Building tabs when a project has zero apps.
- Deployment-log render strips ANSI escape sequences.
Infrastructure
- Added
scripts/deploy-vm.shfor fast Parallels-VM iteration on Apple Silicon. - Fixed 7 pre-existing clippy errors;
cargo clippywith-D warningsnow exits 0.
[v0.10.19] - 2026-03-25
Fixed
- Zero-downtime HTTPS during instance restarts: proxy listeners are now pre-bound once in
main.rsand shared, so the HTTPS server inherits its systemd socket instead of failing with "Address already in use." Connections now queue at the kernel during restarts instead of getting refused.
[v0.10.18] - 2026-03-25
Added
- Service resource monitor: the service detail page now shows live CPU, memory, and network stats when running.
- Service public port exposure: services can expose a container port on the host via a new Network tab, with port-conflict checks and auto-restart on change.
- Full backup includes service data: backups now bundle Compose files and database dumps for running service containers (Postgres, MySQL/MariaDB, Redis-family, MongoDB), with non-fatal dump failures.
Fixed
- Migrations 104 and 105 not auto-applied: both are now registered with idempotent guards so they apply on next startup.
[v0.10.17] - 2026-03-25
Changed
- AI provider config moved to dashboard: provider, API key, model, and max-token cap are now set under Settings, stored in the database, and hot-applied with no restart. The
[ai]config section remains a startup fallback; the raw key is never returned by the API.
Added
- Settings AI Provider card: configure provider (Claude, OpenAI, Gemini, Moonshot), masked API key, model override, and max-tokens, with a "Configured" badge.
[v0.10.16] - 2026-03-25
Added
- AI-powered features (Phase 1): multi-provider AI client across the platform, all requiring an
[ai]API key inrivetr.toml.- Deployment error diagnosis: sends recent logs to the AI and returns a structured diagnosis with actionable suggestions.
- Deployment insights: success rate, average build time, and 30-day trend with an optional AI summary.
- Cost optimisation suggestions: AI-generated resource tuning recommendations on the Monitoring tab.
- Dockerfile Optimizer: returns an optimised Dockerfile with a list of improvements.
- Security & Compliance Advisor: five rule-based checks plus an optional AI summary, surfaced in a new Security tab; a global scan aggregates across all apps.
[v0.10.15] - 2026-03-25
Fixed
- ACME cert saved under wrong directory on renewal:
save_certificatenow takes an explicitinstance_domainso renewed certs land in the correct directory and survive restarts. - Uptime checker skipped apps with no custom domain: the poller now falls back to
auto_subdomainand checks*.rivetr.sitesubdomains over HTTPS. - Monitoring page showed "100% availability" with 0 checks: now renders
"-"when there are zero checks. - Uptime summary stats ignored period selector: the period dropdown now threads through to the backend and re-fetches.
- Westel Dockerfiles: removed unsupported BuildKit cache mounts, upgraded PHP 8.3 to 8.4, and preserved layer-ordering optimisations.
[v0.10.13] - 2026-03-22
Fixed
- App API boolean types: app endpoints now return
AppResponse, mapping SQLite integer columns to JSON booleans and fixing frontend deserialization errors. - Frontend error handling for non-JSON responses: the API helper now catches
SyntaxErrorand surfaces the raw text body instead of a confusing JSON-parse message. - Docker image prune filter: replaced the invalid
system prune --filter dangling=truewithdocker image prune -f. - Full system backup failure:
ManagedDatabasequeries now useSELECT *so newer schema fields no longer cause column-not-found errors. - Firewall security check false positive: the check no longer marks inactive firewalls as active.
Added
- Webhook events pagination:
GET /api/webhook-eventsnow acceptspage/per_pageand returns a paginated envelope; the UI persists state in URL params. - Disk pressure auto-cleanup: the cleanup engine checks disk usage and, above 85% full, keeps only the latest deployment per app and prunes images and build cache.
- Docker build cache pruning: every cleanup cycle now runs
docker builder prune -fto reclaim cache that previously grew unbounded. - Reduced default deployment retention:
max_deployments_per_appdefault lowered from 10 to 3.
[v0.10.12] - 2026-03-18
Added
- Proxy access logs: every proxied request is now logged to a
proxy_logstable (host, method, path, status, latency, bytes, client IP, user agent), with a Settings page offering filters and auto-refresh. - User Preferences panel: a Settings page with localStorage preferences for theme, date/time format, default log lines, deployment notifications, and compact mode.
- 11 new service templates (Sprint 26): MediaWiki, SuperTokens, Netbird, AFFiNE, HeyForm, OpnForm, GitHub Actions Runner, Bluesky PDS, PeerTube, Roundcube, and docker-mailserver. Rivetr now has 335+ one-click templates.
[v0.10.11] - 2026-03-18
Added
- Custom container labels: apps support arbitrary Docker labels via a key-value editor, applied at launch alongside built-in Rivetr labels.
- Proxy-level www redirect:
www_redirect_modenow issues 301 redirects at the proxy layer before any upstream connection. - 5 new service templates (Sprint 25): Joomla, Drupal, Grafana standalone, Etebase, Obsidian Remote. Rivetr now has 315+ one-click templates.
Fixed
- Missing migrations 092-099: the runner was missing these migrations, causing 500s on app/server endpoints; now registered.
- Migration 101 column check: the guard now checks for the
destination_idcolumn, not just table existence, fixing a 500 on fresh deployments.
[v0.10.10] - 2026-03-18
Added
- Docker Destinations: named Docker networks that apps can be assigned to, mirroring Coolify's destinations.
- CA Certificate management: upload trusted CA certificates (PEM) for custom TLS trust chains.
- Inline Dockerfile: deploy from a pasted Dockerfile with no git repo, skipping the clone entirely.
- Fetch server details: SSHes into a server to collect OS, Docker version, disk, CPU, and RAM, shown via "Refresh details."
- WWW redirect mode: per-domain dropdown (No redirect / Serve both / to www / to non-www) issuing 301s for the redirect variants.
- Instance timezone: global IANA timezone for scheduled tasks and log timestamps.
- 11 new service templates (Sprint 24): Vaultwarden, LiteLLM, MindsDB, Matrix Synapse, Rocket.Chat, NodeBB, Zipline, Joplin Server, Siyuan Notes, Hatchet, EasyAppointments. Rivetr now has ~113 one-click templates.
[v0.10.9] - 2026-03-18
Fixed
- Cost analysis pricing: estimates were 300-600x too low. Fixed with a per-server
hourly_ratemodel (default $0.036/hr matching DigitalOcean), DO-aligned fallback rates ($10/vCPU + $1/GB per month) for unassigned apps, and billing against allocated rather than used memory.
Added
- Hourly rate field on servers: the server edit dialog now includes an "Hourly Cost (USD/hr)" input with DigitalOcean size hints.
Added
- Git clone options: per-app toggles for submodules (
--recurse-submodules), LFS (git lfs pull), and shallow clone (--depth 1, default on). - Build cache control: a
disable_build_cachetoggle passes--no-cacheto Dockerfile/Nixpacks builds for a clean rebuild. - SOURCE_COMMIT build arg: an
include_source_committoggle injects the current git SHA as a Docker build argument. - Custom container name: overrides the auto-generated
rivetr-<app-name>name. - Static site flag: marks an app as a static site, toggled in Build Settings.
- Generate domain: auto-assigns a random subdomain from the server's base domain (falls back to
sslip.io). - Links dropdown: app nav now lists all configured domains as quick-open external links.
- Environment Clone: duplicate a project environment's apps, databases, and services into a fresh environment (containers stopped, domains cleared, deployment state reset).
- 8 new service templates (Sprint 23): Flowise, Langflow, Open WebUI, AnythingLLM, Pocket ID, Activepieces, Trigger.dev, SigNoz. Rivetr now has ~102 one-click templates.
- Server timezone setting: per-server IANA timezone (default
UTC), in the Edit Server dialog. - Strip URL prefix: a per-app
strip_prefixremoves a URL prefix before proxying, in both HTTP and WebSocket forwarding. - Resend notification channel: fixed validation for the
resend,mattermost,lark, andgotifychannel types, which were previously blocked. - Theme toggle in top nav: the Light/Dark/System toggle is now in the header bar as well as the sidebar.
- Version + feedback in sidebar: the footer now shows the current version (linked to GitHub releases) and a Feedback link.
- 7 new service templates (Sprint 22): Minecraft Java, Palworld, Terraria, Satisfactory, Argilla, Mage AI, Glitchtip. Rivetr now has ~94 one-click templates.
- 13 new service templates (Sprint 21): Beszel Agent, ClassicPress, CloudBeaver, Diun, Homebox, Karakeep, Linkding, PairDrop, Readeck, Ryot, Shlink, Slash, Wakapi. Rivetr now has ~87 one-click templates.
[v0.10.8] - 2026-03-17
Fixed
- Server status stuck offline: the SSH health check now falls back to
sshpasspassword auth when a stored key fails to load, instead of leaving the server permanently offline. - Server action buttons cluttered: replaced the flat row of buttons with Terminal and Files as primaries and the rest grouped in a
...dropdown.
[v0.10.7] - 2026-03-16
Added
- Service resource monitoring: built-in template services now have a Stats tab with live CPU, RAM, and network, aggregated across all containers in the Compose project.
- Deployment Cleanup Settings UI: configure
max_deployments_per_appand image pruning from Settings; values persist in the database and fall back to config defaults. - Restart History in Deployments Tab: app restarts now create deployment records with logs and a distinct "restart" trigger badge.
- TUI (
rivetr tui): a terminal UI with tabbed Apps/Deployments/Servers/Logs views, keyboard navigation, and live log polling (enable with--features tui). - Fine-grained RBAC: per-resource permission overrides let admins grant or deny individual members access to specific apps, projects, databases, or services.
- Deployment Queue Cancellation: any queued or running deployment can be cancelled via the detail view, aborting the current pipeline stage.
- Community Template Submissions: users can submit Compose templates for admin review; approved submissions are promoted to the live registry.
- Remote Filesystem Browser: browse, read, write, and delete files on any connected server over SSH, with a full file browser and inline editor.
Fixed
- GitHub App webhooks silently dropped by HTTPS redirect:
/webhooks/paths are now excluded from the HTTP-to-HTTPS redirect so push events aren't dropped after TLS is issued. - GitHub App webhook URL used wrong scheme after HTTPS setup: the registered URL now defaults to HTTPS, and a new sync endpoint updates the GitHub App's webhook URL.
- App settings never showed webhook setup instructions: the General tab now shows an "Auto-Deploy Setup" card with the ready-to-paste webhook URL and steps for the detected provider.
- Duplicate webhook deployments on push: fixed four overlapping bugs (non-atomic delivery-ID guard, unfiltered branch-deletion events, missing per-app idempotency, and a too-narrow active-status check) so a single push deploys once.
- CPU chart compared against full host CPU instead of allocated limit: the Resource Monitor now normalises against the container's CPU limit so 100% means the allocated quota.
- API token auth in middleware:
rvt_-prefixed tokens are now validated inauth_middleware, fixing 401s on endpoints that don't use the user extractor. - TUI ping using auth-required endpoint: switched to the public
/healthendpoint so connectivity and auth failures are reported separately. - TUI
/api/deployments404: replaced the nonexistent global query with merged per-app requests. - Stale
container_idcausing stuck 'starting' state: when a database's container is gone, Rivetr now clears the id, resets status, and provisions a fresh container. - Reconciliation queries failing after new migrations: recovery queries now use
SELECT *to stay resilient to schema additions. - 5-field cron expressions rejected by scheduler: 5-field Unix cron strings are now normalized by prepending a seconds field.
- React setState-during-render in LogRetentionSection: moved the sync state update into a
useEffect. - MySQL/MariaDB user not created on reused data directory: Rivetr now idempotently provisions the app user via the Unix socket after every container start.
- New app subdomains missing SSL coverage: certs can now be hot-swapped without a restart, and the renewal manager reissues immediately when new app subdomains appear.
- Orphaned restart containers causing CPU/RAM drain: stale
rivetr-*-restart-*containers are now removed on startup, and the stop/remove task logs failures. - No swap warning: Rivetr now warns at startup when the host has no swap, and the installer creates a 2-4 GB swapfile with
swappiness=10.
Planned
- SAML 2.0 support
- Remote build execution (SSH-based)
- Overlay networking and rolling updates for Docker Swarm
[0.10.6] - 2026-03-14
Added
- Container Resource Limits UI: configure CPU and memory limits per app, with an "Apply Now (Live)" button that enforces them on the running container via
docker update, no redeploy needed. - DragonFlyDB: new Redis-compatible managed database type (port 6379,
redis://, RDB backups). - KeyDB: new multi-threaded Redis-compatible managed database type (port 6379,
redis://). - ClickHouse: new columnar analytics managed database (port 8123,
clickhouse://) with access management and post-start init. - Docker Compose Raw Mode: a per-service toggle that deploys the compose file exactly as written, skipping Rivetr network injection, name namespacing, and labels.
- Ansible Playbook:
ansible/rivetr.ymlfor idempotent server provisioning on Ubuntu/Debian (Docker, binary, systemd, UFW). - Service Templates Master Registry: a reference doc listing all unique templates by category to prevent duplicates.
Fixed
- Duplicate Service Templates: removed 55 duplicate entries, reducing unique templates from 328 to 273.
- Env Vars in Storage Settings: removed the duplicate Environment Variables panel; env vars are managed only from the dedicated tab.
[0.10.5] - 2026-03-13
Added
- 27 New Service Templates: added across Dashboards, AI, Analytics, Backup, Communication, Dev Tools, Media, Storage, and Security categories. Total now ~119.
- Port Conflict Validation: ports already in use are now rejected at template deployment (debounced live check), custom service creation, and database external-port update (409 Conflict), backed by a
check-portendpoint. - Auto-Subdomain for Template Services: template-deployed services now get a
{name}.{base_domain}subdomain with a proxy route on startup.
Fixed
- Service Stop Status: template services now show "Stopped" instead of "Failed" after stop (fixed a compose-dir lookup that ignored the temp dir).
[0.10.4] - 2026-03-12
Added
- API Tokens: create named tokens (prefixed
rvt_, stored as SHA-256 hashes, optional expiry) for programmatic access via/api/tokens. Existing admin-token scripts are unaffected.
Fixed
- Version Reporting:
Cargo.tomlversion now matches the release so Auto Updates reports the correct running version. - Breadcrumbs: added missing entries for Cost Analysis and the Previews/Jobs/Log Drains/Monitoring app sub-tabs.
- Notification Channels 403: the team channels endpoint now grants access to the admin API token.
- Team Breadcrumb: the team detail page now shows the team name instead of "Page."
- Build Server Docker Column: no longer shows "vnot installed"; the
vprefix is added only for version strings. - SSH Password Auth for Servers & Build Servers: servers can now be registered with a password (no key required), using
sshpasstransparently.
[0.10.3] - 2026-03-12
Added
- Recharts Dashboard: replaced custom SVG charts with Recharts across the dashboard and monitoring pages.
- Service Domain Routing: Compose services now support a configurable domain with full proxy integration (registered on start, removed on stop/delete, restored on startup).
- Service Restart Button: services now have a Restart button alongside Stop when running.
Fixed
- Proxy Route Restore on Startup: running apps now have routes (including Basic Auth and www variants) fully restored after a restart, preventing post-update 404s.
- Audit Log User Display: the audit log now shows the user's email instead of their UUID.
- Audit Log Resource Type Formatting: multi-word types like
ssh_keynow display as "SSH Key." - SSH Key Delete Audit Log: deleting a key now records its name, not the UUID.
- DB Backup Download 401: backup downloads now fall back to the stored auth token.
- Database Data Directory Uniqueness: data directories now include the first 8 chars of the DB UUID to prevent path collisions.
- Deployment Detail Status Badge: now shows "Running" for active deployments (plus "Replaced" and "Stopped" labels).
- Service Logs Duplication: the log viewer no longer shows REST and SSE history entries simultaneously.
- Service Network Tab Open Link: now uses the configured domain URL when the port matches.
- Dashboard Stats Console Errors: the app stats endpoint now returns zeroed stats (200) for apps with no running deployment.
- Recent Events Replaced Status: superseded deployments now show a descriptive message instead of "unknown."
- Deployment Log Streaming: Docker and Nixpacks build output is now streamed in real time.
- Logout Auth Header: logout now passes the Authorization header and clears the token.
- Team-Scoped Queries Backward Compat: team-scoped queries now include
OR team_id IS NULLso legacy resources stay visible. - Freeze Windows API Path: the frontend now calls the correct freeze-windows endpoint.
- Migration 067/068 Registration: the container-slug and service domain/port migrations are now registered.
- Admin API Token Permissions: the admin token now has full access to all teams and can delete apps without a password.
- Stuck Deployments Cleanup: deployments stuck in
running/pendingare cleaned up on startup. - TypeScript Fixes: corrected a
DeploymentLog.idtype mismatch, a missing icon prop, and a log sort comparison.
[0.10.2] - 2026-03-11
Added
- Deployment Detail Page: shows real-time build logs over WebSocket plus metadata and error details, navigated to automatically after a deploy.
- GitLab Source in New App: a GitLab repo picker is now available alongside GitHub in the new-app form.
Fixed
- Git Clone Authentication: HTTPS clones for private GitHub/GitLab/Bitbucket repos now inject the provider's token so git doesn't prompt for credentials.
- App Name Validation: names are auto-sanitized in the frontend and validation is relaxed; the global uniqueness constraint was removed (apps are identified by UUID).
- Bitbucket Auth: migrated from deprecated App Passwords to Atlassian API Tokens.
- HTTP-to-HTTPS Redirect: port 80 no longer redirects to HTTPS until a TLS certificate is confirmed.
- Sidebar URL Restructure: infrastructure and access items now live at clean top-level URLs.
- Missing Project Routes: the project environments and env-vars routes are now registered.
Changed
- Deployment Diff & Build Logs Modals: widened for readability.
- "View Full Logs" Button: now navigates to the deployment detail page instead of a small modal.
- Deploy Button: now takes the user to the deployment detail page to watch live logs.
- Database Migration 066: removed the
apps.nameUNIQUE constraint (existing data preserved).
[0.10.1] - 2026-03-10
Fixed
- PackConfig Default:
trust_buildernow correctly defaults totrue, fixingtest_empty_config. - Frontend TypeScript: fixed option-object args and removed a reference to a nonexistent app field.
- servers.tsx: replaced an inline
require("react")with proper top-level imports. - Cargo.toml: bumped version to
0.10.1and fixed the repository URL. - install.sh: fixed the Railpack download URL (uses
-musl, includes the version tag). - Database migrations: fixed a startup crash in the comment-aware SQL parser and registered missing migrations (051, 052, 054, 055, 056, 065).
[0.10.0] - 2026-03-10
Added
Container Registry Push
- Registry Push on Deploy: apps can push built images to any Docker registry after a successful build (URL, username, encrypted password, per-app toggle), configured in a new app settings section.
Rollback Retention Policies
- Configurable Retention: keep 1-50 previous deployments per app (default 10); older deployments and logs are trimmed after each successful deploy. Configurable in deployment settings.
Community Template Suggestions
- Suggest a Template: users can submit template suggestions (name, image, category, description, URL); admins can list and approve them into the service templates.
Auto-scaling Foundation
- Autoscaling Rules: define per-app CPU/memory threshold rules with min/max replica bounds and cooldowns, enforced by a 60-second background scaler, managed from an app settings card.
Enhanced Prometheus Metrics
- New metrics for deployment count and duration by app, live app/database gauges, and webhook ingestion by provider.
Webhook Audit Log
- Webhook Events: all incoming webhook events are logged (provider, type, repo, branch, apps triggered, status) and viewable on a Settings page with filters and auto-refresh.
MCP Server
- Model Context Protocol: a
/mcpendpoint exposes Rivetr tools (list_apps,deploy_app,get_app_status,get_deployment_logs) for AI assistant integration.
[0.9.0] - 2026-03-10
Added
Multi-Server Enhancements
- Server App Assignment: assign apps to specific registered servers, with a
RemoteContextfoundation for the remote build pipeline. - Remote Server Terminal: an xterm.js WebSocket SSH terminal embedded in the server settings page.
- Server App Management API: endpoints to list, assign, and remove server apps.
Docker Swarm Integration
- Swarm Management: initialize/leave a Swarm and store join tokens.
- Node Management: list, sync, and drain/activate nodes.
- Service Scaling: create, scale, remove, and inspect Swarm services.
- Swarm Dashboard: a settings page with status, nodes, and services tables.
Build Servers
- Dedicated Build Server Registration: separate build servers with encrypted SSH keys, concurrency limits, and health checks, plus full CRUD and a dashboard.
Deployment Preview Diff
- Diff View: a per-deployment "View Diff" button showing the commit range, count, messages, and changed files in a modal.
Instance Backup to S3
- Upload to S3: a per-backup button to upload an instance backup to S3.
[0.8.0] - 2026-03-10
Added
DockerHub Webhook
- DockerHub Integration: apps with a matching
docker_imageauto-deploy when the image is pushed to DockerHub, with callback acknowledgement.
Scheduled Backups
- Backup Schedules: cron-based scheduling for instance and S3 backups with configurable retention and an enable/disable toggle, run by a 60s background scheduler.
2FA Enforcement Per Team
- Team-level 2FA Requirement: owners can require all members to have 2FA, blocking non-TOTP users from team resources, via an owner-only Security tab.
Template Search & Filtering
- Template Search: a
searchparam filters templates by name/description, with a result count and scrollable category pills.
Service Dependency Graph
- Dependency Visualization: projects show a graph of apps, databases, and services with labeled nodes and edges, backed by dependency endpoints and a
service_dependenciestable.
Zero-Downtime Indicator
- Deployment Phase Banner: the Deployments tab shows a real-time phase indicator (Stable, Deploying, Health Checking, Switching Traffic), and app status now returns
deployment_phase,active_deployment_id, anduptime_seconds.
Multi-Server Support
- SSH Server Registration: register remote servers with encrypted credentials; health checks gather CPU/memory/disk/OS/Docker stats, shown on a management page with per-server "Check Now."
SSO/OIDC
- OpenID Connect: a full OIDC auth flow with provider management and quick-fill presets for Auth0, Keycloak, Google, Azure AD, and Okta; the callback creates or links a user account.
Container Replicas
- Replica Scaling: set 1-10 replicas per app; the pipeline starts N containers and the proxy round-robins across them via a lock-free
RoundRobinBackend.
Refactored
- Split all Rust files over 1000 lines into organized submodules, and split the frontend API types into 7 domain files and several large pages into components (all imports unchanged).
[0.5.0] - 2026-03-10
Added
Deployment Enhancements
- Approval Workflow: apps can require approval before deploys; pending deployments await admin sign-off with an approve/reject UI and reason field, surfaced via a badge and timeline status.
- Scheduled Deployments: deploy at a specific time via
scheduled_at, picked up by a 60s scheduler. - Deployment Freeze Windows: define windows (days + UTC start/end) when deploys are blocked (returns 409).
Bulk Operations & App Management
- Bulk Actions: multi-select apps to Start/Stop/Restart/Deploy at once.
- App Cloning: deep-copy an app's config, env vars, and domains as
{name}-copy. - Config Snapshots: save and restore named point-in-time snapshots of app config and env vars.
- Project Export/Import: download a full project as JSON and re-import to recreate it.
- Maintenance Mode: toggle per-app maintenance mode with a custom message and header badge.
Shared Environment Variables
- Inheritance Chain: team, project, environment, and app variables resolve in that order (highest wins), with a "Resolved" tab showing effective variables and source badges, managed from team and project settings.
[0.4.0] - 2026-03-10
Added
S3 Backup Integration
- S3 Storage Configs: support for AWS S3, MinIO, Cloudflare R2, and any S3-compatible endpoint with encrypted credentials.
- Backup to S3 / Restore from S3: upload instance, database, and volume backups to S3 and restore any of them with one click, managed from an S3 settings UI.
Advanced Monitoring
- Full-Text Log Search: search deployment logs by query, date range, and level.
- Uptime Tracking: 60s health checks with availability percentage, response time, and 24h/7d/30d history.
- Log Retention Policies: per-app retention (days + max size) with daily background cleanup.
- Scheduled Container Restarts: cron-based per-app restarts with an enable/disable toggle.
- Monitoring Tab: a per-app tab combining log search, uptime, retention, and scheduled restarts.
Log Draining
- Provider Support: Axiom, New Relic, Datadog, Logtail (Better Stack), and a generic Custom HTTP target.
- Batched Forwarding: logs buffered and flushed every 5 seconds or 100 lines, with error tracking and a per-app management tab with test button.
Changed
- Watch path filtering added to the GitHub push handler (was missing; only Gitea/GitLab had it).
[0.3.0] - 2026-03-09
Added
Preview Deployments
- PR Preview Environments: automatic preview deploys for pull/merge requests across GitHub, GitLab, and Gitea, with unique subdomains, auto-posted GitHub PR comments, automatic cleanup on close/merge, and lower default resource limits.
Watch Paths
- Selective Deployment: configure per-app glob patterns so pushes only deploy when matched files change, applied across all four Git providers, with a settings card.
Bitbucket Webhooks
- Bitbucket Support: push and PR webhook handling with HMAC-SHA256 verification, a
bitbucket_secretconfig option, and a Git Providers tab with webhook URL, copy, and connection test.
Notification Channels (4 New)
- Telegram, Microsoft Teams, Pushover, Ntfy: added rich-formatted integrations, bringing Rivetr to 8 notification channels.
Instance Backup & Restore
- Full Instance Backup: bundle the database (after WAL checkpoint), config, and SSL certs to a tar.gz, with create/list/download/delete/restore endpoints,
rivetr backup/restoreCLI commands, and a Settings page.
OAuth Login
- GitHub & Google OAuth: full authorization flows with user creation/linking, account linking in settings, an admin provider config page, and conditional login buttons.
Project Environments
- Environments: dev/staging/production environments per project (auto-created) with environment-scoped variables, predefined system variables (
RIVETR_ENV,RIVETR_APP_NAME,RIVETR_URL), a switcher, and a management page.
Two-Factor Authentication
- TOTP 2FA: compatible with standard authenticator apps, with QR-code setup, 10 hashed recovery codes, AES-256-GCM-encrypted secrets, a 2FA-aware login flow, and a security settings page.
Service Templates Expansion (26 to 74)
- Added ~48 templates across AI/ML, Analytics, Automation, CMS, Communication, Development, Documentation, File/Media, Monitoring, Security, Search, and Project Management, with new category enum variants for gallery organization.
Scheduled Jobs
- Cron Scheduler: a 60s background evaluator runs container jobs via Docker/Podman, with CRUD endpoints, a
scheduled_job_runshistory table, and a per-app management tab.
Deploy by Commit/Tag
- Commit/Tag Deploy: deploy a specific commit SHA or tag (
commit_sha/git_tag); the pipeline checks out the ref, the API lists commits/tags, and a deploy modal offers a selector with timeline badges.
Changed
- Updated the notification channel CHECK constraint to include all 8 providers.
- Login response now includes
requires_2fa. - Project creation auto-creates production, staging, and development environments.
- The deployment pipeline merges environment-scoped and system variables and supports commit/tag checkout.
- The template gallery now shows 74 templates across 12+ categories.
0.2.16 - 2026-02-13
Fixed
- Auto-Update Download: fixed the "Downloaded update undefined" message by adding a
versionfield to the response. - Auto-Update Apply: fixed the "Failed to create backup" error by falling back to a temp dir when the install dir is read-only, with symlink resolution and proper permissions.
- Delete GitHub App: fixed a 405 by adding and registering the DELETE handler that also removes installations.
- Git Providers FK Constraint: fixed a 500 when adding GitLab/Bitbucket providers by using the authenticated user's ID instead of a hardcoded one.
Added
- Audit Logging: extended audit logging to Auth (login/setup), SSH Keys, GitHub App deletes, and Git Provider add/delete, with new action and resource constants.
0.2.15 - 2026-02-13
Fixed
- Install Script: changed the default version to
latestso it auto-fetches a real release instead of failing on a never-released tag, and added a frontend build step beforecargo buildto fix theRustEmbedcompilation error. - GitHub App Callback: corrected the post-install redirect to the existing git-providers page.
0.2.14 - 2026-02-05
Fixed
- Container Monitor: added the missing
team_idcolumn to database queries, ending the recurring "no column found" warning. - Notification Channels: migration 038 adds
webhookto the channel-type CHECK constraint, handling foreign keys correctly.
0.2.13 - 2026-02-05
Fixed
- Teams API Panic: fixed a string-slicing panic when creating a Personal team for user IDs shorter than 8 characters, using safe character iteration for slug generation.
0.2.12 - 2025-02-05
Fixed
- Dashboard Stats Chart: fixed an auth-token key mismatch so the stats history API receives the token on the dashboard and monitoring pages.
0.2.11 - 2025-02-05
Added
- Auto-Update System: background update checking (default 6h) with version-info, check, download, and apply endpoints, configured via
[auto_update]inrivetr.toml, with an optional auto-apply mode.
Changed
- Added comprehensive testing documentation.
0.2.10 - 2025-02-05
Fixed
- PORT Environment Variable: Rivetr now auto-injects
PORT(set to the container port) into deployments, rollbacks, and previews when not already set, so Heroku-style apps work out of the box.
0.2.9 - 2025-02-05
Changed
- Version bump for release pipeline.
0.2.8 - 2025-02-04
Fixed
- Container Monitor: added the missing
team_idcolumn to the services query, fixing a SQL error when restarting crashed services.
0.2.7 - 2025-02-04
Added
- Personal Team Auto-Creation: new users get a "Personal" team on first login, and existing teamless users get one when needed.
0.2.6 - 2025-02-04
Fixed
- Frontend API URL: uses
window.location.hostnameinstead of hardcodedlocalhost, so the dashboard works via IP or custom domain.
0.2.5 - 2025-02-04
Fixed
- Systemd Service: multiple Docker/Podman compatibility fixes (read-only home, added ReadWritePaths, created the rivetr home directory).
- Install Script: auto-detect
external_urlfrom the server IP. - Cost API: fixed a SQL type mismatch in cost calculations.
0.2.4 - 2025-01-10
Added
- Team Collaboration (Multi-tenant): full multi-tenant teams with resource scoping via
team_id, a sidebar team switcher, email invitations (7-day expiry) with HTML/text templates, role hierarchy (owner > admin > developer > viewer) and member management, app sharing, team-scoped stats, audit logging with a paginated UI, amigrate-teamsCLI command, and a Personal workspace fallback. - Resource Alerts & Cost Estimation: per-app CPU/memory/disk/network metrics, customizable alert thresholds with email notifications and event history, configurable cost rates, daily cost snapshots, and a team-cost aggregation API.
- Embedded Frontend Assets: frontend files are embedded via
rust-embedfor single-binary deployment, with compressed cached assets, SPA fallback, and MIME detection. - CLI Tool:
status,apps list/show,deploy,logs --follow, andconfig check, with--api-url/--tokenoptions and env-var equivalents. - Metrics Storage with Retention:
stats_hourly(30-day) andstats_daily(365-day) aggregates from an hourly background task, configurable retention, and a stats-summary endpoint.
Fixed
- Team Switcher: fixed switching back to the Personal workspace by persisting an explicit marker in localStorage.
- Install Script: corrected the binary download URL and architecture detection, added
CAP_NET_BIND_SERVICEfor ports 80/443, added build-dependency installation, and added dynamic version fetching forlatest.
0.2.3 - 2025-01-10
Fixed
- Updated the macOS x86_64 build runner from retired
macos-13tomacos-15-intel.
0.2.2 - 2025-01-10
Fixed
- Resolved OpenSSL cross-compilation issues by adding
git2'svendored-opensslfeature. - Changed macOS builds to native runners instead of cross-compilation for reliability.
0.2.1 - 2025-01-10
Fixed
- Switched
reqwestfromnative-tlstorustls-tlsfor cross-platform builds.
0.2.0 - 2025-01-09
Added
- Railpack Builder: Railway's Nixpacks successor with BuildKit integration.
- Cloud Native Buildpacks: Heroku and Paketo buildpack support via the
packCLI. - Auto-rollback: automatic rollback on health-check failure.
- Paginated Deployments API:
GET /api/apps/:id/deploymentswithpage/per_page.
Changed
- Updated Claude Code agents and skills documentation.
Fixed
- JWT generation test for malformed PEM structures.
- Redeployment for ZIP-uploaded apps using existing images.
0.1.0 - 2025-01-08
Added
Core Deployment Engine
- Git deployments from GitHub, GitLab, and Gitea with webhook signature verification.
- Multiple build types: Dockerfile, Nixpacks, and static sites.
- Docker and Podman runtime support with auto-detection.
- Zero-downtime deployments with health checks.
- Real-time build and runtime log streaming via WebSocket/SSE.
- Rollback to any previous deployment.
Platform Services
- Managed Databases: one-click PostgreSQL, MySQL, MongoDB, and Redis.
- Docker Compose: deploy multi-container apps from a compose file.
- 26 Service Templates: Portainer, Grafana, Uptime Kuma, Gitea, n8n, MinIO, Traefik, and more.
- Database Backups: scheduled hourly/daily/weekly backups.
Security
- HTTPS with automatic Let's Encrypt certificates and renewal.
- Team management with RBAC (owner/admin/developer/viewer).
- Rate limiting with a sliding-window algorithm.
- Input validation and command-injection protection.
- Security-headers middleware.
- AES-256-GCM encryption for environment variables at rest.
- Constant-time comparison for timing-attack prevention.
Dashboard
- A React + TypeScript dashboard with SSR (React Router v7).
- Real-time deployment status and resource monitoring.
- Browser-based container terminal (xterm.js).
- Theme switching (light/dark/system).
- A build-logs viewer for all historical deployments.
Operations
- ZIP-upload deployment with build-type auto-detection.
- GitHub App integration for repository access.
- Container crash recovery with exponential backoff.
- Startup self-checks (database, runtime, directories, disk).
- A Prometheus metrics endpoint (
/metrics). - Disk-space monitoring with alerts.
Configuration
- Per-app and build resource limits.
- Custom Dockerfile path and build targets.
- Pre/post deployment commands.
- Multiple domains per app with auto-SSL.
- HTTP Basic Auth protection.
- Container labels for Traefik/Caddy integration.
- Volume management with backup/export.
Infrastructure
- GitHub Actions CI/CD with multi-platform releases.
- SQLite with WAL mode.
- An embedded reverse proxy with ArcSwap for lock-free route updates.
Version History Summary
| Version | Date | Highlights |
|---|---|---|
| 0.10.20 | 2026-05-02 | Coolify-style deploy log side panel, MariaDB managed DB type, container monitor service-health regression fix, AI insights 503 to 404 |
| 0.2.16 | 2026-02-13 | Auto-update fixes, delete GitHub App, git provider FK fix, audit logging |
| 0.2.15 | 2026-02-13 | Install script download fix, GitHub App callback fix |
| 0.2.14 | 2026-02-05 | Container monitor and notification webhook fixes |
| 0.2.13 | 2025-02-05 | Teams API panic fix for short user IDs |
| 0.2.12 | 2025-02-05 | Dashboard stats chart auth fix |
| 0.2.11 | 2025-02-05 | Auto-update system with API endpoints |
| 0.2.10 | 2025-02-05 | Auto-inject PORT env var for containers |
| 0.2.9 | 2025-02-05 | Release pipeline update |
| 0.2.8 | 2025-02-04 | Container monitor team_id fix |
| 0.2.7 | 2025-02-04 | Personal team auto-creation |
| 0.2.6 | 2025-02-04 | Frontend dynamic hostname |
| 0.2.5 | 2025-02-04 | Systemd and install script fixes |
| 0.2.4 | 2025-01-10 | Team collaboration, resource alerts, cost estimation |
| 0.2.3 | 2025-01-10 | macOS runner update |
| 0.2.2 | 2025-01-10 | OpenSSL vendoring fix |
| 0.2.1 | 2025-01-10 | rustls-tls migration |
| 0.2.0 | 2025-01-09 | Railpack, CNB buildpacks, auto-rollback |
| 0.1.0 | 2025-01-08 | Initial release with full PaaS features |
Migration Notes
Upgrading to 0.2.x
No breaking changes. The 0.2.x releases focus on build system improvements and new builder support.
From Source
git pull origin main
cargo build --release
# Restart the service
Using Install Script
curl -fsSL https://raw.githubusercontent.com/KwaminaWhyte/rivetr/main/install.sh | sudo bash