# Meezi — full stack (Postgres, Redis, API, Dashboard, Marketing Website) # # Setup: # copy .env.example .env # powershell -File scripts/docker-up-full.ps1 # — or — docker compose up -d --build # # If image pulls fail (Iran / MCR timeout): VPN on, or see docs/DOCKER.md # # URLs (defaults): # Dashboard http://localhost:3101/fa/login # Website http://localhost:3010/fa # Finder http://localhost:3103/fa # API http://localhost:5080/swagger # Health http://localhost:5080/health services: 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 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:${FINDER_PORT:-3103} 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: # TCP probe only — no apt-get/curl in image (build works offline / without Ubuntu mirrors) test: ["CMD-SHELL", "bash -c 'cat /dev/tcp/127.0.0.1/8080' || exit 1"] interval: 10s timeout: 5s retries: 12 start_period: 40s 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" website: build: context: . dockerfile: docker/website/Dockerfile args: MEEZI_API_URL: http://api:8080 NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:-http://localhost:3010} 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:-http://localhost:3010} ports: - "${WEBSITE_PORT:-3010}:3000" finder: build: context: . dockerfile: docker/finder/Dockerfile args: NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:5080} NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_FINDER_URL:-http://localhost:3103} container_name: meezi-finder restart: unless-stopped depends_on: api: condition: service_healthy environment: PORT: "3000" HOSTNAME: 0.0.0.0 NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:5080} NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_FINDER_URL:-http://localhost:3103} ports: - "${FINDER_PORT:-3103}:3000" volumes: postgres_data: redis_data: api_uploads: