Skip to content

Installation

This walks you from a fresh clone to a live stack you can build on. It targets developers evaluating AnvilBase locally; production operators should also read Self-Hosting.

Prerequisites

  • Docker 25+ and Docker Compose v2
  • openssl (to generate secrets)
  • git
  • ~4 GB free RAM — the stack runs 10+ containers
  • Optional: the Rust toolchain if you want to build the anvilbase CLI

Option A — the CLI (fastest)

If you have the CLI (cargo install --path cli, or a release binary), it generates secrets and brings the stack up for you:

Terminal window
git clone https://github.com/paxtone-studio/anvilbase.git
cd anvilbase
anvilbase start # creates .env with fresh secrets on first run, waits for health

On success it prints the local endpoints. Skip to Confirm health. Otherwise, use Option B.

Option B — Docker Compose by hand

1. Clone and configure secrets

Terminal window
git clone https://github.com/paxtone-studio/anvilbase.git
cd anvilbase
cp .env.example .env

Open .env and fill every variable marked # Generate: …. This one-liner fills the required secret material for you:

Terminal window
for k in POSTGRES_PASSWORD ANVILBASE_DB_PASSWORD MINIO_ROOT_PASSWORD \
VALKEY_PASSWORD IMGPROXY_SALT; do
sed -i.bak -E "s|^${k}=.*|${k}=$(openssl rand -hex 24)|" .env
done
for k in CONTROL_PLANE_SECRET AUTH_SECRET IMGPROXY_KEY INTERNAL_SECRET; do
sed -i.bak -E "s|^${k}=.*|${k}=$(openssl rand -hex 32)|" .env
done
# Phoenix requires SECRET_KEY_BASE >= 64 chars
sed -i.bak -E "s|^SECRET_KEY_BASE=.*|SECRET_KEY_BASE=$(openssl rand -hex 64)|" .env
# MinIO SSE-S3 KMS key (key-id:base64) — required for bucket encryption
sed -i.bak -E "s|^MINIO_KMS_SECRET_KEY=.*|MINIO_KMS_SECRET_KEY=anvilbase-dev:$(openssl rand -base64 32)|" .env
rm -f .env.bak

Verify nothing is left empty:

Terminal window
grep -E '^[A-Z_]+=$' .env && echo "STOP: empty required fields above" || echo "ok"

The MINIO_KMS_SECRET_KEY is required — project provisioning calls put_bucket_encryption on every new bucket, and MinIO rejects it without a KMS key, rolling back project creation. The dev key above is fine locally; use an operator-managed key in production (Security Hardening).

2. (Optional) internal mTLS

Leave ANVILBASE_MTLS_ENABLED=false for local evaluation. For production, generate certs with docker/mtls/generate-certs.sh and flip it to true — see Network Security.

3. Bring up the stack

Terminal window
docker compose up -d

First boot builds the Postgres image (installs wal-g) and the Rust services — expect 3–6 minutes on a warm cache, longer on first pull. Watch progress:

Terminal window
docker compose ps
docker compose logs -f control-plane

The stack is ready when control-plane, postgres, auth, realtime, console, and minio all report healthy.

4. Confirm health

Terminal window
curl -s http://localhost:39001/health | jq .
curl -s http://localhost:39001/health/services | jq .

Both should return "ok". A non-empty warnings[] is a soft signal (things still work) — see Monitoring.

5. Open the console

The web console is at http://localhost:39004. The control-plane API is at http://localhost:39001.

Default ports

AnvilBase uses a dedicated 39xxx host-port block so it won’t collide with other local services. Override any with *_PORT in .env; container-internal ports stay at their conventional defaults.

ServiceHost portInternal
Control plane (API)390013001
Auth390023002
Webhooks390033003
Console390043004
Realtime390404000
Postgres394325432
Valkey396376379
Supavisor39654
MinIO (S3 / console)39900 / 399019000 / 9001
Traefik (http/https/dash)39080 / 39443 / 3908180 / 443 / 8080

Full list: Reference → Ports.

Storage backend (MinIO vs RustFS)

AnvilBase runs MinIO by default. An opt-in overlay swaps in RustFS (an S3-compatible server in Rust). Switch by editing .env:

Terminal window
# Default (MinIO):
COMPOSE_FILE=docker-compose.yml
# RustFS:
COMPOSE_FILE=docker-compose.yml:docker-compose.rustfs.yml

Then docker compose down && docker compose up -d. The service name and hostname stay minio, so nothing else changes. MinIO’s web console (:39901) is inactive under RustFS; the S3 API (:39900) still works.

Tear down

Terminal window
docker compose down # stop containers, keep volumes (data preserved)
docker compose down -v # ALSO wipe Postgres + MinIO data (destructive)

Troubleshooting

  • up hangs on image pulls — check network / Docker Hub rate limits; isolate the build with docker compose build postgres control-plane.
  • Control plane stuck startingdocker compose logs control-plane; almost always a missing/misspelled env var.
  • Realtime: “SECRET_KEY_BASE must be at least 64 bytes” — regenerate with openssl rand -hex 64.
  • Project creation rolls back — usually MINIO_KMS_SECRET_KEY is unset (see step 1).
  • Port conflicts — override the relevant *_PORT in .env.

Next: Quickstart.