Marketing site (bargevasat.ir) + admin-editable store links + subdomain split
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 4m40s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m7s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 41s

- New standalone Next.js marketing site under site/ (static export, SEO):
  landing, download/install guide (Bazaar/Myket/iOS-PWA/web), FAQ (JSON-LD),
  privacy, terms, support, /admin link editor. fa RTL, sitemap/robots/manifest.
- Backend: SiteLinksService (JSON-file persisted) + GET /api/site/links (public)
  + POST /api/admin/site/links (X-Admin-Token). ADMIN_TOKEN + Site__DataDir via env.
- compose: hokm-site service (:1520) + hokm_data volume for links JSON.
- CI deploy job builds + deploys the site container.
- deploy/SUBDOMAIN_SPLIT.md: nginx blocks, cert reissue, DNS, ENV split.
- Exclude site/ from root tsc + web docker context.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-08 07:19:43 +03:30
parent 8d0d4dc991
commit 5d38312ef0
39 changed files with 8207 additions and 2 deletions
+118
View File
@@ -0,0 +1,118 @@
# Subdomain split: marketing site + game + API
After this change there are **three** public hosts (all → edge nginx `185.239.1.100`):
| Host | Serves | Upstream (on 171.22.25.73) |
|---|---|---|
| `bargevasat.ir`, `www.bargevasat.ir` | Marketing site (`hokm-site`) | `:1520` |
| `app.bargevasat.ir` | The game (`hokm-web`) | `:1500` |
| `api.bargevasat.ir` | API + SignalR (`hokm-server`) | `:1505` (CDN **bypass**) |
## 1. DNS
Add/confirm Arecords (all → `185.239.1.100`):
```
bargevasat.ir A 185.239.1.100 (CDN ok)
www.bargevasat.ir A 185.239.1.100 (CDN ok)
app.bargevasat.ir A 185.239.1.100 (CDN ok)
api.bargevasat.ir A 185.239.1.100 (CDN BYPASS / DNS-only)
```
## 2. TLS cert — reissue to include `app`
The current cert covers `bargevasat.ir, www, api` — add `app`:
```bash
sudo certbot certonly --webroot -w /var/www/certbot \
-d bargevasat.ir -d www.bargevasat.ir -d app.bargevasat.ir -d api.bargevasat.ir \
--agree-tos --no-eff-email --email you@example.com
# then copy/symlink fullchain.pem + privkey.pem into /etc/ssl/bargevasat/
```
(Or DNS01 if behind the CDN — see SSL notes.)
## 3. nginx (edit /root/mirror-server/nginx/nginx.conf)
Replace the single Barge Vasat web block with these three:
```nginx
# Redirect http → https for all three
server {
listen 80;
server_name bargevasat.ir www.bargevasat.ir app.bargevasat.ir api.bargevasat.ir;
location /.well-known/acme-challenge/ { root /var/www/certbot; }
location / { return 301 https://$host$request_uri; }
}
# Marketing site → hokm-site :1520
server {
listen 443 ssl;
http2 on;
server_name bargevasat.ir www.bargevasat.ir;
ssl_certificate /etc/ssl/bargevasat/fullchain.pem;
ssl_certificate_key /etc/ssl/bargevasat/privateKey.pem;
location / {
proxy_pass http://171.22.25.73:1520;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# Game (Next static SPA) → hokm-web :1500
server {
listen 443 ssl;
http2 on;
server_name app.bargevasat.ir;
client_max_body_size 25m;
ssl_certificate /etc/ssl/bargevasat/fullchain.pem;
ssl_certificate_key /etc/ssl/bargevasat/privateKey.pem;
location / {
proxy_pass http://171.22.25.73:1500;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# API + SignalR → hokm-server :1505 (WebSocket; keep CDN bypassed for this host)
server {
listen 443 ssl;
http2 on;
server_name api.bargevasat.ir;
client_max_body_size 50m;
ssl_certificate /etc/ssl/bargevasat/fullchain.pem;
ssl_certificate_key /etc/ssl/bargevasat/privateKey.pem;
location / {
proxy_pass http://171.22.25.73:1505;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;
}
}
```
Reload: `docker compose exec nginx nginx -t && docker compose exec nginx nginx -s reload`
## 4. ENV_FILE secret (Gitea) — add/confirm
```
SITE_PORT=1520
NEXT_PUBLIC_APP_URL=https://app.bargevasat.ir
NEXT_PUBLIC_SITE_URL=https://bargevasat.ir
NEXT_PUBLIC_SERVER_URL=https://api.bargevasat.ir
CORS_ORIGINS=https://bargevasat.ir,https://www.bargevasat.ir,https://app.bargevasat.ir
ADMIN_TOKEN=<openssl rand -hex 24>
```
## 5. Deploy
`docker compose build site web server && docker compose up -d`
(Add the `site` service to the CI deploy job's build/up + healthwait, same pattern as web.)
## 6. Verify
```bash
curl -I https://bargevasat.ir # marketing (200)
curl -I https://app.bargevasat.ir # game (200)
curl -I https://api.bargevasat.ir # API (405 to HEAD is fine)
```
Admin: open `https://bargevasat.ir/admin`, enter `ADMIN_TOKEN`, set Bazaar/Myket links → Save.