Files
Musify/deploy/docker-compose.yml
T
Admin 5614033294 chore(deploy): add pgAdmin to the dev stack
Runs alongside Postgres in the unified compose file at
http://localhost:5050, config via PGADMIN_* env vars.
2026-07-15 16:10:18 +02:00

164 lines
5.5 KiB
YAML

name: musify-dev
# Infrastructure stack for Musify development: everything the backend needs
# (Postgres, Zitadel, RabbitMQ, SeaweedFS + bucket, Jaeger/OTLP). The .NET apps
# run from the IDE and connect over the published ports. Config in deploy/.env
#
# docker compose -f deploy/docker-compose.yml up -d
services:
postgres:
image: postgres:17-alpine
container_name: musify-postgres
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
ports:
- "${POSTGRES_HOST_PORT}:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 10
restart: unless-stopped
pgadmin:
image: dpage/pgadmin4:latest
container_name: musify-pgadmin
environment:
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
PGADMIN_CONFIG_SERVER_MODE: "False"
depends_on:
postgres:
condition: service_healthy
ports:
- "${PGADMIN_HOST_PORT}:80"
volumes:
- pgadmin_data:/var/lib/pgadmin
restart: unless-stopped
zitadel:
image: ghcr.io/zitadel/zitadel:latest
container_name: musify-zitadel
command: 'start-from-init --masterkeyFromEnv --tlsMode disabled'
environment:
ZITADEL_MASTERKEY: ${ZITADEL_MASTERKEY}
ZITADEL_EXTERNALSECURE: "false"
ZITADEL_EXTERNALDOMAIN: ${ZITADEL_EXTERNAL_DOMAIN}
ZITADEL_EXTERNALPORT: ${ZITADEL_EXTERNAL_PORT}
ZITADEL_TLS_ENABLED: "false"
# Reuses the same Postgres: the admin user creates the 'zitadel' database
# and the 'zitadel' user on first start.
ZITADEL_DATABASE_POSTGRES_HOST: postgres
ZITADEL_DATABASE_POSTGRES_PORT: 5432
ZITADEL_DATABASE_POSTGRES_DATABASE: zitadel
ZITADEL_DATABASE_POSTGRES_USER_USERNAME: zitadel
ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: zitadel
ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE: disable
ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME: ${POSTGRES_USER}
ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD: ${POSTGRES_PASSWORD}
ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE: disable
# Initial console admin. Login: <user>@zitadel.<domain>
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_USERNAME: ${ZITADEL_ADMIN_USERNAME}
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD: ${ZITADEL_ADMIN_PASSWORD}
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORDCHANGEREQUIRED: "false"
# Service account + PAT for automatic provisioning. Zitadel writes the PAT
# to PATPATH on init; provision.ps1 uses it to create the project and app.
ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_USERNAME: zitadel-admin-sa
ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_NAME: Admin Service Account
ZITADEL_FIRSTINSTANCE_ORG_MACHINE_PAT_EXPIRATIONDATE: "2099-01-01T00:00:00Z"
ZITADEL_FIRSTINSTANCE_PATPATH: /output/admin-sa.pat
depends_on:
postgres:
condition: service_healthy
ports:
- "${ZITADEL_EXTERNAL_PORT}:8080"
volumes:
- ./zitadel/.output:/output
restart: unless-stopped
rabbitmq:
image: rabbitmq:4-management-alpine
container_name: musify-rabbitmq
environment:
RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER}
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS}
ports:
- "5672:5672" # AMQP -> MassTransit (API + Worker)
- "15672:15672" # management UI
volumes:
- rabbitmq_data:/var/lib/rabbitmq
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"]
interval: 10s
timeout: 5s
retries: 10
restart: unless-stopped
seaweedfs:
image: chrislusf/seaweedfs:latest
container_name: musify-seaweedfs
# All-in-one dev server: master + volume + filer + S3 gateway.
command: >
server
-ip.bind=0.0.0.0
-dir=/data
-master.volumeSizeLimitMB=1024
-volume.max=0
-filer
-s3
-s3.config=/etc/seaweedfs/s3.conf
ports:
- "9333:9333" # master (admin/UI)
- "8888:8888" # filer HTTP -> StreamingGateway
- "8333:8333" # S3 API -> WebApi/Worker (InfrastructureStorage:Address)
volumes:
- seaweedfs_data:/data
- ./seaweedfs/s3.conf:/etc/seaweedfs/s3.conf:ro
healthcheck:
test: ["CMD", "wget", "-q", "-O", "-", "http://localhost:9333/cluster/healthz"]
interval: 10s
timeout: 5s
retries: 10
restart: unless-stopped
# One-shot: creates the app bucket in SeaweedFS (it is not auto-created).
seaweedfs-init:
image: amazon/aws-cli:latest
container_name: musify-seaweedfs-init
depends_on:
seaweedfs:
condition: service_healthy
environment:
AWS_ACCESS_KEY_ID: ${S3_ACCESS_KEY}
AWS_SECRET_ACCESS_KEY: ${S3_SECRET_KEY}
AWS_DEFAULT_REGION: us-east-1
entrypoint: ["/bin/sh", "-c"]
command:
- |
aws --endpoint-url http://seaweedfs:8333 s3 mb s3://${S3_BUCKET} 2>/dev/null || true
aws --endpoint-url http://seaweedfs:8333 s3 ls
restart: "no"
# OTLP collector + trace UI (MassTransit/EF/HTTP spans). OtlpEndpoint = :4317
jaeger:
image: jaegertracing/all-in-one:latest
container_name: musify-jaeger
environment:
COLLECTOR_OTLP_ENABLED: "true"
ports:
- "16686:16686" # UI
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
restart: unless-stopped
volumes:
postgres_data:
pgadmin_data:
rabbitmq_data:
seaweedfs_data: