Python Workflow with Docker

2014-09-02 16:43

Here are some initial notes on a workflow setup for Python web development using Docker.

Note: This is not a HowTo nor a Beginners Guide.

Advantages

  • Rapid startup for new projects
  • Rapid setup for new developers
  • Isolated development environment
  • Identical environment for development, test and production
  • Automated integration test
  • Automated delivery
  • Easy to add new instances (scalable)
  • Provider independent
  • Easy to migrate

Heterogeneous Environment

If you are working in a heterogeneous environment where your desktop operating system differs from your target OS and you are unable to install Docker locally you can use Vagrant to host a development environment. This is probably only true if you're unfortunately to have Windows as your desktop.

Make sure Vagrant and Git is installed and then create the host OS in Vagrant by running the following from a command prompt:

git clone https://github.com/roppert/vagrantdocker
cd vagrantdocker
vagrant up

Congrats, you just installed a development host OS! Everything under vagrantdocker directory will be mapped to the directory /vagrant in the Vagrant system you just started.

Note: If using Vagrant you should use /vagrant as the root working directory for the purpose of this document.

The Docker image

Start out by creating a working directory for your project. (If using a Vagrant image you should create this directory inside the /vagrant directory inside the Vagrant system.)

mkdir myproject && cd myproject

Then check out a what we will use as the base for our Docker image and build it:

git clone https://github.com/mrmrcoleman/python_webapp
cd python_webapp
sudo docker build -t python_webapp .

Now move back to the project directory and clone the example flask project:

cd ..
git clone https://github.com/amouat/example_app
cd example_app
sudo docker build -t example_app .
docker run -p 5000:5000 -v $(pwd)/example_app:/opt/example_app/ -i -t example_app

Now you can access the example_app from your desktop by pointing your browser to http://localhost:5000/.

Starting Docker as shown above launches the application through Apache just as it would run in production. To run it for development we explicitly gives it a command to run:

docker run -p 5000:5000 -v $(pwd)/example_app:/opt/example_app/ -i -t example_app python /opt/example_app/run.py

Now we can edit the code in our IDE on our desktop and have the code automatically reloaded in the docker container to reflect our development.

What happened here?

First we created a Vagrant VM to host the development environment. To understand this take a look at the project https://github.com/roppert/vagrantdocker. Vagrantfile contains instructions for how to setup the VM and it references the Manifest/init.pp that contains instructions to be run by Puppet on startup of this new VM.

Next we built a base Docker image from the project https://github.com/mrmrcoleman/python_webapp. Take a look at the Dockerfile to understand how this is orchestrated.

After this we made use of this base image to create a Docker image for our own project by utilizing the project https://github.com/amouat/example_app. Take a look at its Dockerfile to understand how it does this. In a real world situation we would clone the example_app project as the scaffolding for our project. The vagrantdocker and example_app we would leave unchanged as they are part of our infrastructure and not a part of our project.

Where to go next

The next step is to extend this setup to enable Continuous Integration (CI) and Continuous Delivery (CD). The step after that is to setup system monitoring and alerts.

Resources

  1. Python
  2. Docker User Guide
  3. Docker as Python Developer Environment
  4. Vagrant
  5. Git
  6. Puppet