# LXC 103 - Dokploy + Traefik (Control Plane Public) ## Informații Generale - **CTID:** 103 - **IP:** 10.0.20.167 - **Rol:** Dokploy Control Plane + Traefik routing public - **Host Proxmox:** pvemini (10.0.20.201) - **Status:** Running (onboot: enabled) --- ## Arhitectura LXC 103 este nodul central pentru deployment-ul aplicațiilor publice ROMFAST. ``` Internet → 188.26.14.103 → VM 201 IIS (SSL termination) │ *.roa.romfast.ro, roa-qr, dokploy │ LXC 103 :443 (Traefik) ├── dokploy.romfast.ro → Dokploy UI :3000 ├── roa-qr.romfast.ro → pdf-qr-app container ├── app1.roa.romfast.ro → app1 container └── app2.roa.romfast.ro → app2 container ``` ### De ce app-urile publice stau pe LXC 103 Dokploy instalează Traefik SEPARAT pe fiecare server. Traefik LXC 103 și Traefik LXC 100 nu comunică între ele. Wildcadul `*.roa.romfast.ro` poate fi conectat doar la UN singur Traefik — LXC 103. **LXC 100** se folosește pentru: - Backend-uri consumate intern (fără DNS public) - Job-uri cron, workers, servicii administrative --- ## Servicii Instalate | Serviciu | Port | Descriere | |----------|------|-----------| | Dokploy UI | 3000 | Management deployment, CI/CD | | Traefik | 443 | Routing HTTPS pentru toate app-urile publice | | Traefik Dashboard | 8080 | Monitoring routelor (intern) | --- ## Domenii Gestionate | Domeniu | Destinație | |---------|-----------| | `dokploy.romfast.ro` | Dokploy UI (port 3000) | | `roa-qr.romfast.ro` | pdf-qr-app container | | `*.roa.romfast.ro` | Orice app deployată prin Dokploy | --- ## Setup Inițial ### Pasul 1 — Oprire nginx existent pe LXC 100 > **Executat pe LXC 100** (10.0.20.170) via Portainer terminal sau Proxmox console: ```bash docker stop docker-nginx-1 docker rm docker-nginx-1 # Verifică porturile sunt libere ss -tlnp | grep -E ':80|:443' ``` ### Pasul 2 — Generare SSH Key în Dokploy + Adăugare LXC 100 **În Dokploy UI** (https://dokploy.romfast.ro): 1. Settings → SSH Keys → **Create SSH Key** 2. Copiază public key-ul generat **Pe LXC 100** (10.0.20.170): ```bash echo "ssh-ed25519 AAAA...[cheia copiată din Dokploy]" >> /root/.ssh/authorized_keys chmod 600 /root/.ssh/authorized_keys ``` **În Dokploy UI:** 1. Servers → **Add Server** 2. IP: `10.0.20.170`, User: `root` 3. **Test Connection** → **Setup Server** 4. Verificare: pe LXC 100, `docker ps` → trebuie container Traefik ### Pasul 3 — Deploy pdf-qr-app pe LXC 103 **În Dokploy UI:** 1. Services → **Create Service** → Docker Compose 2. **Server:** LXC 103 (local) 3. Docker Compose: conținutul app-ului pdf-qr (vezi `docs/pdf-qr-app.md`) 4. Domain: `roa-qr.romfast.ro` 5. **Deploy** --- ## Workflow: Adăugare App Nouă ``` 1. Dokploy UI → New Service → docker-compose → domain: numeapp.roa.romfast.ro 2. DNS: adaugă numeapp.roa.romfast.ro A 188.26.14.103 (dacă e sub *.roa.romfast.ro, wildcard DNS acoperă automat) 3. SSL: Win-ACME pe VM 201 generează cert dacă nu există wildcard 4. Gata — Traefik pe LXC 103 routează automat ``` --- ## Verificare ```bash # Traefik funcționează (din LAN) curl -I https://10.0.20.167/ # Dokploy UI accesibil curl -I https://dokploy.romfast.ro/ # pdf-qr-app accesibil curl -I https://roa-qr.romfast.ro/ # Test wildcard (după deploy app cu hostname) curl -I https://app1.roa.romfast.ro/ # LXC 100 Portainer funcționează în continuare curl -sk https://10.0.20.170:9443/api/status ``` --- ## Configurare Traefik (gestionat automat de Dokploy) Traefik pe LXC 103 este configurat și actualizat automat de Dokploy la fiecare deploy. Nu modificați manual configurația Traefik fără să înțelegeți impactul. ```bash # Status containere pe LXC 103 docker ps # Logs Traefik docker logs traefik -f # Verificare routere Traefik curl http://localhost:8080/api/http/routers | jq . ``` --- ## Fix: Docker Swarm VIP DNS (Bug Permanent Rezolvat) ### Problema Docker Swarm folosește implicit **VIP (Virtual IP)** pentru load balancing intern. IPVS (mecanismul kernel care implementează VIP) **nu funcționează în LXC containers**. Când Traefik încearcă să rezolve `http://qr-qrgenerator-vqkwsu:80`, primea VIP-ul serviciului (ex: 10.0.1.8) în loc de IP-ul real al task-ului (ex: 10.0.1.12) → **502 Bad Gateway**. ### Soluția Schimbăm endpoint mode-ul serviciilor Swarm din `vip` → `dnsrr` (DNS Round Robin). Cu `dnsrr`, DNS-ul rezolvă direct la IP-ul real al containerului, bypassing IPVS. ### Implementare: `dokploy-dnsrr-fix` (systemd service) Un listener permanent care prinde orice serviciu Swarm nou creat/actualizat de Dokploy și îl setează automat la `dnsrr`: ```bash # Script: /usr/local/bin/dokploy-dnsrr-fix.sh # Service: /etc/systemd/system/dokploy-dnsrr-fix.service ``` ```bash # Verificare status systemctl status dokploy-dnsrr-fix # Logs (confirmare că fixul s-a aplicat la ultimul deploy) journalctl -u dokploy-dnsrr-fix -n 20 ``` Output normal după un deploy: ``` Setting dnsrr for qr-qrgenerator-vqkwsu (was: vip) OK - qr-qrgenerator-vqkwsu now uses dnsrr ``` ### Timeline la fiecare redeploy ``` 0s Dokploy creează/actualizează serviciul Swarm (vip mode) → Traefik: 502 Bad Gateway 1s Listener prinde evenimentul update 3s docker service update --endpoint-mode dnsrr 13s Service converge, DNS rezolvă corect → Traefik: 200 OK ``` **Downtime la redeploy: ~13 secunde** (inevitabil cu Swarm în LXC). ### Dacă fix-ul nu funcționează (manual recovery) ```bash # 1. Identifică serviciul cu problemă docker service ls --format '{{.Name}} {{.Mode}}' # 2. Setează manual dnsrr docker service update --endpoint-mode dnsrr # 3. Repornește listener dacă e oprit systemctl restart dokploy-dnsrr-fix ``` --- ## Documentație Asociată - **Arhitectură completă IIS:** `../vm201-windows/docs/vm201-dokploy-infrastructure.md` - **Setup IIS VM 201:** `../vm201-windows/scripts/setup-new-iis-sites.ps1` - **Web.config IIS proxy:** `../vm201-windows/iis-configs/` - **LXC 100 (Remote Node):** `../lxc100-portainer/README.md` *(de creat)* --- **Ultima actualizare:** 2026-03-03 **Autor:** Marius Mutu **Proiect:** ROMFASTSQL - LXC 103 Dokploy