# TimeTracker — NAS-friendly Docker Compose stack # # Designed for QNAP Container Station, Synology Container Manager, Portainer, # and other NAS UIs where you paste YAML directly (no git clone required). # # Quick install: # 1. Paste this entire file into your NAS stack / project editor. # 2. Set SECRET_KEY and POSTGRES_PASSWORD (required). Generate with: openssl rand -hex 32 # 3. Deploy the stack, then open http://:8080 # Do not port-forward the DB; keep this stack on a trusted LAN only. # # Full guide: docs/admin/deployment/NAS_DEPLOYMENT.md services: app: image: ghcr.io/drytrix/timetracker:latest container_name: timetracker-app environment: - TZ=${TZ:-Europe/Brussels} - CURRENCY=${CURRENCY:-EUR} - ROUNDING_MINUTES=${ROUNDING_MINUTES:-1} - SINGLE_ACTIVE_TIMER=${SINGLE_ACTIVE_TIMER:-true} - ALLOW_SELF_REGISTER=${ALLOW_SELF_REGISTER:-true} - IDLE_TIMEOUT_MINUTES=${IDLE_TIMEOUT_MINUTES:-30} - ADMIN_USERNAMES=${ADMIN_USERNAMES:-admin} # Required — generate with: openssl rand -hex 32 - SECRET_KEY=${SECRET_KEY:?Generate one with openssl rand -hex 32} - POSTGRES_DB=${POSTGRES_DB:-timetracker} - POSTGRES_USER=${POSTGRES_USER:-timetracker} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?Set a strong POSTGRES_PASSWORD} # Database (bundled Postgres) — password must match db service - DATABASE_URL=postgresql+psycopg2://${POSTGRES_USER:-timetracker}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-timetracker} - LOG_FILE=/app/logs/timetracker.log # CSRF & cookies (HTTP-safe defaults for LAN access via NAS IP) - WTF_CSRF_ENABLED=${WTF_CSRF_ENABLED:-true} - WTF_CSRF_TIME_LIMIT=${WTF_CSRF_TIME_LIMIT:-3600} - WTF_CSRF_SSL_STRICT=${WTF_CSRF_SSL_STRICT:-false} - SESSION_COOKIE_SECURE=${SESSION_COOKIE_SECURE:-false} - REMEMBER_COOKIE_SECURE=${REMEMBER_COOKIE_SECURE:-false} - CSRF_COOKIE_SECURE=${CSRF_COOKIE_SECURE:-false} - CSRF_COOKIE_HTTPONLY=${CSRF_COOKIE_HTTPONLY:-false} - CSRF_COOKIE_SAMESITE=${CSRF_COOKIE_SAMESITE:-Lax} - CSRF_COOKIE_NAME=${CSRF_COOKIE_NAME:-XSRF-TOKEN} - SESSION_COOKIE_SAMESITE=${SESSION_COOKIE_SAMESITE:-Lax} - PREFERRED_URL_SCHEME=${PREFERRED_URL_SCHEME:-http} # Optional features (off by default) - AI_ENABLED=${AI_ENABLED:-false} - ENABLE_TELEMETRY=${ENABLE_TELEMETRY:-false} ports: - "${HTTP_PORT:-8080}:8080" volumes: - app_data:/data - app_uploads:/app/app/static/uploads - app_logs:/app/logs depends_on: db: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "-s", "-o", "/dev/null", "http://localhost:8080/_health"] interval: 30s timeout: 10s retries: 3 start_period: 40s db: image: postgres:16-alpine container_name: timetracker-db environment: - POSTGRES_DB=${POSTGRES_DB:-timetracker} - POSTGRES_USER=${POSTGRES_USER:-timetracker} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?Set a strong POSTGRES_PASSWORD} - TZ=${TZ:-Europe/Brussels} volumes: - db_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"] interval: 10s timeout: 5s retries: 5 start_period: 30s restart: unless-stopped volumes: app_data: driver: local app_uploads: driver: local app_logs: driver: local db_data: driver: local