Python - Flask App - Docker: Dev and Prod Environments
Docker Container Development Environment

Python - Flask App - Docker: Dev and Prod Environments

Recently I explored setting up a Development environment for Python Flask application. The development environment was a breeze to setup but when it was time to move it to an Amazon EC2 Instance, I soon realized that the python manage.py runserver was not going to be a viable option. You ask why?? Well python manage.py runserver starts a development server and if you are a .NET Developer like me you know that cassini is not a production hosting environment.

The recommended setup is NGINX with UWSGI and there are several steps involved in moving the application to Production. I felt that though these steps might not have to repeated it might always help to have a "Production Like" Development environment on the Macbook alongside the development environment for performance benchmarking or debugging.

Enter Docker and Docker Containers. A Lightweight solution to replicate Production Like environments without buying additional hardware to replicate production environments in development machines.

So I went ahead to create the necessary Docker Files and Docker-Compose files for both the development environment and "Production Like" environment on Development machines. All the necessary files can be found at https://bitbucket.org/patvin80/basicflaskapp/overview

Docker Development Environment:

  1. Dockerfile-dev is a Docker file to build the Web Container which holds the Web Component of the Python Flask Application.
  2. docker-compose-dev.yml file which is used to build the Postgres Database Container and adds the dependency to the web container.
  3. Build the containers in the development environment by executing the command as:
docker-compose --file docker-compose-dev.yml up  --build

Note: --file argument in the up command.

Some Gotchas:

  • In the Development environment, since we have mapped the current directory to the /app folder in the container, any changes to the local folder will take effect in the docker container and will reflect in the application.
volumes:
 - .:/app
  • To start the application, the CMD in the docker file is the command you would use to start the application locally with the port and host specified.
CMD python manage.py runserver -h https://www.dhirubhai.net/redir/invalid-link-page?url=0%2e0%2e0%2e0 -p 80 -d
  • In the docker-compose file the Postgres image has abilities to create a new database and database user with environment variables.
  environment:
    - POSTGRES_USER=test
    - POSTGRES_PASSWORD=test
    - POSTGRES_DB=test_db
  • The data in the database volumes can be made permanent by leveraging volumes and mapping the volumes to the postgres-data folder of the local drive.
image: "postgres:9.4"
volumes:
  - ./postgres-data:/var/lib/postgresql/data
  • While building the Web Container, the default behavior is to build the file named Dockerfile when build . is specified. This can be overridden using the following in the compose file:
build:
  context: .
  dockerfile: Dockerfile-dev
  • Once the containers are up the, the application can be accessed in the development environment using the URL https://localhost:4444. If you are wondering if you started the app with port 80, why is it accessible at 4444? Well that happens because of the port mapping in the Docker-compose-dev.yml file:
ports:
 - "4444:80"
  • Instead of using the default command docker-compose up --build, we need to specify that docker-compose use the docker-compose-dev.yml file. Hence the --file attribute in the command.

Production Like Environment

For setting up the Production like environment, we rely on the images on the docker hub provided by https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask/. The best part of leveraging images is that it comes preinstalled with most of the software packages relevant to your solution and excludes the ones you do not need (Virtual Machine like :-))

As we are using an image our docker file is relatively simple:

FROM tiangolo/uwsgi-nginx-flask:flask

COPY . /app

# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt

The Docker-Compose file looks similar to the development file but instead of exposing the web on port 4444 we are now hosting on 80 so that it would be similar to the hosting environment. Also since the file is called Docker File we simply provide the build as .

  web:
    build: .
    ports:
     - "80:80"
    volumes:
     - .:/app
    links: 
      - db

To bring up the Production Like environment we simply build the images and up the containers using the command:

docker-compose up -- build

Some Gotchas:

  • The USGI.ini file is included in the project and is not the same as the one provided in the documentation of the images. One of the limitations of using the image is that app = Flask() has to be initialized in the main.py file. In my case I was using the app.py file and hence I had to overwrite the default behavior:
[uwsgi]
module = app
callable = app
  • Code Updates are not reflected real time and need to build the images using the docker-compose up --build command.




要查看或添加评论,请登录

社区洞察

其他会员也浏览了