- Fix Enter key detection: handle multiple Enter key formats (\n, \r, \r\n)
- Reduce flickering: lower render frequency from 60 FPS to 30 FPS
- Fix menu bar visibility: re-render menu bar after content to prevent overwriting
- Fix content positioning: explicit line positioning for categories and commands
- Fix line shifting: clear lines before writing, control newlines manually
- Limit visible items: prevent overflow with maxVisibleCategories/Commands
- Improve CPU usage: increase sleep interval when no events processed
This fixes:
- Enter key not working for selection
- Strong flickering of the application
- Menu bar not visible or being overwritten
- Top half of selection list not displayed
- Lines being shifted/misaligned
- 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
- Use repository artifacts in test and build jobs (reduces 2-3 git clones per run)
- Add comprehensive workflow performance monitoring system
- Add monitoring playbook and Gitea workflow for automated metrics collection
- Add monitoring documentation and scripts
Optimizations:
- Repository artifact caching: changes job uploads repo, test/build jobs download it
- Reduces Gitea load by eliminating redundant git operations
- Faster job starts (artifact download is typically faster than git clone)
Monitoring:
- Script for local workflow metrics collection via Gitea API
- Ansible playbook for server-side system and Gitea metrics
- Automated Gitea workflow that runs every 6 hours
- Tracks workflow durations, system load, Gitea API response times, and more
- Replace http://localhost:8080/api/http/services with traefik show providers docker
- Replace http://localhost:8080/api/http/routers with traefik show providers docker
- Update debug messages to reference CLI command instead of HTTP API
- Fixes false 'NOT_FOUND' errors since api.insecure: false is set in traefik.yml
The Traefik CLI (traefik show providers docker) works without credentials
and is the recommended method for Traefik v3. It shows all Docker providers
including services, routers, and middlewares, so Gitea will be visible if
registered correctly.
- Fix YAML parsing error by quoting task name with colon
- Add PostgreSQL Staging Stack check and auto-start for staging deployments
- Ensures postgres-staging-internal network is created by the stack itself
- Network creation remains as fallback if stack doesn't create them
- Improves deployment reliability by ensuring dependencies are available
This addresses the root cause: PostgreSQL Staging Stack should be running
before the application stack tries to use its network.
- Extract external networks from docker-compose.base.yml and compose override files
- Extract network names from 'name:' fields when external: true
- Create all required external networks before docker compose up
- Fixes error: 'network postgres-staging-internal declared as external, but could not be found'
This ensures all external networks (traefik-public, app-internal, postgres-staging-internal, etc.)
are created before attempting to start containers.
- fix-gitea-timeouts.yml: Add when conditions to wait_for and uri tasks
- Wait for Traefik only if traefik_restart.changed
- Wait for Gitea via Traefik only if traefik_restart or gitea_restart changed
- fix-gitea-complete.yml: Same fixes as fix-gitea-timeouts.yml
- Wait for Traefik only if traefik_restart.changed
- Wait for Gitea and service discovery checks only if restart occurred
- fix-gitea-traefik-connection.yml: Fix wait and test tasks
- Register traefik_restart to track if restart happened
- Wait for Traefik only if traefik_restart.changed
- Test Gitea via Traefik only if traefik_restart.changed
- Update message to reflect actual restart status
- update-gitea-traefik-service.yml: Fix pause block
- Register traefik_restart to track if restart happened
- Wait for Traefik only if traefik_restart.changed
This prevents unnecessary blocking when traefik_auto_restart=false and
ensures wait/healthcheck tasks only run when a restart actually occurred.
- Replace docker_image module with shell command for more reliable pulling
- Add detailed error output from pull command (stdout/stderr)
- Show actual docker pull error messages when pull fails
- Simplify pull logic - always attempt pull regardless of local existence
- Check if image exists before pull to determine if force pull is needed
- Use docker images command to verify image exists locally (more reliable)
- Fix registries_to_login Jinja2 template to ensure it's always a list
- Add better error messages when image pull fails
- Only tag image if it was successfully verified to exist
- Add debug output for image pull process
- Improve error handling: verify image exists after pull before tagging
- Fix registries_to_login Jinja2 template to handle undefined variables
- Add explicit failure if image pull fails
- Only tag image if it was successfully pulled
- Change docker-compose.staging.yml: git.michaelschiemer.de:5000 -> localhost:5000
- Update deploy-image.yml playbook to:
- Pull images from registry.michaelschiemer.de (source registry)
- Tag and push to localhost:5000 (local registry) for local containers
- Remove hardcoded git.michaelschiemer.de:5000 logic
- Use local_registry from compose files for deployment
This ensures:
- Workflow pushes to registry.michaelschiemer.de (external, HTTPS)
- Containers use localhost:5000 (local, faster, no HTTPS overhead)
- Consistent registry usage across staging and production
The playbook was using docker_registry (registry.michaelschiemer.de) but
docker-compose.staging.yml uses git.michaelschiemer.de:5000. Now the playbook:
- Extracts the actual registry URL from docker-compose files
- Uses that registry for deploy_image
- Updates docker-compose file with the correct registry
This ensures the image is pulled from and deployed to the correct registry.
The previous regex matched 'redis:7-alpine' because it saw ':7' as a port.
New regex requires:
- TLD with optional port (e.g. git.michaelschiemer.de:5000)
- Hostname with numeric port only (e.g. localhost:5000)
- localhost with optional port
This excludes image names like 'redis:7-alpine' or 'minio/minio:latest'.
Ansible doesn't allow .append() on lists in Jinja2 templates.
Changed to use select() filter with regex match instead of loop with append.
This is the same filtering logic but using immutable operations.
The previous regex was removing port numbers from registry URLs.
Now using sed to only remove the image name part after the slash,
preserving the full registry URL including port (e.g. git.michaelschiemer.de:5000)
Registry Login Fixes:
- Filter out service names (minio, redis) from registry URL extraction
- Only recognize actual registry URLs (with TLD or port)
- Preserve port numbers in registry URLs (e.g. git.michaelschiemer.de:5000)
- Better error messages for failed logins
Traefik Restart Loop Prevention:
- Set traefik_auto_restart default to false in traefik role
- Add traefik_auto_restart, traefik_ssl_restart, gitea_auto_restart to staging vars
- Add guard to fix-gitea-traefik-connection.yml restart task
- Add guard and deprecation warning to update-gitea-traefik-service.yml
This ensures that:
- CI/CD pipelines won't cause Traefik restart loops
- Staging environment uses same safe defaults as production
- Deprecated playbooks fail by default unless explicitly enabled
- Only actual Docker registries are used for login, not service names
- Extract actual registry URLs from docker-compose files
- Login to all registries found in compose files (e.g. git.michaelschiemer.de:5000)
- This fixes the 'no basic auth credentials' error when pulling images
- The playbook now automatically detects which registry is used in compose files
- Falls back to docker_registry variable if no registry found in compose files
- Add traefik_auto_restart check to fix-gitea-timeouts.yml
- Add traefik_auto_restart check to fix-gitea-ssl-routing.yml
- Add traefik_auto_restart check to fix-gitea-complete.yml
- Set traefik_auto_restart=false in all Gitea workflow Ansible calls
- Set gitea_auto_restart=false in all Gitea workflow Ansible calls
- Add redeploy-traefik-gitea.yml playbook for clean redeployment
This prevents CI/CD pipelines from causing Traefik restart loops by
ensuring all remediation playbooks respect the traefik_auto_restart
flag, which is set to false in group_vars/production/vars.yml.
- Set traefik_auto_restart: false in group_vars to prevent automatic restarts after config deployment
- Set traefik_ssl_restart: false to prevent automatic restarts during SSL certificate setup
- Set gitea_auto_restart: false to prevent automatic restarts when healthcheck fails
- Modify traefik/tasks/ssl.yml to only restart if explicitly requested or acme.json was created
- Modify traefik/tasks/config.yml to respect traefik_auto_restart flag
- Modify gitea/tasks/restart.yml to respect gitea_auto_restart flag
- Add verify-traefik-fix.yml playbook to monitor Traefik stability
This fixes the issue where Traefik was restarting every minute due to
automatic restart mechanisms triggered by config deployments and health checks.
The restart loops caused 504 Gateway Timeouts for Gitea and other services.
Fixes: Traefik restart loop causing service unavailability
- Add deploy-traefik-config.yml to copy updated config files to server
- Deploys docker-compose.yml and traefik.yml
- Shows deployment status and next steps
- Required before restarting Traefik with new configuration
- Change health check to use docker exec traefik healthcheck
- HTTP ping endpoint requires BasicAuth (401), internal check is more reliable
- Improves health check accuracy in restart-traefik.yml playbook
- Add restart-traefik.yml playbook to restart Traefik container
- Verify Traefik health after restart
- Check for ACME challenge errors in logs
- Display status summary with next steps
- Useful after Traefik configuration changes
- Add retry logic (5 retries, 10s delay) to git clone and update tasks
- Handle 504 Gateway Timeout errors from Gitea gracefully
- Fail with clear error message if all retries are exhausted
- Prevents workflow failures due to temporary Gitea unavailability
- Add FIX_RUNNER_CONFIG.md with manual steps to re-register runner
- Add fix-gitea-runner-config.yml to diagnose runner issues
- Add register-gitea-runner.yml to re-register runner via Ansible
- Fixes issue where runner falls back to GitHub on 504 errors
- Add fix-gitea-runner-config.yml to diagnose runner configuration issues
- Add register-gitea-runner.yml to re-register runner with correct Gitea URL
- Check for GitHub URLs in runner configuration (should only use git.michaelschiemer.de)
- Verify .env file has correct GITEA_INSTANCE_URL
- Fixes 504 timeouts caused by runner trying to connect to GitHub fallback
- Check Gitea container status
- Check Gitea health endpoint
- Display container logs
- Restart container if unhealthy or not running
- Wait for Gitea to be ready after restart
- Display comprehensive status summary
- Helps diagnose and fix 504 Gateway Timeout issues
- Change Docker daemon wait from TCP port 2375 to Unix socket /var/run/docker.sock
- Add Docker registry login task before docker compose up
- Ensures authentication is available when pulling images
- Fixes 'no basic auth credentials' error during image pull
- Replace append() with list concatenation (+ operator)
- Use combine filter instead of update() method
- Avoids 'unsafe append' error with AnsibleLazyTemplateList
- All operations are now immutable and safe
- Replace Python heredoc in shell script with native Ansible modules
- Use slurp to read existing daemon.json
- Use set_fact and copy modules to update configuration
- Fixes YAML parsing error with heredoc syntax
- More idempotent and Ansible-native approach
- Add Docker daemon configuration to use HTTP for git.michaelschiemer.de:5000 registry
- Configure insecure-registries in /etc/docker/daemon.json
- Add GIT_BRANCH environment variable (staging for staging, main for production)
- Set default GIT_REPOSITORY_URL if not provided
- Fixes 'http: server gave HTTP response to HTTPS client' error
- Fixes missing GIT_BRANCH variable warnings
- Change registry_accessible to string comparison ('true'/'false') instead of bool
- Fix 'argument of type bool is not iterable' error in when conditions
- Set correct owner/group for .env file (ansible_user instead of root)
- Fixes 'permission denied' error when docker compose reads .env file
- Fix 'argument of type bool is not iterable' error in image pull task
- Check if .env file exists before docker compose up
- Create minimal .env file if it doesn't exist with required variables
- Load secrets from vault file if available
- Set database and MinIO variables from vault or defaults
- Pass environment variables to docker compose command
- Fixes missing MINIO_ROOT_USER, DB_USERNAME, DB_PASSWORD, SECRETS_DIR errors
- Add registry_accessible flag to safely check registry status
- Fix 'argument of type bool is not iterable' error in when conditions
- Only pull image if registry is accessible
- Add ignore_errors to image pull task to prevent failures
- Improves handling of registry connectivity issues
- Fix recursive loop in app_name variable
- Set app_name and deploy_image using set_fact tasks
- Replace application_stack_dest with application_code_dest (consistent with other playbooks)
- Change registry URL from HTTP to HTTPS
- Add validate_certs: no for registry accessibility check
- Fixes 'Recursive loop detected' error in image deployment
- Remove container start logic - containers should be started by deploy-image.yml
- Add clear error message if container is not running
- Provides helpful instructions for manual container start if needed
- Check if container is running before executing composer
- Start container if not running
- Display detailed error output for debugging
- Fixes composer install failures when container is not running
- Change from stacks path to application code directory (/home/deploy/michaelschiemer/current)
- docker-compose files are in the application root, not in deployment/stacks
- Fixes 'no such file or directory' error for docker-compose.base.yml
- Change stacks_base_path_default from /home/deploy to /home/deploy/deployment/stacks
- Matches actual server directory structure where stacks are located
- Check if destination directory exists separately from git repo check
- Remove directory if it exists but is not a git repository
- Prevents 'destination path already exists' error during clone
- ansible.builtin.git no longer supports owner and group parameters
- Set ownership in separate file task after git operations
- Fixes 'Unsupported parameters' error
- Use git_repo_url instead of git_repository_url in tasks
- Set git_repo_url based on whether git_repository_url is provided
- This completely avoids the recursive loop issue