Generals Subfolder recommendations and tips

The app.yml changes currently described in this subfolder support how-to, that complements the normal installation, have indeed helped me to install Discourse as a subfolder like example.com/forum instead of subdomain forum.example.com when suitable.

However, there was still the problem of port conflict (80, 443), and I had to shut down the rest of the site at example.com (WordPress) on the same virtual server (by stopping its Nginx in my case) to be able to run Discourse at example.com/forum, or vice versa.

For example, the how-to Running other websites on the same machine as Discourse is for a similar but different case, with subdomain forum.example.com and other domains on the server, instead of Discourse as part of a site in the same domain.

The solution for this one-server subfolder problem was hidden in a link from a multi-server subfolder how-to thread. That is, using -in the Nginx configuration- a location /forum/ directive for the Discourse folder, and location / for the rest of the site. This has worked well.

In summary, the main additional installation steps for this case (Nginx, Discourse in subfolder, rest of the site in the same domain and same server), adapted from the mentioned sources, would be the following, of course trying this first on a dev or test server:

Edit the file /var/discourse/discourse-setup to comment out two lines:

# check_ports

# ./launcher bootstrap $app_name && ./launcher start $app_name

In this way, discourse-setup just creates a file for Docker /var/discourse/containers/app.yml that can be customized (and then used to bootstrap or rebuild) like in the first post of this subfolder support how-to, with the additional changes:

Add this line:

templates:
  ...
  - "templates/web.socketed.template.yml"

Comment out these two lines:

expose:
#   - "80:80"   # http
#   - "443:443" # https

And modify as said (after making a backup) the Nginx configuration file of our existing non-Discourse rest of the site, possibly /etc/nginx/sites-available/example.com (with symlink /etc/nginx/sites-enabled/example.com).

This is done by just moving the Nginx configuration of the existing site into a location / directive, and adding a location /forum/ block (using Unix socket file instead of ports) for the Discourse folder.

A simple example for http without SSL, in this particular case using Virtualmin, would be the following (https with SSL is similar but a little more complex than this example):

