Prerequisites

  • Docker and Docker Compose v2+
  • At least 1 GB RAM available
  • Ports 8080 (API) and 5432 (Postgres) available

Quick Start

1

Clone the repository

git clone https://github.com/nickkdesignss/unisave.git
cd unisave/unisave-backend
2

Configure environment

cp .env.example .env
Edit .env with your settings. At minimum, change:
  • UNISAVE_JWT_HMAC_KEY — at least 32 bytes, random
  • UNISAVE_REFRESH_TOKEN_PEPPER — at least 16 bytes, random
Generate secure values:
# JWT key (32 bytes, base64)
openssl rand -base64 32

# Refresh token pepper (16 bytes, hex)
openssl rand -hex 16
3

Start the stack

docker compose up -d
This starts:
  • PostgreSQL 16 with pgvector extension
  • Migrate — runs database migrations automatically
  • API server — HTTP on port 8080
  • Worker — background enrichment processor
4

Verify

curl http://localhost:8080/healthz
Expected response:
{"status": "ok"}

Docker Compose Services

ServiceImagePurposePort
postgrespgvector/pgvector:pg16Database5432
migrateBuilt from cmd/migrate/Schema migrations
apiBuilt from cmd/api/HTTP API server8080
workerBuilt from cmd/worker/Enrichment background jobs
The migrate service runs once at startup, applies pending migrations, then exits. The api and worker services depend on successful migration.

Data Persistence

PostgreSQL data is stored in a Docker volume (postgres-data). To reset:
docker compose down -v   # Warning: deletes all data
docker compose up -d

Running Smoke Tests

With the stack running:
bash scripts/smoke-api.sh
This exercises all API endpoints with test data and reports pass/fail.

Production Considerations

The default Docker Compose setup is for development. For production:
  • Use strong secrets — generate random JWT_HMAC_KEY and REFRESH_TOKEN_PEPPER
  • Enable TLS — put a reverse proxy (nginx, Caddy, Traefik) in front of the API
  • Backup Postgres — set up pg_dump or continuous archiving
  • Monitor — the API exports OpenTelemetry traces; connect to Jaeger, Datadog, etc.
  • Resource limits — set CPU/memory limits in docker-compose.yml
  • External Postgres — for HA, use a managed Postgres (RDS, Cloud SQL) instead of the containerized one

Updating

git pull
docker compose build
docker compose up -d
Migrations run automatically on startup — no manual migration step needed.