Quick start
This brings up a local stack with the bundled database. For production, read Production hardening first.
1. Get the code
git clone <repo> cloud-exit-intranet
cd cloud-exit-intranet
2. Create an environment file
cp .env.example .env
Set at least a real session secret:
openssl rand -hex 32 # copy the value into BETTER_AUTH_SECRET
For a local stack you can leave sign-in blank and use the dev shortcut, or point
OAUTH_* at Authentik (see Single sign-on). Compose reads
.env for ${VAR} substitution.
3. Build and start
docker compose up --build # or: podman compose up --build
Compose runs db (healthchecked), applies migrations in the one-shot migrate
service, then starts app and worker.
4. Open the app
Browse http://localhost:3000. With no provider configured you can sign in with
the dev shortcut:
http://localhost:3000/dev/login?email=abdul@cloud-exit.com&role=admin
Valid roles are engineer, reviewer, finance, and admin.
5. Seed demo data (optional)
docker compose run --rm migrate pnpm db:seed
Add -- --reset to clear domain and credential tables first:
docker compose run --rm migrate pnpm db:seed -- --reset
Everyday commands
docker compose logs -f app # follow app logs
docker compose ps # service status
docker compose run --rm migrate pnpm db:migrate # re-run migrations
docker compose restart app worker # restart after a config change
docker compose down # stop (keeps the db volume)
docker compose down -v # stop and delete the database volume
Override the published ports and database credentials with APP_PORT,
POSTGRES_PORT, POSTGRES_USER, POSTGRES_PASSWORD, and POSTGRES_DB. Change
POSTGRES_PASSWORD and BETTER_AUTH_SECRET before any shared deployment.
docker compose down -v deletes the pgdata volume and therefore all data.
Back up first if it matters.