name: carcontrol # Full Car Control / DriverVault stack: PocketBase (database) + API Server + Web App. # Traffic flow (browser): Web App (nginx) --/api--> API Server --> PocketBase. # Copy .env.example to .env and fill in the secrets before `docker compose up`. services: pocketbase: build: context: ./pocketbase image: carcontrol-pocketbase container_name: carcontrol-pocketbase restart: unless-stopped environment: # Superuser is created/updated on boot so the API Server can authenticate. PB_ADMIN_EMAIL: "${PB_ADMIN_EMAIL:?set PB_ADMIN_EMAIL in .env}" PB_ADMIN_PASSWORD: "${PB_ADMIN_PASSWORD:?set PB_ADMIN_PASSWORD in .env}" volumes: - pb_data:/pb/pb_data ports: # Admin UI / API exposed on the host for management (http://host:8090/_/). - "${PB_PORT:-8090}:8090" healthcheck: test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8090/api/health || exit 1"] interval: 10s timeout: 3s retries: 12 start_period: 10s api-server: build: context: ../API Server image: carcontrol-api container_name: carcontrol-api restart: unless-stopped depends_on: pocketbase: condition: service_healthy environment: PORT: "8080" # Reach PocketBase by its service name on the internal network. PB_URL: "http://pocketbase:8090" PB_ADMIN_EMAIL: "${PB_ADMIN_EMAIL}" PB_ADMIN_PASSWORD: "${PB_ADMIN_PASSWORD}" AUTH_SECRET: "${AUTH_SECRET:?set AUTH_SECRET in .env}" # Same-origin requests go through nginx, so CORS is only needed if the # browser ever calls the API Server directly. Default to the web origin. CORS_ORIGINS: "${CORS_ORIGINS:-http://localhost:8081}" AUTH_USERS_COLLECTION: "${AUTH_USERS_COLLECTION:-users}" ports: # Optional direct access to the API Server; the Web App uses the internal # network, not this host port. - "${API_PORT:-8080}:8080" web-app: build: context: ../Web App args: # Empty -> bundle uses same-origin "/api", which nginx proxies below. VITE_API_BASE: "${VITE_API_BASE:-}" image: drivervault-web container_name: drivervault-web restart: unless-stopped depends_on: - api-server environment: # nginx proxies /api/ to the API Server over the internal network. API_TARGET: "http://api-server:8080" ports: - "${WEB_PORT:-8081}:80" volumes: pb_data: