I’m running Discourse behind Traefik in a custom setup - giving Discourse its own VM is not an option here.
My Discourse doesn’t have SSL/Let’sEncrypt templates enabled, since Traefik won’t let plain HTTP requests reach the container - it’s set to redirect HTTP requests to HTTPs.
I’m having issues setting up DiscourseConnect, because, since the Traefik -> nginx[Discourse] request is sent over plain-text HTTP (because nginx doesn’t have SSL set up), the rule in /etc/nginx/conf.d/discourse.conf that tries to preserve the proto, must be in http context makes Discourse (the Rails app) to receive a plain-text HTTP request, thus returning a plain-text HTTP redirect to /session/sso - even if I have force_https enabled.
I think that’s the bug: regardless of my setup, with force_https enabled, Discourse should always generate HTTPs URLs - which it’s not doing.
I think the offending code is application_controller#redirect_to_login, but I haven’t dug that much into Discourse source code to be sure.
Is this solvable in the code itself?
As a workaround, I’m trying to add a rule patching the nginx’s discourse.conf to remove that rule.
What was easiest for me was to set an extra label in Discourse’s app.yml to tell my Traefik to add an X-Forwarded-Proto: https header, but then nginx would override that parameter with it’s own version.
And Discourse’s nginx config plays a role here:
There Discourse tries to guess the protocol from the original request (which, in my setup, is always plain-text since that’s what Traefik sends). And then uses that to set the X-Forwarded-Proto multiple times.
In the end, I edited my containers/app.yml to hard-code those headers to https:
run:
- exec: echo "Beginning of custom commands"
## If you want to set the 'From' email address for your first registration, uncomment and change:
## After getting the first signup email, re-comment the line. It only needs to run once.
# - exec: rails r "SiteSetting.notification_email='no-reply@forum.cabana.network'"
- replace:
filename: "/etc/nginx/conf.d/discourse.conf"
from: /# attempt to preserve the proto, must be in http context\nmap \$http_x_forwarded_proto \$thescheme {\n default \$scheme;\n "~https\$" https;\n\}/
to: |
# force https scheme so Discourse generates HTTPs links and redirects (ie, `/login`)
- replace:
filename: "/etc/nginx/conf.d/discourse.conf"
from: "$thescheme"
global: "true"
to: "https"
- exec: echo "End of custom commands"
Once again, I think if there’s a force_https setting, Discourse-the-rails-app should honor it, regardless of what the reverse proxy or other parties handle or not.