There was a few flaws in the current implementation of nginx guix service type, for example the one described here: https://issues.guix.gnu.org/37388 There are other things, for example it's really hard or even impossible to implement some cases in a sane way: adding rtmp context and later extending it from other guix services and probably much more. In the report above created by Ludo, he mentioned an idea of using s-expressions for representing nginx configuration, like sxml for xml. I prototyped such implementation and even migrated my personal nginx instance to it. It works quite well and implementation of service type became really simple: https://git.sr.ht/~abcdw/rde/tree/e5bcfc0654/src/rde/system/services/web.scm#L43 It allows to generate configuration in much more programmatic way and have much less boilerplate. My real-world nginx configuration itself: https://git.sr.ht/~abcdw/trop.in/tree/4eb2e07d38/src/tropin/machines.scm#L24 which expands to: --8<---------------cut here---------------start------------->8--- user nginx nginx; pid /var/run/nginx/pid; load_module /gnu/store/19apmplkgpmnvn963cfydgjhhnvpf9fs-nginx-rtmp-module-1.2.2/etc/nginx/modules/ngx_rtmp_module.so; events { } http { server_tokens off; proxy_temp_path /var/run/nginx/proxy_temp; include /gnu/store/lavf43rgvvmi9a6hqi8f2lmmavipq0vd-nginx-1.23.3/share/nginx/conf/mime.types; server { listen 80; listen [::]:80; listen 443 ssl; listen [::]:443 ssl; ssl_certificate /srv/nginx/ssl/hundredrps.pem; ssl_certificate_key /srv/nginx/ssl/hundredrps.key; ssl_protocols TLSv1.2; server_name guix.trop.in guix.ygg.trop.in; location / { proxy_pass https://guix.gnu.org; proxy_set_header HOST guix.gnu.org; } } server { listen 80; listen [::]:80; listen 443 ssl; listen [::]:443 ssl; ssl_certificate /srv/nginx/ssl/hundredrps.pem; ssl_certificate_key /srv/nginx/ssl/hundredrps.key; ssl_protocols TLSv1.2; server_name ci.guix.trop.in ci.guix.ygg.trop.in; location / { proxy_pass https://ci.guix.gnu.org; proxy_set_header HOST ci.guix.gnu.org; } } server { listen 80; listen [::]:80; listen 443 ssl; listen [::]:443 ssl; ssl_certificate /srv/nginx/ssl/hundredrps.pem; ssl_certificate_key /srv/nginx/ssl/hundredrps.key; ssl_protocols TLSv1.2; server_name issues.guix.trop.in issues.guix.ygg.trop.in; location / { proxy_pass https://issues.guix.gnu.org; proxy_set_header HOST issues.guix.gnu.org; } } server { listen 80; listen [::]:80; listen 443 ssl; listen [::]:443 ssl; ssl_certificate /etc/letsencrypt/live/trop.in/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/trop.in/privkey.pem; ssl_protocols TLSv1.2; server_name trop.in *.trop.in; location /rde/meetups { return 302 https://meet.jit.si/rde-meetup; } location / { root /srv/nginx/trop.in; if ($request_uri ~ ^/(.*)\.html(\?|$)) { return 302 /$1; } try_files $uri $uri.html $uri/ =404; } } server { listen 80; listen [::]:80; server_name files.trop.in files.ygg.trop.in; root /srv/nginx/public; autoindex on; } } rtmp { server { listen 1935; chunk_size 4096; application live { live on; push rtmp://a.rtmp.youtube.com/live2/key1; push rtmp://diode.zone:1935/live/key2; record off; } } } --8<---------------cut here---------------end--------------->8--- The configuration structure and merge logic is visible in tests: https://git.sr.ht/~abcdw/rde/tree/e5bcfc0654/tests/rde/serializers/nginx-test.scm#L159 https://git.sr.ht/~abcdw/rde/tree/e5bcfc0654/src/rde/serializers/nginx.scm#L20 The merge logic have a few problems rn, which I highlighted in those xtests: https://git.sr.ht/~abcdw/rde/commit/e5bcfc0654 LMKWYT! -- Best regards, Andrew Tropin