services: gitea: image: gitea/gitea:1.25 container_name: gitea restart: unless-stopped depends_on: - postgres - redis networks: - traefik-public - gitea-internal environment: # Container-specific settings only - TZ=Europe/Berlin - USER_UID=1000 - USER_GID=1000 # Postgres password for postgres container (not for Gitea config) - POSTGRES_PASSWORD=gitea_password # All Gitea configuration is now in app.ini (deployed via Ansible) # Environment variables removed for better reliability and maintainability # Migration benefits: # - Cache now works correctly (environment variables had a bug in Gitea 1.25) # - All settings are versioned in Git # - Better documentation and maintainability volumes: - gitea-data:/data - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro labels: - "traefik.enable=true" # HTTP Router configuration - "traefik.http.routers.gitea.rule=Host(`git.michaelschiemer.de`)" - "traefik.http.routers.gitea.entrypoints=websecure" - "traefik.http.routers.gitea.tls=true" - "traefik.http.routers.gitea.tls.certresolver=letsencrypt" - "traefik.http.routers.gitea.priority=100" # Service configuration (Docker provider uses port, not url) - "traefik.http.services.gitea.loadbalancer.server.port=3000" # ServersTransport for longer timeouts (prevents 504 for SSE/Long-Polling like /user/events) # Temporarily removed to test if this is causing the service discovery issue # - "traefik.http.services.gitea.loadbalancer.serversTransport=gitea-transport@docker" # - "traefik.http.serverstransports.gitea-transport.forwardingtimeouts.dialtimeout=10s" # - "traefik.http.serverstransports.gitea-transport.forwardingtimeouts.responseheadertimeout=120s" # - "traefik.http.serverstransports.gitea-transport.forwardingtimeouts.idleconntimeout=180s" # - "traefik.http.serverstransports.gitea-transport.maxidleconnsperhost=100" # X-Forwarded-Proto header (helps with redirects/cookies) - "traefik.http.middlewares.gitea-headers.headers.customrequestheaders.X-Forwarded-Proto=https" - "traefik.http.routers.gitea.middlewares=gitea-headers@docker" # Explicitly reference the service (like MinIO does) - "traefik.http.routers.gitea.service=gitea" healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/api/healthz"] interval: 30s timeout: 10s retries: 3 start_period: 30s postgres: image: postgres:16-alpine container_name: gitea-postgres restart: unless-stopped networks: - gitea-internal environment: - TZ=Europe/Berlin - POSTGRES_DB=gitea - POSTGRES_USER=gitea - POSTGRES_PASSWORD=gitea_password command: > postgres -c max_connections=300 -c authentication_timeout=180 -c statement_timeout=30000 -c idle_in_transaction_session_timeout=30000 volumes: - postgres-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-gitea} -d ${POSTGRES_DB:-gitea}"] interval: 30s timeout: 10s retries: 3 start_period: 30s redis: image: redis:7-alpine container_name: gitea-redis restart: unless-stopped networks: - gitea-internal environment: - TZ=Europe/Berlin command: > redis-server --requirepass ${REDIS_PASSWORD:-gitea_redis_password} --appendonly yes --maxmemory 512mb --maxmemory-policy allkeys-lru volumes: - redis-data:/data healthcheck: test: ["CMD", "redis-cli", "--raw", "incr", "ping"] interval: 30s timeout: 10s retries: 3 start_period: 10s volumes: gitea-data: name: gitea-data postgres-data: name: gitea-postgres-data redis-data: name: gitea-redis-data networks: traefik-public: external: true gitea-internal: name: gitea-internal driver: bridge