- Docker 24+
- Docker Compose v2+
Copy the example env file and fill in your values. Secrets are never baked into
the image — they are mounted at runtime via env_file.
cp .env.example .env
# edit .env with your Stellar keys, DATABASE_URL, etc.The DATABASE_URL in .env is overridden by Compose to point at the internal
postgres service, so you only need to set it for local non-Docker use.
# from Nova-Rewards/novaRewards/
docker build -t nova-rewards-api ./backendThe Dockerfile uses a two-stage build:
| Stage | Base | Purpose |
|---|---|---|
| builder | node:20-alpine | Installs all deps, copies source |
| runner | node:20-alpine | Production deps only + app source |
# from Nova-Rewards/novaRewards/
docker compose up --buildServices started:
| Service | Port(s) | Description |
|---|---|---|
| api | 3001 | Nova Rewards backend |
| postgres | 5432 | PostgreSQL 16 |
| redis | 6379 | Redis 7 |
| mailhog | 1025 / 8025 | SMTP trap + web UI |
The PostgreSQL service is configured with WAL archiving enabled, and the backend
now writes encrypted base backups to ./backups/base while PostgreSQL archives
encrypted WAL segments to ./backups/wal.
Stop everything:
docker compose downStop and remove volumes (wipes the database):
docker compose down -vMigrations live in database/ and are run with migrate.js.
docker compose exec api node /app/../database/migrate.jsOr run a one-off container that shares the same network:
docker compose run --rm \
-v "$(pwd)/database:/database" \
api node /database/migrate.jsDATABASE_URL=postgresql://nova:nova@localhost:5432/nova_rewards \
node database/migrate.js# Tail API logs
docker compose logs -f api
# Open a psql shell
docker compose exec postgres psql -U nova -d nova_rewards
# MailHog web UI
open http://localhost:8025