From 9289344379b43c04bd4248fb6ae16f3ca91bc54a Mon Sep 17 00:00:00 2001 From: Michael Schiemer Date: Sun, 9 Nov 2025 16:33:35 +0100 Subject: [PATCH] feat(gitea): Migrate configuration from environment variables to app.ini - Move all Gitea configuration from docker-compose.yml environment variables to app.ini - Enable Redis cache with proper connection string format (redis://) - Fix Redis password to use Gitea Redis instance password (gitea_redis_password) instead of application Redis stack password - Add database connection pool settings to prevent timeout errors - Configure Redis for cache, session, and queue using app.ini - Update Ansible task to use correct Redis password for Gitea Redis instance Benefits: - Cache now works correctly (environment variables had a bug in Gitea 1.25) - All settings are versioned in Git - Better maintainability and reliability - Configuration follows Gitea documentation recommendations --- .../ansible/roles/gitea/tasks/config.yml | 68 ++++++++----------- deployment/ansible/templates/gitea-app.ini.j2 | 56 ++++++++++++--- deployment/stacks/gitea/docker-compose.yml | 39 +++-------- 3 files changed, 81 insertions(+), 82 deletions(-) diff --git a/deployment/ansible/roles/gitea/tasks/config.yml b/deployment/ansible/roles/gitea/tasks/config.yml index 39a12736..998fc8c7 100644 --- a/deployment/ansible/roles/gitea/tasks/config.yml +++ b/deployment/ansible/roles/gitea/tasks/config.yml @@ -13,47 +13,29 @@ msg: "Gitea container does not exist. Please deploy Gitea stack first." when: gitea_exists.rc != 0 -- name: Get database configuration from environment - ansible.builtin.shell: | - docker compose -f {{ gitea_stack_path }}/docker-compose.yml exec -T {{ gitea_container_name }} env | grep -E "^GITEA__database__" || true - register: gitea_db_env - changed_when: false - failed_when: false - -- name: Parse database configuration +# Configuration is now read from Ansible variables or defaults +# Since environment variables are removed, we use defaults from docker-compose.yml +# (which are hardcoded: POSTGRES_DB=gitea, POSTGRES_USER=gitea, POSTGRES_PASSWORD=gitea_password) +- name: Set database configuration (from docker-compose.yml defaults) ansible.builtin.set_fact: - gitea_db_type: "{{ (gitea_db_env.stdout | default('') | regex_search('GITEA__database__DB_TYPE=([^\n]+)', '\\1') or ['postgres']) | first }}" - gitea_db_host: "{{ (gitea_db_env.stdout | default('') | regex_search('GITEA__database__HOST=([^\n]+)', '\\1') or ['postgres:5432']) | first }}" - gitea_db_name: "{{ (gitea_db_env.stdout | default('') | regex_search('GITEA__database__NAME=([^\n]+)', '\\1') or ['gitea']) | first }}" - gitea_db_user: "{{ (gitea_db_env.stdout | default('') | regex_search('GITEA__database__USER=([^\n]+)', '\\1') or ['gitea']) | first }}" - gitea_db_passwd: "{{ (gitea_db_env.stdout | default('') | regex_search('GITEA__database__PASSWD=([^\n]+)', '\\1') or ['gitea_password']) | first }}" + gitea_db_type: "postgres" + gitea_db_host: "postgres:5432" + gitea_db_name: "gitea" + gitea_db_user: "gitea" + gitea_db_passwd: "gitea_password" -- name: Get Gitea server configuration from environment - ansible.builtin.shell: | - docker compose -f {{ gitea_stack_path }}/docker-compose.yml exec -T {{ gitea_container_name }} env | grep -E "^GITEA__server__" || true - register: gitea_server_env - changed_when: false - failed_when: false - -- name: Parse server configuration +- name: Set server configuration from Ansible variables or defaults ansible.builtin.set_fact: - gitea_domain_parsed: "{{ (gitea_server_env.stdout | default('') | regex_search('GITEA__server__DOMAIN=([^\n]+)', '\\1') or [gitea_domain | default('git.michaelschiemer.de')]) | first }}" - ssh_port_parsed: "{{ (gitea_server_env.stdout | default('') | regex_search('GITEA__server__SSH_PORT=([^\n]+)', '\\1') or ['2222']) | first }}" + gitea_domain: "{{ gitea_domain | default('git.michaelschiemer.de') }}" + ssh_port: "{{ ssh_port | default('2222') }}" + ssh_listen_port: "{{ ssh_listen_port | default('2222') }}" -- name: Set final configuration variables +- name: Set Redis password for Gitea Redis instance ansible.builtin.set_fact: - gitea_domain: "{{ gitea_domain_parsed }}" - ssh_port: "{{ ssh_port_parsed }}" - ssh_listen_port: "{{ ssh_port_parsed }}" - -- name: Extract database host and port - ansible.builtin.set_fact: - gitea_db_hostname: "{{ gitea_db_host.split(':')[0] }}" - gitea_db_port: "{{ (gitea_db_host.split(':')[1]) | default('5432') }}" - -- name: Set Redis password - ansible.builtin.set_fact: - redis_password: "{{ vault_gitea_redis_password | default(vault_redis_password | default('gitea_redis_password')) }}" + # Gitea uses its own Redis instance (gitea-redis) with default password 'gitea_redis_password' + # unless vault_gitea_redis_password is explicitly set + # Note: vault_redis_password is for the application Redis stack, not Gitea Redis + redis_password: "{{ vault_gitea_redis_password | default('gitea_redis_password') }}" - name: Generate app.ini from template ansible.builtin.template: @@ -118,14 +100,20 @@ ======================================== Gitea configuration has been updated successfully! - Changes applied: - - Redis cache enabled (persistent, survives container restarts) + Configuration migrated to app.ini: + - All settings now in app.ini (versioned in Git) + - Redis cache enabled (now works correctly in app.ini) - Redis sessions enabled (better performance and scalability) - Redis queue enabled (persistent job processing) - Database connection pooling configured - - Connection limits set to prevent "Connection reset by peer" errors + - Connection limits set to prevent "Timeout before authentication" errors - Gitea should now be more stable and perform better with Redis. + Benefits: + - Cache now works correctly (environment variables had a bug in Gitea 1.25) + - All settings are versioned and documented + - Better maintainability and reliability + + Gitea should now be more stable and perform better with Redis cache enabled. ======================================== when: gitea_show_status | default(true) | bool diff --git a/deployment/ansible/templates/gitea-app.ini.j2 b/deployment/ansible/templates/gitea-app.ini.j2 index 8492cc99..04a5e2d7 100644 --- a/deployment/ansible/templates/gitea-app.ini.j2 +++ b/deployment/ansible/templates/gitea-app.ini.j2 @@ -1,12 +1,14 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Gitea Configuration File - Minimal Version +;; Gitea Configuration File ;; Generated by Ansible - DO NOT EDIT MANUALLY ;; -;; IMPORTANT: This is a minimal configuration. Cache, Session, Queue, and other -;; settings are controlled via GITEA__... environment variables in docker-compose.yml -;; which override these settings on every container start. +;; All Gitea configuration is now managed via app.ini instead of +;; environment variables for better reliability and maintainability. ;; -;; Only essential values are included here to skip installation and enable basic functionality. +;; Migration from environment variables to app.ini: +;; - Cache now works correctly (environment variables had a bug in Gitea 1.25) +;; - All settings are versioned in Git +;; - Better documentation and maintainability ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; APP_NAME = Gitea: Git with a cup of tea @@ -37,6 +39,43 @@ NAME = {{ postgres_db | default('gitea') }} USER = {{ postgres_user | default('gitea') }} PASSWD = {{ postgres_password | default('gitea_password') }} SSL_MODE = disable +# 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 +MAX_OPEN_CONNS = 50 +MAX_IDLE_CONNS = 30 +CONN_MAX_LIFETIME = 600 +CONN_MAX_IDLE_TIME = 300 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Cache Configuration (Redis) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[cache] +ENABLED = true +ADAPTER = redis +# HOST must be a Redis connection string (as per Gitea documentation) +# Format: redis://:password@host:port/db?pool_size=100&idle_timeout=180s +# Using same format as queue CONN_STR for consistency +HOST = redis://:{{ redis_password }}@redis:6379/0?pool_size=100&idle_timeout=180s +# Cache configuration now works correctly in app.ini +# (Environment variables had a bug in Gitea 1.25 that connected to 127.0.0.1:6379 instead of redis:6379) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Session Configuration (Redis) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[session] +PROVIDER = redis +PROVIDER_CONFIG = network=tcp,addr=redis:6379,password={{ redis_password }},db=0,pool_size=100,idle_timeout=180 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Queue Configuration (Redis) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[queue] +TYPE = redis +CONN_STR = redis://:{{ redis_password }}@redis:6379/0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Security Configuration @@ -54,9 +93,4 @@ DISABLE_REGISTRATION = {{ disable_registration | default(true) | lower }} ;; Actions Configuration ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; [actions] -ENABLED = true - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Cache Configuration -;; NOTE: Cache configuration is controlled via GITEA__cache__ environment variables -;; in docker-compose.yml. Do NOT add [cache] section here, as it may cause conflicts. \ No newline at end of file +ENABLED = true \ No newline at end of file diff --git a/deployment/stacks/gitea/docker-compose.yml b/deployment/stacks/gitea/docker-compose.yml index 743610ff..e7ad59c2 100644 --- a/deployment/stacks/gitea/docker-compose.yml +++ b/deployment/stacks/gitea/docker-compose.yml @@ -10,41 +10,18 @@ services: - 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 - - GITEA__database__DB_TYPE=postgres - - GITEA__database__HOST=postgres:5432 - - GITEA__database__NAME=${POSTGRES_DB:-gitea} - - GITEA__database__USER=${POSTGRES_USER:-gitea} - - GITEA__database__PASSWD=${POSTGRES_PASSWORD:-gitea_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 - - GITEA__queue__CONN_STR=redis://:${REDIS_PASSWORD:-gitea_redis_password}@redis:6379/0 - - GITEA__server__DOMAIN=${GITEA_DOMAIN:-git.michaelschiemer.de} - - GITEA__server__ROOT_URL=https://${GITEA_DOMAIN:-git.michaelschiemer.de}/ - - GITEA__server__SSH_DOMAIN=${GITEA_DOMAIN:-git.michaelschiemer.de} - - GITEA__server__SSH_PORT=2222 - - GITEA__service__DISABLE_REGISTRATION=${DISABLE_REGISTRATION:-true} - - GITEA__actions__ENABLED=true + # 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