Adds root-level config files: solution (.slnx), NuGet, global.json, Docker Compose files for all services (API, dashboard, website, finder, admin), environment example, and developer documentation. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
5.5 KiB
Meezi — Docker (full platform)
Run all services with one command.
Services
| Service | Description | Default Port |
|---|---|---|
| postgres | PostgreSQL 16 database | 5434 (host) |
| redis | Redis 7 (session, rate-limit, refresh tokens) | 6381 (host) |
| api | Main ASP.NET Core 10 API | 5080 |
| admin-api | Admin ASP.NET Core 10 API | 5081 |
| web | Customer-facing Next.js dashboard | 3101 |
| website | Marketing / landing website | 3010 |
| admin-web | Admin panel Next.js | 3102 |
Quick start — full stack (all 7 services)
cd F:\Projects\Meezi
copy .env.example .env
docker compose -f docker-compose.full.yml up -d --build
Quick start — core stack only (dashboard + API)
docker compose up -d --build
Quick start — with admin panel
docker compose -f docker-compose.yml -f docker-compose.admin.yml up -d --build
Default URLs
| Service | URL |
|---|---|
| Dashboard (customer) | http://localhost:3101/fa/login |
| Marketing website | http://localhost:3010/fa |
| Admin panel | http://localhost:3102/fa/admin/login |
| Main API Swagger | http://localhost:5080/swagger |
| Admin API Swagger | http://localhost:5081/swagger |
| Health (main API) | http://localhost:5080/health |
| Health (admin API) | http://localhost:5081/health |
| Hangfire (main API) | http://localhost:5080/hangfire |
Demo login: 09121234567 — OTP appears in API logs (docker compose logs -f api).
Ports (change in .env)
| Variable | Default | Purpose |
|---|---|---|
WEB_PORT |
3101 | Next.js dashboard |
WEBSITE_PORT |
3010 | Marketing website |
ADMIN_WEB_PORT |
3102 | Admin panel |
API_PORT |
5080 | Main ASP.NET API |
ADMIN_API_PORT |
5081 | Admin ASP.NET API |
POSTGRES_PORT |
5434 | Postgres on host |
REDIS_PORT |
6381 | Redis on host |
If a port is taken, edit .env:
copy .env.example .env
# Edit .env — change WEB_PORT, WEBSITE_PORT, etc.
docker compose -f docker-compose.full.yml up -d --build
Build args and API URLs
NEXT_PUBLIC_API_URL — what the browser uses to call the Main API. Must be a host URL (not api:8080).
MEEZI_API_URL — what the website server uses for internal SSR calls. Uses the Docker service name http://api:8080.
# Rebuild only the website after changing NEXT_PUBLIC_SITE_URL:
docker compose -f docker-compose.full.yml up -d --build website
Useful commands
# Status
docker compose -f docker-compose.full.yml ps
# Logs
docker compose -f docker-compose.full.yml logs -f api
docker compose -f docker-compose.full.yml logs -f website
docker compose -f docker-compose.full.yml logs -f web
# Stop everything
docker compose -f docker-compose.full.yml down
# Stop and remove volumes (wipes DB!)
docker compose -f docker-compose.full.yml down -v
# Rebuild a single service
docker compose -f docker-compose.full.yml up -d --build website
docker compose -f docker-compose.full.yml up -d --build api
Printer setup (inside Docker)
The Meezi API sends print jobs directly from the browser dashboard — the API itself does not talk to printers. This means:
- Your thermal printer only needs to be on the same WiFi/LAN as the browser running the dashboard
- No Docker-specific configuration needed for printers
- See the full guide at: http://localhost:3010/fa/printer-guide
Dev without Docker
Still works:
docker compose up -d postgres redis
# then in separate terminals:
dotnet run --project src/Meezi.API
dotnet run --project src/Meezi.Admin.API
cd web/website && npm run dev # port 3010
cd web/dashboard && npm run dev # port 3000 → maps to 3101
cd web/admin && npm run dev # port 3102
Sprint 10 — billing & integrations (dev)
ZarinPal (mock): leave ZarinPal:MerchantId empty. In dashboard تنظیمات → upgrade Pro/Business → redirected through mock pay URL back to /fa/settings?billing=success.
Snappfood webhook (demo café vendor demo_vendor):
$body = '{"orderId":"sf-001","vendorId":"demo_vendor","customerName":"Test","customerPhone":"09121111111","total":150000,"items":[{"name":"لاته","quantity":1,"unitPrice":150000}]}'
$hmac = [System.BitConverter]::ToString((New-Object System.Security.Cryptography.HMACSHA256([Text.Encoding]::UTF8.GetBytes("meezi-dev-snappfood-secret"))).ComputeHash([Text.Encoding]::UTF8.GetBytes($body))).Replace("-","").ToLower()
Invoke-RestMethod -Method Post -Uri "http://localhost:5080/api/webhooks/snappfood" -Body $body -ContentType "application/json" -Headers @{ "X-Snappfood-Signature" = $hmac }
Taraz: Settings → «ارسال به تاراز» (logs only until Taraz:Username is set).
Hangfire: renewal reminder job runs daily — dashboard at http://localhost:5080/hangfire (dev).
Tables & QR
- Dashboard:
/fa/tables— floor plan, add table, print QR (PNG) - Dev QR URL in codes:
http://localhost:3101/q/{qrCode}(seeApp__QrPublicBaseUrl) - Scan
demo_table_01in Flutter or open manual entry on QR screen
Production env (Arvan)
See DEPLOY.md. Key additional website vars:
NEXT_PUBLIC_SITE_URL=https://meezi.ir
MEEZI_API_URL=http://api:8080
Menu images (Food-101)
- Manifest:
data/menu-image-manifest.json - API upserts images on dev seed via
EnsureMenuImagesAsync - Optional import:
dotnet run --project tools/MenuImageImporter -- --food101 <path-to-food-101/images>