# Deploy — Barg-e Vasat (Soroush CI/CD) CI/CD runs on **Gitea Actions** (`git.soroushasadi.com`) with all packages and base images pulled through the **Nexus mirror** (`mirror.soroushasadi.com`). Pushing to `main` triggers build → deploy. ## Topology | Service | Image | Container | Host port | Notes | |---|---|---|---|---| | Postgres | `postgres:16-alpine` | `hokm-db` | `1510` | named volume `hokm_db_data` | | API (.NET SignalR) | `hokm-server:latest` | `hokm-server` | `1505` → 5005 | EF Core → Postgres | | Web (static Next → nginx) | `hokm-web:latest` | `hokm-web` | `1500` → 80 | `NEXT_PUBLIC_*` baked at build | Ports are in **1500–1600** on purpose, so the deployed stack runs alongside a manual `npm run dev` (:3000) and `dotnet run` (:5005) without colliding. ## Pipeline (`.gitea/workflows/ci-cd.yml`) 1. **CI – API**: restore (Nexus NuGet) → `dotnet build server/Hokm.slnx` → run `Hokm.Sim` (engine rules validation). 2. **CI – Web**: `npm install` (Nexus npm) → `tsc --noEmit` → `next build` (static export). 3. **Deploy** (`self-hosted`, push to `main` only): backup DB → tag rollback image → build images → bring up `db` (wait healthy) → `server` (stop+rm+up, wait healthy) → `web` (stop+rm+up, wait healthy) → prune. Deploy follows the safety rules: pre-deploy `pg_dump` backup to `/opt/hokm-backups`, rollback tag before replace, explicit `stop + rm + up --no-deps` (no `--force-recreate`, no bare `docker compose down`). ## One-time setup 1. **Secret**: fill `deploy/ENV_FILE.example` and paste into the Gitea repo secret `ENV_FILE` at `.../HokmPlay/settings/secrets`. At minimum set `JWT_KEY` (`openssl rand -hex 32`) and `POSTGRES_PASSWORD`. 2. **Runner**: an `act_runner` registered with both labels (`ubuntu-latest:docker://...` for CI, `self-hosted:host` for deploy) — reused from existing Soroush projects. 3. **Push**: `git push origin main` → watch `.../HokmPlay/actions`. ## Reaching the stack - Same machine as the deploy host: open `http://localhost:1500`. - Different machine (browser elsewhere): set `NEXT_PUBLIC_SERVER_URL` and `CORS_ORIGINS` in `ENV_FILE` to the host **LAN IP** (e.g. `http://172.28.144.1:1505` / `http://172.28.144.1:1500`) and push again — the API URL is baked into the web bundle at build time. (localhost can be hijacked by the VPN; prefer the LAN IP.) ## Local test (no Gitea, on your machine) ```bash cd D:\Projects\hokm copy deploy\ENV_FILE.example .env # then edit JWT_KEY / POSTGRES_PASSWORD docker compose build server web docker compose up -d # web → http://localhost:1500 api → http://localhost:1505/ docker compose logs -f server ``` Tear down (keeps the DB volume): ```bash docker compose stop ``` ## Migrations The server auto-applies EF migrations when any exist, else `EnsureCreated()` (current state — no migration classes yet, so the Postgres schema is created on first boot). When you generate them: ```bash cd server/src/Hokm.Server $env:HOKM_DESIGN_CONN="Host=localhost;Port=1510;Database=hokm;Username=hokm;Password=" dotnet ef migrations add Init ``` Then the next deploy runs `Database.Migrate()` automatically. ## Rollback ```bash docker stop hokm-server && docker rm hokm-server docker run -d --name hokm-server --network hokm_default -p 1505:5005 \ --env-file <(grep -E '^(JWT_|Database__|ConnectionStrings__|Cors__|Zarinpal__)' .env) \ hokm-server:rollback ``` (or just revert the commit and push — CI redeploys the previous code.)