- IIS site dedicat 'autopass' (ID 7) pe VM201 → proxy Traefik LXC103, cert win-acme HTTP-01 selfhosting + install IIS (auto-renew/auto-bind) - monitor-ssl-certificates.sh: +autopass.romfast.ro (ID 7), -roa-qr (decom) - doc autopass.md: setup domeniu public + pasul Dokploy (Add Domain + redeploy) roa-qr.romfast.ro decomisionat (migrat la qr.roa.romfast.ro, acoperit de wildcard): site IIS + dir + cert + renewal win-acme eliminate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
7.9 KiB
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.
- Domenii:
autopass.romfast.ro(public, site IIS dedicat) +autopass.roa.romfast.ro(prin wildcard) - Server: LXC 103 (10.0.20.167)
- Deployment: Dokploy → Docker Compose, provider Custom Git
- Repo:
git@gitea.romfast.ro:romfast/rar-autopass.git, branchmain
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 (entrypointweb)worker— procesează coada; partajează volumulautopass-datașiAUTOPASS_CREDS_KEYautoheal— restarteazăworker-ul când probe-ul îl marchează unhealthy (proces agățat)
Deploy în Dokploy UI
1. Creare Service
- https://dokploy.romfast.ro → Services → Create Service → Docker Compose
- 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 |
# 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):
- Dokploy → General → copiază Webhook URL (
https://dokploy.romfast.ro/api/deploy/compose/<token>) - Gitea → repo → Settings → Webhooks → Add Webhook → Gitea:
- Target URL: (URL-ul din Dokploy), Method
POST, Content Typeapplication/json - Branch filter:
main, trigger Push Events, Active - Test Delivery → trebuie
200
- Target URL: (URL-ul din Dokploy), Method
- Doar ce e
git push-uit pemaindeclanș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:
<rule name="Proxy to LXC 103 Traefik" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://10.0.20.167/{R:1}" />
...
</rule>
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
# 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: testAUTOPASS_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.romfast.ro A 188.26.14.103
autopass.roa.romfast.ro A 188.26.14.103
autopass.roa… e acoperit de wildcard *.roa.romfast.ro. autopass.romfast.ro e
single-name → are site IIS + cert propriu (vezi mai jos).
Domeniu public autopass.romfast.ro (site IIS dedicat)
Spre deosebire de *.roa, domeniul public single-name are nevoie de site IIS propriu
pe VM 201 (model identic cu roa-qr — pattern din setup-new-iis-sites.ps1).
IIS (VM 201, 10.0.20.122) — Site ID 7, nume autopass:
- HTTP
:80+ HTTPS:443hostHeaderautopass.romfast.ro, SNI (SslFlags 1) C:\inetpub\autopass\web.config= catch-all rewrite →http://10.0.20.167/{R:1}(Traefik LXC 103) cuX-Forwarded-Proto/Host+X-Real-IP
Cert SSL — win-acme HTTP-01, auto-renew (la fel ca site-urile 1–5):
C:\Tools\win-acme\wacs.exe --source iis --siteid 7 --host autopass.romfast.ro `
--validationmode http-01 --validation selfhosting --installation iis `
--store certificatestore --accepttos --emailaddress admin@romfast.ro
- Validation
selfhosting(c7d5e050) — ascultă pe http.sys, nu e blocat de catch-all-ul din web.config. Installiis(ea6a5be3) → re-leagă automat binding-ul SNI la renew. - Renewal:
[IIS] autopass, autopass.romfast.ro, Scheduled Task "win-acme renew", next ~2026-08-23. - Monitorizat în
monitor-ssl-certificates.sh(Site ID 7) ca safety-net.
Pas necesar în Dokploy (Traefik rutează după Host → trebuie domeniul adăugat explicit):
Dokploy → service
autopass→ Domains → Add Domain
- Host:
autopass.romfast.ro, Service:api, Container Port:8010, Path:/- HTTPS: OFF (entrypoint
web) — TLS-ul public se termină la IIS; Certificate: None Save → Traefik hot-reload. Înainte de pas:https://autopass.romfast.ro/→ 404 (Traefik n-are router pe acest Host). După pas: 200.