Installation
This page helps you get Actual Bench running with the simplest supported installation. Actual Bench is distributed as a Docker image, so Docker (with or without Compose) is the recommended way to run it.
Before you start
Section titled “Before you start”- Docker (and optionally Docker Compose) installed on the host.
- A free host port to publish the app on. The container listens on port 3000.
- A location for a persistent volume so Actual Bench keeps its metadata across restarts.
- Browser access to wherever you publish Actual Bench.
- For Direct Actual Server mode: your browser must be able to reach your Actual Server, which has CORS and cross-origin isolation requirements. See Connect to Actual Budget.
- For HTTP API Server mode: the Actual Bench container must be able to reach your
actual-http-apiserver.
Choose a release channel
Section titled “Choose a release channel”Actual Bench publishes multi-architecture images (linux/amd64 and linux/arm64):
| Tag | Stability | Use it when |
|---|---|---|
latest |
Stable | Normal production / self-hosting (default) |
:<version> (e.g. :1.2.4) |
Stable, pinned | You want a specific, unchanging version |
edge |
Unstable — rebuilt on every merge | Testing the newest changes before a release |
Install with Docker Compose
Section titled “Install with Docker Compose”Create a docker-compose.yml:
services: actual-bench: image: xrous/actual-bench:latest container_name: actual-bench ports: - "3000:3000" environment: ACTUAL_BENCH_DB_PATH: /data/actual-bench.sqlite # --- Optional settings (uncomment to use; see the Configuration guide) --- # DIRECT_BROWSER_API: "0" # offer only HTTP API Server mode # LOG_LEVEL: info # debug | info | warn | error # SYNC_VAULT_KEY: "<strong-secret>" # enable unattended server-side sync # SYNC_SCHEDULER_SECRET: "<strong-secret>" # enable the external scheduler trigger volumes: - actual-bench-data:/data restart: unless-stopped
volumes: actual-bench-data:Start it:
docker compose up -dNo environment variables are required for a basic setup — ACTUAL_BENCH_DB_PATH is shown here only to
make the metadata location explicit; it already defaults to /data/actual-bench.sqlite. The commented
lines are optional settings you can provide; see Configuration
for what each one does.
Install with the Docker CLI
Section titled “Install with the Docker CLI”The equivalent without Compose:
docker run -d \ --name actual-bench \ --restart unless-stopped \ -p 3000:3000 \ -v actual-bench-data:/data \ xrous/actual-bench:latestOpen Actual Bench
Section titled “Open Actual Bench”Open the app in your browser:
- Local host:
http://localhost:3000 - Remote host:
http://<your-server>:3000, or your reverse-proxy URL
You should land on the connection screen. Setting up the connection is covered in Connect to Actual Budget.
Verify the installation
Section titled “Verify the installation”- The app loads and shows the connection screen.
- The version appears in the sidebar footer (for example
v1.2.4). - Open App Health (under Tools) and confirm:
- Writable is
Yes. - Schema shows a version number (not
Not initialized). - Persistence reads Persistent when /data is mounted.
- Writable is
If Writable is No or persistence looks wrong, re-check the /data volume mount and its
permissions before connecting.
Persistent metadata storage
Section titled “Persistent metadata storage”Actual Bench stores its own workflow metadata in a SQLite database at /data/actual-bench.sqlite (set
ACTUAL_BENCH_DB_PATH to change the path). Persist and back up the /data volume to keep this data
across container recreation.
Update the container
Section titled “Update the container”To move to a newer image:
docker compose pulldocker compose up -dFor a safe upgrade — including backups, version pinning, and database migration notes — follow the Upgrading and Backups guide.
Next step
Section titled “Next step”Continue to Connect to Actual Budget.
