How to password protect staging environment?

As Discourse is not using Apache how to password protect e.g. a staging environment (Digital Ocean droplet with Discourse docker) as you would do with .htaccess (Apache)?

There is no apache, but NGINX is running inside the Discourse container. This topic may help:


Perfect, thanks @david :innocent:

1 Like

Just added it but now every picture from and requires to enter the auth password. Is there a way to only protect

Otherwise I get this now:

I’m not sure exactly how to achieve that, but maybe someone else will jump in if they have some ideas. It should be possible with some tweaks to the nginx config.

As a workaround, and since this is a staging server, could you just disable the CDN? If you use the same domain for assets, they will automatically be sent the authentication header so you won’t need to enter the auth password again.

1 Like

Yes sure, if that is the recommended approach for a staging environment if you use S3 buckets for backups and uploads as well as CloudFront as CDN for uploads and origin on production.

No need to really have all of that for a staging environment?

This nginx change certainly shouldn’t affect S3 uploads or the S3 CDN. NGINX is not involved there at all. I had assumed you were using local uploads with a CDN?

The ideal situation is to make the staging site configured identically to the production site.

  DISCOURSE_S3_REGION: us-east-1
  DISCOURSE_S3_BUCKET: example-uploads
  DISCOURSE_S3_BACKUP_BUCKET: example-backup

And the main domain for staging is currently

Still, I am auth prompted for every single request from cnd-origin with the proposed code when accessing

Update for those running into the same issue:

We had to whitelist the Authorization headers in Cloudfront for cdn-origin.

It’s seem I was not prompted for auth for cdn-uploads.

Works now.


I turn on login required on the staging site. You can do it with an environment variable in the app.yml so that it’s persistent.

No good enough if Google or anybody else is finding the site. Anyways works now.

1 Like

They’ll see the site but not be able to see any content. Right?

In our case, we have to be able to see how the site reacts to anonymous users as well. So fair enough, works now with basic_auth.


Well, you have me rethinking how I do this!

Hey @Terrapop

Here is an idea for you and is how we do it.

If you run your staging env behind Apache2 (or nginx) as a reverse proxy you can set up access rules in the reverse proxy as you would with .htaccess like you are familiar with.

There are myriad advantages for running Discourse behind a reverse proxy and ease of access control is just one benefit.


Is there a fool proof how-to guide for nginix? We’re hosting on Digitalocean via Droplet and Docker.

Hi @Terrapop

There are plenty of great tutorials on meta on how to setup Discourse in a “two container” configuration behind a reverse proxy.

You can try searching on meta:

two container  reverse proxy

Hope this helps.

Please note for simply staging, many people do not set up “two containers” and only do this in production; but if you want to stage “exact as in production” then “two containers” is certainly a great way to go. However, you do not need “two containers” to run a web app behind a reverse proxy. I regularly run ROR and Docker web apps behind a reverse proxy in both production and development.


Hello. Just want to know how you properly whitelisted the authorization headers in CloudFront? Added “auth_basic” in app.yml as given above. Password-protect is working when browsing via desktop but getting this when browsing via mobile (after entering user and password):

I have this in my “cdn-origin”:

“whitelist-authorization-headers” policy:

Fairly new to CloudFront and I might just be missing something very obvious (for mobile configuration).