Skip to content

Getting started

This guide gets you from a fresh clone to a running local stack.

When to use this page

Use this page for first-time local startup and health validation before deeper user or developer workflows.

Audience

  • New users who want to run the platform locally.
  • New developers who need a known-good baseline before changing code.

Prerequisites

  • Docker Engine with the Docker Compose plugin.
  • At least 8 GB RAM available to Docker.
  • Available host ports: 5173, 8000, 8001, 5432, 1025, 1883, 1884, 8025, 8083, 8084, 8883, and 18083.

1. Configure the environment

Create the ignored local configuration file from the tracked development template:

cp .env.example .env

Before using Off-Key outside local development, replace every example credential. At minimum, configure:

  • EMQX_DASHBOARD_PASSWORD with a strong value.
  • JWT_SECRET and INTERNAL_API_SECRET with distinct values of at least 32 characters.
  • SUPERUSER_MAIL with the intended administrator mailbox.

Generate independent random values without writing them to documentation or source control:

openssl rand -hex 32
$bytes = New-Object byte[] 32
[System.Security.Cryptography.RandomNumberGenerator]::Fill($bytes)
[Convert]::ToHexString($bytes).ToLower()

See Environment variables for the configuration catalog and validation rules.

2. Start the stack

From the repository root:

docker swarm init --advertise-addr 127.0.0.1  # once; RADAR runs as Swarm services
docker compose up -d --build

RADAR workloads start only when TACTIC launches a monitoring service.

3. Verify the stack

docker compose ps

The core services should be running; health-checked services should become healthy after their startup grace periods.

curl http://localhost:8000/health
curl http://localhost:8001/ready
Interface URL
Frontend http://localhost:5173
Mailpit http://localhost:8025
EMQX dashboard http://localhost:18083

4. Create the first user

Run docker compose exec -T tactic-middleware /app/bin/python -m off_key_tactic_middleware.bootstrap_admin. Open the printed invitation URL, choose a password, and log in. The account uses SUPERUSER_MAIL. Invite colleagues from Account → Members. See Single-organization operation for upgrades and SMTP.

5. Prepare monitoring when needed

TACTIC creates one RADAR workload per monitoring service. Build the local RADAR image before starting the first monitoring service, and rebuild it after RADAR source or dependency changes:

docker compose build mqtt-radar

6. Stop or reset

Stop containers while retaining volumes:

docker compose down

Delete local containers and volumes only when you intentionally want a full data reset:

docker compose down -v

Warning

docker compose down -v deletes the local database and other named-volume data for this Compose project.

Common first-run issues

Symptom Likely cause First action
API gateway keeps restarting Database schema or TACTIC is not ready Wait for startup, then inspect db-sync, tactic-middleware, and gateway logs
EMQX fails its health check Dashboard password is missing or the persisted node state has incompatible bootstrap settings Check .env; recreate the local EMQX volume only if its data can be discarded
Invitation email is missing Mailpit is unavailable Check the mailpit service and open its UI
Frontend cannot reach the API Vite proxy target is wrong Check API_PROXY_TARGET for the selected run mode
Monitoring start cannot find its image Local RADAR image has not been built Run docker compose build mqtt-radar