Following is what the Nginx config (/etc/nginx/conf.d/discourse.conf) in the container contains, there was no reference to outlets/before-server:
# Additional MIME types that you'd like nginx to handle go in here
types {
text/csv csv;
}
upstream discourse { server 127.0.0.1:3000; }
proxy_cache_path /var/nginx/cache keys_zone=one:10m max_size=200m;
# see: https://meta.discourse.org/t/x/74060
proxy_buffer_size 8k;
# If you are going to use Puma, use these:
#
# upstream discourse {
# server unix:/var/www/discourse/tmp/sockets/puma.sock;
# }
# attempt to preserve the proto, must be in http context
map $http_x_forwarded_proto $thescheme {
default $scheme;
https https;
}
log_format log_discourse '[$time_local] "$http_host" $remote_addr "$request" "$http_user_agent" "$sent_http_x_discourse_route" $status $bytes_sent "$http_referer" $upstream_response_time $request_time "$sent_http_x_discourse_username"';
limit_req_zone $binary_remote_addr zone=flood:10m rate=12r/s;
limit_req_zone $binary_remote_addr zone=bot:10m rate=200r/m;
limit_req_status 429;
limit_conn_zone $binary_remote_addr zone=connperip:10m;
limit_conn_status 429;
server {
listen 80;
return 301 https://discourse.example.org$request_uri;
}
server {
access_log /var/log/nginx/access.log log_discourse;
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_certificate /shared/ssl/discourse.example.org.cer;
ssl_certificate /shared/ssl/discourse.example.org_ecc.cer;
ssl_certificate_key /shared/ssl/discourse.example.org.key;
proxy_ignore_headers "Set-Cookie";
proxy_hide_header "Set-Cookie";
proxy_cache one;
proxy_cache_key $uri;
proxy_cache_valid 200 7d;
proxy_cache_valid 404 1m;
proxy_set_header Connection "";
proxy_pass https://avatars.discourse.org/;
break;
}
# we need buffering off for message bus
location /message-bus/ {
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header Host $http_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 $thescheme;
proxy_http_version 1.1;
proxy_buffering off;
proxy_pass http://discourse;
break;
}
# this means every file in public is tried first
try_files $uri @discourse;
}
location /downloads/ {
internal;
alias $public/;
}
location @discourse {
add_header Strict-Transport-Security 'max-age=31536000'; # remember the certificate for a year and automatically connect to HTTPS for this domain
limit_conn connperip 20;
limit_req zone=flood burst=12 nodelay;
limit_req zone=bot burst=100 nodelay;
add_header Referrer-Policy 'no-referrer-when-downgrade';
proxy_set_header Host $http_host;
proxy_set_header X-Request-Start "t=${msec}";
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 $thescheme;
proxy_pass http://discourse;
}
}
So I installed vim and dos2unix and edited the files to add the line:
include conf.d/outlets/before-server/*.conf;
And I stopped and started Nginx and then exited the container and ran ./launcher rebuild app again but the same error was returned:
FAILED
--------------------
Pups::ExecError: 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 ) failed with return #<Process::Status: pid 300 exit 1>
Location of failure: /usr/local/lib/ruby/gems/3.3.0/gems/pups-1.3.0/lib/pups/exec_command.rb:131:in `spawn'
exec failed with the params {"cmd"=>["cp $home/config/nginx.sample.conf /etc/nginx/conf.d/discourse.conf", "rm /etc/nginx/sites-enabled/default", "mkdir -p /var/nginx/cache", "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 )", "mkdir -p /etc/nginx/conf.d/outlets/before-server", "touch /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf", "touch /etc/nginx/conf.d/outlets/before-server/30-ratelimited.conf", "mkdir -p /etc/nginx/conf.d/outlets/server", "touch /etc/nginx/conf.d/outlets/server/10-http.conf", "touch /etc/nginx/conf.d/outlets/server/20-https.conf", "touch /etc/nginx/conf.d/outlets/server/30-offline-page.conf", "mkdir -p /etc/nginx/conf.d/outlets/discourse", "touch /etc/nginx/conf.d/outlets/discourse/20-https.conf", "touch /etc/nginx/conf.d/outlets/discourse/30-ratelimited.conf"]}
bootstrap failed with exit code 1
** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one.
./discourse-doctor may help diagnose the problem.
b18ed0cbde3a34dfe76ea066657ece16c5a063ff18627d4a7e4b9787268917c0
So I restarted the container (./launcher start app) to check it:
grep -q 'outlets/before-server' /etc/nginx/conf.d/discourse.conf
echo $?
0
So I don’t understand why it is failing when the Nginx include is present?
There are a lot of differences between /var/www/discourse/config/nginx.sample.conf and /etc/nginx/conf.d/discourse.conf — should I try replacing the file with the sample and editing it to update the domain name?
Update
Earlier the Discourse web interface wouldn’t allow updates, it said updates must be done using the CLI, however now it does allow them (why is that?) so I have updated discourse_docker using the Web UI:
And also discourse:
So this issue is resolved however what, if anything, I did to solve it is a mystery… ![]()


