# Production configuration for deploy/compose.yml + compose.prod.yml. # Copy to deploy/.env.prod, then: # # 1. replace every `example.com` with your domain, # 2. replace every CHANGE_ME with a strong random value # (`openssl rand -hex 24`; the Zitadel masterkey needs exactly 32 chars), # 3. point these DNS records at the server, all proxied/TLS-terminated the # same way: example.com, www, api, auth, stream, s3. # # Not versioned. Keep it readable only by the deploy user (chmod 600). DOTNET_ENVIRONMENT=Production # --- Domain ------------------------------------------------------------------ # ROOT_DOMAIN drives the nginx vhosts; the URLs below must agree with it. ROOT_DOMAIN=example.com PUBLIC_WEB_URL=https://example.com PUBLIC_API_URL=https://api.example.com PUBLIC_STREAM_URL=https://stream.example.com PUBLIC_AUTH_URL=https://auth.example.com S3_PUBLIC_URL=https://s3.example.com # --- PostgreSQL (shared by Musify and Zitadel) ------------------------------- POSTGRES_USER=postgres POSTGRES_PASSWORD=CHANGE_ME POSTGRES_DB=musify_db # --- Zitadel (OIDC) ---------------------------------------------------------- # The masterkey MUST be exactly 32 characters and can never be rotated in place. ZITADEL_MASTERKEY=CHANGE_ME_32_CHARACTERS_EXACTLY_ ZITADEL_EXTERNAL_DOMAIN=auth.example.com ZITADEL_EXTERNAL_PORT=443 ZITADEL_EXTERNAL_SECURE=true ZITADEL_DATABASE_PASSWORD=CHANGE_ME # Console login: @zitadel. ZITADEL_ADMIN_USERNAME=admin ZITADEL_ADMIN_PASSWORD=CHANGE_ME # Keep OIDC apps strict about https redirect URIs in production. ZITADEL_DEV_MODE=false # OIDC clients: the zitadel-init one-shot service (see compose.yml) fills # these in automatically on `docker compose up -d`. AUTH_CLIENT_ID= WEB_CLIENT_ID= WEB_CLIENT_SECRET= # --- RabbitMQ (MassTransit) -------------------------------------------------- RABBITMQ_DEFAULT_USER=musify RABBITMQ_DEFAULT_PASS=CHANGE_ME # --- SeaweedFS (S3) ---------------------------------------------------------- S3_ACCESS_KEY=CHANGE_ME S3_SECRET_KEY=CHANGE_ME S3_BUCKET=webapi-storage S3_USE_HTTP=false # --- Web player -------------------------------------------------------------- # Key material for the encrypted session cookie. Rotating it logs everyone out. SESSION_SECRET=CHANGE_ME AUTH_ALLOW_INSECURE_HTTP=false # --- Misc -------------------------------------------------------------------- AUTH_REQUIRE_HTTPS=true # Largest request body nginx accepts (audio uploads go through the web player). MAX_UPLOAD_SIZE=1024m # Disk nginx gives to the cached YouTube artwork it serves for the web player. THUMBNAIL_CACHE_SIZE=2g # Extra yt-dlp flags for the Worker. The cookie jar avoids YouTube's bot checks; # drop it here if you do not have one: deploy/secrets/ is mounted at /secrets. YTDLP_ADDITIONAL_ARGUMENTS=--cookies /secrets/youtube_cookies.txt --extractor-retries 1 --socket-timeout 15 -N 4