veza/ansible/README.md
2025-12-03 22:56:50 +01:00

215 lines
5.6 KiB
Markdown

# 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 <container-name> -- journalctl -u <service-name> -f
# Restart container
incus restart <container-name>
# Access container shell
incus exec <container-name> -- 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