# Local / self-hosted stack — builds the image from this checkout instead of # pulling registry.reversed.dev. No .env file required: every variable has a # working localhost default below, so this comes up ready to set up. # # docker compose -f docker-compose.local.yml up -d --build # # Then open http://localhost:5000 and register — the first account becomes ADMIN. # # Note: BuildKit builds the `build` and `runtime` stages in parallel, which can # exhaust Docker Desktop's memory limit during pnpm install. If `--build` fails # with "cannot allocate memory", warm the first stage on its own and retry: # # docker build --target build -t patchpass-build . # docker compose -f docker-compose.local.yml up -d --build services: backend: build: context: . dockerfile: Dockerfile target: runtime image: patchpass/core:local restart: unless-stopped ports: - "${PORT:-5000}:${PORT:-5000}" environment: NODE_ENV: production TZ: ${TZ:-Europe/Berlin} PORT: ${PORT:-5000} DATABASE_URL: postgresql://patchpass:patchpass@database:5432/patchpass # Cookie scope + public URLs. Change these when you expose the instance # on a real hostname or a LAN IP. DOMAIN: ${DOMAIN:-localhost} UI_URL: ${UI_URL:-http://localhost:5000} REACT_APP_API_URL: ${REACT_APP_API_URL:-http://localhost:5000} CORS_URLS: ${CORS_URLS:-http://localhost:5000,http://localhost:3000} # Signs approval receipts (HMAC-SHA256) and hashes sessions. # DEV DEFAULT — override with a real 32-byte hex secret for anything # beyond local testing: openssl rand -hex 32 INSTANCE_SECRET: ${INSTANCE_SECRET:-0000000000000000000000000000000000000000000000000000000000000000} RATELIMIT: ${RATELIMIT:-1000} LOG_LEVEL: ${LOG_LEVEL:-info} REQUEST_DEBUGGING: ${REQUEST_DEBUGGING:-false} RESPONSE_DEBUGGING: ${RESPONSE_DEBUGGING:-false} depends_on: database: condition: service_healthy healthcheck: test: - CMD-SHELL - node -e "fetch('http://127.0.0.1:'+(process.env.PORT||5000)+'/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))" interval: 10s timeout: 5s retries: 10 start_period: 40s database: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_USER: patchpass POSTGRES_PASSWORD: patchpass POSTGRES_DB: patchpass # Exposed so you can point Prisma Studio or psql at it. Host port 5434 keeps # it clear of the dev database on 5433. ports: - "${DB_PORT:-5434}:5432" volumes: - patchpass_local_db:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U patchpass -d patchpass"] interval: 5s timeout: 5s retries: 10 volumes: patchpass_local_db: