Set Environmental Variables

:notebook_with_decorative_cover: This is a how-to guide that will walk you through the process of setting up environmental variables in a self-hosted Discourse Installation.

Environmental variables are a crucial part of configuring your Discourse instance, and they can be used to store sensitive information such as API keys and database passwords.

Adding environmental variables to a .yml (YAML) file is straightforward. Here’s a basic example:

# This is a YAML file with environmental variables
env:
  VARIABLE_NAME: "Variable Value"
  ANOTHER_VARIABLE: "Another Value"

In the context of a Discourse Docker container, environmental variables are stored in the env section of your app.yml file.

Here's an example of an app.yml file:
## 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
##
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"

## 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"

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: 3

  ## TODO: The domain name this Discourse instance will respond to
  DISCOURSE_HOSTNAME: 'discourse.example.com'

  ## 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: 'user@example.com'

  ## TODO: The SMTP mail server used to validate new accounts and send notifications
  DISCOURSE_SMTP_ADDRESS: smtp.example.com         # (mandatory)
  DISCOURSE_SMTP_PORT: 587                        # (optional)
  DISCOURSE_SMTP_USER_NAME: user@example.com      # (optional)
  DISCOURSE_SMTP_PASSWORD: a_s3cr3t_p@ssword      # (optional)
  #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: me@example.com

  ## The CDN address for this Discourse instance (configured to pull)
  #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"
  ## If you want to set the 'From' email address for your first registration, uncomment and change:
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  ## After getting the first signup email, re-comment the line. It only needs to run once.
  - exec: echo "End of custom commands"

Let’s get started with adding environmental variables to your site! :mage:

:information_source: The following instructions are written for a Standard Discourse Installation

Login to Your Server

Use a tool like PuTTY or the terminal on Unix-based systems to SSH into your server.

ssh username@your-server-ip

Navigate to the Discourse Directory

Once you have access to your server, navigate to the directory containing your Discourse Docker setup, this is typically located at /var/discourse.

cd /var/discourse

Open the app.yml File

You’ll need to open the app.yml file in a text editor. For this example we’ll be using nano.

nano containers/app.yml

Add Your Environmental Variables

In the app.yml file, you’ll find an env section. This is where you can add your environmental variables.

env:
  DISCOURSE_HOSTNAME: 'discourse.example.com'
  DISCOURSE_SMTP_ADDRESS: smtp.example.com
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: user@example.com
  DISCOURSE_SMTP_PASSWORD: a_s3cr3t_p@ssword

For example, if you wanted to set the DISCOURSE_ENABLE_CORS environmental variable to true to enable Cross-Origin Resource Sharing (CORS), you would add the following line to the env section:

env:
  DISCOURSE_ENABLE_CORS: "true"
  ...

:person_tipping_hand: The whitespace and formatting is important here, so make sure to maintain the correct indentation (two spaces) for the new line

Once you’ve modified your variables, save and close the file.

Rebuild the Discourse Container

Finally, you’ll need to rebuild your Discourse Docker container for the changes to take effect. You can do this with the following command:

./launcher rebuild app

Alternatively, to update environmental variables for a running container without rebuilding, you can also use:

./launcher destroy app
./launcher start app

After the rebuild process completes, your updated environmental variables will be available to your Discourse application! :tada:

3 Likes

This would be much more useful if it explained how to use env variables to override (and give from the UX) system settings or the global settings in the default global variable file (
and linked to it so people could see those settings like obscure redis settings

This is a confusing example since it has nothing to do with discourse.

You could mention that it’s the same as using the analogous command like setting in docker, perhaps.

I see you made this because you made Setup Cross-Origin Resource Sharing (CORS), so maybe use that as an example.

7 Likes

Is there a place in which one can find all the possible environment variable used in discourse?

That would have been much more useful rather than a topic that says that the environment variable go in the app.yml under the section env: :laughing:

Also, to have the application “load” the changed environment variable, I’m pretty sure you can just restart and don’t need to rebuild but please someone correct me if I’m wrong.

You can destroy and start the container; that’s added to the OP, I think. The only issue is if you did upgrades from the UX they are lost.

You can set any site setting with DISCOURSE_SETTING_NAME. See also the default settings under config. https://github.com/discourse/discourse/blob/main/config/discourse_defaults.conf

4 Likes

Hi @SaraDev, may I know how these environment variables change the behaviour of the Discourse? For example, all of variable mentioned in this post Available settings for global rate limits and throttling I cannot find any of them in the Discouse source code, then how these variable are hooked to Discourse? Thanks!

I believe you can see them here:

3 Likes

Thank you so much @Arkshine.

1 Like

Is there a way to set environment variables on a non-docker hosted dev environment? I plan on hosting with docker eventually but am developing locally with this setup: Install Discourse on macOS for development
There’s no app.yml in this case

You can set them in the command line before you start rails, but what are you trying to do with those ENV variables?

I’m trying to set DISCOURSE_ENABLE_CORS to true for SSO. Would you mind sending me a sample command? I’m new to discourse / rails development. Also what does that ultimately do? Create a record in the site_settings table?

I am trying to setup discourse automatically within kubernetes. Therefore I plan to build a custom docker image (DinD).
BUT if I were to run ./discourse-setup.sh in my Dockerfile, it would ask me for config options - which docker can not answer (as this should be done automatically).

I understand that I could put those env variables inside the app.yml file, but at this point there will not be any app.yaml file at all, as the ./discourse-setup script has not been run yet.

So my question would be: How can I pre-configure discourse for my purposes, so that ./discourse-setup does not require my user input?

The discourse/docs/INSTALL-cloud.md at main · discourse/discourse (github.com) install guide does not say anything about pre-configurations or config files at all.

Thanks in advance!

2 Likes

Try

./launcher start-cmd app

That’ll give you the docker start command used to crank up the container. You should be able to use that to figure out how to crank things up in k8s.

4 Likes

Are there any other common places that app.yml file could live, or could it be possible that this file needs to be created from scratch? I “went into” my Docker container (docker exec -it discourse_dev /bin/bash), and was unable to find any file named app.yml.

The app.yml file should be outside of your container, rather than inside of it.

2 Likes