services: postgres: image: postgres:18-alpine environment: POSTGRES_USER: levyraati POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env} POSTGRES_DB: levyraati # The 18 image moved its default data directory; pin it so the ./pgdata mount below # is still where the database lives. PGDATA: /var/lib/postgresql/data volumes: - ./pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U levyraati"] interval: 5s timeout: 3s retries: 10 restart: unless-stopped app: build: . environment: DATABASE_URL: postgres://levyraati:${POSTGRES_PASSWORD}@postgres:5432/levyraati ADMIN_USER: ${ADMIN_USER:-admin} ADMIN_PASSWORD: ${ADMIN_PASSWORD:?set ADMIN_PASSWORD in .env} ADDR: ":8080" # Inside the container the admin listener must bind the container's own interface; it is not # published below, so it stays unreachable from outside without a tunnel or the proxy. ADMIN_ADDR: ":8081" SECURE_COOKIES: ${SECURE_COOKIES:-true} volumes: - ./storage:/storage ports: - "127.0.0.1:8080:8080" - "127.0.0.1:8081:8081" depends_on: postgres: condition: service_healthy restart: unless-stopped