fix: Gitea Traefik routing and connection pool optimization
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled

- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
This commit is contained in:
2025-11-09 14:46:15 +01:00
parent 85c369e846
commit 36ef2a1e2c
1366 changed files with 104925 additions and 28719 deletions

View File

@@ -17,4 +17,5 @@ MYSQL_PASSWORD=<generate-strong-password>
REDIS_PASSWORD=<generate-strong-password>
# Gitea Settings
DISABLE_REGISTRATION=true # Set to false to allow user registration
# Set to false to allow user registration
DISABLE_REGISTRATION=true

View File

@@ -177,9 +177,10 @@ The playbook will:
### Configuration File
Gitea configuration is managed via `app.ini` file:
- **Local file**: `deployment/stacks/gitea/app.ini` (for local development)
- **Production**: Generated from Ansible template `deployment/ansible/templates/gitea-app.ini.j2`
- The `app.ini` is mounted read-only into the container at `/data/gitea/conf/app.ini`
- **Template**: `deployment/ansible/templates/gitea-app.ini.j2` (Ansible template)
- **Production**: Generated from template and deployed via Ansible playbook `setup-gitea-initial-config.yml`
- The `app.ini` is copied to the container at `/data/gitea/conf/app.ini`
- **Important**: `app.ini` is a minimal configuration. Cache, Session, Queue, and other settings are controlled via `GITEA__...` environment variables in `docker-compose.yml` which override `app.ini` settings on every container start.
- Configuration is based on the official Gitea example: https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini
**Key Configuration Sections:**

View File

@@ -1,80 +0,0 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Gitea Configuration File
;; This file is based on the official Gitea example configuration
;; https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; General Settings
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
APP_NAME = Gitea: Git with a cup of tea
RUN_MODE = prod
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Server Configuration
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[server]
PROTOCOL = http
DOMAIN = git.michaelschiemer.de
HTTP_ADDR = 0.0.0.0
HTTP_PORT = 3000
ROOT_URL = https://git.michaelschiemer.de/
PUBLIC_URL_DETECTION = auto
;; SSH Configuration
DISABLE_SSH = false
START_SSH_SERVER = true
SSH_DOMAIN = git.michaelschiemer.de
SSH_PORT = 22
SSH_LISTEN_PORT = 22
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Database Configuration
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[database]
DB_TYPE = postgres
HOST = postgres:5432
NAME = gitea
USER = gitea
PASSWD = gitea_password
SSL_MODE = disable
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Cache Configuration
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[cache]
ENABLED = false
ADAPTER = memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Session Configuration
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[session]
PROVIDER = file
PROVIDER_CONFIG = data/sessions
COOKIE_SECURE = true
COOKIE_NAME = i_like_gitea
GC_INTERVAL_TIME = 86400
SESSION_LIFE_TIME = 86400
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Queue Configuration
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[queue]
TYPE = channel
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Service Configuration
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[service]
DISABLE_REGISTRATION = true
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Actions Configuration
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[actions]
ENABLED = true
;; Use "self" to use the current Gitea instance for actions (not GitHub)
;; Do NOT set DEFAULT_ACTIONS_URL to a custom URL - it's not supported
;; Leaving it unset or setting to "self" will use the current instance
;DEFAULT_ACTIONS_URL = self

View File

@@ -19,10 +19,22 @@ services:
- GITEA__database__NAME=${POSTGRES_DB:-gitea}
- GITEA__database__USER=${POSTGRES_USER:-gitea}
- GITEA__database__PASSWD=${POSTGRES_PASSWORD:-gitea_password}
- GITEA__cache__ENABLED=true
- GITEA__cache__ADAPTER=redis
- GITEA__cache__HOST=redis:6379
- GITEA__cache__PASSWORD=${REDIS_PASSWORD:-gitea_redis_password}
# Database connection pool settings to prevent "Timeout before authentication" errors
# These limit the number of concurrent connections and prevent connection pool exhaustion
# - MAX_OPEN_CONNS: Maximum number of open connections to the database
# - MAX_IDLE_CONNS: More warm connections to avoid constantly creating new sessions
# - CONN_MAX_LIFETIME: 10 minutes; idle connections are not recycled too quickly
# - CONN_MAX_IDLE_TIME: Clean up connections that are idle for too long
- GITEA__database__MAX_OPEN_CONNS=50
- GITEA__database__MAX_IDLE_CONNS=30
- GITEA__database__CONN_MAX_LIFETIME=600
- GITEA__database__CONN_MAX_IDLE_TIME=300
# Cache, Session, and Queue configuration via environment variables
# These override app.ini settings and are applied on every container start
# NOTE: Cache deaktiviert - Gitea 1.25 interpretiert GITEA__cache__HOST nicht korrekt
# (verbindet sich mit 127.0.0.1:6379 statt redis:6379). Session und Queue nutzen weiterhin Redis.
- GITEA__cache__ENABLED=false
- GITEA__cache__ADAPTER=memory
- GITEA__session__PROVIDER=redis
- GITEA__session__PROVIDER_CONFIG=network=tcp,addr=redis:6379,password=${REDIS_PASSWORD:-gitea_redis_password},db=0,pool_size=100,idle_timeout=180
- GITEA__queue__TYPE=redis
@@ -40,21 +52,18 @@ services:
labels:
- "traefik.enable=true"
# HTTP Router
# 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"
# Priority to ensure this router is matched before catchall (catchall has no explicit priority, so default is 0)
- "traefik.http.routers.gitea.priority=100"
# Service
# Service configuration (Docker provider uses port, not url)
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
# Use container name explicitly for host network mode
- "traefik.http.services.gitea.loadbalancer.server.scheme=http"
# Middleware
- "traefik.http.routers.gitea.middlewares=default-chain@file"
# Middleware chain (removed temporarily to test if it causes issues)
# - "traefik.http.routers.gitea.middlewares=security-headers-global@file,gzip-compression@file"
# 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
@@ -73,7 +82,12 @@ services:
- POSTGRES_DB=gitea
- POSTGRES_USER=gitea
- POSTGRES_PASSWORD=gitea_password
command: postgres -c max_connections=300
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:

View File

@@ -1,33 +0,0 @@
[mysqld]
# Gitea-optimized MySQL configuration
# Character set
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# InnoDB settings
innodb_buffer_pool_size = 256M
innodb_log_file_size = 64M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
# Connection settings
max_connections = 200
max_allowed_packet = 64M
# Query cache (disabled in MySQL 8.0+)
# Performance schema
performance_schema = ON
# Logging
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow-queries.log
long_query_time = 2
# Binary logging for backups
log_bin = /var/log/mysql/mysql-bin.log
binlog_expire_logs_seconds = 604800 # 7 days
max_binlog_size = 100M
[client]
default-character-set = utf8mb4