Skip to main content
Run the full Manifest stack on your own machine. No Node.js required, just Docker. To run Manifest somewhere other than your own machine, see the other self-hosting paths. All three paths end in the same place: a running stack at http://localhost:2099 where you sign up. The first account you create becomes the admin. No demo credentials are pre-seeded.
The bundled compose file binds port 2099 to 127.0.0.1 only, so the dashboard is reachable on the host machine but not over the LAN. See Exposing on the LAN to change this.

Installation

Verify

After connecting a provider, send a test request and watch it land in the dashboard. Grab your Manifest API key from the dashboard (it starts with mnfst_) and run:
If the response comes back with That doesn't look like a Manifest key, you’re still using the placeholder — replace mnfst_YOUR_KEY_HERE with the real key from the dashboard.

Verifying the image signature

Published images are signed with cosign keyless signing (Sigstore). Verify before pulling:

Custom port

If port 2099 is taken, change both the mapping and BETTER_AUTH_URL:
Or in docker-compose.yml:
…and in .env:
If you see an “Invalid origin” error on the login page, BETTER_AUTH_URL doesn’t match the URL you’re accessing the dashboard on. The host matters as much as the port.
Upgrading from a pre-2099 install? Your existing stack keeps running on port 3001 with no changes — the backend’s own fallback is still 3001, so the new image works against your old compose file. If you want to refresh your compose file but stay on the legacy port (to avoid reconfiguring OAuth callbacks, reverse proxies, or bookmarks), set PORT=3001 in .env and the bundled compose file will honour it for both the host binding and the internal listener.

Exposing on the LAN

By default the compose file binds port 2099 to 127.0.0.1 only. The dashboard is reachable from the host but not from other machines on the network. To expose it on the LAN:
1

Change the port binding

Edit docker-compose.yml and change the ports line from "127.0.0.1:2099:2099" to "2099:2099".
2

Set BETTER_AUTH_URL

In .env, set BETTER_AUTH_URL to the host you’ll reach the dashboard on, e.g. http://192.168.1.20:2099 or https://manifest.mydomain.com. This must match the URL in the browser or Better Auth will reject the login with “Invalid origin”.
3

Apply

Image tags

Every release is published with the following tags: Images are built for both linux/amd64 and linux/arm64.

Upgrading

Manifest ships a new image on every release. To upgrade an existing compose install:
Database migrations run automatically on boot, no manual steps. Your data in the pgdata volume is preserved across upgrades. Pin to a specific major version (e.g. manifestdotbuild/manifest:5) in docker-compose.yml if you want control over when major upgrades happen.

Backup and persistence

All state lives in the pgdata named volume mounted at /var/lib/postgresql/data in the postgres service. Nothing else in the Manifest container is stateful. Back up (from the host, with the stack running):
Restore into a fresh stack:
To list or remove the volume manually:

Environment variables

Core Only the first two are required, and the installer generates both for you, so a default install boots without you setting anything. Everything else is optional: bind address and CORS, rate limits, provider timeouts, email delivery for alerts and password resets, OAuth logins, connection-pool sizing, and Sentry. See Environment variables for the full list with defaults.

Stop and clean up

Data and privacy

Manifest keeps metadata about each request — model, provider, tier, token counts, cost, latency — and never the message bodies. Prompts and completions are not written to the database.

Telemetry

Once a day, each install sends an anonymous aggregate report: version, provider mix, token and cost totals. Never prompts, keys, or anything tied to a user. Set MANIFEST_TELEMETRY_DISABLED=1 in your .env to turn it off. Full field list, what’s never sent, and how to point it at your own endpoint: Data and telemetry.

Docker Hub

The image is available at manifestdotbuild/manifest on Docker Hub.