Developing web applications with Python and Docker

Zachary Wilson
2 min readNov 27, 2018

Developing a web application with Python can seem like a daunting task. At first glance, the language’s strengths would appear to be geared towards scripting more so than full-blown application development. Building a production grade web application using only the Standard Library would be a grueling exercise. However, Python’s modular import system, pip, and a handful of external packages can make application development a much more palatable process, maybe even "fun" at times.

Configuring your environment

For Python purists, I highly recommend pipenv. For those looking for maximum flexibility and development platform independence, the only way to go is Docker. I use both (despite the fact that containerization essentially make virtual environments redundant).

You can install pipenv with pip

$ pip3 install pipenv

Create a virtual environment for your project

$ mkdir myproject && cd myproject/ && pipenv shell

You’ll also probably want to use a web framework. There are two major players in the Python web framework arena: Django and Flask. The best way to differentiate the two:

  • Django: Batteries included
  • Flask: Batteries not included

I actually recommend flask for beginners for a three reasons:

  1. It’s easier to get “up and running” with Flask. Django makes some assumptions about your experience level which may be confusing for newcomers.
  2. It pairs extraordinarily well with Docker.
  3. It helps beginners learn the fundamentals of application development but follows a predictable pattern that’s easy to build on.

A Minimal Web Application

Directory structure

myproject/
├── Dockerfile
├── Pipfile
├── Pipfile.lock
├── app
│ └── app.py
├── docker-compose.yml
└── requirements.txt

Create a requirements.txt file

$ echo "flask" >> requirements.txt

Here’s a minimal Python web application written using the Flask web framework.

from flask import Flask

app = Flask(__name__)


@app.route('/')
def home():
return "Hello, world!"


if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000, debug=True)

A Dockerfile containing build instructions

# Dockerfile
FROM python:alpine

ENV PYTHONUNBUFFERED 1

WORKDIR /usr/src/app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY ./app .

ENV FLASK_APP app.py

EXPOSE 5000

CMD ["python", "app.py"]

A docker-compose.yml file to build and run the application

version:      "3.7"

services:
app:
image: webapp
build: .
env_file: .env
environment:
- PYTHONUNBUFFERED=1
- FLASK_APP=app.py
- FLASK_ENV=development
- FLASK_DEBUG=True
ports:
- 5000:5000
volumes:
- ./app:/usr/src/app
command: python -m flask run --host 0.0.0.0

Now you can run the whole thing with

$ docker-compose up

--

--