Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling environment variables in flask with docker deployment

I'm setting up flask with docker. I've two ways to set environment variables, one in flask .cfg files and another in docker .env files.

I'm wondering which one is the better practice. Evaluating the pros and cons, if I move my environment variables to docker .env files, I would have to do os.environ.get at all the places in my application code, including handling of defaults which brings extra dependency inside application from os environment variables. On the other hand, adding environment variables like DB password, secret keys, etc inside flask config might not be a right idea, although all my environment variables and defaults would be at one single place.

like image 999
pkumar Avatar asked Sep 01 '25 04:09

pkumar


2 Answers

You don't have to settle for one or the other.

Is not an unusual practice to use environment variables for configuring every aspect of your application, including DB passwords. This is staring to be an often practice in container environments such as Kubernetes or using docker secrets as they give the ability of keeping critical information encrypted and mount it as an environment variable to your container.

You could directly check in your application for the values of the environment variables or another option is to have an entrypoint in docker that checks for those values and ends up creating a configuration file that you use in your application. This last option allows you to use environment variables to configure your application or if you don't want to you could directly mount a configuration file to your container skipping the envs completely.

This is used for example on the logstash docker image.

like image 181
Esteban Garcia Avatar answered Sep 02 '25 18:09

Esteban Garcia


Just to add to the great answer by Esteban Garcia, another good way is to use both. Have a configuration file, class-based configs are great here because you can take advantage of config inheritance, and have all non-sensitive options in there. For the sensitive stuff like secrets, database passwords, etc - define them right in the config with os.environ.get to extract these values from the environment. So it ends up looking like this:

class DefaultConfig(Config):
    TESTING = False
    DEBUG = False
    SECRET_KEY = os.getenv('APP_SECRET_KEY')
    SQLALCHEMY_DATABASE_URI = os.getenv('APP_DATABASE_URI')

This way you can keep using app.config and not have to do os.environ.get all over your app.

like image 28
dmitrybelyakov Avatar answered Sep 02 '25 18:09

dmitrybelyakov