handling environment variables in flask with docker deployment

  • Last Update :
  • Techknowledgy :

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')

First thing is to move from python code to a syntax that is compatible with docker-compose. So, if you have this in settings.py:

# ** ** ** ** ** ** ** ** ** ** ** ** ** ** *
   # Environment specific settings
# ** ** ** ** ** ** ** ** ** ** ** ** ** ** *

   # DO NOT use "DEBUG = True" in production environments
DEBUG = True

# DO NOT use Unsecure Secrets in production environments
SECRET_KEY = 'This is an UNSECURE Secret. CHANGE THIS for production environments.'

# SQLAlchemy settings
SQLALCHEMY_DATABASE_URI = 'postgresql:///../app.postgresql'

Rename that file to settings.env and change the content to:

# ** ** ** ** ** ** ** ** ** ** ** ** ** ** *
   # Environment specific settings
# ** ** ** ** ** ** ** ** ** ** ** ** ** ** *

   # DO NOT use "DEBUG=True" in production environments
DEBUG = True

# DO NOT use Unsecure Secrets in production environments
SECRET_KEY = This is an UNSECURE Secret.CHANGE THIS
for production environments.

# SQLAlchemy settings
SQLALCHEMY_DATABASE_URI = postgresql: ///../app.postgresql

After that, you need to load that file on the docker-compose.yaml file:

version: '3.1'
services:
   web:
   image: web - server
env_file: path_to / settings.env

You can add a prefix to the vars on settings.env like this:

YOURAPP_DEBUG = True

And then on the app creation:

# Instantiate Flask
app = Flask(__name__)

for variable, value in os.environ.items():
   if variable.startswith("YOURAPP_"):
   env_name = variable.split("YOURAPP_")[1]
app.config[env_name] = value

Suggestion : 2

I'm setting up flask with docker. I've two anycodings_python ways to set environment variables, one in anycodings_python flask .cfg files and another in docker .env anycodings_python files. ,This way you can keep using app.config anycodings_flask and not have to do os.environ.get all anycodings_flask over your app.,Rename that file to settings.env and anycodings_flask change the content to:,First thing is to move from python code anycodings_flask to a syntax that is compatible with anycodings_flask docker-compose. So, if you have this in anycodings_flask settings.py:

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

First thing is to move from python code anycodings_flask to a syntax that is compatible with anycodings_flask docker-compose. So, if you have this in anycodings_flask settings.py:

# ** ** ** ** ** ** ** ** ** ** ** ** ** ** *
   # Environment specific settings
# ** ** ** ** ** ** ** ** ** ** ** ** ** ** *

   # DO NOT use "DEBUG = True" in production environments
DEBUG = True

# DO NOT use Unsecure Secrets in production environments
SECRET_KEY = 'This is an UNSECURE Secret. CHANGE THIS for production environments.'

# SQLAlchemy settings
SQLALCHEMY_DATABASE_URI = 'postgresql:///../app.postgresql'

Rename that file to settings.env and anycodings_flask change the content to:

# ** ** ** ** ** ** ** ** ** ** ** ** ** ** *
   # Environment specific settings
# ** ** ** ** ** ** ** ** ** ** ** ** ** ** *

   # DO NOT use "DEBUG=True" in production environments
DEBUG = True

# DO NOT use Unsecure Secrets in production environments
SECRET_KEY = This is an UNSECURE Secret.CHANGE THIS
for production environments.

# SQLAlchemy settings
SQLALCHEMY_DATABASE_URI = postgresql: ///../app.postgresql

After that, you need to load that file anycodings_flask on the docker-compose.yaml file:

version: '3.1'
services:
   web:
   image: web - server
env_file: path_to / settings.env

You can add a prefix to the vars on anycodings_flask settings.env like this:

YOURAPP_DEBUG = True

And then on the app creation:

# Instantiate Flask
app = Flask(__name__)

for variable, value in os.environ.items():
   if variable.startswith("YOURAPP_"):
   env_name = variable.split("YOURAPP_")[1]
