Pipeline (.gitea/workflows/ci-cd.yml), all images/packages via Nexus mirror: - CI api-build: dotnet restore/build server/Hokm.slnx + run Hokm.Sim (rules). - CI web-check: npm install + tsc --noEmit + next build (static export). - deploy (self-hosted): pre-deploy pg_dump backup, rollback image tag, build, bring up db -> server -> web with stop+rm+up --no-deps (no force-recreate, no bare compose down), health-wait each, prune. Local stack (docker-compose.yml), ports in 1500-1600 so it coexists with manual dev on 3000/5005: web :1500 (nginx static) -> server :1505 (.NET) -> db :1510 (postgres, named volume + backups). Dockerfiles: server (.NET, NuGet via nuget.docker.config, binds 0.0.0.0, busybox wget healthcheck) + web (Next static export -> nginx, NEXT_PUBLIC_* baked as build args). nginx.conf SPA fallback. Config: server CORS is now config-driven (Cors__Origins) so the deployed web origin is allowed without code edits. deploy/ENV_FILE.example documents the Gitea ENV_FILE secret; DEPLOY.md covers setup/run/LAN-IP/rollback/migrations. Fonts: switch Vazirmatn + Plus Jakarta Sans from next/font/google (build-time Google fetch -> fails on the Iran CI runner) to self-hosted @fontsource-variable packages. Build is offline and ~3x faster; 7 woff2 emitted into out/. Verified locally: dotnet build slnx + Hokm.Sim (300 matches, exit 0); tsc clean; next build clean with self-hosted fonts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.4 KiB
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)
- CI – API: restore (Nexus NuGet) →
dotnet build server/Hokm.slnx→ runHokm.Sim(engine rules validation). - CI – Web:
npm install(Nexus npm) →tsc --noEmit→next build(static export). - Deploy (
self-hosted, push tomainonly): backup DB → tag rollback image → build images → bring updb(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
- Secret: fill
deploy/ENV_FILE.exampleand paste into the Gitea repo secretENV_FILEat.../HokmPlay/settings/secrets. At minimum setJWT_KEY(openssl rand -hex 32) andPOSTGRES_PASSWORD. - Runner: an
act_runnerregistered with both labels (ubuntu-latest:docker://...for CI,self-hosted:hostfor deploy) — reused from existing Soroush projects. - 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_URLandCORS_ORIGINSinENV_FILEto 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)
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):
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:
cd server/src/Hokm.Server
$env:HOKM_DESIGN_CONN="Host=localhost;Port=1510;Database=hokm;Username=hokm;Password=<pw>"
dotnet ef migrations add Init
Then the next deploy runs Database.Migrate() automatically.
Rollback
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.)