diff --git a/changes/changelog.d/nginxtemplates.feature b/changes/changelog.d/nginxtemplates.feature
new file mode 100644
index 000000000..69755d4ed
--- /dev/null
+++ b/changes/changelog.d/nginxtemplates.feature
@@ -0,0 +1 @@
+Generate all nginx configurations from one template
diff --git a/deploy/docker.proxy.template b/deploy/docker.proxy.template
index a4b297f20..e208c5ef2 100644
--- a/deploy/docker.proxy.template
+++ b/deploy/docker.proxy.template
@@ -1,7 +1,8 @@
 upstream fw {
-    # depending on your setup, you may want to update this
     server ${FUNKWHALE_API_IP}:${FUNKWHALE_API_PORT};
 }
+
+# Required for websocket support.
 map $http_upgrade $connection_upgrade {
     default upgrade;
     ''      close;
@@ -10,15 +11,31 @@ map $http_upgrade $connection_upgrade {
 server {
     listen 80;
     listen [::]:80;
+    # update this to match your instance name
     server_name ${FUNKWHALE_HOSTNAME};
-    location / { return 301 https://$host$request_uri; }
+
+    # useful for Let's Encrypt
+    location /.well-known/acme-challenge/ {
+        allow all;
+    }
+
+    location / {
+        return 301 https://$host$request_uri;
+    }
 }
+
 server {
     listen      443 ssl http2;
     listen [::]:443 ssl http2;
+
     server_name ${FUNKWHALE_HOSTNAME};
 
     # TLS
+    # Feel free to use your own configuration for SSL here or simply remove the
+    # lines and move the configuration to the previous server block if you
+    # don't want to run funkwhale behind https (this is not recommended)
+    # have a look here for let's encrypt configuration:
+    # https://certbot.eff.org/all-instructions/#debian-9-stretch-nginx
     ssl_protocols TLSv1.2;
     ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
     ssl_prefer_server_ciphers on;
@@ -29,12 +46,10 @@ server {
     # HSTS
     add_header Strict-Transport-Security "max-age=31536000";
 
-    # Security related headers
 
-    # If you are using S3 to host your files, remember to add your S3 URL to the
-    # media-src and img-src headers (e.g. img-src 'self' https://<your-S3-URL> data:)
-
-    add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; object-src 'none'; media-src 'self' data:";
+    # General configs
+    client_max_body_size ${NGINX_MAX_BODY_SIZE};
+    charset utf-8;
 
     # compression settings
     gzip on;
@@ -42,7 +57,6 @@ server {
     gzip_min_length    256;
     gzip_proxied       any;
     gzip_vary          on;
-
     gzip_types
         application/javascript
         application/vnd.geo+json
@@ -61,10 +75,13 @@ server {
         text/vtt
         text/x-component
         text/x-cross-domain-policy;
+    # end of compression settings
+
+
 
     location / {
-        include /etc/nginx/funkwhale_proxy.conf;
-        client_max_body_size ${NGINX_MAX_BODY_SIZE};
-        proxy_pass   http://fw;
+        expires 1d;
+        proxy_pass http://fw
     }
+
 }
diff --git a/deploy/nginx.template b/deploy/nginx.template
index 5ba2ccfa1..d8ba11962 100644
--- a/deploy/nginx.template
+++ b/deploy/nginx.template
@@ -1,10 +1,15 @@
-# This file was generated from Funkwhale's nginx.template
 
 upstream funkwhale-api {
     # depending on your setup, you may want to update this
     server ${FUNKWHALE_API_IP}:${FUNKWHALE_API_PORT};
 }
 
+# Required for websocket support.
+map $http_upgrade $connection_upgrade {
+    default upgrade;
+    ''      close;
+}
+
 server {
     listen 80;
     listen [::]:80;
@@ -21,16 +26,10 @@ server {
     }
 }
 
-# Required for websocket support.
-map $http_upgrade $connection_upgrade {
-    default upgrade;
-    ''      close;
-}
-
 server {
     listen      443 ssl http2;
     listen [::]:443 ssl http2;
-    charset     utf-8;
+
     server_name ${FUNKWHALE_HOSTNAME};
 
     # TLS
@@ -49,12 +48,11 @@ server {
     # HSTS
     add_header Strict-Transport-Security "max-age=31536000";
 
-    add_header Content-Security-Policy "default-src 'self'; connect-src https: wss: http: ws: 'self' 'unsafe-eval'; script-src 'self' 'wasm-unsafe-eval'; style-src https: http: 'self' 'unsafe-inline'; img-src https: http: 'self' data:; font-src https: http: 'self' data:; media-src https: http: 'self' data:; object-src 'none'";
-    add_header Referrer-Policy "strict-origin-when-cross-origin";
-    add_header X-Frame-Options "SAMEORIGIN" always;
-    add_header Service-Worker-Allowed "/";
 
-    root ${FUNKWHALE_FRONTEND_PATH};
+    # General configs
+    root ${FUNKWHALE_FRONTEND_PATH},
+    client_max_body_size ${NGINX_MAX_BODY_SIZE};
+    charset utf-8;
 
     # compression settings
     gzip on;
@@ -62,7 +60,6 @@ server {
     gzip_min_length    256;
     gzip_proxied       any;
     gzip_vary          on;
-
     gzip_types
         application/javascript
         application/vnd.geo+json
@@ -83,6 +80,12 @@ server {
         text/x-cross-domain-policy;
     # end of compression settings
 
+    # headers
+    add_header Content-Security-Policy "default-src 'self'; connect-src https: wss: http: ws: 'self' 'unsafe-eval'; script-src 'self' 'wasm-unsafe-eval'; style-src https: http: 'self' 'unsafe-inline'; img-src https: http: 'self' data:; font-src https: http: 'self' data:; media-src https: http: 'self' data:; object-src 'none'";
+    add_header Referrer-Policy "strict-origin-when-cross-origin";
+    add_header X-Frame-Options "SAMEORIGIN" always;
+    add_header Service-Worker-Allowed "/";
+
     location /api/ {
         include /etc/nginx/funkwhale_proxy.conf;
         # This is needed if you have file import via upload enabled.
@@ -91,16 +94,16 @@ server {
     }
 
     location / {
-        alias ${FUNKWHALE_FRONTEND_PATH}/;
         expires 1d;
+        alias ${FUNKWHALE_FRONTEND_PATH}/,
         try_files $uri $uri/ /index.html;
     }
 
     location ~ "/(front/)?embed.html" {
+        alias ${FUNKWHALE_FRONTEND_PATH}/embed.html,
         add_header Content-Security-Policy "connect-src https: http: 'self'; default-src 'self'; script-src 'self' unpkg.com 'unsafe-inline' 'unsafe-eval'; style-src https: http: 'self' 'unsafe-inline'; img-src https: http: 'self' data:; font-src https: http: 'self' data:; object-src 'none'; media-src https: http: 'self' data:";
         add_header Referrer-Policy "strict-origin-when-cross-origin";
 
-        alias ${FUNKWHALE_FRONTEND_PATH}/embed.html;
         expires 1d;
     }
 
@@ -158,7 +161,7 @@ server {
         # has been checked on API side.
         # Set this to the same value as your MUSIC_DIRECTORY_PATH setting.
         internal;
-        alias   ${MUSIC_DIRECTORY_SERVE_PATH}/;
+        alias   ${MUSIC_DIRECTORY_PATH}/;
         add_header Access-Control-Allow-Origin '*';
     }
 
@@ -166,4 +169,5 @@ server {
         # If the reverse proxy is terminating SSL, nginx gets confused and redirects to http, hence the full URL
         return 302 ${FUNKWHALE_PROTOCOL}://${FUNKWHALE_HOSTNAME}/api/v1/instance/spa-manifest.json;
     }
+
 }
diff --git a/docker/nginx/conf.dev b/docker/nginx/conf.dev
index e4717bc2f..aecf2688d 100644
--- a/docker/nginx/conf.dev
+++ b/docker/nginx/conf.dev
@@ -1,6 +1,9 @@
+
 upstream funkwhale-api {
+    # depending on your setup, you may want to update this
     server ${FUNKWHALE_API_IP}:${FUNKWHALE_API_PORT};
 }
+
 upstream funkwhale-front {
     server ${FUNKWHALE_FRONT_IP}:${FUNKWHALE_FRONT_PORT};
 }
@@ -11,17 +14,18 @@ map $http_upgrade $connection_upgrade {
     ''      close;
 }
 
+
 server {
     listen      80;
     listen [::]:80;
-    charset     utf-8;
-    client_max_body_size ${NGINX_MAX_BODY_SIZE};
-    include /etc/nginx/funkwhale_proxy.conf;
 
-    add_header Content-Security-Policy "default-src 'self'; connect-src https: wss: http: ws: 'self' 'unsafe-eval'; script-src 'self' 'wasm-unsafe-eval'; style-src https: http: 'self' 'unsafe-inline'; img-src https: http: 'self' data:; font-src https: http: 'self' data:; media-src https: http: 'self' data:; object-src 'none'";
-    add_header Referrer-Policy "strict-origin-when-cross-origin";
-    add_header X-Frame-Options "SAMEORIGIN" always;
-    add_header Service-Worker-Allowed "/";
+    server_name _;
+
+
+    # General configs
+    root /usr/share/nginx/html;
+    client_max_body_size ${NGINX_MAX_BODY_SIZE};
+    charset utf-8;
 
     # compression settings
     gzip on;
@@ -29,7 +33,6 @@ server {
     gzip_min_length    256;
     gzip_proxied       any;
     gzip_vary          on;
-
     gzip_types
         application/javascript
         application/vnd.geo+json
@@ -50,6 +53,12 @@ server {
         text/x-cross-domain-policy;
     # end of compression settings
 
+    # headers
+    add_header Content-Security-Policy "default-src 'self'; connect-src https: wss: http: ws: 'self' 'unsafe-eval'; script-src 'self' 'wasm-unsafe-eval'; style-src https: http: 'self' 'unsafe-inline'; img-src https: http: 'self' data:; font-src https: http: 'self' data:; media-src https: http: 'self' data:; object-src 'none'";
+    add_header Referrer-Policy "strict-origin-when-cross-origin";
+    add_header X-Frame-Options "SAMEORIGIN" always;
+    add_header Service-Worker-Allowed "/";
+
     location /api/ {
         include /etc/nginx/funkwhale_proxy.conf;
         # This is needed if you have file import via upload enabled.
@@ -58,15 +67,15 @@ server {
     }
 
     location / {
-        proxy_pass   http://funkwhale-front;
         expires 1d;
+        proxy_pass http://funkwhale-front;
     }
 
     location = /embed.html {
+        proxy_pass http://funkwhale-front;
         add_header Content-Security-Policy "connect-src https: http: 'self'; default-src 'self'; script-src 'self' unpkg.com 'unsafe-inline' 'unsafe-eval'; style-src https: http: 'self' 'unsafe-inline'; img-src https: http: 'self' data:; font-src https: http: 'self' data:; object-src 'none'; media-src https: http: 'self' data:";
         add_header Referrer-Policy "strict-origin-when-cross-origin";
 
-        proxy_pass   http://funkwhale-front;
         expires 1d;
     }
 
@@ -81,14 +90,6 @@ server {
         proxy_pass   http://funkwhale-api/api/subsonic/rest/;
     }
 
-    location /media/__sized__/ {
-        alias /protected/media/__sized__/;
-    }
-
-    location /media/attachments/ {
-        alias /protected/media/attachments/;
-    }
-
     location /.well-known/ {
         include /etc/nginx/funkwhale_proxy.conf;
         proxy_pass   http://funkwhale-api;
@@ -96,13 +97,13 @@ server {
 
     # Allow direct access to only specific subdirectories in /media
     location /media/__sized__/ {
-        alias /protected/media/__sized__/;
+        alias ${MEDIA_ROOT}/__sized__/;
         add_header Access-Control-Allow-Origin '*';
     }
 
     # Allow direct access to only specific subdirectories in /media
     location /media/attachments/ {
-        alias /protected/media/attachments/;
+        alias ${MEDIA_ROOT}/attachments/;
         add_header Access-Control-Allow-Origin '*';
     }
 
@@ -119,10 +120,10 @@ server {
     # if you're storing media files in a S3 bucket.
     location ~ /_protected/media/(.+) {
         internal;
-        alias   /protected/media/$1;                                        # NON-S3
+        alias   ${MEDIA_ROOT}/$1;                                           # NON-S3
         # Needed to ensure DSub auth isn't forwarded to S3/Minio, see #932.
-#           proxy_set_header Authorization "";                                  # S3
-#           proxy_pass $1;                                                      # S3
+#       proxy_set_header Authorization "";                                  # S3
+#       proxy_pass $1;                                                      # S3
         add_header Access-Control-Allow-Origin '*';
     }
 
@@ -132,7 +133,7 @@ server {
         # has been checked on API side.
         # Set this to the same value as your MUSIC_DIRECTORY_PATH setting.
         internal;
-        alias   /music/;
+        alias   ${MUSIC_DIRECTORY_PATH}/;
         add_header Access-Control-Allow-Origin '*';
     }
 
@@ -142,7 +143,6 @@ server {
     }
 
     location /staticfiles/ {
-        alias /staticfiles/;
+        alias /usr/share/nginx/html/staticfiles/;
     }
-
 }
diff --git a/front/docker/funkwhale.conf.template b/front/docker/funkwhale.conf.template
index af2fac74d..abbf636d5 100644
--- a/front/docker/funkwhale.conf.template
+++ b/front/docker/funkwhale.conf.template
@@ -1,5 +1,7 @@
+
 upstream funkwhale-api {
-    server ${FUNKWHALE_API_HOST}:${FUNKWHALE_API_PORT};
+    # depending on your setup, you may want to update this
+    server ${FUNKWHALE_API_IP}:${FUNKWHALE_API_PORT};
 }
 
 # Required for websocket support.
@@ -8,18 +10,18 @@ map $http_upgrade $connection_upgrade {
     ''      close;
 }
 
+
 server {
     listen      80;
     listen [::]:80;
-    charset     utf-8;
+
     server_name _;
 
-    add_header Content-Security-Policy "default-src 'self'; connect-src https: wss: http: ws: 'self' 'unsafe-eval'; script-src 'self' 'wasm-unsafe-eval'; style-src https: http: 'self' 'unsafe-inline'; img-src https: http: 'self' data:; font-src https: http: 'self' data:; media-src https: http: 'self' data:; object-src 'none'";
-    add_header Referrer-Policy "strict-origin-when-cross-origin";
-    add_header X-Frame-Options "SAMEORIGIN" always;
-    add_header Service-Worker-Allowed "/";
 
+    # General configs
     root /usr/share/nginx/html;
+    client_max_body_size ${NGINX_MAX_BODY_SIZE};
+    charset utf-8;
 
     # compression settings
     gzip on;
@@ -27,7 +29,6 @@ server {
     gzip_min_length    256;
     gzip_proxied       any;
     gzip_vary          on;
-
     gzip_types
         application/javascript
         application/vnd.geo+json
@@ -48,6 +49,12 @@ server {
         text/x-cross-domain-policy;
     # end of compression settings
 
+    # headers
+    add_header Content-Security-Policy "default-src 'self'; connect-src https: wss: http: ws: 'self' 'unsafe-eval'; script-src 'self' 'wasm-unsafe-eval'; style-src https: http: 'self' 'unsafe-inline'; img-src https: http: 'self' data:; font-src https: http: 'self' data:; media-src https: http: 'self' data:; object-src 'none'";
+    add_header Referrer-Policy "strict-origin-when-cross-origin";
+    add_header X-Frame-Options "SAMEORIGIN" always;
+    add_header Service-Worker-Allowed "/";
+
     location /api/ {
         include /etc/nginx/funkwhale_proxy.conf;
         # This is needed if you have file import via upload enabled.
@@ -56,16 +63,16 @@ server {
     }
 
     location / {
-        alias /usr/share/nginx/html/;
         expires 1d;
+        alias /usr/share/nginx/html/;
         try_files $uri $uri/ /index.html;
     }
 
     location ~ "/(front/)?embed.html" {
+        alias /usr/share/nginx/html/embed.html;
         add_header Content-Security-Policy "connect-src https: http: 'self'; default-src 'self'; script-src 'self' unpkg.com 'unsafe-inline' 'unsafe-eval'; style-src https: http: 'self' 'unsafe-inline'; img-src https: http: 'self' data:; font-src https: http: 'self' data:; object-src 'none'; media-src https: http: 'self' data:";
         add_header Referrer-Policy "strict-origin-when-cross-origin";
 
-        alias /usr/share/nginx/html/embed.html;
         expires 1d;
     }
 
@@ -131,4 +138,5 @@ server {
         # If the reverse proxy is terminating SSL, nginx gets confused and redirects to http, hence the full URL
         return 302 ${FUNKWHALE_PROTOCOL}://${FUNKWHALE_HOSTNAME}/api/v1/instance/spa-manifest.json;
     }
+
 }
diff --git a/scripts/compile-templates.py b/scripts/compile-templates.py
new file mode 100644
index 000000000..596e7bb70
--- /dev/null
+++ b/scripts/compile-templates.py
@@ -0,0 +1,38 @@
+from jinja2 import Environment, FileSystemLoader
+
+file_loader = FileSystemLoader("templates")
+env = Environment(
+    loader=file_loader, trim_blocks=True, lstrip_blocks=True, keep_trailing_newline=True
+)
+
+files = [
+    {
+        "output": "docker/nginx/conf.dev",
+        "config": {"proxy_frontend": True, "inside_docker": True},
+    },
+    {
+        "output": "front/docker/funkwhale.conf.template",
+        "config": {"proxy_frontend": False, "inside_docker": True},
+    },
+    {
+        "output": "deploy/nginx.template",
+        "config": {"proxy_frontend": False, "inside_docker": False},
+    },
+    {
+        "output": "deploy/docker.proxy.template",
+        "config": {
+            "proxy_frontend": False,
+            "inside_docker": False,
+            "reverse_proxy": True,
+        },
+    },
+]
+
+template = env.get_template("nginx.conf.j2")
+for f in files:
+    print(f["output"])
+    output = template.render(config=f["config"])
+
+    output_file = open(f["output"], "w")
+    output_file.write(output)
+    output_file.close()
diff --git a/templates/nginx.conf.j2 b/templates/nginx.conf.j2
new file mode 100644
index 000000000..8b88ced42
--- /dev/null
+++ b/templates/nginx.conf.j2
@@ -0,0 +1,231 @@
+{% if config.reverse_proxy %}
+upstream fw {
+    server ${FUNKWHALE_API_IP}:${FUNKWHALE_API_PORT};
+}
+{% else %}
+
+upstream funkwhale-api {
+    # depending on your setup, you may want to update this
+    server ${FUNKWHALE_API_IP}:${FUNKWHALE_API_PORT};
+}
+{% endif %}
+{% if config.proxy_frontend %}
+
+upstream funkwhale-front {
+    server ${FUNKWHALE_FRONT_IP}:${FUNKWHALE_FRONT_PORT};
+}
+{% endif %}
+
+# Required for websocket support.
+map $http_upgrade $connection_upgrade {
+    default upgrade;
+    ''      close;
+}
+
+{% if not config.inside_docker %}
+server {
+    listen 80;
+    listen [::]:80;
+    # update this to match your instance name
+    server_name ${FUNKWHALE_HOSTNAME};
+
+    # useful for Let's Encrypt
+    location /.well-known/acme-challenge/ {
+        allow all;
+    }
+
+    location / {
+        return 301 https://$host$request_uri;
+    }
+}
+{% endif %}
+
+server {
+{% if not config.inside_docker %}
+    listen      443 ssl http2;
+    listen [::]:443 ssl http2;
+
+    server_name ${FUNKWHALE_HOSTNAME};
+
+    # TLS
+    # Feel free to use your own configuration for SSL here or simply remove the
+    # lines and move the configuration to the previous server block if you
+    # don't want to run funkwhale behind https (this is not recommended)
+    # have a look here for let's encrypt configuration:
+    # https://certbot.eff.org/all-instructions/#debian-9-stretch-nginx
+    ssl_protocols TLSv1.2;
+    ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
+    ssl_prefer_server_ciphers on;
+    ssl_session_cache shared:SSL:10m;
+    ssl_certificate     /etc/letsencrypt/live/${FUNKWHALE_HOSTNAME}/fullchain.pem;
+    ssl_certificate_key /etc/letsencrypt/live/${FUNKWHALE_HOSTNAME}/privkey.pem;
+
+    # HSTS
+    add_header Strict-Transport-Security "max-age=31536000";
+
+{% else %}
+    listen      80;
+    listen [::]:80;
+
+    server_name _;
+
+{% endif %}
+
+    # General configs
+{% if not config.reverse_proxy %}
+{% if config.inside_docker %}
+    root /usr/share/nginx/html;
+{% else %}
+    root ${FUNKWHALE_FRONTEND_PATH},
+{% endif %}
+{% endif %}
+    client_max_body_size ${NGINX_MAX_BODY_SIZE};
+    charset utf-8;
+
+    # compression settings
+    gzip on;
+    gzip_comp_level    5;
+    gzip_min_length    256;
+    gzip_proxied       any;
+    gzip_vary          on;
+    gzip_types
+        application/javascript
+        application/vnd.geo+json
+        application/vnd.ms-fontobject
+        application/x-font-ttf
+        application/x-web-app-manifest+json
+        font/opentype
+        image/bmp
+        image/svg+xml
+        image/x-icon
+        text/cache-manifest
+        text/css
+        text/plain
+        text/vcard
+        text/vnd.rim.location.xloc
+        text/vtt
+        text/x-component
+        text/x-cross-domain-policy;
+    # end of compression settings
+
+{% if not config.reverse_proxy %}
+    # headers
+    add_header Content-Security-Policy "default-src 'self'; connect-src https: wss: http: ws: 'self' 'unsafe-eval'; script-src 'self' 'wasm-unsafe-eval'; style-src https: http: 'self' 'unsafe-inline'; img-src https: http: 'self' data:; font-src https: http: 'self' data:; media-src https: http: 'self' data:; object-src 'none'";
+    add_header Referrer-Policy "strict-origin-when-cross-origin";
+    add_header X-Frame-Options "SAMEORIGIN" always;
+    add_header Service-Worker-Allowed "/";
+{% endif %}
+
+{% if not config.reverse_proxy %}
+    location /api/ {
+        include /etc/nginx/funkwhale_proxy.conf;
+        # This is needed if you have file import via upload enabled.
+        client_max_body_size ${NGINX_MAX_BODY_SIZE};
+        proxy_pass   http://funkwhale-api;
+    }
+{% endif %}
+
+    location / {
+        expires 1d;
+{% if config.proxy_frontend and not config.reverse_proxy %}
+        proxy_pass http://funkwhale-front;
+{% elif not config.proxy_frontend and config.reverse_proxy %}
+        proxy_pass http://fw
+{% else %}
+{% if config.inside_docker %}
+        alias /usr/share/nginx/html/;
+{% else %}
+        alias ${FUNKWHALE_FRONTEND_PATH}/,
+{% endif %}
+        try_files $uri $uri/ /index.html;
+{% endif %}
+    }
+
+{% if not config.reverse_proxy %}
+{% if config.proxy_frontend %}
+    location = /embed.html {
+        proxy_pass http://funkwhale-front;
+{% else %}
+    location ~ "/(front/)?embed.html" {
+{% if config.inside_docker %}
+        alias /usr/share/nginx/html/embed.html;
+{% else %}
+        alias ${FUNKWHALE_FRONTEND_PATH}/embed.html,
+{% endif %}
+{% endif %}
+        add_header Content-Security-Policy "connect-src https: http: 'self'; default-src 'self'; script-src 'self' unpkg.com 'unsafe-inline' 'unsafe-eval'; style-src https: http: 'self' 'unsafe-inline'; img-src https: http: 'self' data:; font-src https: http: 'self' data:; object-src 'none'; media-src https: http: 'self' data:";
+        add_header Referrer-Policy "strict-origin-when-cross-origin";
+
+        expires 1d;
+    }
+
+    location /federation/ {
+        include /etc/nginx/funkwhale_proxy.conf;
+        proxy_pass   http://funkwhale-api;
+    }
+
+    # You can comment this if you do not plan to use the Subsonic API.
+    location /rest/ {
+        include /etc/nginx/funkwhale_proxy.conf;
+        proxy_pass   http://funkwhale-api/api/subsonic/rest/;
+    }
+
+    location /.well-known/ {
+        include /etc/nginx/funkwhale_proxy.conf;
+        proxy_pass   http://funkwhale-api;
+    }
+
+    # Allow direct access to only specific subdirectories in /media
+    location /media/__sized__/ {
+        alias ${MEDIA_ROOT}/__sized__/;
+        add_header Access-Control-Allow-Origin '*';
+    }
+
+    # Allow direct access to only specific subdirectories in /media
+    location /media/attachments/ {
+        alias ${MEDIA_ROOT}/attachments/;
+        add_header Access-Control-Allow-Origin '*';
+    }
+
+    # Allow direct access to only specific subdirectories in /media
+    location /media/dynamic_preferences/ {
+        alias ${MEDIA_ROOT}/dynamic_preferences/;
+        add_header Access-Control-Allow-Origin '*';
+    }
+
+    # This is an internal location that is used to serve
+    # media (uploaded) files once correct permission / authentication
+    # has been checked on API side.
+    # Comment the "NON-S3" commented lines and uncomment "S3" commented lines
+    # if you're storing media files in a S3 bucket.
+    location ~ /_protected/media/(.+) {
+        internal;
+        alias   ${MEDIA_ROOT}/$1;                                           # NON-S3
+        # Needed to ensure DSub auth isn't forwarded to S3/Minio, see #932.
+#       proxy_set_header Authorization "";                                  # S3
+#       proxy_pass $1;                                                      # S3
+        add_header Access-Control-Allow-Origin '*';
+    }
+
+    location /_protected/music/ {
+        # This is an internal location that is used to serve
+        # local music files once correct permission / authentication
+        # has been checked on API side.
+        # Set this to the same value as your MUSIC_DIRECTORY_PATH setting.
+        internal;
+        alias   ${MUSIC_DIRECTORY_PATH}/;
+        add_header Access-Control-Allow-Origin '*';
+    }
+
+    location /manifest.json {
+        # If the reverse proxy is terminating SSL, nginx gets confused and redirects to http, hence the full URL
+        return 302 ${FUNKWHALE_PROTOCOL}://${FUNKWHALE_HOSTNAME}/api/v1/instance/spa-manifest.json;
+    }
+
+{% if config.proxy_frontend %}
+    location /staticfiles/ {
+        alias /usr/share/nginx/html/staticfiles/;
+    }
+{% endif %}
+{% endif %}
+}