app.config[env_name] = value

Suggestion : 3

Another way, would be to use an .env file with docker-compose, or to pass parameters from the host directly to the container. You can read more about working with Docker environment variables in this giant guide.,If you want to learn more about working with Docker, deployment pipelines and similar topics, here’s a list of cool resources you can check out next:,Functional automation is a blessing when you’re getting into deployment tasks, and a good first step towards building a deployment pipeline down the line. You can read more about building a deployment pipeline in this article.,One way would be to use an env_file. This way, you can set multiple environment variables at once and would also help you to get your secrets out of the command line:

Project files aren’t copied into the filesystem root.

WORKDIR / home / microblog

The Dockerfile introduces a non-root user.

RUN adduser - D microblog
#...
   RUN chown - R microblog: microblog. /
   USER microblog

Before the whole code of the project is added to the new image, the following lines are executed:

COPY requirements.txt requirements.txt
#...
   RUN venv / bin / pip install - r requirements.txt

When working with bash scripts, mine usually start with these lines:

#! /bin/bash

set - euo pipefail

As the scripts in the article rely on /bin/sh and don’t use pipes, I’d suggest them to start this way:

#! /bin/sh

set - eu

Suggestion : 4

ENV – To set environment variables in a Docker container, ENV is used. You can have multiple variables in a single Dockerfile.,It can be created on Linux OS or Windows OS. Docker Containers provide flexibility in deploying and managing software applications. You can start, stop, delete and perform various operations on a Docker Container using the Docker CLI or API.,Docker Compose is a tool that helps to define multi-container applications in a file and manage several different containers quickly and easily. ,A Docker Container is a loosely isolated environment where the application runs.

  1. Go to the home directory
    $ cd /home/ubuntu/
  2. Create a new directory
    $ mkdir clickittech
  3. Change your current working directory and stay in it throughout the article.
    $ cd clickittech/
  4. Create a directory to put Python Flask Application files under it
    $ mkdir flask
  5. Create a main.py under the flask directory
    $ vim flask/main.py
import redisfrom flask
import Flaskapp = Flask(__name__) redis = redis.Redis(host = 'redis', port = 6379, db = 0) @app.route('/') def hello_world(): return 'This is a Python Flask Application with redis and accessed through Nginx'
@app.route('/visitor') def visitor(): redis.incr('visitor') visitor_num = redis.get('visitor').decode("utf-8") return "Visit Number = : %s" % (visitor_num) @app.route('/visitor/reset') def reset_visitor(): redis.set('visitor', 0) visitor_num = redis.get('visitor').decode("utf-8") return "Visitor Count has been reset to %s" % (visitor_num)
  1. Stay in the same directory(/home/ubuntu/clickittech) and create a Dockerfile in the “flask” directory for creating an image of the Python Flask Application.
    $ vim flask/Dockerfile
FROM python: 3.7 - alpine
RUN mkdir / app
WORKDIR / app
ADD requirements.txt / app
ADD main.py / app
RUN pip3 install - r requirements.txt
CMD["gunicorn", "-w 4", "-b", "0.0.0.0:8000", "main:app"]
  1. Now create a file containing application requirements
    $ vim flask/requirements.txt
Flask == 1.1 .2
redis == 3.4 .1
gunicorn >= 19, < 20 F
  1. Also, create a conf file that will hold the routing configuration
    $ vim nginx/conf
server {
   listen 80;
   server_name localhost;
   location / {
      proxy_pass http: //app:8000;
   }
   location / hit {
      proxy_pass http: //app:8000/visitor;
   }
   location / hit / reset {
      proxy_pass http: //app:8000/visitor/reset;
   }
}
  1. Stay in your “/home/ubuntu/clickittech” directory and create a docker-compose.yml in it.
    $ vim docker-compose.yml
version: '3'
services: app: build: flask volumes: -app: /app    ports:      - "8000:8000"