fix(console): comprehensive TUI rendering fixes
- 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
This commit is contained in:
242
deployment/ansible/playbooks/setup/infrastructure.yml
Normal file
242
deployment/ansible/playbooks/setup/infrastructure.yml
Normal file
@@ -0,0 +1,242 @@
|
||||
---
|
||||
- name: Deploy Infrastructure Stacks on Production Server
|
||||
hosts: production
|
||||
become: no
|
||||
gather_facts: yes
|
||||
|
||||
vars:
|
||||
# All deployment variables are now defined in group_vars/production.yml
|
||||
# Variables can be overridden via -e flag if needed
|
||||
vault_file: "{{ playbook_dir }}/../secrets/production.vault.yml"
|
||||
|
||||
pre_tasks:
|
||||
- name: Verify vault file exists
|
||||
ansible.builtin.stat:
|
||||
path: "{{ vault_file }}"
|
||||
register: vault_stat
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
|
||||
- name: Load encrypted secrets from vault
|
||||
ansible.builtin.include_vars:
|
||||
file: "{{ vault_file }}"
|
||||
when: vault_stat.stat.exists
|
||||
no_log: yes
|
||||
ignore_errors: yes
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
|
||||
- name: Verify vault secrets were loaded
|
||||
ansible.builtin.debug:
|
||||
msg: |
|
||||
Vault secrets loaded:
|
||||
- vault_db_password: {{ 'SET (length: ' + (vault_db_password | default('') | string | length | string) + ')' if (vault_db_password | default('') | string | trim) != '' else 'NOT SET or EMPTY' }}
|
||||
- vault_redis_password: {{ 'SET' if (vault_redis_password | default('') | string | trim) != '' else 'NOT SET' }}
|
||||
- vault_app_key: {{ 'SET' if (vault_app_key | default('') | string | trim) != '' else 'NOT SET' }}
|
||||
- vault_docker_registry_password: {{ 'SET (length: ' + (vault_docker_registry_password | default('') | string | length | string) + ')' if (vault_docker_registry_password | default('') | string | trim) != '' else 'NOT SET or EMPTY' }}
|
||||
when: vault_stat.stat.exists
|
||||
no_log: yes
|
||||
|
||||
- name: Warn if vault file is missing
|
||||
ansible.builtin.debug:
|
||||
msg: "WARNING: Vault file not found at {{ vault_file }}. Some roles may fail if they require vault secrets."
|
||||
when: not vault_stat.stat.exists
|
||||
|
||||
tasks:
|
||||
- name: Debug - Show variables
|
||||
debug:
|
||||
msg:
|
||||
- "stacks_base_path: {{ stacks_base_path | default('NOT SET') }}"
|
||||
- "deploy_user_home: {{ deploy_user_home | default('NOT SET') }}"
|
||||
when: true # Debugging enabled
|
||||
|
||||
- name: Check if deployment stacks directory exists
|
||||
stat:
|
||||
path: "{{ stacks_base_path }}"
|
||||
register: stacks_dir
|
||||
|
||||
- name: Create deployment stacks directory if it doesn't exist
|
||||
file:
|
||||
path: "{{ stacks_base_path }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
owner: "{{ ansible_user }}"
|
||||
group: "{{ ansible_user }}"
|
||||
when: not stacks_dir.stat.exists
|
||||
|
||||
- name: Ensure rsync is installed (required for synchronize)
|
||||
ansible.builtin.apt:
|
||||
name: rsync
|
||||
state: present
|
||||
update_cache: no
|
||||
become: yes
|
||||
|
||||
- name: Sync infrastructure stacks to server
|
||||
synchronize:
|
||||
src: "{{ playbook_dir }}/../../stacks/"
|
||||
dest: "{{ stacks_base_path }}/"
|
||||
delete: no
|
||||
recursive: yes
|
||||
rsync_opts:
|
||||
- "--chmod=D755,F644"
|
||||
- "--exclude=.git"
|
||||
- "--exclude=*.log"
|
||||
- "--exclude=data/"
|
||||
- "--exclude=volumes/"
|
||||
- "--exclude=acme.json"
|
||||
- "--exclude=*.key"
|
||||
- "--exclude=*.pem"
|
||||
|
||||
- name: Ensure executable permissions on PostgreSQL backup scripts
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
mode: '0755'
|
||||
loop:
|
||||
- "{{ stacks_base_path }}/postgresql-production/scripts/backup-entrypoint.sh"
|
||||
- "{{ stacks_base_path }}/postgresql-production/scripts/backup.sh"
|
||||
- "{{ stacks_base_path }}/postgresql-production/scripts/restore.sh"
|
||||
- "{{ stacks_base_path }}/postgresql-staging/scripts/backup-entrypoint.sh"
|
||||
- "{{ stacks_base_path }}/postgresql-staging/scripts/backup.sh"
|
||||
- "{{ stacks_base_path }}/postgresql-staging/scripts/restore.sh"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Ensure system packages are up to date
|
||||
include_role:
|
||||
name: system
|
||||
when: system_update_packages | bool
|
||||
|
||||
# Create external networks required by all stacks
|
||||
- name: Create traefik-public network
|
||||
community.docker.docker_network:
|
||||
name: traefik-public
|
||||
driver: bridge
|
||||
state: present
|
||||
|
||||
- name: Create app-internal network
|
||||
community.docker.docker_network:
|
||||
name: app-internal
|
||||
driver: bridge
|
||||
state: present
|
||||
|
||||
# 1. Deploy Traefik (Reverse Proxy & SSL)
|
||||
- name: Deploy Traefik stack
|
||||
import_role:
|
||||
name: traefik
|
||||
|
||||
# 2. Deploy PostgreSQL Production (Database)
|
||||
- name: Deploy PostgreSQL Production stack
|
||||
import_role:
|
||||
name: postgresql-production
|
||||
|
||||
# 3. Deploy Redis (Cache & Session Store)
|
||||
- name: Deploy Redis stack
|
||||
import_role:
|
||||
name: redis
|
||||
|
||||
# 4. Deploy Docker Registry (Private Registry)
|
||||
- name: Deploy Docker Registry stack
|
||||
import_role:
|
||||
name: registry
|
||||
|
||||
# 5. Deploy MinIO (Object Storage)
|
||||
- name: Deploy MinIO stack
|
||||
import_role:
|
||||
name: minio
|
||||
|
||||
# 6. Deploy Gitea (CRITICAL - Git Server + MySQL)
|
||||
- name: Deploy Gitea stack
|
||||
import_role:
|
||||
name: gitea
|
||||
|
||||
# 7. Deploy Monitoring (Portainer + Grafana + Prometheus)
|
||||
- name: Deploy Monitoring stack
|
||||
import_role:
|
||||
name: monitoring
|
||||
|
||||
# 8. Deploy Production Stack
|
||||
- name: Deploy Production Stack
|
||||
import_role:
|
||||
name: application
|
||||
vars:
|
||||
application_stack_src: "{{ playbook_dir | default(role_path + '/..') }}/../../stacks/production"
|
||||
application_stack_dest: "{{ app_stack_path | default(stacks_base_path + '/production') }}"
|
||||
application_compose_suffix: "production.yml"
|
||||
application_service_name: "php"
|
||||
application_env_template: "{{ role_path }}/../../templates/application.env.j2"
|
||||
app_env: "production"
|
||||
# Explicitly pass vault variables to the role
|
||||
vault_docker_registry_password: "{{ vault_docker_registry_password | default('') }}"
|
||||
app_domain: "michaelschiemer.de"
|
||||
app_debug: "false"
|
||||
db_name: "{{ db_name_default }}"
|
||||
db_host: "{{ db_host_default }}"
|
||||
|
||||
# Verification
|
||||
- name: List all running containers
|
||||
command: >
|
||||
docker ps --format 'table {{ "{{" }}.Names{{ "}}" }}\t{{ "{{" }}.Status{{ "}}" }}\t{{ "{{" }}.Ports{{ "}}" }}'
|
||||
register: docker_ps_output
|
||||
|
||||
- name: Display running containers
|
||||
debug:
|
||||
msg: "{{ docker_ps_output.stdout_lines }}"
|
||||
|
||||
- name: Verify Gitea accessibility via HTTPS
|
||||
uri:
|
||||
url: "https://{{ gitea_domain }}"
|
||||
method: GET
|
||||
validate_certs: no
|
||||
status_code: 200
|
||||
timeout: 10
|
||||
register: gitea_http_check
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Display Gitea accessibility status
|
||||
debug:
|
||||
msg: "Gitea HTTPS check: {{ 'SUCCESS' if gitea_http_check.status == 200 else 'FAILED - Status: ' + (gitea_http_check.status|string) }}"
|
||||
|
||||
# 8. Deploy Production Stack
|
||||
- name: Deploy Production Stack
|
||||
import_role:
|
||||
name: application
|
||||
|
||||
- name: Display application health status
|
||||
debug:
|
||||
msg: "Application health: {{ application_health_output if application_health_output != '' else 'All services healthy or starting' }}"
|
||||
|
||||
- name: Display migration result
|
||||
debug:
|
||||
msg: |
|
||||
Migration Result:
|
||||
{{ application_migration_stdout if application_migration_stdout != '' else 'Migration may have failed - check logs with: docker compose -f ' + application_stack_dest + '/docker-compose.yml logs app' }}
|
||||
when: application_stack_changed and application_run_migrations
|
||||
|
||||
- name: Display application accessibility status
|
||||
debug:
|
||||
msg: >-
|
||||
Application health check: {{
|
||||
'SUCCESS (HTTP ' + (application_healthcheck_status | string) + ')'
|
||||
if application_healthcheck_status == 200 else
|
||||
'FAILED or not ready yet (HTTP ' + (application_healthcheck_status | string) + ')'
|
||||
}}
|
||||
when: application_stack_changed and application_healthcheck_url | length > 0
|
||||
|
||||
- name: Summary
|
||||
debug:
|
||||
msg:
|
||||
- "=== Infrastructure Deployment Complete ==="
|
||||
- "Traefik: {{ 'Deployed' if traefik_stack_changed is defined and traefik_stack_changed else 'Already running' }}"
|
||||
- "PostgreSQL: {{ 'Deployed' if postgresql_stack_changed is defined and postgresql_stack_changed else 'Already running' }}"
|
||||
- "Redis: {{ 'Deployed' if redis_stack_changed is defined and redis_stack_changed else 'Already running' }}"
|
||||
- "Docker Registry: {{ 'Deployed' if registry_stack_changed is defined and registry_stack_changed else 'Already running' }}"
|
||||
- "MinIO: {{ 'Deployed' if minio_stack_changed is defined and minio_stack_changed else 'Already running' }}"
|
||||
- "Gitea: {{ 'Deployed' if gitea_stack_changed is defined and gitea_stack_changed else 'Already running' }}"
|
||||
- "Monitoring: {{ 'Deployed' if monitoring_stack_changed is defined and monitoring_stack_changed else 'Already running' }}"
|
||||
- "Application: {{ 'Deployed' if application_stack_changed is defined and application_stack_changed else 'Already running' }}"
|
||||
- ""
|
||||
- "Next Steps:"
|
||||
- "1. Access Gitea at: https://{{ gitea_domain }}"
|
||||
- "2. Complete Gitea setup wizard if first-time deployment"
|
||||
- "3. Navigate to Admin > Actions > Runners to get registration token"
|
||||
- "4. Continue with Phase 1 - Gitea Runner Setup"
|
||||
- "5. Access Application at: https://{{ app_domain }}"
|
||||
Reference in New Issue
Block a user