Explore Flask

5.3. Configuring based on environment variables

The instance folder shouldn't be in version control. This means that you won't be able to track changes to your instance configurations. That might not be a problem with one or two variables, but if you have finely tuned configurations for various environments (production, staging, development, etc.) you don't want to risk losing that.

Flask gives us the ability to choose a configuration file on load based on the value of an environment variable. This means that we can have several configuration files in our repository and always load the right one. Once we have several configuration files, we can move them to their own config directory.

requirements.txt
run.py
config/
  __init__.py # Empty, just here to tell Python that it's a package.
  default.py
  production.py
  development.py
  staging.py
instance/
  config.py
yourapp/
  __init__.py
  models.py
  views.py
  static/
  templates/

In this listing we have a few different configuration files.

File Description
config/default.py Default values, to be used for all environments overridden by individual environments. An example might be setting DEBUG = False in config/default.py and DEBUG = True in config/development.py.
config/development.py Values to be used during development. Here you might specify the URI of a database sitting on localhost.
config/production.py Values to be used in production. Here you might specify the URI for your database server, as opposed to the localhost database URI used for development.
config/staging.py Depending on your deployment process, you may have a staging step where you test changes to your application on a server that simulates a production environment. You'll probably use a different database, and you may want to alter other configuration values for staging applications.

To decide which configuration file to load, we'll call app.config.from_envvar().

# yourapp/__init__.py

app = Flask(__name__, instance_relative_config=True)

# Load the default configuration
app.config.from_object('config.default')

# Load the configuration from the instance folder
app.config.from_pyfile('config.py')

# Load the file specified by the APP_CONFIG_FILE environment variable
# Variables defined here will override those in the default configuration
app.config.from_envvar('APP_CONFIG_FILE')

The value of the environment variable should be the absolute path to a configuration file.

How we set this environment variable depends on the platform in which we're running the app. If we're running on a regular Linux server, we can set up a shell script that sets our environment variables and runs run.py.

# start.sh

APP_CONFIG_FILE=/var/www/yourapp/config/production.py
python run.py

start.sh is unique to each environment, so it should be left out of version control. On Heroku, we'll want to set the environment variables with the Heroku tools. The same idea applies to other PaaS platforms.