services: postgres: image: postgres:18-alpine environment: POSTGRES_DB: perler POSTGRES_USER: perler POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD} volumes: - postgres-data:/var/lib/postgresql healthcheck: test: [CMD-SHELL, 'pg_isready -U perler -d perler'] interval: 5s timeout: 3s retries: 10 restart: unless-stopped redis: image: redis:8-alpine environment: REDIS_PASSWORD: ${REDIS_PASSWORD:?Set REDIS_PASSWORD} command: [sh, -c, 'exec redis-server --appendonly yes --requirepass "$$REDIS_PASSWORD"'] volumes: - redis-data:/data healthcheck: test: [CMD-SHELL, 'REDISCLI_AUTH="$$REDIS_PASSWORD" redis-cli ping'] interval: 5s timeout: 3s retries: 10 restart: unless-stopped server: build: ./perler-beads-server environment: APP_ENV: ${APP_ENV:-production} GIN_MODE: release LISTEN_ADDR: :8080 DATABASE_URL: postgres://perler:${POSTGRES_PASSWORD}@postgres:5432/perler?sslmode=disable REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0 ADMIN_USERNAME: ${ADMIN_USERNAME:?Set ADMIN_USERNAME} ADMIN_PASSWORD: ${ADMIN_PASSWORD:?Set ADMIN_PASSWORD} WECHAT_APP_ID: ${WECHAT_APP_ID:-} WECHAT_APP_SECRET: ${WECHAT_APP_SECRET:-} CORS_ORIGINS: ${CORS_ORIGINS:-} SEED_DEMO: ${SEED_DEMO:-false} ports: ['127.0.0.1:8080:8080'] depends_on: postgres: {condition: service_healthy} redis: {condition: service_healthy} restart: unless-stopped webui: build: ./perler-beads-webui ports: ['127.0.0.1:8088:80'] depends_on: [server] restart: unless-stopped volumes: postgres-data: redis-data: