Appearance
Docker Compose Services
The docker-compose.yaml file defines five services for a complete production-like deployment.
Services
postgres
| Property | Value |
|---|---|
| Image | postgres:16-alpine |
| Host port | 35432 → container 5432 |
| Restart | unless-stopped |
| Volume | ./data/pg:/var/lib/postgresql/data |
| Health check | pg_isready -U tt |
Environment: POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB (from .env.backend)
redis
| Property | Value |
|---|---|
| Image | redis:7-alpine |
| Host port | 36379 → container 6379 |
| Restart | unless-stopped |
| Volume | ./data/redis:/data |
| Command | redis-server --appendonly yes (AOF persistence enabled) |
| Health check | redis-cli ping |
rustfs
S3-compatible object storage for invoice files.
| Property | Value |
|---|---|
| Image | rustfs/rustfs:latest |
| Host ports | 39000 → 9000 (API), 39001 → 9001 (web console) |
| Restart | unless-stopped |
| Volumes | ./data/rustfs/data:/data, ./data/rustfs/logs:/app/logs |
Environment: RUSTFS_ROOT_USER, RUSTFS_ROOT_PASSWORD, RUSTFS_ACCESS_KEY, RUSTFS_SECRET_KEY, RUSTFS_ADDRESS=:9000, RUSTFS_CONSOLE_ENABLE=true
Access the web console at http://localhost:39001 to browse uploaded files.
api
The NestJS REST API.
| Property | Value |
|---|---|
| Build | services/api/Dockerfile |
| Host port | 33000 → container 3000 |
| Restart | unless-stopped |
| Depends on | postgres (healthy), redis (healthy), rustfs (started) |
The API runs prisma migrate deploy on startup. If migrations fail, the container exits and Docker restarts it.
worker
The BullMQ background worker.
| Property | Value |
|---|---|
| Build | services/worker/Dockerfile |
| Exposed port | None |
| Restart | unless-stopped |
| Depends on | postgres (healthy), redis (healthy), rustfs (started) |
Data persistence
All state is stored under ./data/ on the host machine:
data/
├── pg/ ← PostgreSQL data directory
├── redis/ ← Redis AOF journal
└── rustfs/
├── data/ ← Uploaded invoice files
└── logs/ ← RustFS logsBack up this directory to protect your data. The ./data/ directory is created automatically on first run.
Starting only infrastructure
For local development, start just the infrastructure without building the API and worker:
bash
pnpm db:up
# equivalent to: docker compose up postgres redis rustfs -d