Subfolder support with Docker

:warning: Discourse Official Statement about Subfolder setup

We support subfolder setups for our hosted customers at the enterprise level and up. Due to heavy technical setup complexity we strongly recommend you do not use this setup unless you are very experienced in custom subfolder setups.

It is critical you have a deep understanding of

  • NGINX setup in the Discourse Docker container
  • Secure original IP forwarding using custom headers in the proxy chain
  • Rate limiting in front proxy server

If this all sounds odd and strange to you we strongly recommend you avoid this setup.

To serve Discourse from a subfolder (a.k.a. with a path prefix) on your domain, like http://www.example.com/=SUBFOLDER=, here’s how to do it!

Docker config

In the env section of your docker container yml file, add the DISCOURSE_RELATIVE_URL_ROOT setting with the subfolder you want to use. Make sure it does not end with a /.

Editing this will update the entire guide.

env:
  ...
  DISCOURSE_RELATIVE_URL_ROOT: /=SUBFOLDER=

The run section needs some changes to send all Discourse routes to the right place. Here is a complete run section with subfolder support:

run:
    - exec:
        cd: $home
        cmd:
          - mkdir -p public/=SUBFOLDER=
          - cd public/=SUBFOLDER= && ln -s ../uploads && ln -s ../backups
    - replace:
       global: true
       filename: /etc/nginx/conf.d/discourse.conf
       from: proxy_pass http://discourse;
       to: |
          rewrite ^/(.*)$ /=SUBFOLDER=/$1 break;
          proxy_pass http://discourse;
    - replace:
       filename: /etc/nginx/conf.d/discourse.conf
       from: etag off;
       to: |
          etag off;
          location /=SUBFOLDER= {
             rewrite ^/=SUBFOLDER=/?(.*)$ /$1;
          }
    - replace:
         filename: /etc/nginx/conf.d/discourse.conf
         from: $proxy_add_x_forwarded_for
         to: $http_your_original_ip_header
         global: true

$http_your_original_ip_header stands for Your-Original-Ip-Header, which is a trusted Header you set on the origin which contains the actual client IP.

This is required cause traffic passes through a central proxy, if Discourse happens to have a public IP you can spoof it. If Discourse is private you may be able to get away with X-Forwarded-For

After making these changes, bootstrap your Docker container as usual, or rebuild if you’re changing an existing container.

./launcher bootstrap app

or

./launcher rebuild app

Attached is a complete example yml file of a standalone container.

subfolder-sample.yml (3.1 KB)

Rate limiting concerns

If you are going for this setup you probably want to rate limit requests prior to them landing on NGINX in the container, that means you probably will avoid using our rate limiting template. It is very hard to configure NGINX in the container to limit on a remapped IP and would require complex changes to the template.

Existing posts

