Files
HokmPlay/docker-compose.yml
T
soroush.asadi fdf4235fbd
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 50s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m11s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 34s
feat(auth): real SMS OTP via Kavenegar (replaces the mock 1234 code)
- OtpService: generates a 5-digit code, stores it (in-memory, 120s TTL, max 5
  tries, single-use), and sends it via Kavenegar verify/lookup
  (template "hokmotp", %token = code). Normalizes +98/98 → 09xxxxxxxxx.
- /api/auth/otp/request + /verify now use it. No SMS_API_KEY ⇒ dev mode
  (accepts a fixed code, returns devCode for local testing).
- Config: Sms section (appsettings) + Sms__* compose mapping + SMS_* in the
  ENV_FILE template.

Security: sanitized deploy/ENV_FILE.example back to placeholders (it had picked
up real secrets) and added /deploy/ENV_FILE.local to .gitignore as the real
master copy (never committed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 23:50:33 +03:30

137 lines
5.2 KiB
YAML
Raw 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.
# Barg-e Vasat — local/self-hosted stack.
# Ports live in the 15001600 range so this stack can run alongside a manual
# `npm run dev` (:3000) and `dotnet run` (:5005) without colliding.
# web → http://localhost:1500
# api → http://localhost:1505
# db → localhost:1510 (postgres)
# All values come from .env (the deploy job writes it from the ENV_FILE secret).
services:
db:
image: mirror.soroushasadi.com/postgres:16-alpine
container_name: hokm-db
restart: unless-stopped
environment:
POSTGRES_DB: hokm
POSTGRES_USER: hokm
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-hokm_dev_pass}
volumes:
- hokm_db_data:/var/lib/postgresql/data
ports:
- "${DB_PORT:-1510}:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U hokm -d hokm"]
interval: 5s
timeout: 5s
retries: 10
server:
build:
context: ./server
dockerfile: Dockerfile
args:
# Plain-HTTP Nexus (no SSL) — the HTTPS mirror serves a partial cert chain
# containers can't validate. Override via .env if needed.
NUGET_INDEX: ${NUGET_INDEX:-http://171.22.25.73:8081/repository/nuget-group/index.json}
image: hokm-server:latest
container_name: hokm-server
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
ASPNETCORE_ENVIRONMENT: Production
ASPNETCORE_URLS: http://0.0.0.0:5005
Database__Provider: postgres
ConnectionStrings__Default: "Host=db;Port=5432;Database=hokm;Username=hokm;Password=${POSTGRES_PASSWORD:-hokm_dev_pass}"
# Default empty so `docker compose build` (which interpolates the whole file)
# never blocks on a runtime-only secret. The server REFUSES to boot in
# Production with a missing/dev key (see Program.cs guard).
Jwt__Key: ${JWT_KEY:-}
Jwt__Issuer: ${JWT_ISSUER:-hokm}
Jwt__Audience: ${JWT_AUDIENCE:-hokm-clients}
# Comma-separated origins the browser uses to reach the web app.
Cors__Origins: ${CORS_ORIGINS:-http://localhost:1500}
Zarinpal__MerchantId: ${ZARINPAL_MERCHANT_ID:-299685fb-cadf-4dfc-98e2-d4af5d81528d}
Zarinpal__Sandbox: ${ZARINPAL_SANDBOX:-true}
Zarinpal__CallbackUrl: ${ZARINPAL_CALLBACK_URL:-http://localhost:1505/api/coins/pay/callback}
Zarinpal__ClientReturnUrl: ${ZARINPAL_CLIENT_RETURN_URL:-http://localhost:1500}
# Store in-app billing verification (Cafe Bazaar / Myket) — fill from panels.
Iab__PackageName: ${IAB_PACKAGE_NAME:-com.bargevasat.app}
Iab__BazaarClientId: ${IAB_BAZAAR_CLIENT_ID:-}
Iab__BazaarClientSecret: ${IAB_BAZAAR_CLIENT_SECRET:-}
Iab__BazaarRefreshToken: ${IAB_BAZAAR_REFRESH_TOKEN:-}
Iab__MyketAccessToken: ${IAB_MYKET_ACCESS_TOKEN:-}
Iab__AllowUnverified: ${IAB_ALLOW_UNVERIFIED:-false}
# SMS OTP (Kavenegar). Empty key ⇒ dev mode (no SMS, accepts the dev code).
Sms__Provider: ${SMS_PROVIDER:-kavenegar}
Sms__ApiKey: ${SMS_API_KEY:-}
Sms__Template: ${SMS_TEMPLATE:-hokmotp}
# Admin panel (marketing-site links editor) — shared-token auth.
Admin__Token: ${ADMIN_TOKEN:-}
# Where the admin-editable site-links JSON is persisted (mounted volume).
Site__DataDir: /data
volumes:
- hokm_data:/data
ports:
- "${API_PORT:-1505}:5005"
healthcheck:
test: ["CMD", "wget", "-q", "-O-", "http://127.0.0.1:5005/"]
interval: 10s
timeout: 5s
retries: 12
start_period: 20s
web:
build:
context: .
dockerfile: Dockerfile
args:
# Baked into the static bundle at build time. Must be the address the
# BROWSER uses to reach the API (host-mapped api port, or LAN IP).
NEXT_PUBLIC_USE_SERVER: "1"
NEXT_PUBLIC_SERVER_URL: ${NEXT_PUBLIC_SERVER_URL:-http://localhost:1505}
# Plain-HTTP Nexus (no SSL). Override via .env if needed.
NPM_REGISTRY: ${NPM_REGISTRY:-http://171.22.25.73:8081/repository/npm-group/}
image: hokm-web:latest
container_name: hokm-web
restart: unless-stopped
depends_on:
server:
condition: service_healthy
ports:
- "${WEB_PORT:-1500}:80"
healthcheck:
test: ["CMD", "wget", "-q", "-O-", "http://127.0.0.1/"]
interval: 10s
timeout: 5s
retries: 6
start_period: 10s
# Marketing website (bargevasat.ir) — separate static Next.js project in ./site.
site:
build:
context: ./site
dockerfile: Dockerfile
args:
# Browser-facing API (for reading admin-editable store links) + game URL.
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_SERVER_URL:-http://localhost:1505}
NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-http://localhost:1500}
NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:-http://localhost:1520}
NPM_REGISTRY: ${NPM_REGISTRY:-http://171.22.25.73:8081/repository/npm-group/}
image: hokm-site:latest
container_name: hokm-site
restart: unless-stopped
ports:
- "${SITE_PORT:-1520}:80"
healthcheck:
test: ["CMD", "wget", "-q", "-O-", "http://127.0.0.1/"]
interval: 10s
timeout: 5s
retries: 6
start_period: 10s
volumes:
hokm_db_data:
hokm_data: