# Veza V5 Ultra - Ansible Deployment This directory contains Ansible playbooks and configuration for deploying Veza V5 Ultra using Incus/OVN + HAProxy-in-container + Let's Encrypt. ## Architecture - **Single Debian host** (192.168.0.12) with Incus containers - **HAProxy** running inside an Incus container as edge proxy - **Let's Encrypt** ACME HTTP-01 validation handled in HAProxy container - **OVN networking** for container communication - **Applications** in separate containers: - `veza-backend` (Go API on port 8080) - `veza-chat` (Rust WebSocket on port 8081) - `veza-stream` (Rust HLS on port 8082) - `veza-web` (React + nginx on port 80) ## Prerequisites ### Control Node (Your Machine) - Ansible ≥ 2.16 - SSH access to target host with key-based authentication - Required collections: ```bash ansible-galaxy collection install community.general ansible-galaxy collection install community.docker ``` ### Target Host (192.168.0.12) - Debian 12 (Bookworm) - SSH access for user `senke` - Open ports: 22, 80, 443, 8080, 8081, 8082 - Sufficient resources for containers ## Quick Start ### 1. Full Deployment ```bash cd ansible ./deploy-veza.sh ``` ### 2. Custom Domain and Email ```bash ./deploy-veza.sh -d myapp.example.com -e admin@example.com ``` ### 3. Step-by-Step Deployment ```bash # Bootstrap host ./deploy-veza.sh --bootstrap-only # Setup infrastructure ./deploy-veza.sh --infra-only # Deploy applications ./deploy-veza.sh --apps-only # Run tests ./deploy-veza.sh --test-only ``` ## Manual Playbook Execution ```bash # 1. Bootstrap remote host ansible-playbook -i inventory/prod/hosts.yml playbooks/00-bootstrap-remote.yml # 2. Install Incus + OVN ansible-playbook -i inventory/prod/hosts.yml playbooks/10-incus-ovn.yml # 3. Create containers ansible-playbook -i inventory/prod/hosts.yml playbooks/20-incus-containers.yml # 4. Configure HAProxy + ACME ansible-playbook -i inventory/prod/hosts.yml playbooks/30-haproxy-in-container.yml \ -e domain=veza.talas.fr -e acme_email=ops@talas.fr # 5. Deploy applications ansible-playbook -i inventory/prod/hosts.yml playbooks/40-veza-apps.yml # 6. Run smoke tests ansible-playbook -i inventory/prod/hosts.yml playbooks/50-smoke.yml ``` ## Configuration ### Inventory - `inventory/prod/hosts.yml` - Target host configuration - `group_vars/all.yml` - Global variables (domain, ports, etc.) ### Key Variables - `domain`: Target domain (default: veza.talas.fr) - `acme_email`: Email for Let's Encrypt (default: ops@talas.fr) - `veza_*_port`: Application ports - `veza_database_url`: PostgreSQL connection string - `veza_redis_url`: Redis connection string ## Post-Deployment ### 1. DNS Configuration Point your domain's A record to the target host IP: ``` veza.talas.fr. IN A 192.168.0.12 ``` ### 2. Get Let's Encrypt Certificate After DNS is configured, re-run the HAProxy playbook: ```bash ansible-playbook -i inventory/prod/hosts.yml playbooks/30-haproxy-in-container.yml \ -e domain=veza.talas.fr -e acme_email=ops@talas.fr ``` ### 3. Verify Deployment ```bash # Check container status incus list # Check services incus exec veza-haproxy -- systemctl status haproxy incus exec veza-backend -- systemctl status veza-backend incus exec veza-chat -- systemctl status veza-chat incus exec veza-stream -- systemctl status veza-stream incus exec veza-web -- systemctl status nginx # Test endpoints curl -k https://192.168.0.12/ curl -k https://192.168.0.12/api/health ``` ## Troubleshooting ### Container Issues ```bash # Check container logs incus exec -- journalctl -u -f # Restart container incus restart # Access container shell incus exec -- bash ``` ### HAProxy Issues ```bash # Check HAProxy config incus exec veza-haproxy -- haproxy -c -f /etc/haproxy/haproxy.cfg # Check HAProxy logs incus exec veza-haproxy -- journalctl -u haproxy -f # Reload HAProxy incus exec veza-haproxy -- systemctl reload haproxy ``` ### ACME Issues ```bash # Check ACME webroot incus exec veza-haproxy -- ls -la /var/www/acme-challenge/ # Test ACME challenge curl http://192.168.0.12/.well-known/acme-challenge/test # Manual certificate renewal incus exec veza-haproxy -- /opt/dehydrated/dehydrated -c ``` ## File Structure ``` ansible/ ├── deploy-veza.sh # Deployment script ├── inventory/ │ └── prod/ │ └── hosts.yml # Target host inventory ├── group_vars/ │ └── all.yml # Global variables ├── playbooks/ │ ├── 00-bootstrap-remote.yml # Host bootstrap │ ├── 10-incus-ovn.yml # Incus + OVN setup │ ├── 20-incus-containers.yml # Container creation │ ├── 30-haproxy-in-container.yml # HAProxy + ACME │ ├── 40-veza-apps.yml # Application deployment │ └── 50-smoke.yml # Smoke tests └── roles/ # Existing Ansible roles ├── incus/ ├── ovn/ ├── haproxy/ └── ... ``` ## Security Notes - All containers run with `security.nesting=true` - HAProxy enforces HTTPS redirects - Security headers are configured (HSTS, CSP, etc.) - Let's Encrypt certificates are automatically renewed - Firewall rules restrict access to necessary ports only ## Monitoring The deployment includes basic health checks and logging. For production monitoring, consider: - Prometheus + Grafana for metrics - ELK stack for log aggregation - Uptime monitoring for external services - Container resource monitoring ## Support For issues or questions: 1. Check container logs first 2. Verify network connectivity 3. Check HAProxy configuration 4. Review Ansible playbook output for errors