Run database, backend, and frontend using the repository Docker Compose stack.
- Docker Desktop (or Docker Engine + Compose plugin)
- Ports available on host:
3000(frontend)3002(backend)5432(internal to container network unless exposed)
From repository root, create .env from the provided example:
copy .env.docker.example .envIf you are not on Windows:
cp .env.docker.example .envSet at least:
POSTGRES_DBPOSTGRES_USERPOSTGRES_PASSWORDJWT_SECRET(minimum 32 characters recommended)
Optional seed variables:
SEED_DATABASE=trueruns the backend seed script during backend startup. Development Docker defaults this totrue; production Docker defaults it tofalse.ADMIN_EMAILandADMIN_PASSWORDlet the current seed script create or promote an admin user. If either value is missing, the seed step exits without changing data.
From repository root:
docker compose up --buildThis starts:
db(PostgreSQL)backend(Express + Prisma)frontend(Nginx serving React build)
Compose waits for PostgreSQL to pass its health check before starting backend, and waits for the backend /api/health endpoint before starting frontend.
- Frontend app:
http://localhost:3000 - Backend API from host:
http://localhost:3002
When using the browser app, requests go through frontend Nginx proxy:
/api/*on port3000is proxied to backend containerbackend:3001
On backend container startup, command includes:
npm run prisma:migrate:prodnpm run prisma:seedwhenSEED_DATABASE=true
That means existing migration files are automatically applied before backend starts serving requests. Roadmap work such as viewpoints and pin metadata must include Prisma migration files under backend/prisma/migrations; Docker startup will deploy those migrations.
The current seed script only manages the admin user. Example metamodels, models, views, viewpoints, and pin examples are frontend-bundled sample data unless a future migration or seed script explicitly imports them into the database.
For production compose:
docker compose -f docker-compose.prod.yml up --buildProduction does not run the seed script by default. To intentionally run it, set SEED_DATABASE=true in the production environment together with ADMIN_EMAIL and ADMIN_PASSWORD, start the backend once, then set SEED_DATABASE=false again for normal restarts.
- Open app:
http://localhost:3000 - Health endpoint via backend host port:
http://localhost:3002/api/health - Container health status:
docker compose ps
Safe config validation commands:
docker compose config
docker compose -f docker-compose.prod.yml config
docker compose build backend frontendStart in detached mode:
docker compose up -dView logs:
docker compose logs -fRestart one service:
docker compose restart backendStop and remove containers:
docker compose downStop and remove containers + named volumes:
docker compose down -v- Stop local processes using
3000or3002 - Or adjust port mappings in
docker-compose.yml
- Inspect logs:
docker compose logs backend - Check
JWT_SECRETand DB credentials in root.env - Ensure db is healthy and accepting connections
- Confirm backend container is running
- Confirm Nginx proxy route
/api/is active