Skip to content

Installation

Brittle runs as a Docker container with Postgres. One command installs both:

Terminal window
curl -fsSL https://brittle.dev/install.sh | sh

When it’s done, open http://localhost:3100 and finish the setup wizard.

  • Docker 24 or newer, with Compose v2.
  • A free port. Default is 3100.

If you’d rather not pipe a script to shell, the manual flow is the same stack written by hand. Save the file below as docker-compose.yml in a new directory.

docker-compose.yml
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: brittle
POSTGRES_PASSWORD: brittle
POSTGRES_DB: brittle
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U brittle']
interval: 5s
retries: 5
init-artifacts:
image: alpine:3
volumes:
- artifacts:/data
command: ['sh', '-c', 'chown -R 1000:1000 /data']
brittle:
image: ghcr.io/brittlehq/brittle:latest
container_name: brittle
depends_on:
postgres:
condition: service_healthy
init-artifacts:
condition: service_completed_successfully
ports:
- '3100:3100'
configs:
- source: hub-config
target: /etc/brittle/hub.config.yaml
volumes:
- artifacts:/var/lib/brittle/artifacts
environment:
BRITTLE_CONFIG_PATH: /etc/brittle/hub.config.yaml
DATABASE_URL: postgresql://brittle:brittle@postgres:5432/brittle?schema=public
JWT_SECRET: ${JWT_SECRET}
BRITTLE_AI_SECRET_KEY: ${BRITTLE_AI_SECRET_KEY}
volumes:
postgres-data:
artifacts:
configs:
hub-config:
content: |
server:
host: 0.0.0.0
port: 3100
database:
url: $${DATABASE_URL}
auth:
jwtSecret: $${JWT_SECRET}
artifacts:
store: local:/var/lib/brittle/artifacts
redis: {}
session: {}
nodes:
heartbeat: {}
internal: {}
tunnel: {}
ai:
enabled: false

Generate two secrets and save them next to the Compose file:

Terminal window
cat > .env <<EOF
JWT_SECRET=$(openssl rand -hex 32)
BRITTLE_AI_SECRET_KEY=$(openssl rand -hex 32)
EOF
chmod 600 .env

Then bring up the stack:

Terminal window
docker compose up -d

The first time you open the dashboard, three short forms appear.

  1. Account. Email and password. Your admin login.
  2. Organization. Name and slug. The slug appears in URLs.
  3. Project. Name and slug.

From the dashboard: Manage → Projects → your project → Tokens → New token.

  • service: long-lived. Use in CI.
  • personal: bound to your user. Use on a laptop.

Copy the token immediately. The plaintext is shown once.

Wire it into your suite at Reporter overview.

Terminal window
BRITTLE_PORT=4000 INSTALL_DIR=~/code/brittle \
sh -c "$(curl -fsSL https://brittle.dev/install.sh)"

The chosen port is remembered. Re-running the installer reuses it.

Re-run the installer. Your data, secrets, and port survive.

Terminal window
curl -fsSL https://brittle.dev/install.sh | sh

If you installed with Compose, pull and restart from the install directory:

Terminal window
docker compose pull && docker compose up -d
Terminal window
cd ~/brittle && docker compose down -v

down -v wipes Postgres and artifacts. Delete the install directory to remove everything else.

Port already in use. Re-run with BRITTLE_PORT=4000, or stop whatever’s holding the port.

Docker not running. Start Docker Desktop on macOS or Windows, or sudo systemctl start docker on Linux.

Dashboard never responds. Tail the logs:

Terminal window
cd ~/brittle && docker compose logs -f brittle