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

@@ -0,0 +1,268 @@
---
- name: Create Comprehensive Backups
hosts: production
gather_facts: yes
become: no
vars:
backup_retention_days: "{{ backup_retention_days | default(7) }}"
pre_tasks:
- name: Ensure backup directory exists
file:
path: "{{ backups_path }}"
state: directory
mode: '0755'
become: yes
- name: Create timestamp for backup
set_fact:
backup_timestamp: "{{ ansible_date_time.epoch }}"
backup_date: "{{ ansible_date_time.date }}"
backup_time: "{{ ansible_date_time.time }}"
- name: Create backup directory for this run
file:
path: "{{ backups_path }}/backup_{{ backup_date }}_{{ backup_time }}"
state: directory
mode: '0755'
register: backup_dir
become: yes
- name: Set backup directory path
set_fact:
current_backup_dir: "{{ backup_dir.path }}"
tasks:
- name: Backup PostgreSQL Database
when: backup_postgresql | default(true) | bool
block:
- name: Check if PostgreSQL stack is running
shell: docker compose -f {{ stacks_base_path }}/postgresql/docker-compose.yml ps --format json | jq -r '.[] | select(.Service=="postgres") | .State' | grep -q "running"
register: postgres_running
changed_when: false
failed_when: false
- name: Get PostgreSQL container name
shell: docker compose -f {{ stacks_base_path }}/postgresql/docker-compose.yml ps --format json | jq -r '.[] | select(.Service=="postgres") | .Name'
register: postgres_container
changed_when: false
when: postgres_running.rc == 0
- name: Read PostgreSQL environment variables
shell: |
cd {{ stacks_base_path }}/postgresql
grep -E "^POSTGRES_(DB|USER|PASSWORD)=" .env 2>/dev/null || echo ""
register: postgres_env
changed_when: false
failed_when: false
no_log: true
- name: Extract PostgreSQL credentials
set_fact:
postgres_db: "{{ postgres_env.stdout | regex_search('POSTGRES_DB=([^\\n]+)', '\\1') | first | default('michaelschiemer') }}"
postgres_user: "{{ postgres_env.stdout | regex_search('POSTGRES_USER=([^\\n]+)', '\\1') | first | default('postgres') }}"
postgres_password: "{{ postgres_env.stdout | regex_search('POSTGRES_PASSWORD=([^\\n]+)', '\\1') | first | default('') }}"
when: postgres_running.rc == 0
no_log: true
- name: Create PostgreSQL backup
shell: |
cd {{ stacks_base_path }}/postgresql
PGPASSWORD="{{ postgres_password }}" docker compose exec -T postgres pg_dump \
-U {{ postgres_user }} \
-d {{ postgres_db }} \
--clean \
--if-exists \
--create \
--no-owner \
--no-privileges \
| gzip > {{ current_backup_dir }}/postgresql_${postgres_db}_{{ backup_date }}_{{ backup_time }}.sql.gz
when: postgres_running.rc == 0
no_log: true
- name: Verify PostgreSQL backup
stat:
path: "{{ current_backup_dir }}/postgresql_{{ postgres_db }}_{{ backup_date }}_{{ backup_time }}.sql.gz"
register: postgres_backup_file
when: postgres_running.rc == 0
- name: Display PostgreSQL backup status
debug:
msg: "PostgreSQL backup: {{ 'SUCCESS' if (postgres_running.rc == 0 and postgres_backup_file.stat.exists) else 'SKIPPED (PostgreSQL not running)' }}"
- name: Backup Application Data
when: backup_application_data | default(true) | bool
block:
- name: Check if production stack is running
shell: docker compose -f {{ stacks_base_path }}/production/docker-compose.base.yml -f {{ stacks_base_path }}/production/docker-compose.production.yml ps --format json | jq -r '.[] | select(.Service=="php") | .State' | grep -q "running"
register: app_running
changed_when: false
failed_when: false
- name: Backup application storage directory
archive:
path: "{{ stacks_base_path }}/production/storage"
dest: "{{ current_backup_dir }}/application_storage_{{ backup_date }}_{{ backup_time }}.tar.gz"
format: gz
when: app_running.rc == 0
ignore_errors: yes
- name: Backup application logs
archive:
path: "{{ stacks_base_path }}/production/storage/logs"
dest: "{{ current_backup_dir }}/application_logs_{{ backup_date }}_{{ backup_time }}.tar.gz"
format: gz
when: app_running.rc == 0
ignore_errors: yes
- name: Backup application .env file
copy:
src: "{{ stacks_base_path }}/production/.env"
dest: "{{ current_backup_dir }}/application_env_{{ backup_date }}_{{ backup_time }}.env"
remote_src: yes
when: app_running.rc == 0
ignore_errors: yes
- name: Display application backup status
debug:
msg: "Application data backup: {{ 'SUCCESS' if app_running.rc == 0 else 'SKIPPED (Application not running)' }}"
- name: Backup Gitea Data
when: backup_gitea | default(true) | bool
block:
- name: Check if Gitea stack is running
shell: docker compose -f {{ stacks_base_path }}/gitea/docker-compose.yml ps --format json | jq -r '.[] | select(.Service=="gitea") | .State' | grep -q "running"
register: gitea_running
changed_when: false
failed_when: false
- name: Get Gitea volume name
shell: docker compose -f {{ stacks_base_path }}/gitea/docker-compose.yml config --volumes | head -1
register: gitea_volume
changed_when: false
when: gitea_running.rc == 0
- name: Backup Gitea volume
shell: |
docker run --rm \
-v {{ gitea_volume.stdout }}:/source:ro \
-v {{ current_backup_dir }}:/backup \
alpine tar czf /backup/gitea_data_{{ backup_date }}_{{ backup_time }}.tar.gz -C /source .
when: gitea_running.rc == 0 and gitea_volume.stdout != ""
ignore_errors: yes
- name: Display Gitea backup status
debug:
msg: "Gitea backup: {{ 'SUCCESS' if (gitea_running.rc == 0 and gitea_volume.stdout != '') else 'SKIPPED (Gitea not running)' }}"
- name: Backup Docker Registry Images (Optional)
when: backup_registry | default(false) | bool
block:
- name: Check if registry stack is running
shell: docker compose -f {{ stacks_base_path }}/registry/docker-compose.yml ps --format json | jq -r '.[] | select(.Service=="registry") | .State' | grep -q "running"
register: registry_running
changed_when: false
failed_when: false
- name: List registry images
shell: |
cd {{ stacks_base_path }}/registry
docker compose exec -T registry registry garbage-collect --dry-run /etc/docker/registry/config.yml 2>&1 | grep -E "repository|tag" || echo "No images found"
register: registry_images
changed_when: false
when: registry_running.rc == 0
ignore_errors: yes
- name: Save registry image list
copy:
content: "{{ registry_images.stdout }}"
dest: "{{ current_backup_dir }}/registry_images_{{ backup_date }}_{{ backup_time }}.txt"
when: registry_running.rc == 0 and registry_images.stdout != ""
ignore_errors: yes
- name: Display registry backup status
debug:
msg: "Registry backup: {{ 'SUCCESS' if registry_running.rc == 0 else 'SKIPPED (Registry not running)' }}"
- name: Create backup metadata
copy:
content: |
Backup Date: {{ backup_date }} {{ backup_time }}
Backup Timestamp: {{ backup_timestamp }}
Host: {{ inventory_hostname }}
Components Backed Up:
- PostgreSQL: {{ 'YES' if ((backup_postgresql | default(true) | bool) and (postgres_running.rc | default(1) == 0)) else 'NO' }}
- Application Data: {{ 'YES' if ((backup_application_data | default(true) | bool) and (app_running.rc | default(1) == 0)) else 'NO' }}
- Gitea: {{ 'YES' if ((backup_gitea | default(true) | bool) and (gitea_running.rc | default(1) == 0)) else 'NO' }}
- Registry: {{ 'YES' if ((backup_registry | default(false) | bool) and (registry_running.rc | default(1) == 0)) else 'NO' }}
Backup Location: {{ current_backup_dir }}
dest: "{{ current_backup_dir }}/backup_metadata.txt"
mode: '0644'
- name: Verify backup files
when: verify_backups | default(true) | bool
block:
- name: List all backup files
find:
paths: "{{ current_backup_dir }}"
file_type: file
register: backup_files
- name: Check backup file sizes
stat:
path: "{{ item.path }}"
register: backup_file_stats
loop: "{{ backup_files.files }}"
- name: Display backup summary
debug:
msg: |
Backup Summary:
- Total files: {{ backup_files.files | length }}
- Total size: {{ backup_file_stats.results | map(attribute='stat.size') | sum | int / 1024 / 1024 }} MB
- Location: {{ current_backup_dir }}
- name: Fail if no backup files created
fail:
msg: "No backup files were created in {{ current_backup_dir }}"
when: backup_files.files | length == 0
- name: Cleanup old backups
block:
- name: Find old backup directories
find:
paths: "{{ backups_path }}"
patterns: "backup_*"
file_type: directory
register: backup_dirs
- name: Calculate cutoff date
set_fact:
cutoff_timestamp: "{{ (ansible_date_time.epoch | int) - (backup_retention_days | int * 86400) }}"
- name: Remove old backup directories
file:
path: "{{ item.path }}"
state: absent
loop: "{{ backup_dirs.files }}"
when: item.mtime | int < cutoff_timestamp | int
become: yes
- name: Display cleanup summary
debug:
msg: "Cleaned up backups older than {{ backup_retention_days }} days"
post_tasks:
- name: Display final backup status
debug:
msg: |
==========================================
Backup completed successfully!
==========================================
Backup location: {{ current_backup_dir }}
Retention: {{ backup_retention_days }} days
==========================================