Installation
Use this page if you run Actual Bench yourself. Docker is the supported installation method. If another person runs it for you, go to Connect to a budget.
Before you start
Section titled “Before you start”- Docker (and optionally Docker Compose) installed on the host.
- A spare port on the host. The container listens on 3000.
- Somewhere to put a persistent volume for the metadata database, or Bench forgets itself every restart.
- Browser access to wherever you publish it.
- For Direct Actual Server mode: your browser has to reach the Actual Server, which brings CORS and cross-origin isolation requirements with it. See Connect to a budget.
- For HTTP API Server mode: the container has to reach
actual-http-api.
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) --- # 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 -dA basic setup needs no environment variables at all. ACTUAL_BENCH_DB_PATH appears above only to make
the metadata location obvious - it already defaults to that path. Everything commented out is
optional; Configuration says 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:latestInstall on a hosted platform
Section titled “Install on a hosted platform”Prefer not to run your own Docker host? Actual Bench also deploys on:
- Fly.io -
fly launch --from https://github.com/x-rous/actual-bench --generate-name --ha=false - PikaPods - available once the official listing is approved
Both run the same image as Docker Compose above. See Deployment → Hosted platforms for the full walkthrough of each.
Open 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
The app opens on the connection screen. Continue with Connect to a 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 is incorrect, fix the database mount or its permissions before
you connect a budget.
Persistent metadata storage
Section titled “Persistent metadata storage”Bench keeps its own workflow metadata in a SQLite database at /data/actual-bench.sqlite; set
ACTUAL_BENCH_DB_PATH to move it. Persist and back up the volume that database sits on - /data
unless you moved it, in which case persist the directory ACTUAL_BENCH_DB_PATH names instead.
Recreate the container without it and that metadata is gone.
Update the container
Section titled “Update the container”To move to a newer image:
docker compose pulldocker compose up -dBefore a real upgrade, read Upgrading and Backups. It covers backups, pinning a version, and what happens to the database.
Next step
Section titled “Next step”Continue to Connect to Actual Budget.
