Files
Claude Agent bcc2592f23 docs(lxc103): staging autopass-test.roa.romfast.ro
Flux de lucru pentru mediu staging autopass: un branch = un environment
(main->prod, staging->test), serviciu Dokploy separat autopass-test, domeniu
via wildcard *.roa (fara IIS/cert nou), env care opreste trimiterile reale la
RAR. Link incrucisat din autopass.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 16:44:25 +00:00

189 lines
8.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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)
- **Staging:** branch `staging``autopass-test.roa.romfast.ro` — vezi [autopass-staging.md](autopass-staging.md)
- **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/<token>`)
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
<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
```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.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 `:443` hostHeader `autopass.romfast.ro`, SNI (SslFlags 1)
- `C:\inetpub\autopass\web.config` = catch-all rewrite → `http://10.0.20.167/{R:1}`
(Traefik LXC 103) cu `X-Forwarded-Proto/Host` + `X-Real-IP`
**Cert SSL — win-acme HTTP-01, auto-renew** (la fel ca site-urile 15):
```powershell
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. Install `iis` (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**.