Files
Musify/docs/development.md
T
Admin c4f5e6754c feat(deploy): consolidated dev stack with auto-provisioned Zitadel
Single docker-compose stack for local development (Postgres, Zitadel,
RabbitMQ, SeaweedFS + bucket init, Jaeger) plus an optional overlay to run
the .NET apps in Docker. up.ps1 orchestrates the full bootstrap: stack up,
stream-ticket keys, EF Core migrations and Zitadel provisioning.

- Zitadel is provisioned automatically (service-account PAT -> project +
  OIDC app with JWT access token); the generated ClientId is wired into
  Musify.Api user-secrets and .env. No manual console steps.
- ZITADEL_EXTERNAL_DOMAIN=host.docker.internal so token validation works
  both with local apps and full-docker.
- App Dockerfiles copy AppSettings*.json to lowercase so config loads on
  case-sensitive Linux; Worker image ships ffmpeg.
- Scripts split by responsibility (common/stream-keys/migrate/provision);
  apps overlay de-duped via YAML anchors.
- Remove the superseded standalone seaweedfs compose; point docs/development
  at the unified stack.
2026-07-05 20:32:40 +02:00

3.5 KiB

Entorno de desarrollo

Cómo levantar todo en local y probarlo.

Dependencias (Docker)

Todo (PostgreSQL, Zitadel, RabbitMQ, SeaweedFS, Jaeger) vive en un solo stack en deploy/. Bootstrap completo (levanta + bucket + claves + migraciones):

./deploy/up.ps1

O solo la infraestructura:

docker compose -f deploy\docker-compose.yml up -d

Config (usuarios/claves/puertos) en deploy/.env. Ver deploy/README.md para el detalle y el paso de configuración de Zitadel (crear la app OIDC y copiar el ClientId).

Aplicaciones (.NET)

dotnet run --project Musify.WebApi\WebApi                    # :5111
dotnet run --project Musify.StreamingGateway\StreamingGateway # :8081
dotnet run --project Musify.Worker\Worker                     # background

Mapa de puertos

Servicio Puerto
WebApi 5111 (/scalar/v1, /openapi/v1.json)
StreamingGateway 8081 (/health, /media/...)
SeaweedFS S3 / filer / master 8333 / 8888 / 9333
Zitadel 8080
PostgreSQL 59000 (→ 5432 en el contenedor)
RabbitMQ AMQP / management 5672 / 15672
pgAdmin 5050

DB: musify_db, usuario postgres/postgres. Bucket S3: webapi-storage (credenciales admin_access_key/admin_secret_key).

Migraciones

No hay migración automática al arrancar. deploy/up.ps1 las aplica en el bootstrap; para hacerlo a mano tras cambios de esquema:

dotnet ef database update --project backend\Musify.Infrastructure --startup-project backend\Musify.Infrastructure --context Database

La cadena de conexión para dotnet ef se lee de DesignSettings.json / user-secrets del proyecto Infrastructure (up.ps1 la deja en user-secrets automáticamente).

Stream-tickets (claves RS256)

La WebApi firma los stream-tickets con una clave privada y el gateway valida con la pública:

openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out stream_private.pem
openssl rsa -in stream_private.pem -pubout -out stream_public.pem
  • WebApi: StreamTicket:PrivateKeyPath → stream_private.pem.
  • Gateway: StreamTicket:PublicKeyPath → stream_public.pem.

Consola de pruebas: player.html

Un único archivo HTML para probar todo sin front:

  1. Sírvelo o ábrelo directo (el CORS está abierto en Development).
  2. Pega tu access token de Zitadel y la API base (http://localhost:5111).
  3. Permite: crear/actualizar/eliminar playlists, listar canciones, añadir/quitar canciones de una playlist, ver las canciones de una playlist y reproducir (pide el ticket y abre el .m4a con ?t=<ticket>).

Nota: player.html todavía usa dash.js; tras el cambio a .m4a debe actualizarse para reproducir el fichero directo (elemento <audio> por HTTP range).

Para obtener un token: login OAuth2 en Scalar (/scalar/v1) o cópialo de DevTools.

Config (AppSettings)

Convención: AppSettings.json = plantilla con valores vacíos/por defecto; AppSettings.Development.json = valores reales de dev. Secretos sensibles (claves, connection strings) van idealmente en user-secrets.

Secciones clave: Authentication (Zitadel), Database, MassTransit, InfrastructureStorage (S3), ApplicationStorage (bucket), Track, PlayList, UploadIntent, AudioTranscoder, Workers, StreamGateway/StreamTicket.

Requisitos del host

  • .NET 10 SDK.
  • ffmpeg en el PATH (transcode de audio del Worker).
  • Docker Desktop.
  • Directorio temporal de trabajo del Worker (Workers:Routes:TemporaryFilesDirectory, p. ej. D:\tempsFilesDev).