Files
meezi/docker-compose.full.yml
soroush.asadi 8ea98bdc09
CI/CD / CI · API (dotnet build + test) (push) Successful in 5m47s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 34s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m10s
CI/CD / CI · Admin Web (tsc) (push) Successful in 40s
CI/CD / CI · Website (tsc) (push) Successful in 47s
CI/CD / CI · Koja (tsc) (push) Successful in 51s
CI/CD / Deploy · all services (push) Successful in 3m53s
fix(seo): website/koja base URL defaulted to localhost → de-indexed in GSC
Production serves robots.txt Host/Sitemap, sitemap <loc>, and every page's
canonical + og:url as http://localhost:3010 — so Google rejects all URLs
("URL not allowed") and indexes nothing. Cause: NEXT_PUBLIC_SITE_URL is baked in
at BUILD time and was unset in prod, so it fell back to the localhost defaults in
the compose files + website Dockerfile.

Changes the defaults to the real domains (website → https://meezi.ir, koja →
https://koja.meezi.ir) in docker-compose.yml, docker-compose.full.yml, the
website Dockerfile ARG, and .env.example.

Build-time var → the website image MUST be rebuilt + redeployed (CI does this on
push), then purge the WCDN cache and resubmit the sitemap in Search Console.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:58:38 +03:30

189 lines
6.0 KiB
YAML

# Meezi — FULL platform (all 7 services in one file)
#
# Includes: Postgres, Redis, Main API, Admin API,
# Dashboard (web), Admin Panel (admin-web), Marketing Website
#
# Setup:
# copy .env.example .env
# docker compose -f docker-compose.full.yml up -d --build
#
# URLs (defaults):
# Dashboard http://localhost:3101/fa/login
# Website http://localhost:3010/fa
# Admin panel http://localhost:3102/fa/admin/login
# Main API http://localhost:5080/swagger
# Admin API http://localhost:5081/swagger
services:
# ── Infrastructure ──────────────────────────────────────────────────────────
postgres:
image: postgres:16-alpine
container_name: meezi-db
restart: unless-stopped
environment:
POSTGRES_DB: meezi
POSTGRES_USER: meezi
POSTGRES_PASSWORD: meezi_local_pass
ports:
- "${POSTGRES_PORT:-5434}:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U meezi -d meezi"]
interval: 5s
timeout: 5s
retries: 10
redis:
image: redis:7-alpine
container_name: meezi-redis
restart: unless-stopped
ports:
- "${REDIS_PORT:-6381}:6379"
command: redis-server --appendonly yes
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 10
# ── Backend APIs ────────────────────────────────────────────────────────────
api:
build:
context: .
dockerfile: docker/api/Dockerfile
args:
DOTNET_SDK_IMAGE: ${DOTNET_SDK_IMAGE:-mcr.microsoft.com/dotnet/sdk:10.0}
DOTNET_ASPNET_IMAGE: ${DOTNET_ASPNET_IMAGE:-mcr.microsoft.com/dotnet/aspnet:10.0}
container_name: meezi-api
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
environment:
ASPNETCORE_ENVIRONMENT: Development
ASPNETCORE_URLS: http://+:8080
RUN_MIGRATIONS: "true"
ConnectionStrings__DefaultConnection: Host=postgres;Port=5432;Database=meezi;Username=meezi;Password=meezi_local_pass
ConnectionStrings__Redis: redis:6379
App__PublicBaseUrl: ${NEXT_PUBLIC_API_URL:-http://localhost:5080}
App__QrPublicBaseUrl: http://localhost:${WEB_PORT:-3101}
Cors__Origins__0: http://localhost:${WEB_PORT:-3101}
Cors__Origins__1: http://localhost:${WEBSITE_PORT:-3010}
Cors__Origins__2: http://localhost:${ADMIN_WEB_PORT:-3102}
Auth__MaxOtpAttemptsPerHour: "100"
Kavenegar__ApiKey: ""
Billing__DashboardBaseUrl: http://localhost:${WEB_PORT:-3101}
Snappfood__WebhookSecret: meezi-dev-snappfood-secret
ZarinPal__MerchantId: "${ZARINPAL_MERCHANT_ID:-}"
ZarinPal__Sandbox: "${ZARINPAL_SANDBOX:-true}"
ports:
- "${API_PORT:-5080}:8080"
volumes:
- api_uploads:/app/uploads
healthcheck:
test: ["CMD-SHELL", "bash -c 'cat </dev/null >/dev/tcp/127.0.0.1/8080' || exit 1"]
interval: 10s
timeout: 5s
retries: 12
start_period: 40s
admin-api:
build:
context: .
dockerfile: docker/admin-api/Dockerfile
args:
DOTNET_SDK_IMAGE: ${DOTNET_SDK_IMAGE:-mcr.microsoft.com/dotnet/sdk:10.0}
DOTNET_ASPNET_IMAGE: ${DOTNET_ASPNET_IMAGE:-mcr.microsoft.com/dotnet/aspnet:10.0}
container_name: meezi-admin-api
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
environment:
ASPNETCORE_ENVIRONMENT: Development
ASPNETCORE_URLS: http://+:8080
RUN_MIGRATIONS: "false"
ConnectionStrings__DefaultConnection: Host=postgres;Port=5432;Database=meezi;Username=meezi;Password=meezi_local_pass
ConnectionStrings__Redis: redis:6379
Cors__Origins__0: http://localhost:${ADMIN_WEB_PORT:-3102}
Cors__Origins__1: http://localhost:${WEB_PORT:-3101}
Kavenegar__ApiKey: ""
ports:
- "${ADMIN_API_PORT:-5081}:8080"
healthcheck:
test: ["CMD-SHELL", "bash -c 'cat </dev/null >/dev/tcp/127.0.0.1/8080' || exit 1"]
interval: 10s
timeout: 5s
retries: 12
start_period: 40s
# ── Frontend Services ───────────────────────────────────────────────────────
web:
build:
context: .
dockerfile: docker/web/Dockerfile
args:
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:5080}
container_name: meezi-web
restart: unless-stopped
depends_on:
api:
condition: service_healthy
environment:
PORT: "3000"
HOSTNAME: 0.0.0.0
ports:
- "${WEB_PORT:-3101}:3000"
admin-web:
build:
context: .
dockerfile: docker/admin-web/Dockerfile
args:
NEXT_PUBLIC_ADMIN_API_URL: ${NEXT_PUBLIC_ADMIN_API_URL:-http://localhost:5081}
container_name: meezi-admin-web
restart: unless-stopped
depends_on:
admin-api:
condition: service_healthy
environment:
PORT: "3000"
HOSTNAME: 0.0.0.0
ports:
- "${ADMIN_WEB_PORT:-3102}:3000"
website:
build:
context: .
dockerfile: docker/website/Dockerfile
args:
MEEZI_API_URL: http://api:8080
NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:-https://meezi.ir}
container_name: meezi-website
restart: unless-stopped
depends_on:
api:
condition: service_healthy
environment:
PORT: "3000"
HOSTNAME: 0.0.0.0
MEEZI_API_URL: http://api:8080
NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:-https://meezi.ir}
ports:
- "${WEBSITE_PORT:-3010}:3000"
volumes:
postgres_data:
redis_data:
api_uploads: