From d5792cd93c3eb1a5be87bbfbffc07bf0441cadb5 Mon Sep 17 00:00:00 2001 From: Bianca Nenciu Date: Fri, 9 May 2025 13:50:08 +0300 Subject: [PATCH] Reapply "Use Nginx config with outlets (#913)" (#958) This reverts commit 3c2234830a71e7590a0eaa9b73da46fd2c09ea71. --- samples/standalone.yml | 2 - samples/web_only.yml | 2 - templates/offline-page.template.yml | 19 ++--- templates/sshd.template.yml | 4 + templates/web.ipv6.template.yml | 12 ++- templates/web.letsencrypt.ssl.template.yml | 22 ++---- templates/web.ratelimited.template.yml | 17 ++--- templates/web.socketed.template.yml | 8 +- templates/web.ssl.template.yml | 86 ++++++++++------------ templates/web.template.yml | 38 ++++++---- 10 files changed, 97 insertions(+), 113 deletions(-) diff --git a/samples/standalone.yml b/samples/standalone.yml index 3f43a62..99f9060 100644 --- a/samples/standalone.yml +++ b/samples/standalone.yml @@ -11,8 +11,6 @@ templates: - "templates/postgres.template.yml" - "templates/redis.template.yml" - "templates/web.template.yml" - ## Uncomment the next line to enable the IPv6 listener - #- "templates/web.ipv6.template.yml" - "templates/web.ratelimited.template.yml" ## Uncomment these two lines if you wish to add Lets Encrypt (https) #- "templates/web.ssl.template.yml" diff --git a/samples/web_only.yml b/samples/web_only.yml index c4753dd..d335c84 100644 --- a/samples/web_only.yml +++ b/samples/web_only.yml @@ -3,8 +3,6 @@ templates: - "templates/web.template.yml" - ## Uncomment the next line to enable the IPv6 listener - #- "templates/web.ipv6.template.yml" - "templates/web.ratelimited.template.yml" ## Uncomment these two lines if you wish to add Lets Encrypt (https) #- "templates/web.ssl.template.yml" diff --git a/templates/offline-page.template.yml b/templates/offline-page.template.yml index 9bcd772..7d03501 100644 --- a/templates/offline-page.template.yml +++ b/templates/offline-page.template.yml @@ -7,17 +7,14 @@ params: offline_page_repository: https://github.com/discourse/discourse-offline-page.git run: - - replace: - filename: "/etc/nginx/conf.d/discourse.conf" - global: true - from: /server.+{/ - to: | - server { - error_page 502 /error_page.html; - location /error_page.html { - root /var/www/discourse-offline-page/html; - internal; - } + - file: + path: "/etc/nginx/conf.d/outlets/server/30-offline-page.conf" + contents: | + error_page 502 /error_page.html; + location /error_page.html { + root /var/www/discourse-offline-page/html; + internal; + } - exec: cmd: git clone $offline_page_repository /var/www/discourse-offline-page diff --git a/templates/sshd.template.yml b/templates/sshd.template.yml index d9bf57c..b8f3f15 100644 --- a/templates/sshd.template.yml +++ b/templates/sshd.template.yml @@ -1,2 +1,6 @@ # This file is deprecated; you can remove it from your app.yml +# TODO(2026-01-01): Remove this file run: + - exec: |- + echo "Deprecation warning: sshd is no longer supported" + echo "Remove templates/sshd.template.yml from your containers/*.yml files" diff --git a/templates/web.ipv6.template.yml b/templates/web.ipv6.template.yml index bf589fe..c429fc3 100644 --- a/templates/web.ipv6.template.yml +++ b/templates/web.ipv6.template.yml @@ -1,8 +1,6 @@ +# This file is deprecated; you can remove it from your app.yml +# TODO(2026-01-01): Remove this file run: - - exec: echo "Enabling IPv6 listener" - - replace: - filename: "/etc/nginx/conf.d/discourse.conf" - from: listen 80; - to: | - listen 80; - listen [::]:80; + - exec: |- + echo "Deprecation warning: IPv6 is enabled by default when possible" + echo "Remove templates/web.ipv6.template.yml from your containers/*.yml files" diff --git a/templates/web.letsencrypt.ssl.template.yml b/templates/web.letsencrypt.ssl.template.yml index ba5f551..04412af 100644 --- a/templates/web.letsencrypt.ssl.template.yml +++ b/templates/web.letsencrypt.ssl.template.yml @@ -106,13 +106,6 @@ hooks: /usr/sbin/nginx -c /etc/nginx/letsencrypt.conf -s stop - - replace: - filename: "/etc/nginx/conf.d/discourse.conf" - from: /ssl_certificate.+/ - to: | - ssl_certificate /shared/ssl/$$ENV_DISCOURSE_HOSTNAME.cer; - ssl_certificate /shared/ssl/$$ENV_DISCOURSE_HOSTNAME_ecc.cer; - - replace: filename: /shared/letsencrypt/account.conf from: /#?ACCOUNT_EMAIL=.+/ @@ -120,14 +113,15 @@ hooks: ACCOUNT_EMAIL=$$ENV_LETSENCRYPT_ACCOUNT_EMAIL - replace: - filename: "/etc/nginx/conf.d/discourse.conf" + filename: "/etc/nginx/conf.d/outlets/server/20-https.conf" + from: /ssl_certificate.+/ + to: | + ssl_certificate /shared/ssl/$$ENV_DISCOURSE_HOSTNAME.cer; + ssl_certificate /shared/ssl/$$ENV_DISCOURSE_HOSTNAME_ecc.cer; + + - replace: + filename: "/etc/nginx/conf.d/outlets/server/20-https.conf" from: /ssl_certificate_key.+/ to: | ssl_certificate_key /shared/ssl/$$ENV_DISCOURSE_HOSTNAME.key; ssl_certificate_key /shared/ssl/$$ENV_DISCOURSE_HOSTNAME_ecc.key; - - - replace: - filename: "/etc/nginx/conf.d/discourse.conf" - from: /add_header.+/ - to: | - add_header Strict-Transport-Security 'max-age=63072000'; diff --git a/templates/web.ratelimited.template.yml b/templates/web.ratelimited.template.yml index ae9cd63..46bbd21 100644 --- a/templates/web.ratelimited.template.yml +++ b/templates/web.ratelimited.template.yml @@ -6,21 +6,18 @@ params: conn_per_ip: 20 run: - - replace: - filename: "/etc/nginx/conf.d/discourse.conf" - from: /server.+{/ - to: | + - file: + path: "/etc/nginx/conf.d/outlets/before-server/30-ratelimited.conf" + contents: | limit_req_zone $binary_remote_addr zone=flood:10m rate=$reqs_per_secondr/s; limit_req_zone $binary_remote_addr zone=bot:10m rate=$reqs_per_minuter/m; limit_req_status 429; limit_conn_zone $binary_remote_addr zone=connperip:10m; limit_conn_status 429; - server { - - replace: - filename: "/etc/nginx/conf.d/discourse.conf" - from: "/location @discourse {/" - to: | - location @discourse { + + - file: + path: "/etc/nginx/conf.d/outlets/discourse/30-ratelimited.conf" + contents: | limit_conn connperip $conn_per_ip; limit_req zone=flood burst=$burst_per_second nodelay; limit_req zone=bot burst=$burst_per_minute nodelay; diff --git a/templates/web.socketed.template.yml b/templates/web.socketed.template.yml index e6748ba..131c531 100644 --- a/templates/web.socketed.template.yml +++ b/templates/web.socketed.template.yml @@ -12,14 +12,14 @@ run: #!/bin/bash rm -rf /shared/nginx.http*.sock - replace: - filename: "/etc/nginx/conf.d/discourse.conf" - from: /listen 80;/ + filename: "/etc/nginx/conf.d/outlets/server/10-http.conf" + from: /listen 80;(\nlisten \[::\]:80;)?/ to: | listen unix:/shared/nginx.http.sock; set_real_ip_from unix:; - replace: - filename: "/etc/nginx/conf.d/discourse.conf" - from: /listen 443 ssl;/ + filename: "/etc/nginx/conf.d/outlets/server/20-https.conf" + from: /listen 443 ssl;(\nlisten \[::\]:443 ssl;)?/ to: | listen unix:/shared/nginx.https.sock ssl; set_real_ip_from unix:; diff --git a/templates/web.ssl.template.yml b/templates/web.ssl.template.yml index 06c3514..8c6e2ce 100644 --- a/templates/web.ssl.template.yml +++ b/templates/web.ssl.template.yml @@ -1,56 +1,46 @@ run: - exec: - cmd: - - "mkdir -p /shared/ssl/" - - replace: - filename: "/etc/nginx/conf.d/discourse.conf" - from: /listen 80;\s+listen \[::\]:80;/m - to: | - listen 443 ssl; - listen [::]:443 ssl; - http2 on; - SSL_TEMPLATE_SSL_BLOCK - - replace: - filename: "/etc/nginx/conf.d/discourse.conf" - from: /listen 80;/ - to: | - listen 443 ssl; - http2 on; - SSL_TEMPLATE_SSL_BLOCK - - replace: - hook: ssl - filename: "/etc/nginx/conf.d/discourse.conf" - from: /SSL_TEMPLATE_SSL_BLOCK/ - to: | + cmd: + - "mkdir -p /shared/ssl/" + - file: + path: "/etc/nginx/conf.d/outlets/before-server/10-redirect-http-to-https.conf" + contents: | + server { + listen 80; + return 301 https://$$ENV_DISCOURSE_HOSTNAME$request_uri; + } + - exec: rm /etc/nginx/conf.d/outlets/server/10-http.conf + - file: + hook: ssl + path: "/etc/nginx/conf.d/outlets/server/20-https.conf" + contents: | + listen 443 ssl; + http2 on; - ssl_protocols TLSv1.2 TLSv1.3; - ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; - ssl_prefer_server_ciphers off; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; + ssl_prefer_server_ciphers off; - ssl_certificate /shared/ssl/ssl.crt; - ssl_certificate_key /shared/ssl/ssl.key; + ssl_certificate /shared/ssl/ssl.crt; + ssl_certificate_key /shared/ssl/ssl.key; - ssl_session_tickets off; - ssl_session_timeout 1d; - ssl_session_cache shared:SSL:1m; + ssl_session_tickets off; + ssl_session_timeout 1d; + ssl_session_cache shared:SSL:1m; - add_header Strict-Transport-Security 'max-age=31536000'; # remember the certificate for a year and automatically connect to HTTPS for this domain + add_header Strict-Transport-Security 'max-age=31536000'; - if ($http_host != $$ENV_DISCOURSE_HOSTNAME) { + if ($http_host != $$ENV_DISCOURSE_HOSTNAME) { rewrite (.*) https://$$ENV_DISCOURSE_HOSTNAME$1 permanent; - } - - replace: - filename: "/etc/nginx/conf.d/discourse.conf" - from: "location @discourse {" - to: | - location @discourse { - add_header Strict-Transport-Security 'max-age=31536000'; # remember the certificate for a year and automatically connect to HTTPS for this domain - - replace: - filename: "/etc/nginx/conf.d/discourse.conf" - from: /server.+{/ - to: | - server { - listen 80; - return 301 https://$$ENV_DISCOURSE_HOSTNAME$request_uri; - } - server { + } + - file: + path: "/etc/nginx/conf.d/outlets/discourse/20-https.conf" + contents: | + add_header Strict-Transport-Security 'max-age=31536000'; + - exec: + cmd: + - |- + if [ -f "/proc/net/if_inet6" ] ; then + sed -i 's/listen 80;/listen 80;\nlisten [::]:80;/g' /etc/nginx/conf.d/outlets/before-server/10-redirect-http-to-https.conf + sed -i 's/listen 443 ssl;/listen 443 ssl;\nlisten [::]:443 ssl;/g' /etc/nginx/conf.d/outlets/server/20-https.conf + fi diff --git a/templates/web.template.yml b/templates/web.template.yml index 813a63f..0c913f3 100644 --- a/templates/web.template.yml +++ b/templates/web.template.yml @@ -135,6 +135,14 @@ run: - "cp $home/config/nginx.sample.conf /etc/nginx/conf.d/discourse.conf" - "rm /etc/nginx/sites-enabled/default" - "mkdir -p /var/nginx/cache" + - "mkdir -p /etc/nginx/conf.d/outlets/before-server" + - "mkdir -p /etc/nginx/conf.d/outlets/server" + - "mkdir -p /etc/nginx/conf.d/outlets/discourse" + + # Stop building the container if the Nginx outlets are missing + - "grep -q 'outlets/before-server' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'The \"before-server\" Nginx outlet is missing. This version of discourse_docker is not compatible with the chosen Discourse version.' ; exit 1 )" + - "grep -q 'outlets/server' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'The \"server\" Nginx outlet is missing. This version of discourse_docker is not compatible with the chosen Discourse version.' ; exit 1 )" + - "grep -q 'outlets/discourse' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'The \"discourse\" Nginx outlet is missing. This version of discourse_docker is not compatible with the chosen Discourse version.' ; exit 1 )" - replace: filename: /etc/nginx/nginx.conf @@ -142,26 +150,25 @@ run: to: daemon off; - replace: - filename: "/etc/nginx/conf.d/discourse.conf" - from: /upstream[^\}]+\}/m - to: "upstream discourse { - server 127.0.0.1:3000; - }" - - - replace: - filename: "/etc/nginx/conf.d/discourse.conf" - from: /server_name.+$/ - to: server_name _ ; + filename: "/etc/nginx/nginx.conf" + from: /worker_connections.+$/ + to: worker_connections $nginx_worker_connections; - replace: filename: "/etc/nginx/conf.d/discourse.conf" from: /client_max_body_size.+$/ - to: client_max_body_size $upload_size ; + to: client_max_body_size $upload_size; - - replace: - filename: "/etc/nginx/nginx.conf" - from: /worker_connections.+$/ - to: worker_connections $nginx_worker_connections ; + - exec: + cmd: + # Move `listen 80` to an outlet + - sed -i 's#listen 80;##g' /etc/nginx/conf.d/discourse.conf + - |- + if [ -f "/proc/net/if_inet6" ]; then + echo "listen 80;\nlisten [::]:80;" > /etc/nginx/conf.d/outlets/server/10-http.conf + else + echo "listen 80;" > /etc/nginx/conf.d/outlets/server/10-http.conf + fi - exec: cmd: echo "done configuring web" @@ -222,6 +229,7 @@ run: hook: assets_precompile cmd: - su discourse -c 'SKIP_EMBER_CLI_COMPILE=1 bundle exec rake themes:update assets:precompile' + - replace: tag: precompile filename: /etc/service/unicorn/run