Develop a Python Flask Application with Docker and Deploy to AWS – Part 1 Docker Beginnings
Jan 12, 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!
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
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.
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:
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.
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.