Develop a Python Flask Application with Docker and Deploy to AWS – Part 1 Docker Beginnings

aws docker flask python Jan 11, 2019

I am currently taking the Udacity Machine Learning Engineer Nanodegree, and as a part of my project I wanted to deploy my dockerized machine learning model, along with a (very) simple front end interface, to AWS. I needed to review some materials, and realized I was having a lot of trouble finding a single resource that went from A-Z in all the various moving pieces. In this series I will go over:

  • Build a single docker container using Miniconda
  • Create a small python flask application
  • Serve our flask application with docker-compose
  • Deploy our application to AWS

The Sweet Promise of Victory

Have you ever had an idea completely crash and burn because you couldn't move it from your computer to the remote server, or the cloud, or because you updated your operating system and broke absolutely everything?

Me too! (I break operating systems frequently. It's a problem.) 

That is why I started developing, from start to finish, in docker. I build, I copy, I deploy.

What is Docker? Why Should you Use Docker?

Why should you use docker? Docker images can be versioned (you can undo bad things!), shared, and run from everywhere. Are you on Mac, but your colleague is on Windows?  Are you on a windows, but want to deploy your application to the cloud? Do you have dreams of world domination? Use docker!

  •  Docker containers are cross platform, and act the same whether run on Mac, Linux, or Windows. 
  •  Docker containers can be deployed anywhere - cloud (AWS, GCP, Azure), remote servers, or your coworkers desktop. 
  •  Docker containers can be saved, versioned, and uploaded to share.

I go into some detail about docker here, I'm taking more of a build stuff approach, but there are much more in depth guides and classes around. I found a particularly good one here on medium titled Docker - from the beginning. 

Install Docker

If you don't already have docker installed, the best thing is to head on over to the official docker site and download the correct docker for you computer. ​Docker Install

Getting Started With Docker and Python

I always use the anaconda distribution of python. I adore the conda package manager, and you can use it to install much more than just python packages. Luckily, there is a base miniconda docker image all prepared for us. All that we need now is just a Dockerfile and a conda environment definition.

The Dockerfile

The Dockerfile is our build definition for our images. It informs docker of the base image we want to use (ubuntu, centos, miniconda, mysql, etc), any additional packages, custom files, and finally, custom commands. 

The Software Stack

My favorite method of building software stacks is to use conda. Specifically, I like to use the conda env utility in conda. In a nutshell to use conda env, you create a software stack definition (shown below), and tell conda to create the environment.

Build Your Container

Let's download the files and start building!

Download the Files

wget https://gist.githubusercontent.com/jerowe/7c7057ce26b13c596cd3728006e43a70/raw/17220abdba4cfa65cc4bc6dca41716ea99d1490e/python-flask-dockerfile.Dockerfile -O Dockerfile
wget https://gist.githubusercontent.com/jerowe/8d4ecbe4b51d0a2d9463e68d2ad7a991/raw/68ad9f717d6a77b7e8c8a1b42cf01b13c41ddc5e/flask-app-environment.yml -O flask-app-environment.yml
Bash

Build your docker container

That's it. Now you're ready to build your docker container, which will have your software stack all ready for you.

docker build --rm -t python_flask_app:latest .
Bash

We can break down this command.

COMMAND

ACTION

docker build

Tells docker we want to build an image

--rm

Remove the build cache - this is very important if you want to avoid filling up your filesystem!

-t

Add a tag to the image, or give the image a name. This is important for eventually uploading images, and because you don't want to search for images by hash

 (No Flag) build context (.)

Supply the build context. We are building a file in our current working directory, relative to our current working directory, so its just ., or $(pwd) . If we wanted to build a docker image using a dockerfile in the directory python_app, we would supply python_app.

Use Your Docker Container

For production use what you normally want to do is to supply a runtime command, using the CMD parameter in the Dockerfile. Since we haven't actually developed our flask app yet, we don't have a runtime command. Instead we are just going to ensure that our image works as expected.

Run a single command and exit

Sometimes you just want to deploy your docker container as a binary, and not worry about running anything else. There are many possible reasons for this, but a few include:

  •  Divvy up responsibilities for a codebase among coworkers (server side, client side)
  •  Train and deploy a machine learning model
  •  Containerize a particularly complex build or configuration
  •  Try out a cool piece of tech without muddying up your base OS.
docker run -it python_flask_app:latest echo "hello"
hello
Bash

In this example we are issuing a simple bash command, but I hope you can see how this can be extended to run more complex scripts and workflows.

Run an interactive shell

An extremely useful function of docker containers it that are literally a container of an operating system. I can drop into a shell on a docker container in the exact same fashion as sshing to a remote server, and running a shell there.

docker run -it python_flask_app:latest bash
Bash

Supplying 'bash' as the command puts is in an ordinary shell inside the container. Try it out! Check what your current working directory is, what user you are, which files are present, or ensure your programs are present in your path, or open an ipython terminal session. Anything you can do on a regular linux terminal you can do in a docker container.