If running on macOS Apple Silicon, Docker and Podman run a Linux VM. Ensure the VM has sufficient resources:
- 8 CPU
- 12 GB memory
- 200 GB disk space
Quick start
Open the sites
- Public site: http://localhost:3000
- Partners site: http://localhost:3001
Services
The following services are defined indocker-compose.yml:
lb
An nginx load balancer that fronts the
api, partners, and public containers. Required to support running multiple replicas of these services.db
PostgreSQL 18 database. Exposed on port
5432. Health-checked before dependent services start.dbinit
Runs the database initialization script from
api/dbinit. Executes once on startup after db is healthy.dbseed
Seeds the database using
yarn db:seed:staging. Runs after the API has started and applied migrations.api
The Bloom API server. Runs DB migrations on start via
yarn db:migration:run && yarn start:prod. Exposed internally on port 3100.partners
The partners Next.js site. Runs
next build at container start, then serves on port 3001.public
The public-facing Next.js site. Runs
next build at container start, then serves on port 3000.pgadmin
Optional pgAdmin 4 UI for inspecting the database. Enabled via the
pgadmin profile. Accessible at http://localhost:3200.Port mappings
| Service | Host port | Container port | Description |
|---|---|---|---|
lb | 3000 | 3000 | Public site (proxied via nginx) |
lb | 3001 | 3001 | Partners site (proxied via nginx) |
lb | 3100 | 3100 | API (proxied via nginx) |
db | 5432 | 5432 | PostgreSQL |
pgadmin | 3200 | 3200 | pgAdmin (optional) |
Dockerfiles
API (api/Dockerfile)
Uses a multi-stage build to minimize the final image size:
- Build stage — Installs all dependencies, generates the Prisma client, and compiles TypeScript to
dist/. - Run stage — Copies only the compiled output and runtime dependencies from the build stage. Runs as a non-root user (
bloom_api, UID 2002).
- vCPU: 1
- Memory: 2 GiB
Public site (Dockerfile.sites.public)
Builds from node:22. Installs dependencies using a cached layer (copies package.json and yarn.lock before source code), then copies the full source. Runs as a non-root user (next, UID 2002).
On startup the container runs a Next.js build followed by the production server:
- vCPU: 2
- Memory: 6 GiB
next build runs at container start time and requires a live API and database to succeed. Resource usage spikes to the limit during the build, then drops significantly once the server starts serving traffic.Partners site (Dockerfile.sites.partners)
Structurally identical to the public site Dockerfile. Uses lower Node.js memory limits:
- vCPU: 2
- Memory: 4 GiB
Environment variables
Key environment variables configured indocker-compose.yml:
- API
- Public site
- Partners site
| Variable | Value | Description |
|---|---|---|
PORT | 3100 | API listen port |
NODE_ENV | production | Runtime environment |
APP_SECRET | totally a secret | Application secret (dev only) |
DATABASE_URL | postgres://bloom_api:bloom_api_pw@db:5432/bloom_prisma | Database connection string |
DB_NO_SSL | TRUE | Disables SSL for local DB |
Common commands
Build, start, and stop
Multiple replicas
By default each ofapi, partners, and public runs a single replica. Control the replica count with environment variables:
pgAdmin
Start pgAdmin alongside the stack to inspect the database:- Username:
[email protected] - Password:
abcdef - DB user:
bloom_readonly - DB password:
bloom_readonly_pw
Restarting and rebuilding
When you exitdocker compose up, containers are stopped but not deleted. If you run docker compose up again, the database retains its prior state and the dbseed container will fail because it already seeded the database.
To avoid this, either:
- Run
docker compose downbetween runs to wipe the database state. - Restart only the application containers to skip re-seeding:
Debugging
Run a command in a running container
Find the container ID:Start an additional container in the network
The Compose stack creates a network calledbloom_default. Attach any container to it with --network=bloom_default:
Database seeding
By default thedbseed service runs yarn db:seed:staging. To use the development seed script instead, edit the dbseed service in docker-compose.yml: