The first release
Connect to your databases: PostgreSQL and TimescaleDB, MySQL and MariaDB, SQLite (files inside containers open as a read-only snapshot), Redis/Valkey and MongoDB. The connect dialog fills in the username and database from the container, can use the container's password (every use is logged), and keeps the password encrypted if you ask. Production databases open read-only until you unlock writes for up to an hour. Community connects up to 5 databases per server; an admin can deactivate one to free its slot.
Browse and edit your data. Open a connection to get its databases, schemas and tables in a tree, and each table in an editable grid. Filter, sort, search and hide fields; the view is in the link, so you can share it. Edits save as you go, with Undo, and Wharfbase warns you when someone changed the row in the meantime. A row form shows the rows it points to and the tables that point back. Also new: a SQL editor that streams results, with history, saved queries and explain; a MongoDB document view and console that keep every BSON type; a Redis key browser and console; and CSV export (up to 10,000 rows on Community). Read-only connections stay read-only, even from SQL.
The wb CLI. On the server, the installer's wharfbase command runs it inside the container with owner rights, no login needed (wharfbase ls, wharfbase query pg17 "…"); from anywhere else, npm i -g wharfbase and wb login. It covers the whole product: status, scan, ls, inspect, topology (a tree or Graphviz), findings, connect, dbs, tables, describe, query (streamed, as a table, JSON or CSV, from an argument or stdin), users, audit verify|tail -f, license status, doctor (with --bundle, a redacted zip for support) and keys rotate (a new master key; every stored password is re-sealed, now or at the next restart when the key is a file you own). wb shell pg17 opens psql, mysql, mongosh or redis-cli already connected, in a throwaway container on the database's network (needs WB_GUARD_ALLOW_EPHEMERAL=true). Every command prints JSON with --json, and exit codes say what went wrong: 2 usage, 3 auth, 4 not found, 5 plan limit, 6 unreachable.
Pro and Team features. Pro: add other servers through outbound-only agents (Settings → Servers) and work with their databases as if they were local; set who can read, write or manage each database; save views of a table, with Kanban, Calendar and Gallery layouts; import CSV files (checked first, then in one transaction); draw ER diagrams; export to Excel; schedule scans and get alerts by email, webhook, Slack, Discord or Telegram when databases appear, go down, get findings or grow; back databases up on a schedule into Wharfbase's data folder, also from other servers (needs WB_GUARD_ALLOW_EPHEMERAL=true); see who's connected to a database right now (Consumers → Check now); and open SQL Server, Oracle, CockroachDB, ClickHouse, Elasticsearch, OpenSearch, Cassandra/Scylla, Neo4j, CouchDB and InfluxDB. Team: sign in with your identity provider (OpenID Connect, optionally SSO only); API tokens for scripts and CI; mask sensitive columns from chosen roles; have editors' writes to production approved by an admin before they run; export the audit log as CSV/NDJSON and stream it to a webhook or syslog. Also fixed: from schema version 10 on, pre-upgrade backups of the metadata database would have been pruned newest first.
Update check and opt-in telemetry.
The update check (on by default, WB_UPDATE_CHECK):
- Once a day, it asks the license server for the latest release. The request carries nothing about the instance, not even its version.
- When a newer release is out, admins see it in the sidebar and under Settings → General (with Check now and a link to the notes), and wb doctor warns about it.
- A pre-release is only offered to a pre-release.
- Builds from source (version 0.0.0) don't check.
Anonymous usage statistics (off unless you turn them on, WB_TELEMETRY):
- Once a day: a random ID, the version and plan, counts of servers, users and databases, databases per engine, and how long after setup the first database was connected.
- Never names, hosts, addresses or anything from your databases.
- Settings → General → Show what's sent displays the next report exactly.
- Turning it off forgets the ID.
New routes: GET /api/v1/system/update, POST /api/v1/system/update/check and GET /api/v1/system/telemetry, for admins.
Three things the 1.0 plan promised that weren't there:
- HTTPS without a proxy: WB_TLS_CERT_FILE and WB_TLS_KEY_FILE now serve HTTPS directly. Before, they were silently ignored, and the container's healthcheck failed. A missing file or a key that doesn't match stops the start. Renewed certificates are picked up within 10 minutes without a restart.
- Search all columns: on SQL databases, All in the grid's search box also looks in numbers, dates, JSON and other columns. A search on a table with nothing to search in now finds nothing instead of every row.
- Query parameters: params in the query API and wb query --params '[42]' bind values to a one-statement script, in the engine's placeholders ($1, ?, @p1, :1).
Restore from a backup (Pro): Restore… on a backup puts it back.
- Engines: PostgreSQL, MySQL, MariaDB and MongoDB. Redis and SQLite backups stay download-only, and the tab says how to restore them.
- Where: into the same database, or another of the same kind and another name, to look at a copy first.
- How: the restore tool runs next to the database, like the dump. PostgreSQL restores as one transaction, so a failure changes nothing.
- Safety: you type the target's name to confirm. The connection must be able to write (a production database needs its unlock), and the file must still match its checksum. A safety backup of the target is taken first, and Undo… restores it.
- History: each database lists its restores. Each one is audited as backup.restored.
Charts for SQL results: the chart button next to a result draws its rows as bars, lines, areas, a scatter or a pie, without running the query again.
- Defaults: dates along X make a line, anything else bars. You can pick the columns, split one value column by another, and stack bars and areas. - Large results: rows with the same X are added up. Past eight series the rest become "Other", and the chart says what it left out. - Reading values: hover, or the arrow keys. - Export: PNG or SVG. - Saved queries: a query saved while charted keeps its chart.
Schema diff (Pro): Compare in the workspace header compares two schemas of the same kind, on one connection or two, and writes the script that makes B look like A.
- Engines: PostgreSQL and CockroachDB, MySQL and MariaDB, SQLite. - What it compares: tables, columns, primary keys, indexes, foreign keys and checks. Each difference is shown with both sides. - The script: it runs in order (keys dropped first, added last). Statements that delete data are commented out until you include them. - Running it: Open in SQL editor puts the script on B's connection. Nothing runs by itself.
DuckDB and Parquet (Pro): scans find DuckDB database files and Parquet files in container volumes, and on the host with the host scan. Other DuckDB, Parquet, CSV and JSON files can be added by path.
- Opening: like SQLite files. A file in a container opens as a read-only snapshot, and a file on the host opens live, read-only unless you allow writes.
- Parquet, CSV and JSON files open as a read-only view named after the file.
- What works: the grid, Structure, the SQL editor with DuckDB's SQL, Explain, charts, exports and the ER diagram.
- Locked down: SQL can't read or write other files, attach databases, or install extensions.
- Also fixed: SQLite connections now have the Diagram and Compare buttons. The diagram opens on the engine's usual schema (main, dbo) instead of always public.
AI-assisted SQL (Pro, your own key): Settings → AI connects the SQL editor to Anthropic or any OpenAI-compatible endpoint, a model on your own machines included. It's off until an admin sets it up.
- The AI menu in the editor: Ask turns a question into SQL, Explain comments the statement at the cursor, and Fix corrects the statement that just failed. Answers go in the editor; nothing runs by itself. - What is sent: the question or the SQL, the engine and version, and the names and types of the tab's tables. Never rows, and never columns masked from the person asking. Settings → AI shows the exact text. - The key is stored encrypted and never shown again. - Audit and limits: requests are audited without their text, and limited per user.
Relay networking: a new network attach mode, Relays (WB_NETWORK_ATTACH=relay), for databases on networks Wharfbase shouldn't join.
- How it works: Wharfbase joins only wharfbase_relay. For each database, a small container of Wharfbase's own image joins the database's network and forwards its one port.
- The relay containers: non-root, with a read-only filesystem, no capabilities and 64 MiB. They are removed 30 minutes after their database is gone.
- The socket-guard allows relays only with GUARD_ALLOW_RELAY=true (WB_GUARD_ALLOW_RELAY in .env). It checks each relay's image, command, user, limits and networks.
- Also: Wharfbase may now always leave a network it joined, even with network attach off.
Kubernetes discovery. Run Wharfbase in a cluster (deploy/kubernetes/wharfbase.yaml, or the Helm chart in deploy/helm/wharfbase). It finds the databases in your pods through a read-only service account: no Docker socket, no privileges, nothing written to the cluster.
- What it reads: pods, Services, StatefulSets, Deployments, PersistentVolumeClaims, NetworkPolicies and Namespaces, followed with watches.
- Each database:
- one per StatefulSet pod or Deployment; Jobs are skipped;
- reached by its pod's own DNS name, its Services or its pod IP;
- with the pods that use it as consumers, counted once per workload.
- Passwords from Secrets:
- "Use the password from the pod" reads the one Secret key the pod references, with get only, and audits the read;
- rbac.secrets=false or WB_SECRET_HINTS=off turns it off.
- NetworkPolicies: when one keeps Wharfbase out, the Reachability tab names it and shows the policy that opens the way.
- Findings in Kubernetes terms: LoadBalancer and NodePort exposure, no persistent volume, no readiness probe.
- New settings: WB_DOCKER=false runs without Docker (/readyz stops waiting for it); WB_KUBERNETES* configures the API, token, namespaces and Wharfbase's own pod.
- Not in a pod yet: backups, restores, wb shell and SQLite files inside pods. They say so.
PostgreSQL store and standby hubs. A hub can keep its data in PostgreSQL 15 or later instead of the SQLite file (WB_STORE_URL, or WB_STORE_URL_FILE for a secret). On Team, a second hub can run next to it as a standby, and take over within seconds when the first one stops (docs/high-availability.md).
- Moving: wb store migrate copies a running hub's store into an empty PostgreSQL schema in one transaction. It checks every table's rows and the audit chain on the copy, then the hub waits for a restart with WB_STORE_URL.
- One leader: the hub holding a lock in PostgreSQL serves; the others answer /readyz with 503 until they take over. A hub that froze stops before it writes again.
- Shared files: WB_SHARED_DIR holds backups, exports and the agents' hub key, on a volume every hub mounts.
- Example: deploy/docker-compose.ha.yml runs two hubs, PostgreSQL and a load balancer.
- Kubernetes: the Helm chart (0.2.0) takes store.existingSecret (or store.url) and replicaCount: replicas that stand by, behind the Service, with a shared volume. Replicas there keep discovering the cluster.
- Nothing changes on SQLite: it stays the default, and the single-container install is the same.
A MongoDB pipeline editor, a JSON editor in the grid, scan progress, and phones.
- Pipeline: MongoDB collections and views have a Pipeline view.
- Build an aggregation stage by stage, in shell syntax, from templates.
- See the output after any stage. Turn stages off and move them.
- It only reads: $out and $merge stay in the console, and Open in console puts the pipeline there.
- JSON editor: JSON and array values in the grid and the row drawer open in a code editor that colors and checks the JSON as you type. ⌘/Ctrl Enter saves.
- Scan progress:
- wb scan shows what the scan is doing: inspecting containers 120/200, checking databases, finding SQLite files. Agents' scans included.
- The header shows the same, live.
- New in the API: GET /api/v1/scans/:id/events, the scan's progress as NDJSON.
- On a phone: a database's tables open from a panel instead of taking half the screen, and the top bar and the license banner fit.
Wharfbase 1.0, the first stable release: databases found on Docker hosts, other servers and Kubernetes, opened in a data browser and SQL editor, and driven from the wb CLI. The changes below add up to it.
wb run as root outside the Wharfbase container (on a server, signed in to a remote hub) stays root. It used to switch to the container's user even with no admin socket around, and then couldn't read its own settings (EACCES).
A hub installed from another registry (WB_REGISTRY) hands out agent compose files that pull from that registry too; they used to default to Docker Hub. When the installer can't pull the images, it says to docker login if the registry is private.
Two Wharfbases on one Docker host leave each other's relays alone. Each relay now carries the id of the Wharfbase that made it (wharfbase.relay.owner, also in its name), and a Wharfbase adopts, removes and counts only its own. Before, one not in relay mode removed every relay on the host.
First alpha (M1). Install with curl -fsSL https://fleeq.net/wharfbase/get | sh or one docker-compose.yml. Wharfbase finds every database in your Docker containers (PostgreSQL, MySQL, MariaDB, MongoDB, Redis/Valkey, ClickHouse, SQLite files in app volumes), shows where each one's data lives, which services use it and what needs fixing, and joins the right Docker networks through the socket-guard. It comes with a web UI for setup, sign-in with 2FA, a live dashboard, per-database details, topology, findings and settings. An optional host scan finds databases installed directly on the server.
Hardening for 1.0.
Read-only connections
- PostgreSQL, MySQL and MariaDB read comments the way the server does, and check after each statement that the session is still read-only.
- SQL Server checks every statement of a batch.
- Oracle refuses inline PL/SQL.
- The Flux console refuses to() however it is written.
- The REST consoles refuse paths with # or dot segments.
Reliability
- A scan that loses Docker halfway keeps the databases it knew, instead of marking them gone.
- A query whose database connection drops ends with an error instead of hanging. On PostgreSQL, the drop could also crash the server.
- A query running on another server whose agent drops ends with AGENT_OFFLINE instead of a cut connection.
- Below 64 MB free in the data volume (WB_MIN_FREE_MB), changes are paused with STORAGE_FULL, while reads, sign-in and deletes keep working.
- A damaged master key file stops the start without touching anything.
Security
- Wharfbase's own data folder can't be opened or scanned.
- API answers are never cached.
- Agents refuse a plain-HTTP hub on a public address (WB_AGENT_ALLOW_INSECURE_HUB).
- Admins can be required to use two-factor sign-in (WB_REQUIRE_TOTP_FOR_ADMINS).
- The audit CSV export neutralizes spreadsheet formulas.
- The SSO callback code is no longer logged.
New: GET /api/v1/system/stats (memory, open handles, event-loop delay) for admins.
Docs: the docs.fleeq.net/wharfbase pages: - how discovery works, networks, the host scan, the socket guard; - the security model, backups, multi-server, upgrading; - troubleshooting, FAQ, support; - one page per engine, with the least-privilege database user; - the CLI, error code and environment references.
Also SECURITY.md.
Plans and licenses. Community stays free; Pro, Team and the one-time Founder license raise the limits on servers, connected databases, users and history. Settings → License shows your plan, what you use against each limit and the key: paste a key and press Activate, or start a 14-day Pro trial with your email (also wb license status|activate|deactivate). Keys are checked on your server; online keys are activated with license.fleeq.net, which hears from your instance about once a day (only IDs, the version and three counts). If it can't be reached, or a subscription lapses, you get 14 days of grace. Back on Community, nothing is deleted: each server keeps 5 connected databases and the owner chooses which. Also fixed: wb shell containers no longer show up as databases.
Wharfbase's own services moved to fleeq.net: the license server (WB_LICENSE_SERVER's default) and the customer portal are at https://license.fleeq.net, the website and pricing at https://fleeq.net/wharfbase, the docs at https://docs.fleeq.net/wharfbase, and the installer at https://fleeq.net/wharfbase/get (WB_INSTALL_BASE_URL's default).