server {
    server_name example.com www.example.com;
    listen 127.0.0.10;

# Configuration for Discourse subfolder.
    location /forum/ {
        proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
        proxy_set_header Host $http_host;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

# Configuration for the rest of the site.
    location / {
        root /srv/www/example/public_html;
        index index.html index.htm index.php;
        access_log /var/log/virtualmin/example.com_access_log;
        error_log /var/log/virtualmin/example.com_error_log;
        fastcgi_param GATEWAY_INTERFACE CGI/1.1;
        fastcgi_param SERVER_SOFTWARE nginx;
        fastcgi_param QUERY_STRING $query_string;
        fastcgi_param REQUEST_METHOD $request_method;
        fastcgi_param CONTENT_TYPE $content_type;
        fastcgi_param CONTENT_LENGTH $content_length;
        fastcgi_param SCRIPT_FILENAME /srv/www/example/public_html$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        fastcgi_param REQUEST_URI $request_uri;
        fastcgi_param DOCUMENT_URI $document_uri;
        fastcgi_param DOCUMENT_ROOT /srv/www/example/public_html;
        fastcgi_param SERVER_PROTOCOL $server_protocol;
        fastcgi_param REMOTE_ADDR $remote_addr;
        fastcgi_param REMOTE_PORT $remote_port;
        fastcgi_param SERVER_ADDR $server_addr;
        fastcgi_param SERVER_PORT $server_port;
        fastcgi_param SERVER_NAME $server_name;
        fastcgi_param HTTPS $https;
        include /srv/www/example/public_html/nginx.conf;
        location ~ \.php$ {
            try_files $uri =404;
            fastcgi_pass unix:/var/php-nginx/147000774813312.sock/socket;
        }
        if (!-e $request_filename) {
            rewrite ^.*$ /index.php last;
        }
        fastcgi_read_timeout 60;
    }
}

Remember to test the modified Nginx configuration:

sudo nginx -t

and correct it before reloading Nginx and bootstrapping or rebuilding the Discourse container.

1 Like

And an Nginx example (file /etc/nginx/sites-available/example.com) that seems to be working well for Discourse subfolder (/forum), WordPress site on the same server (root), and https (with SSL/TLS), including permanent redirections http -> https, and www. -> non-www.:

server {
  listen 127.0.0.10:80;
  server_name www.example.com;
  return 301 https://example.com$request_uri;
}

server {
  listen 127.0.0.10:443 ssl;
  server_name www.example.com;
  ssl_certificate /srv/www/example/ssl.cert;
  ssl_certificate_key /srv/www/example/ssl.key;
  return 301 https://example.com$request_uri;
}

server {
  listen 127.0.0.10:80 default_server;
  server_name example.com;
  return 301 https://example.com$request_uri;
}

server {
  listen 127.0.0.10:443 default_server ssl;
  server_name example.com;
  ssl_certificate /srv/www/example/ssl.cert;
  ssl_certificate_key /srv/www/example/ssl.key;

  # Configuration for the Discourse subfolder /forum
  location /forum/ {
    proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
    proxy_set_header Host $http_host;
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }

  # Configuration for the rest of the site (WordPress)
  location / {
    root /srv/www/example/public_html;
    index index.html index.htm index.php;
    access_log /var/log/virtualmin/example.com_access_log;
    error_log /var/log/virtualmin/example.com_error_log;
    fastcgi_param GATEWAY_INTERFACE CGI/1.1;
    fastcgi_param SERVER_SOFTWARE nginx;
    fastcgi_param QUERY_STRING $query_string;
    fastcgi_param REQUEST_METHOD $request_method;
    fastcgi_param CONTENT_TYPE $content_type;
    fastcgi_param CONTENT_LENGTH $content_length;
    fastcgi_param SCRIPT_FILENAME /srv/www/example/public_html$fastcgi_script_name;
    fastcgi_param SCRIPT_NAME $fastcgi_script_name;
    fastcgi_param REQUEST_URI $request_uri;
    fastcgi_param DOCUMENT_URI $document_uri;
    fastcgi_param DOCUMENT_ROOT /srv/www/example/public_html;
    fastcgi_param SERVER_PROTOCOL $server_protocol;
    fastcgi_param REMOTE_ADDR $remote_addr;
    fastcgi_param REMOTE_PORT $remote_port;
    fastcgi_param SERVER_ADDR $server_addr;
    fastcgi_param SERVER_PORT $server_port;
    fastcgi_param SERVER_NAME $server_name;
    fastcgi_param HTTPS $https;
    include /srv/www/example/public_html/nginx.conf;
    location ~ \.php$ {
      try_files $uri =404;
      fastcgi_pass unix:/var/php-nginx/147000774813312.sock/socket;
    }
    if (!-e $request_filename) {
      rewrite ^.*$ /index.php last;
    }
    fastcgi_read_timeout 60;
  }
}
4 Likes

Since Nginx 1.9.5, we can increase speed by enabling HTTP/2 for SSL, adding “http2” to the listen directives. For the previous example:

listen 127.0.0.10:443 ssl http2;

(…)

listen 127.0.0.10:443 default_server ssl http2;
2 Likes

Hello jmg

I installed discourse in the Ubuntu 14.04 LTS 64 bit, EasyEngine(Wordpress framework, php7 and lets encrypt)

Installationa have no problem but I couldn’t login through discourse, so I need comment for solving problem. How can I use discourse subfolder without any problem?

I can access through radioheaven.co.kr/forum but the initial page have so image like normal installation. And I can’t activate the account by the process.

Thank you so much of your comment!

vi /var/discourse/containers/app.yml

## this is the all-in-one, standalone Discourse Docker container template
##
## After making changes to this file, you MUST rebuild
## /var/discourse/launcher rebuild app
##
## BE *VERY* CAREFUL WHEN EDITING!
## YAML FILES ARE SUPER SUPER SENSITIVE TO MISTAKES IN WHITESPACE OR ALIGNMENT!
## visit http://www.yamllint.com/ to validate this file as needed

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Uncomment these two lines if you wish to add Lets Encrypt (https)
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"
  - "templates/web.socketed.template.yml"

## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another webserver like Apache or nginx,
## see https://meta.discourse.org/t/17247 for details
expose:
#  - "80:80"   # http
#  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"
  ## Set db_shared_buffers to a max of 25% of the total memory.
  ## will be set automatically by bootstrap based on detected RAM, or you can override
  db_shared_buffers: "256MB"

  ## can improve sorting performance, but adds memory usage per-connection
  #db_work_mem: "40MB"

  ## Which Git revision should this container use? (default: tests-passed)
  #version: tests-passed

env:
  LANG: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

  ## How many concurrent web requests are supported? Depends on memory and CPU cores.
  ## will be set automatically by bootstrap based on detected CPUs, or you can override
  UNICORN_WORKERS: 4

  ## TODO: The domain name this Discourse instance will respond to
  DISCOURSE_HOSTNAME: 'radioheaven.co.kr'
  DISCOURSE_RELATIVE_URL_ROOT: /forum

  ## Uncomment if you want the container to be started with the same
  ## hostname (-h option) as specified above (default "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: List of comma delimited emails that will be made admin and developer
  ## on initial signup example 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'angel@radioheaven.co.kr'

  ## TODO: The SMTP mail server used to validate new accounts and send notifications
  DISCOURSE_SMTP_ADDRESS: smtp.mandrillapp.com         # required
  DISCOURSE_SMTP_PORT: 587                        # (optional, default 587)
  DISCOURSE_SMTP_USER_NAME: radioheaven.co.kr      # required
  DISCOURSE_SMTP_PASSWORD: password               # required, WARNING the char '#' in pw can cause problems!
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (optional, default true)

  ## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
  LETSENCRYPT_ACCOUNT_EMAIL: angel@radioheaven.co.kr

  ## The CDN address for this Discourse instance (configured to pull)
  ## see https://meta.discourse.org/t/14857 for details
  #DISCOURSE_CDN_URL: //discourse-cdn.example.com

## The Docker container is stateless; all data is stored in /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Plugins go here
## see https://meta.discourse.org/t/19157 for details
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## Any custom commands to run after building
run:
  - exec: echo "Beginning of custom commands"
  - exec:
      cd: $home
      cmd:
        - mkdir -p public/forum
        - cd public/forum && ln -s ../uploads && ln -s ../backups
  - replace:
     global: true
     filename: /etc/nginx/conf.d/discourse.conf
     from: proxy_pass http://discourse;
     to: |
        rewrite ^/(.*)$ /forum/$1 break;
        proxy_pass http://discourse;
  - replace:
     filename: /etc/nginx/conf.d/discourse.conf
     from: etag off;
     to: |
        etag off;
        location /forum {
           rewrite ^/forum/?(.*)$ /$1;
        }
  - replace:
       filename: /etc/nginx/conf.d/discourse.conf
       from: $proxy_add_x_forwarded_for
       to: $http_fastly_client_ip
       global: true
## 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='info@unconfigured.discourse.org'"
  - exec: echo "End of custom commands"

vi /etc/nginx/sites-available/radioheaven.co.kr

server {

server_name radioheaven.co.kr   www.radioheaven.co.kr;
access_log /var/log/nginx/radioheaven.co.kr.access.log rt_cache;
error_log /var/log/nginx/radioheaven.co.kr.error.log;
root /var/www/radioheaven.co.kr/htdocs;
index index.php index.html index.htm;
include common/php7.conf;
include common/wpcommon-php7.conf;
include common/locations-php7.conf;
include /var/www/radioheaven.co.kr/conf/nginx/*.conf;

}

vi /var/www/radioheaven.co.kr/conf/nginx/discourse.conf

Configuration for the Discourse subfolder /forum

location /forum/ {
proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Please check the attached file for result! When I click the “Click here to activate your account” button, nothing happened!

Maybe email is not yet configured. See Recommended Email Providers for Discourse.

I am using Mandrill from MailChimp for Discourse. In your link, they didn’t recommend Mandrill. Does Mandrill have some problem to connect with Discourse?

I couldn’t understand why I couldn’t see any image except the message. When I install the discourse as full domain, I can see the image without no problems.

Sincerely,

Honggi An

I’m not using Mandrill, but SparkPost is working fine for me with Discourse. However, Mandrill should work. Look in your spam folders, just in case.

Did you follow all the steps in the first post of this howto, including long polling base url, etc.?

No, receiving e-mail no problem, but the activation is not working properly in my discourse.

Should I follow long polling base url in the first installation?

That setting is needed for all subfolder installations.