If you did this with an existing site that was on a subdomain, you’ll find that your uploads are broken. There’s a tool that can help fix all paths to include the subfolder. In the Discourse directory (typically /var/www/discourse'), run it like this after taking a backup:

RAILS_ENV=production bundle exec script/discourse remap '/uploads' '/=SUBFOLDER=/uploads'

See also: Discourse in a subfolder, multiple servers sharing a domain for more esoteric setups.

robots.txt

Now that Discourse is running on a subfolder, it cannot serve its robots.txt file to control which routes are crawled by web crawlers. Crawlers will be looking at your main site’s robots.txt file (http://www.example.com/robots.txt). You need to copy the contents of Discourse’s robots.txt file (found at http://www.example.com/=SUBFOLDER=/robots.txt) and put it in your main site’s robots.txt file.

25 Likes
How can I change my installation from forum.website.com to www.website.com/forum?
Moving Discourse to subdirectory caused all uploads to break
Discourse in a subfolder, multiple servers sharing a domain
Uploaded avatars and Gravatar not working with subfolder installation
Is it possible to install discourse inside a directory?
Launch Discourse on www.example.com/meta/ In a web folder type
Subfolder with SSL and nginx reverse proxy
Moving Discourse to subdirectory caused all uploads to break
404 errors (assets) on Subfolder installation
Discourse in a subfolder, multiple servers sharing a domain
Install Discourse as subfolder within Wordpress website?
Can I install Discourse on existing server that uses Nginx?
Problem with discourse in a subfolder
Non-standard port breaks uploads
Uploaded avatar or gravatar not working
Looking for a developper
Switching forum from subdomain to sub directory
Redirect discourse URL
How to install discourse with nginx as proxy on specific path?
All IPs recorded as 127.0.0.1
How to install discourse with nginx as proxy on specific path?
Install Discourse into domain.com/forums
SetupWizard, blank screen, JS Error "`virtual-dom"
Trouble connecting drupal and discourse
National Flags - Display user nationality in Discourse
Failed to Bootstrap - launcher rebuild app
Redirect from one server to another server and keep everything after the URL
Installation on v-server as a subfolder with other services in subfolders using apache
Is it possible to install Discourse on the same domain of your main website
Subfolder install - external links get changed/redirected to site relative links
Discourse embedded on my WP
Reverse Proxy Assets
Reverse Proxy rewrites domain in external links in posts
Inheriting discourse install - need some assistance
Multisite installation ... in subdirectories?
"Failed to create swap, sorry!"
Generals Subfolder recommendations and tips
Add to route headers?
Sorry, there was an error authorizing your account
Site Logo and Icons Break due to subfolder config
Site Logo and Icons Break due to subfolder config
Site Logo and Icons Break due to subfolder config
Discourse nginx conf
Discourse nginx conf
Subdomain redirect to path
404 errors (assets) on Subfolder installation
404 errors (assets) on Subfolder installation
Moving Discourse from Subdomain to Subfolder
Blank Page After installing Discourse on Subfolder
Trailing slash and subfolder setup
Install Discourse as a subdirectory with existing Nginx
How to run discourse on subdirectory of external domain?
How to run discourse on subdirectory of external domain?
Image lightbox not working in subfolder install
Avatar uploads broken on subfolder installs?
Setup wizard emoji wrong in subfolder install
Digest email issue with 'stable'
Add secondary url / embed into Wordpress
Recent Changes Breaking Subfolder Setup?
Put discourse on a sub url
No subfolder prefixing for some resources
How to run discourse on subdirectory of external domain?
Setup wizard emoji wrong in subfolder install
Wiki topics look incredibly out of date?
Too many redirects when reverse proxying to Discourse from a different server
Blank main page on one forum (subfolder + multisite install)
Moving Discourse to subdirectory caused all uploads to break
Feasible to reverse proxy using qualifier in URL?
Upgrade doesn't work when installed with subfolder
Discourse CDN set up with KeyCDN
Message bus does not respect subfolder during update process
Wiki Posts Not Green?
Base_url and base_uri
Embed whole Discourse board into Wordpresspage
Backup upload failing
Redirect to discourse from a route in another domain
Redirect to discourse from a route in another domain
Problem with discourse in a subfolder
Install Discourse as subfolder within Wordpress website?

:warning: Please discuss the merits of subfolder vs non-subfolder on separate topics.

Any discussion about the subfolder setup here will likely be integrated into the top post and deleted.

I just edited the OP with more warnings!

7 Likes

That remap command wouldn’t work unless I called bundle exec discourse instead of bundle exec script/discourse.

I had to update the external_system_avatars_url site setting, and found I had to also remap things like <subfolder>/user_avatar/<domain>, <subfolder>/plugins, <subfolder>/images, etc…

1 Like

Thanks for mentioning that @vvanpo :slight_smile:

I managed to get this working but do not know where to link <subfolder>/user_avatar/<domain>.

There is no user_avatar folder in the public folder. Where have you pointed (dest) your user_avatar symbolic link placed into <subfolder> ?

Thanks :wink:

Edit: It seems to work without user_avatar link. Maybe images must be rebuilded in background (sidekiq tasks) and this just take some time.

1 Like

thanks @vvanpo

here’s what worked for me:

RAILS_ENV=production bundle exec discourse remap '/uploads' '/<subfolder>/uploads'
RAILS_ENV=production bundle exec discourse remap '/user_avatar/<domain>' '/<subfolder>/user_avatar/<domain>'
RAILS_ENV=production bundle exec discourse remap '/images' '/<subfolder>/images'
RAILS_ENV=production bundle exec discourse remap '/plugins' '/<subfolder>/plugins'
3 Likes