Full site CDN acceleration for Discourse

Some additional notes for anyone who decides to use HTTPS together with Full site CDN acceleration

  1. Discourse internally uses the value of SiteSetting.force_https to decide if your access-control-allow-origin: is the HTTP or HTTPS version of your site. If while polling you see an error in the browser console along the lines of preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value http doesn't match https, double check your force_https setting. Also note the protocol in your DISCOURSE_CORS_ORIGIN in your container definition (http|https) will be overridden by force_https.
    Don’t forget to add DISCORSE_ENABLE_CORS: true in your container definition.

  2. If you were planning to only do HTTPS from your end users to your CDN, and then HTTP from your CDN to your actual Discourse web_only containers, lots of custom configuration will be required.

  3. If your CDN is serving your site on HTTPS, then whatever Long Polling URL you setup must also be on HTTPS, so even if the CDN is handling your HTTPS, you must still setup HTTPS on your Discourse servers. If you run into an error about Same-origin policy, double check that you’re not trying to connect to HTTP instead of HTTPS

    • If you use letsencrypt to generate your certificates, note that fullchain.pem => /shared/ssl/ssl.crt (ssl_certificate)
    • privkey.pem => /shared/ssl/ssl.key (ssl_certificate_key)
  4. You might use the following templates in your container definition:

  - "templates/web.template.yml"
  - "templates/web.ssl.template.yml"
  - "templates/fastly.template.yml"
  • Towards the end of the hook:ssl inside templates/web.ssl.template.yml you’ll see this block being added to your /etc/nginx/conf.d/discourse.conf.
if ($http_host != $$ENV_DISCOURSE_HOSTNAME) {
    rewrite (.*) https://$$ENV_DISCOURSE_HOSTNAME$1 permanent;
}
  • You’ll need to need to comment these lines out, otherwise you’re long polling attempts always serve up 301 redirects back to your origin, instead of respecting whatever you set in SiteSetting.long_polling_base_url
  1. The easiest way I’ve found to do this is to copy templates/web.ssl.template.yml to local.web.ssl.template.yml and just remove those extra lines, and update your container reference to use your local template. If you go that route, you should periodically diff your local version with the origional version, because there are some security improvements that are regularly incorporated into this template.

Some of the error messages you’ll run into until things are configured correctly.

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://polling.example.com/message-bus/37c91c51e6cd4b0c95288b8fc29a0480/poll. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

Reason: CORS header ‘Access-Control-Allow-Origin’ missing

Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource

Failed to load https://polling.example.com/message-bus/8caefcec2cf94de3ae684c4b953a1084/poll: Response for preflight is invalid (redirect)

4 Likes