name: ${COMPOSE_PROJECT_NAME:-myapp}
x-frontend-volumes: &frontend-volumes
- ${FRONTEND_DIR:-../frontend}:/app
- ./docker/frontend/entrypoint.sh:/usr/local/bin/entrypoint.sh:ro
- ./docker/frontend/mobile-stack.sh:/usr/local/bin/mobile-stack.sh:ro
- pnpm_store:/pnpm-store
- fe_nm_root:/app/node_modules
x-frontend-env: &frontend-env
NODE_ENV: development
CHOKIDAR_USEPOLLING: "true"
WATCHPACK_POLLING: "true"
METRO_DISABLE_WATCHMAN: "1"
METRO_POKE: ${METRO_POKE:-true}
METRO_POKE_INTERVAL: ${METRO_POKE_INTERVAL:-1}
METRO_POKE_SETTLE: ${METRO_POKE_SETTLE:-1}
WEB_APP: ${WEB_APP:-web}
ADMIN_APP: ${ADMIN_APP:-admin}
LANDING_APP: ${LANDING_APP:-landing}
DESKTOP_APP: ${DESKTOP_APP:-desktop}
MOBILE_APP: ${MOBILE_APP:-mobile-client}
RUN_DESKTOP: ${RUN_DESKTOP:-false}
MOBILE_WATCH_PACKAGES: ${MOBILE_WATCH_PACKAGES:-}
EXTRA_DEPS_APPS: ${EXTRA_DEPS_APPS:-}
RUN_ADMIN: ${RUN_ADMIN:-true}
RUN_LANDING: ${RUN_LANDING:-true}
VITE_API_BASE_URL: ${VITE_API_BASE_URL:-http://localhost:8000/api}
VITE_WEB_APP_URL: ${VITE_WEB_APP_URL:-http://localhost:5173}
API_PROXY: http://backend:${BACKEND_CONTAINER_PORT:-8000}
API_PROXY_TARGET: http://backend:${BACKEND_CONTAINER_PORT:-8000}
VITE_API_PROXY: http://backend:${BACKEND_CONTAINER_PORT:-8000}
DEV_PROXY_TARGET: http://backend:${BACKEND_CONTAINER_PORT:-8000}
DOCKER: "1"
IN_DOCKER: "true"
VITE_SENTRY_DSN: ${VITE_SENTRY_DSN:-}
VITE_SENTRY_ENV: ${VITE_SENTRY_ENV:-local}
x-frontend-service: &frontend-service
build:
context: ./docker/frontend
image: ${COMPOSE_PROJECT_NAME:-myapp}/frontend:local
working_dir: /app
environment: *frontend-env
volumes: *frontend-volumes
depends_on:
frontend-deps:
condition: service_completed_successfully
restart: unless-stopped
shm_size: ${DOCKER_SHM_SIZE:-64m}
x-backend-env: &backend-env
PORT: ${BACKEND_CONTAINER_PORT:-8000}
API_PORT: ${BACKEND_CONTAINER_PORT:-8000}
APP_PORT: ${BACKEND_CONTAINER_PORT:-8000}
HTTP_PORT: ${BACKEND_CONTAINER_PORT:-8000}
SERVER_PORT: ${BACKEND_CONTAINER_PORT:-8000}
NODE_ENV: ${NODE_ENV:-development}
DATABASE_URL: ${DATABASE_URL:-postgresql://${DB_USERNAME:-myapp}:${DB_PASSWORD:-secret}@postgres:5432/${DB_DATABASE:-myapp}}
REDIS_URL: redis://redis:6379
S3_ENDPOINT: ${S3_ENDPOINT:-}
S3_BUCKET: ${MINIO_BUCKET:-local}
S3_ACCESS_KEY: ${MINIO_ROOT_USER:-minio}
S3_SECRET_KEY: ${MINIO_ROOT_PASSWORD:-minio123}
BACKEND_INSTALL_CMD: ${BACKEND_INSTALL_CMD:-}
BACKEND_BUILD_CMD: ${BACKEND_BUILD_CMD:-}
BACKEND_START_CMD: ${BACKEND_START_CMD:-}
BACKEND_MIGRATE_CMD: ${BACKEND_MIGRATE_CMD:-}
BACKEND_SEED_CMD: ${BACKEND_SEED_CMD:-}
BACKEND_QUEUE_CMD: ${BACKEND_QUEUE_CMD:-}
BACKEND_SCHEDULE_CMD: ${BACKEND_SCHEDULE_CMD:-}
APP_ENV: ${APP_ENV:-local}
APP_DEBUG: ${APP_DEBUG:-true}
APP_URL: http://localhost:${BACKEND_PORT:-8000}
OVERRIDE_APP_KEY: ${APP_KEY:-}
DB_CONNECTION: ${DB_CONNECTION:-pgsql}
DB_HOST: ${DB_HOST:-postgres}
DB_PORT: ${DB_INTERNAL_PORT:-5432}
DB_DATABASE: ${DB_DATABASE:-myapp}
DB_USERNAME: ${DB_USERNAME:-myapp}
DB_PASSWORD: ${DB_PASSWORD:-secret}
REDIS_CLIENT: phpredis
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_PASSWORD: "null"
CACHE_STORE: database
SESSION_DRIVER: database
QUEUE_CONNECTION: database
MAIL_MAILER: smtp
MAIL_HOST: mailpit
MAIL_PORT: 1025
MAIL_USERNAME: "null"
MAIL_PASSWORD: "null"
MAIL_SCHEME: "null"
RUN_MIGRATIONS: ${RUN_MIGRATIONS:-true}
RUN_SEEDERS: ${RUN_SEEDERS:-false}
x-backend-service: &backend-service
build:
context: ./docker/backend/${BACKEND_STACK:-laravel}
image: ${COMPOSE_PROJECT_NAME:-myapp}/backend-${BACKEND_STACK:-laravel}:local
working_dir: /app/${BACKEND_SUBDIR:-}
environment: *backend-env
volumes:
- ${BACKEND_DIR:-../backend}:/app
- ./docker/backend/${BACKEND_STACK:-laravel}/entrypoint.sh:/usr/local/bin/entrypoint.sh:ro
- backend_state:/run-state
depends_on:
postgres:
condition: service_healthy
required: false
mysql:
condition: service_healthy
required: false
redis:
condition: service_started
required: false
restart: unless-stopped
shm_size: ${DOCKER_SHM_SIZE:-64m}
services:
postgres:
profiles: ["postgres"]
image: postgres:16-alpine
environment:
POSTGRES_DB: ${DB_DATABASE:-myapp}
POSTGRES_USER: ${DB_USERNAME:-myapp}
POSTGRES_PASSWORD: ${DB_PASSWORD:-secret}
ports:
- "${POSTGRES_PORT:-5434}:5432"
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME:-myapp} -d ${DB_DATABASE:-myapp}"]
interval: 5s
timeout: 5s
retries: 20
restart: unless-stopped
shm_size: ${DOCKER_SHM_SIZE:-64m}
mysql:
profiles: ["mysql"]
image: mysql:8
environment:
MYSQL_DATABASE: ${DB_DATABASE:-myapp}
MYSQL_USER: ${DB_USERNAME:-myapp}
MYSQL_PASSWORD: ${DB_PASSWORD:-secret}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-secret}
ports:
- "${MYSQL_PORT:-3307}:3306"
volumes:
- mysqldata:/var/lib/mysql
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -u root -p${DB_ROOT_PASSWORD:-secret}"]
interval: 5s
timeout: 5s
retries: 30
restart: unless-stopped
shm_size: ${DOCKER_SHM_SIZE:-64m}
redis:
profiles: ["redis"]
image: redis:7-alpine
ports:
- "${REDIS_PORT:-6380}:6379"
volumes:
- redisdata:/data
restart: unless-stopped
minio:
profiles: ["minio"]
image: minio/minio:latest
command: ["server", "/data", "--console-address", ":9001"]
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minio}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minio123}
ports:
- "${MINIO_PORT:-9000}:9000"
- "${MINIO_CONSOLE_PORT:-9001}:9001"
volumes:
- miniodata:/data
healthcheck:
test: ["CMD-SHELL", "mc ready local || exit 1"]
interval: 5s
timeout: 5s
retries: 20
restart: unless-stopped
dashboard:
build:
context: ./docker/dashboard
image: ${COMPOSE_PROJECT_NAME:-myapp}/dashboard:local
environment:
COMPOSE_PROJECT_NAME: ${COMPOSE_PROJECT_NAME:-myapp}
PROJECT_LABEL: ${PROJECT_LABEL:-${COMPOSE_PROJECT_NAME:-myapp}}
PORT: 8080
BACKEND_PORT: ${BACKEND_PORT:-8000}
BACKEND_CONTAINER_PORT: ${BACKEND_CONTAINER_PORT:-8000}
BACKEND_HEALTH_PATH: ${BACKEND_HEALTH_PATH:-/api/health}
BACKEND_LOGIN_PATH: ${BACKEND_LOGIN_PATH:-/api/auth/login}
WEB_PORT: ${WEB_PORT:-5173}
ADMIN_PORT: ${ADMIN_PORT:-5174}
LANDING_PORT: ${LANDING_PORT:-5175}
DESKTOP_PORT: ${DESKTOP_PORT:-5176}
MOBILE_CLIENT_PORT: ${MOBILE_CLIENT_PORT:-8081}
POSTGRES_PORT: ${POSTGRES_PORT:-5434}
MYSQL_PORT: ${MYSQL_PORT:-3307}
REDIS_PORT: ${REDIS_PORT:-6380}
MAILPIT_UI_PORT: ${MAILPIT_UI_PORT:-8025}
MINIO_PORT: ${MINIO_PORT:-9000}
MINIO_CONSOLE_PORT: ${MINIO_CONSOLE_PORT:-9001}
MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minio}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minio123}
MINIO_BUCKET: ${MINIO_BUCKET:-local}
HOST_OPEN_PORT: ${HOST_OPEN_PORT:-8091}
EXTRA_SERVICES: ${EXTRA_SERVICES:-}
COMPOSE_PROJECTS: ${COMPOSE_PROJECTS:-${COMPOSE_PROJECT_NAME:-myapp}}
DB_DATABASE: ${DB_DATABASE:-myapp}
DB_USERNAME: ${DB_USERNAME:-myapp}
DB_PASSWORD: ${DB_PASSWORD:-secret}
BACKEND_STACK: ${BACKEND_STACK:-laravel}
BACKEND_SUBDIR: ${BACKEND_SUBDIR:-}
DB_ENGINE: ${DB_ENGINE:-postgres}
DESKTOP_STACK: ${DESKTOP_STACK:-none}
WEB_APP: ${WEB_APP:-web}
ADMIN_APP: ${ADMIN_APP:-admin}
LANDING_APP: ${LANDING_APP:-landing}
DESKTOP_APP: ${DESKTOP_APP:-desktop}
MOBILE_APP: ${MOBILE_APP:-mobile-client}
RUN_ADMIN: ${RUN_ADMIN:-true}
RUN_LANDING: ${RUN_LANDING:-true}
RUN_DESKTOP: ${RUN_DESKTOP:-false}
RUN_MOBILE: ${RUN_MOBILE:-auto}
RUN_QUEUE: ${RUN_QUEUE:-true}
RUN_SCHEDULER: ${RUN_SCHEDULER:-true}
RUN_REDIS: ${RUN_REDIS:-true}
RUN_MAILPIT: ${RUN_MAILPIT:-true}
RUN_MINIO: ${RUN_MINIO:-false}
DEPLOY_WEB_TARGET: ${DEPLOY_WEB_TARGET:-none}
DEPLOY_MOBILE_TARGET: ${DEPLOY_MOBILE_TARGET:-none}
DEPLOY_DESKTOP_TARGET: ${DEPLOY_DESKTOP_TARGET:-none}
DEPLOY_WEB_CMD: ${DEPLOY_WEB_CMD:-}
DEPLOY_MOBILE_CMD: ${DEPLOY_MOBILE_CMD:-}
DEPLOY_DESKTOP_CMD: ${DEPLOY_DESKTOP_CMD:-}
DEPLOY_DEFAULT_ENV: ${DEPLOY_DEFAULT_ENV:-staging}
DEPLOY_ENVS: ${DEPLOY_ENVS:-staging production}
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./docker/dashboard:/srv
- ./config:/config:ro
- ${BACKEND_ENV_FILE:-${BACKEND_DIR:-../backend}/${BACKEND_SUBDIR:-}/.env}:/backend.env:ro
extra_hosts:
- "host.docker.internal:host-gateway"
ports:
- "${DASHBOARD_PORT:-8090}:8080"
restart: unless-stopped
mailpit:
profiles: ["mailpit"]
image: axllent/mailpit:latest
ports:
- "${MAILPIT_UI_PORT:-8025}:8025"
restart: unless-stopped
backend:
<<: *backend-service
command: ["serve"]
ports:
- "${BACKEND_PORT:-8000}:${BACKEND_CONTAINER_PORT:-8000}"
queue:
<<: *backend-service
profiles: ["queue"]
command: ["queue"]
scheduler:
<<: *backend-service
profiles: ["scheduler"]
command: ["schedule"]
frontend-deps:
build:
context: ./docker/frontend
image: ${COMPOSE_PROJECT_NAME:-myapp}/frontend:local
working_dir: /app
environment: *frontend-env
volumes: *frontend-volumes
command: ["deps"]
restart: "no"
frontend-packages:
<<: *frontend-service
command: ["watch"]
frontend-sync:
<<: *frontend-service
command: ["sync"]
web:
<<: *frontend-service
command: ["app", "web", "5173"]
environment:
<<: *frontend-env
APP_CMD: ${WEB_CMD:-}
ports:
- "${WEB_PORT:-5173}:5173"
admin:
<<: *frontend-service
profiles: ["admin"]
command: ["app", "admin", "5174"]
environment:
<<: *frontend-env
APP_CMD: ${ADMIN_CMD:-}
ports:
- "${ADMIN_PORT:-5174}:5174"
landing:
<<: *frontend-service
profiles: ["landing"]
command: ["app", "landing", "5175"]
environment:
<<: *frontend-env
APP_CMD: ${LANDING_CMD:-}
ports:
- "${LANDING_PORT:-5175}:5175"
desktop:
<<: *frontend-service
profiles: ["desktop"]
command: ["app", "desktop", "5176"]
environment:
<<: *frontend-env
APP_CMD: ${DESKTOP_CMD:-}
ports:
- "${DESKTOP_PORT:-5176}:5176"
mobile-deps:
build:
context: ./docker/frontend
image: ${COMPOSE_PROJECT_NAME:-myapp}/frontend:local
working_dir: /app
environment: *frontend-env
volumes: *frontend-volumes
command: ["deps-mobile"]
depends_on:
frontend-deps:
condition: service_completed_successfully
restart: "no"
mobile-packages:
<<: *frontend-service
command: ["watch-mobile"]
depends_on:
frontend-deps:
condition: service_completed_successfully
mobile-deps:
condition: service_completed_successfully
mobile-client:
<<: *frontend-service
environment:
<<: *frontend-env
APP_CMD: ${MOBILE_CMD:-}
MOBILE_STACK: ${MOBILE_STACK:-auto}
EXPO_NO_TELEMETRY: "1"
EXPO_DEVTOOLS_LISTEN_ADDRESS: 0.0.0.0
REACT_NATIVE_PACKAGER_HOSTNAME: ${REACT_NATIVE_PACKAGER_HOSTNAME:-localhost}
RCT_METRO_PORT: ${MOBILE_CLIENT_PORT:-8081}
EXPO_PUBLIC_API_BASE_URL: ${EXPO_PUBLIC_API_BASE_URL:-http://localhost:8000/api}
command: ["metro", "mobile"]
ports:
- "${MOBILE_CLIENT_PORT:-8081}:${MOBILE_CLIENT_PORT:-8081}"
depends_on:
frontend-deps:
condition: service_completed_successfully
mobile-deps:
condition: service_completed_successfully
volumes:
pgdata:
mysqldata:
miniodata:
backend_state:
redisdata:
pnpm_store:
fe_nm_root: