Files
meezi/docker-compose.yml
T
soroush.asadi 979dcaa949 fix: route all Docker builds through local Nexus mirrors
- All Node Dockerfiles rewritten with NODE_IMAGE + NPM_REGISTRY build args
  defaulting to local Nexus proxies (171.22.25.73:5000/library/node:20-alpine
  and http://mirror:8081/repository/npm-group/)
- Add extra_hosts: mirror:host-gateway to every build section so the
  mirror hostname resolves during docker build
- Replace nuget.org with nuget.docker.config (Nexus mirror) in api/admin-api
  Dockerfiles to fix NuGet restore in Iranian network
- Rewrite admin-web and website Dockerfiles (were referencing non-existent
  meezi-node:20-alpine base image with no npm install step)
- Update dotnet image defaults to 171.22.25.73:5002 MCR proxy in admin-api
  and docker-compose.admin.yml

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 21:01:43 +03:30

171 lines
5.5 KiB
YAML

# Meezi — main stack (Postgres, Redis, API, Dashboard, Website, Finder)
#
# Local dev:
# cp .env.example .env
# docker compose up -d --build
#
# Production (IP-based, no domain yet):
# Set ENV_FILE secret in Gitea — CI writes .env and runs docker compose up -d
#
# Production (with domain, add Caddy):
# docker compose -f docker-compose.yml -f docker-compose.admin.yml -f docker-compose.caddy.yml up -d
#
# URLs (port-based defaults):
# Dashboard http://SERVER:3101/fa/login
# Website http://SERVER:3010/fa
# Finder http://SERVER:3103/fa
# API http://SERVER:5080/swagger
services:
postgres:
image: postgres:16-alpine
container_name: meezi-db
restart: unless-stopped
environment:
POSTGRES_DB: meezi
POSTGRES_USER: meezi
POSTGRES_PASSWORD: "${DB_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
extra_hosts:
- "mirror:host-gateway"
args:
DOTNET_SDK_IMAGE: ${DOTNET_SDK_IMAGE:-171.22.25.73:5002/dotnet/sdk:10.0}
DOTNET_ASPNET_IMAGE: ${DOTNET_ASPNET_IMAGE:-171.22.25.73:5002/dotnet/aspnet:10.0}
container_name: meezi-api
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
environment:
ASPNETCORE_ENVIRONMENT: "${ASPNETCORE_ENVIRONMENT:-Development}"
ASPNETCORE_URLS: http://+:8080
RUN_MIGRATIONS: "${RUN_MIGRATIONS:-true}"
ConnectionStrings__DefaultConnection: "${DB_CONNECTION_STRING:-Host=postgres;Port=5432;Database=meezi;Username=meezi;Password=meezi_local_pass}"
ConnectionStrings__Redis: redis:6379
Jwt__Key: "${JWT_KEY:-dev-jwt-key-CHANGE-THIS-IN-PRODUCTION-min32chars}"
App__PublicBaseUrl: "${NEXT_PUBLIC_API_URL:-http://localhost:5080}"
App__QrPublicBaseUrl: "${APP_QR_BASE_URL:-http://localhost:3101}"
Billing__DashboardBaseUrl: "${BILLING_DASHBOARD_URL:-http://localhost:3101}"
Cors__Origins__0: "${CORS_ORIGIN_0:-http://localhost:3101}"
Cors__Origins__1: "${CORS_ORIGIN_1:-http://localhost:3010}"
Cors__Origins__2: "${CORS_ORIGIN_2:-http://localhost:3103}"
Auth__MaxOtpAttemptsPerHour: "${OTP_RATE_LIMIT:-100}"
Kavenegar__ApiKey: "${KAVENEGAR_API_KEY:-}"
Snappfood__WebhookSecret: "${SNAPPFOOD_WEBHOOK_SECRET:-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
web:
build:
context: .
dockerfile: docker/web/Dockerfile
extra_hosts:
- "mirror:host-gateway"
args:
NODE_IMAGE: ${NODE_IMAGE:-171.22.25.73:5000/library/node:20-alpine}
NPM_REGISTRY: ${NPM_REGISTRY:-http://mirror:8081/repository/npm-group/}
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
extra_hosts:
- "mirror:host-gateway"
args:
NODE_IMAGE: ${NODE_IMAGE:-171.22.25.73:5000/library/node:20-alpine}
NPM_REGISTRY: ${NPM_REGISTRY:-http://mirror:8081/repository/npm-group/}
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
extra_hosts:
- "mirror:host-gateway"
args:
NODE_IMAGE: ${NODE_IMAGE:-171.22.25.73:5000/library/node:20-alpine}
NPM_REGISTRY: ${NPM_REGISTRY:-http://mirror:8081/repository/npm-group/}
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: