# autopass — Deploy pe Dokploy LXC 103 ## Descriere Gateway RAR AUTOPASS (Python / FastAPI) care preia prezentări de service-auto și le declară la RAR AUTOPASS (Legea 142/2023). Deployat pe Dokploy / LXC 103 ca serviciu Docker Compose. - **Domeniu:** `autopass.roa.romfast.ro` - **Server:** LXC 103 (10.0.20.167) - **Deployment:** Dokploy → Docker Compose, provider **Custom Git** - **Repo:** `git@gitea.romfast.ro:romfast/rar-autopass.git`, branch **`main`** ### Arhitectură ``` Browser → VM201 IIS (TLS, site roa-apps) → Traefik LXC103 (HTTP :80) → api (uvicorn :8010) ↓ worker + autoheal ↓ SQLite /data/autopass.db ``` Servicii Docker Compose (`docker-compose.yml`, un singur image): - `api` — FastAPI/uvicorn pe `:8010`, expus prin Traefik (entrypoint `web`) - `worker` — procesează coada; partajează volumul `autopass-data` și `AUTOPASS_CREDS_KEY` - `autoheal` — restartează `worker`-ul când probe-ul îl marchează unhealthy (proces agățat) --- ## Deploy în Dokploy UI ### 1. Creare Service 1. https://dokploy.romfast.ro → **Services** → **Create Service** → **Docker Compose** 2. Name: `autopass`, Server: **LXC 103 (local)** ### 2. Provider — Custom Git (NU Gitea nativ) Integrarea nativă **Gitea** dă "Failed to fetch repositories: Unauthorized" (token OAuth expirat în Dokploy). Folosește tab-ul **` Git`**: - Repository URL: `git@gitea.romfast.ro:romfast/rar-autopass.git` - Branch: `main` - Compose Path: `./docker-compose.yml` - SSH: adaugă deploy key-ul afișat de Dokploy în Gitea → repo → Settings → Deploy Keys ### 3. Environment (în Dokploy, NU în .env — e gitignored) | Variabilă | Valoare | |-----------|---------| | `AUTOPASS_CREDS_KEY` | cheie Fernet, **partajată api↔worker** (vezi mai jos) | | `AUTOPASS_REQUIRE_API_KEY` | `true` pentru prod | ```bash # Generare AUTOPASS_CREDS_KEY: python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" ``` Fără cheie, compose pică explicit (`:?seteaza AUTOPASS_CREDS_KEY`). ### 4. Domain **Domains** → service **`api`**, port **`8010`**, domain `autopass.roa.romfast.ro`. TLS-ul public se termină la IIS (VM 201), deci în Dokploy e suficient entrypoint `web`. ### 5. Autodeploy (deploy automat la commit) Toggle **Autodeploy** = ON nu e suficient — trebuie webhook în Gitea (Custom Git nu-l creează automat): 1. Dokploy → General → copiază **Webhook URL** (`https://dokploy.romfast.ro/api/deploy/compose/`) 2. Gitea → repo → Settings → Webhooks → Add Webhook → Gitea: - Target URL: *(URL-ul din Dokploy)*, Method `POST`, Content Type `application/json` - Branch filter: `main`, trigger Push Events, Active - **Test Delivery** → trebuie `200` 3. Doar ce e `git push`-uit pe `main` declanșează deploy. --- ## Rutare (de ce NU trebuie regulă IIS per-app) IIS site `roa-apps` (VM 201) are binding wildcard `*.roa.romfast.ro` (80+443) și o regulă URL Rewrite catch-all care forwardează tot către Traefik: ```xml ... ``` ARR are `preserveHostHeader=True`, deci Host-ul original ajunge la Traefik, care rutează după `Host(...)`. Un app nou sub `*.roa` merge automat — **nu** adaugi nimic în IIS, doar domeniul în Dokploy. --- ## Probleme întâlnite la primul deploy (și fix-urile) ### 1. Gitea Unauthorized în Dokploy **Simptom:** "Failed to fetch repositories: Unauthorized", dropdown Repository gol. **Cauză:** token-ul OAuth al integrării native Gitea în Dokploy e expirat/revocat. **Fix:** folosește provider **Custom Git** (vezi pasul 2). Alternativ: regenerează OAuth app / PAT în Gitea și reconectează în Dokploy → Settings → Git. ### 2. 404 la `https://autopass.roa.romfast.ro/` — api în crash-loop **Simptom:** site-ul răspunde **404** (nu 502). `docker ps` → `api` în `Restarting (1)`, worker + autoheal healthy. **Cauză:** `ModuleNotFoundError: No module named 'itsdangerous'`. `SessionMiddleware` (`app/main.py`) îl cere, dar lipsea din `requirements.txt` — era doar instalat local în dev, **nu** tras tranzitiv în imaginea Docker. Worker-ul nu importă SessionMiddleware, de-aia el era healthy. **Fix:** adăugat `itsdangerous==2.2.0` în `requirements.txt`, push → autodeploy a reconstruit imaginea (commit `412102b`). > 404 vs 502: 404 = niciun backend sănătos / niciun router care să răspundă; 502 = portul > din Traefik ≠ portul containerului. Aici api nu pornea deloc → 404. ### 3. (Nu era o problemă) `/` → 303 După fix, root-ul redirectează `303 → /login` (auth pe sesiune). E comportament normal, nu eroare. --- ## Verificare post-deploy ```bash # Stare containere ssh root@10.0.20.201 "pct exec 103 -- docker ps --format '{{.Names}} -> {{.Status}}' | grep autopass" # Așteptat: api Up (healthy), worker Up (healthy), autoheal Up (healthy) # API direct în Traefik (host header), pe LXC 103 ssh root@10.0.20.201 'pct exec 103 -- sh -lc "curl -s -o /dev/null -w \"%{http_code}\n\" -H \"Host: autopass.roa.romfast.ro\" http://localhost/healthz"' # Așteptat: 200 # Lanț complet de pe VM 201 (loopback, TLS real) # autopass.roa.romfast.ro -> HTTP 303 (redirect /login) = OK # Logs api dacă pică ssh root@10.0.20.201 "pct exec 103 -- docker logs \$(ssh ... ) --tail 40" ``` --- ## Atenție: deploy de TEST, nu producție `docker-compose.yml` are hardcodat: - `AUTOPASS_RAR_ENV: test` - `AUTOPASS_WORKER_SEND_ENABLED: "false"` — worker-ul **NU** trimite efectiv la RAR. Pentru producție (trimiteri reale către RAR, Legea 142/2023) acestea trebuie schimbate explicit — preferabil prin Environment în Dokploy, nu hardcodat în compose. --- ## DNS ``` autopass.roa.romfast.ro A 188.26.14.103 ``` Acoperit de wildcard `*.roa.romfast.ro` (DNS + cert win-ACME pe VM 201).