Add Soroush CI/CD (Gitea + Nexus) + self-host fonts for offline build
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>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
# 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=<pw>"
|
||||
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.)
|
||||
Reference in New Issue
Block a user