Whity CLI
whity installs and updates a self-hosted Whity on Docker. It comes from the npm package
@whity/cli and runs on Windows (PowerShell 5.1 and newer), Linux and macOS.
It is not bin/whity-cli. That is the PHP tool that runs on the server against the database
(CLI Reference). whity runs on your machine and calls bin/whity-cli
inside the containers, so migrations and seeding always use the code of the installed release.
What you need
Section titled “What you need”- Node 20 or newer
- Docker with Compose v2 (Docker Desktop on Windows and macOS)
npm install -g @whity/cliInstall
Section titled “Install”whity installThis installs the latest release into ./whity. Name a version with whity install v0.2.22.
The oldest release it supports is v0.2.21.
It checks Docker and the ports, writes the files below with generated secrets, pulls the images,
starts the database, runs migrations and seed, starts everything and checks it. Then it prints
the address and the administrator’s email. The password stays in .env, as
INITIAL_SYSTEM_ADMIN_PASSWORD, so it doesn’t end up in your terminal history. Change it after
you sign in.
| Option | Default | |
|---|---|---|
--dir <path> |
./whity |
Install folder. Its name also names the Compose project. |
--url <url> |
http://localhost:<web port> |
The address people will use. |
--web-port <port> |
3100 |
Port for the web app. |
--api-port <port> |
8100 |
Port for the API. |
--bind <address> |
127.0.0.1 |
Address the ports are published on. |
--admin-email <email> |
system@whity.local |
The administrator’s address. |
If an install fails, fix the cause and run the same command again. It carries on with the same secrets.
Using a real address
Section titled “Using a real address”Outside development the API marks its session cookies Secure, and browsers keep those only over
HTTPS or on localhost. So whity install refuses a plain http:// address other than localhost:
the login page would load, but nobody could stay signed in.
Put a reverse proxy with a certificate in front of the web port, and install with its address:
whity install --url https://app.example.comAlso set TRUSTED_PROXY_HOPS in .env so the API sees each client’s real address
(Deployment Guide). Then run docker compose up -d in the install folder.
What is in the install folder
Section titled “What is in the install folder”| File | |
|---|---|
.env |
Settings and secrets. Keep it private, and back it up: a database backup can’t decrypt what ENCRYPTION_KEY protects without it. Every setting here reaches the app and the workers. |
docker-compose.yml |
The compose file of the installed release. whity update replaces it. |
docker-compose.override.yml |
Optional, and yours. Compose merges it in and the tool never touches it. Use it for changes such as mounting a plugin. |
backups/ |
One folder per update. |
Run the usual Compose commands in this folder: docker compose ps, docker compose logs -f web.
Uploaded files live in the storage volume and the database in postgres_data. docker compose down -v deletes both.
The compose file ships with each release as the whity-compose.yml asset, from
docker/production/docker-compose.yml. Releases made before the asset existed use the copy inside
the package.
Update
Section titled “Update”whity updateThis moves to the latest release. Name a version with whity update v0.2.22. Use --dir if the
install isn’t in ./whity.
- Reads the installed version. It refuses a downgrade, because migrations only go forward.
- Checks that your settings satisfy the new compose file.
- Pulls all three images at the new version. Whity keeps running, so a slow download costs no downtime and a failed one changes nothing.
- Stops everything except the database. Downtime starts here.
- Backs up the database and proves the backup: it restores it into a scratch database and compares row counts with the live one. With writers stopped, the backup holds every accepted change.
- Runs migrations with the new image, through
bin/whity-cli. - Starts the new version.
- Checks that
/api/health,/web-buildand the render service report the new version, that no migrations are pending, and that no service is stopped or restarting.
If a step before migrations fails, Whity goes back to running the old version and nothing has changed. The backup covers the database and the config. It doesn’t copy uploaded files, which stay in their volume across updates.
If an update fails
Section titled “If an update fails”From migrations onward, the update stops and prints the exact commands to go back. They are the
same in PowerShell, bash and zsh. Run them one at a time: docker compose exec reads its input,
so it would swallow the following lines if you pasted them all at once.
They have this shape, with your own paths and names filled in:
cd "<install folder>"docker compose downcp backups/<backup>/.env .envcp backups/<backup>/docker-compose.yml docker-compose.ymldocker compose up -d --wait postgresdocker compose cp backups/<backup>/whity_core.dump postgres:/tmp/restore.dumpdocker compose exec -T postgres dropdb -U whity --force whity_coredocker compose exec -T postgres createdb -U whity whity_coredocker compose exec -T postgres pg_restore -U whity -d whity_core --no-owner --exit-on-error /tmp/restore.dumpdocker compose exec -T postgres rm /tmp/restore.dumpdocker compose up -d --waitrm .whity-update-in-progress.jsonRunning whity update again prints them again and changes nothing. If you fixed the cause and want
to carry on without restoring, add --force.
Language
Section titled “Language”The tool’s own messages are English only. This is a deliberate exception to the rule that every
user-facing string has English and Arabic: Windows PowerShell 5.1’s console garbles Arabic and doesn’t
lay it out right to left. The install and update guide is in both languages instead. All messages live
in packages/cli/src/messages.js, so Arabic can be added there later (WHIT-840).
Troubleshooting
Section titled “Troubleshooting”deniedwhile pulling. The images are public, so this usually means an oldghcr.iologin in Docker. Rundocker logout ghcr.io.- A port is in use. Choose others with
--web-portand--api-port.
Planned
Section titled “Planned”Later versions add commands under the same whity name, tracked as WHIT-841 and WHIT-842:
whity login, then documents, agents, approvals and MCP setup. These go through the API, so permissions, tenant isolation and the audit log still apply.whity plugin: create a plugin, check its manifest against the SDK, and package it.