From e7471ff7e53aaf1e3f347ff82bb57a0a89171692 Mon Sep 17 00:00:00 2001 From: XShine555 Date: Mon, 20 Jul 2026 15:13:45 +0200 Subject: [PATCH] feat(deploy): template the nginx vhosts with the deployment domain ikerdemo.cat was hardcoded in six server blocks, so the stack could only be deployed under that one domain. The vhosts are now a template rendered by the nginx entrypoint from MUSIFY_ROOT_DOMAIN, with the envsubst filter set so it does not eat nginx's own variables. The repeated proxy headers move to a shared snippet, the web player vhost gets the upload body limit it was missing (audio is posted to its form actions), and the streaming vhost turns off proxy buffering so range requests stay responsive. --- deploy/nginx/conf.d/musify.conf | 120 ------------------- deploy/nginx/snippets/proxy.conf | 9 ++ deploy/nginx/templates/default.conf.template | 119 ++++++++++++++++++ 3 files changed, 128 insertions(+), 120 deletions(-) delete mode 100644 deploy/nginx/conf.d/musify.conf create mode 100644 deploy/nginx/snippets/proxy.conf create mode 100644 deploy/nginx/templates/default.conf.template diff --git a/deploy/nginx/conf.d/musify.conf b/deploy/nginx/conf.d/musify.conf deleted file mode 100644 index 7705764..0000000 --- a/deploy/nginx/conf.d/musify.conf +++ /dev/null @@ -1,120 +0,0 @@ -# Cloudflare (Full strict) terminates the public edge; this box only needs to -# trust the Cloudflare Origin Certificate. Each server block proxies to a -# container by its Docker Compose service name. -# -# proxy_pass targets use a variable + the embedded Docker DNS resolver so nginx -# re-resolves the service name on every request instead of caching the first -# container IP (which goes stale whenever a service is recreated/restarted). - -resolver 127.0.0.11 valid=10s; - -server { - listen 80; - server_name api.ikerdemo.cat stream.ikerdemo.cat auth.ikerdemo.cat s3.ikerdemo.cat ikerdemo.cat www.ikerdemo.cat; - return 301 https://$host$request_uri; -} - -server { - listen 443 ssl; - http2 on; - server_name api.ikerdemo.cat; - - ssl_certificate /etc/nginx/certs/origin.pem; - ssl_certificate_key /etc/nginx/certs/origin.key; - - location / { - set $upstream http://api:5111; - proxy_pass $upstream; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto https; - } -} - -server { - listen 443 ssl; - http2 on; - server_name stream.ikerdemo.cat; - - ssl_certificate /etc/nginx/certs/origin.pem; - ssl_certificate_key /etc/nginx/certs/origin.key; - - location / { - set $upstream http://gateway:8081; - proxy_pass $upstream; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto https; - } -} - -server { - listen 443 ssl; - http2 on; - server_name auth.ikerdemo.cat; - - ssl_certificate /etc/nginx/certs/origin.pem; - ssl_certificate_key /etc/nginx/certs/origin.key; - - location / { - set $upstream http://zitadel:8080; - proxy_pass $upstream; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto https; - proxy_set_header X-Forwarded-Host $host; - grpc_set_header Host $host; - } -} - -server { - listen 443 ssl; - http2 on; - server_name s3.ikerdemo.cat; - client_max_body_size 1024m; - - ssl_certificate /etc/nginx/certs/origin.pem; - ssl_certificate_key /etc/nginx/certs/origin.key; - - location / { - set $upstream http://seaweedfs:8333; - proxy_pass $upstream; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto https; - proxy_request_buffering off; - } -} - -server { - listen 443 ssl; - http2 on; - server_name www.ikerdemo.cat; - - ssl_certificate /etc/nginx/certs/origin.pem; - ssl_certificate_key /etc/nginx/certs/origin.key; - - return 301 https://ikerdemo.cat$request_uri; -} - -server { - listen 443 ssl; - http2 on; - server_name ikerdemo.cat; - - ssl_certificate /etc/nginx/certs/origin.pem; - ssl_certificate_key /etc/nginx/certs/origin.key; - - location / { - set $upstream http://web-player:3000; - proxy_pass $upstream; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto https; - } -} diff --git a/deploy/nginx/snippets/proxy.conf b/deploy/nginx/snippets/proxy.conf new file mode 100644 index 0000000..934e050 --- /dev/null +++ b/deploy/nginx/snippets/proxy.conf @@ -0,0 +1,9 @@ +# Shared proxy settings for every Musify vhost. +proxy_http_version 1.1; +proxy_set_header Host $host; +proxy_set_header X-Real-IP $remote_addr; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +proxy_set_header X-Forwarded-Proto https; +proxy_set_header X-Forwarded-Host $host; +proxy_set_header Upgrade $http_upgrade; +proxy_set_header Connection $connection_upgrade; diff --git a/deploy/nginx/templates/default.conf.template b/deploy/nginx/templates/default.conf.template new file mode 100644 index 0000000..ed2ac8a --- /dev/null +++ b/deploy/nginx/templates/default.conf.template @@ -0,0 +1,119 @@ +# Musify edge. The nginx entrypoint renders this with envsubst into +# /etc/nginx/conf.d/default.conf (replacing the image's stock file) using the +# MUSIFY_* variables set in compose.prod.yml. +# +# Cloudflare (Full strict) terminates the public edge; this box only needs to +# serve the Cloudflare Origin Certificate in nginx/certs/. Each vhost proxies to +# a compose service by name through the embedded Docker DNS resolver, so nginx +# re-resolves it instead of caching the IP of a container that may be recreated. + +resolver 127.0.0.11 valid=10s; + +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 80; + listen [::]:80; + server_name ${MUSIFY_ROOT_DOMAIN} www.${MUSIFY_ROOT_DOMAIN} + api.${MUSIFY_ROOT_DOMAIN} auth.${MUSIFY_ROOT_DOMAIN} + stream.${MUSIFY_ROOT_DOMAIN} s3.${MUSIFY_ROOT_DOMAIN}; + return 301 https://$host$request_uri; +} + +# Web player (SvelteKit, adapter-node). Uploads are posted to its own form +# actions, so it needs the large body size too. +server { + listen 443 ssl; + http2 on; + server_name ${MUSIFY_ROOT_DOMAIN}; + client_max_body_size ${MUSIFY_MAX_UPLOAD_SIZE}; + + ssl_certificate /etc/nginx/certs/origin.pem; + ssl_certificate_key /etc/nginx/certs/origin.key; + + location / { + set $upstream http://web-player:3000; + proxy_pass $upstream; + include /etc/nginx/snippets/proxy.conf; + } +} + +server { + listen 443 ssl; + http2 on; + server_name www.${MUSIFY_ROOT_DOMAIN}; + + ssl_certificate /etc/nginx/certs/origin.pem; + ssl_certificate_key /etc/nginx/certs/origin.key; + + return 301 https://${MUSIFY_ROOT_DOMAIN}$request_uri; +} + +server { + listen 443 ssl; + http2 on; + server_name api.${MUSIFY_ROOT_DOMAIN}; + + ssl_certificate /etc/nginx/certs/origin.pem; + ssl_certificate_key /etc/nginx/certs/origin.key; + + location / { + set $upstream http://api:5111; + proxy_pass $upstream; + include /etc/nginx/snippets/proxy.conf; + } +} + +# Audio bytes. Buffering off keeps range requests (seeking) responsive. +server { + listen 443 ssl; + http2 on; + server_name stream.${MUSIFY_ROOT_DOMAIN}; + + ssl_certificate /etc/nginx/certs/origin.pem; + ssl_certificate_key /etc/nginx/certs/origin.key; + + location / { + set $upstream http://gateway:8081; + proxy_pass $upstream; + include /etc/nginx/snippets/proxy.conf; + proxy_buffering off; + } +} + +server { + listen 443 ssl; + http2 on; + server_name auth.${MUSIFY_ROOT_DOMAIN}; + + ssl_certificate /etc/nginx/certs/origin.pem; + ssl_certificate_key /etc/nginx/certs/origin.key; + + location / { + set $upstream http://zitadel:8080; + proxy_pass $upstream; + include /etc/nginx/snippets/proxy.conf; + grpc_set_header Host $host; + } +} + +# Presigned S3 PUT/GET straight from the browser. +server { + listen 443 ssl; + http2 on; + server_name s3.${MUSIFY_ROOT_DOMAIN}; + client_max_body_size ${MUSIFY_MAX_UPLOAD_SIZE}; + + ssl_certificate /etc/nginx/certs/origin.pem; + ssl_certificate_key /etc/nginx/certs/origin.key; + + location / { + set $upstream http://seaweedfs:8333; + proxy_pass $upstream; + include /etc/nginx/snippets/proxy.conf; + proxy_request_buffering off; + } +}