Removes every wrapper script under deploy/ (up.ps1, up.sh, scripts/*,
zitadel/provision.*) and folds their logic into three one-shot services
in compose.yml, following the pattern already used by seaweedfs-init:
keys-init generates the RS256 stream-ticket key pair
migrate applies the EF Core migrations (backend/Musify.Migrator.Dockerfile)
zitadel-init creates the Musify project + OIDC apps, writes the client
ids back into the active env file
Deploying is now two plain `docker compose` commands, no scripts to run
or chmod:
docker compose -f deploy/compose.yml -f deploy/compose.dev.yml up -d
docker compose -f deploy/compose.yml -f deploy/compose.dev.yml --profile apps up -d --build
(swap compose.dev.yml for compose.prod.yml + --env-file deploy/.env.prod
for production). The first command brings up infra and lets the bootstrap
jobs run to completion; the second builds and starts the apps, which by
then read real OIDC values instead of empty ones — compose interpolates
${VAR} once per invocation, so this can't collapse into a single command
without the apps reading their own config file at container start instead
of via compose env (out of scope here).
Also:
- DatabaseDesignTimeFactory now also reads Database__ConnectionString
from the environment, and DesignSettings.json is optional, so the new
migrate container works without user-secrets or a config file excluded
from the Docker build context by .dockerignore.
- nginx's depends_on no longer lists the apps-profile services: it does
not need them at its own startup (every vhost resolves its upstream at
request time via the embedded Docker resolver), and requiring them made
`compose.prod.yml up -d` (without --profile apps) an invalid project.
- env_get/env_set in zitadel-init strip \r: the mounted env file can have
CRLF line endings on Windows, which otherwise makes an empty-looking
value non-empty to `[ -z ... ]`. .env.example/.env.prod.example are
pinned to LF via .gitattributes for the same reason. Also fixed:
rewriting the bind-mounted env file in place instead of renaming a temp
file over it (rename onto a bind-mounted inode fails with "Resource
busy").
- Removed compose.share.yml and zitadel/.output-share/ — a "temporary"
personal overlay that had leaked a real Zitadel service-account PAT
into git history (committed in 70968b3). That token should be rotated.
- Removed deploy/.tmp/ from .gitignore: nothing mounts or creates it
anymore (it never actually did, either — no compose service referenced
it, only the now-removed up.ps1 did).
Verified end-to-end with Docker: a clean `down -v` + fresh `up -d` +
`--profile apps up -d --build` on the dev stack brings up all four one-shot
jobs successfully and all four apps healthy (api/gateway return 200,
worker starts its consumers with no errors, web-player responds). Also
verified compose.prod.yml starts nginx cleanly with dummy certs and no
apps running, confirming the depends_on fix.
86 lines
2.2 KiB
YAML
86 lines
2.2 KiB
YAML
name: musify-dev
|
|
|
|
# Development overlay: publishes the infrastructure ports to the host so the
|
|
# .NET apps and the web player can run from the IDE, and adds pgAdmin.
|
|
#
|
|
# docker compose -f deploy/compose.yml -f deploy/compose.dev.yml up -d
|
|
# docker compose -f deploy/compose.yml -f deploy/compose.dev.yml --profile apps up -d --build
|
|
#
|
|
# `host.docker.internal` (see ZITADEL_EXTERNAL_DOMAIN / *_PUBLIC_URL in .env)
|
|
# resolves to the same address from the browser, from apps on the host and from
|
|
# inside the containers, so the OIDC issuer and the presigned S3 URLs are valid
|
|
# in both modes. `extra_hosts` gives Linux containers that same name.
|
|
|
|
x-host-alias: &host-alias
|
|
- "${ZITADEL_EXTERNAL_DOMAIN}:host-gateway"
|
|
|
|
services:
|
|
postgres:
|
|
ports:
|
|
- "${POSTGRES_HOST_PORT}:5432"
|
|
|
|
zitadel:
|
|
ports:
|
|
- "${ZITADEL_EXTERNAL_PORT}:8080"
|
|
|
|
rabbitmq:
|
|
ports:
|
|
- "5672:5672" # AMQP -> MassTransit
|
|
- "15672:15672" # management UI
|
|
|
|
seaweedfs:
|
|
ports:
|
|
- "9333:9333" # master / admin UI
|
|
- "8888:8888" # filer -> StreamingGateway
|
|
- "8333:8333" # S3 API -> API, Worker and presigned uploads
|
|
|
|
jaeger:
|
|
ports:
|
|
- "16686:16686" # UI
|
|
- "4317:4317" # OTLP gRPC
|
|
- "4318:4318" # OTLP HTTP
|
|
|
|
# zitadel-init (compose.yml) edits whichever env file is mounted here.
|
|
zitadel-init:
|
|
volumes:
|
|
- ./.env:/workspace/.env
|
|
|
|
# Optional Postgres UI: docker compose ... --profile tools up -d
|
|
pgadmin:
|
|
profiles: [tools]
|
|
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
|
|
|
|
api:
|
|
ports:
|
|
- "5111:5111"
|
|
extra_hosts: *host-alias
|
|
|
|
worker:
|
|
extra_hosts: *host-alias
|
|
|
|
gateway:
|
|
ports:
|
|
- "8081:8081"
|
|
extra_hosts: *host-alias
|
|
|
|
web-player:
|
|
ports:
|
|
- "3000:3000"
|
|
extra_hosts: *host-alias
|
|
|
|
volumes:
|
|
pgadmin_data:
|