Skip to content

Dockerizing Python Apps

  • Concept: Python applications can be bundled and distributed at various levels of system isolation, ranging from simple code archives to full hardware deployments.
  • Packaging Strategies:
    • Native Packaging: wheel (.whl) or source archives (.tar.gz). Handled via pip.
    • System Packages: .rpm (RedHat/CentOS) or .deb (Debian/Ubuntu).
    • Conda Packages: Managed via the Anaconda ecosystem, excellent for data science dependencies.
    • Freezers: Tools like PyInstaller or PyOxidizer that compile Python code and the interpreter into a single standalone executable binary.
    • Container Images: Docker. Packages the code, runtime, system tools, and system libraries into an isolated OS-level unit.
    • Virtual Machines: Heavyweight isolation including a full guest operating system.
    • Hardware: Plug-and-play physical deployment.

  • Concept: A Dockerfile is a strict set of sequential instructions that the Docker engine reads to automatically build your isolated application image.
  • Methods & Syntax:
    • FROM: Defines the base OS and Python version to pull from Docker Hub.
    • WORKDIR: Creates and sets the default directory inside the container for subsequent commands.
    • COPY: Transfers files from your host machine into the container’s filesystem.
    • RUN: Executes bash commands during the build phase (used for installing dependencies).
    • CMD: Defines the default command that runs when the container starts (not during the build).

Program (Dockerfile):

# 1. Set base image (Host OS + Python Interpreter)
FROM python:3.8
# 2. Set the working directory inside the container
WORKDIR /code
# 3. Copy the dependency manifest first (optimizes Docker caching)
COPY requirements.txt .
# 4. Install Python dependencies
RUN pip install -r requirements.txt
# 5. Copy the actual application source code into the working directory
COPY src/ .
# 6. Command to execute when the container successfully boots
CMD [ "python", "./server.py" ]

  • Concept: Once the Dockerfile is written, you must compile it into an Image, and then deploy that Image as a running Container.
  • Methods & Syntax:
    • docker build -t <image_name> .: Reads the Dockerfile in the current directory (.) and compiles it into an image tagged with a specific name.
    • docker run: Boots the image into a live container.
    • it: Runs the container interactively (attaches your terminal to it).
    • -rm: Automatically deletes the container from your system the moment it stops running (keeps your system clean).
    • -name: Assigns a human-readable name to the running container instance.

Program (Terminal Execution):

Terminal window
# 1. Build the image
$ docker build -t my-python-app .
# 2. Run the application
$ docker run -it --rm --name my-running-app my-python-app
# (Note: For complex multi-container apps, 'docker-compose' is used instead of running raw docker commands)

  • Concept: The FROM command dictates your container’s underlying architecture. You must balance image file size against dependency compatibility.
  • The Image Variants:
    • Full Official Image (python:x.x.x): Based on the latest stable Debian OS.
      • The safest, most stable choice. It contains all standard system libraries. Best used at the start of a project or when image size is not a concern.
    • Slim Image (python:x.x.x-slim): Based on Debian, but stripped down.
      • Only installs the bare minimum packages needed to run Python. Excellent for saving space, but requires strict Unix knowledge to manually install missing C-libraries if your app needs them.
    • Alpine Image (python:x.x.x-alpine): Based on the Alpine Linux Project.
      • Historically popular because it is incredibly tiny. However, it uses musl instead of glibc (standard C library). This causes massive compatibility issues with complex Python packages (like Pandas, Numpy, or Cryptography) that are extremely difficult to debug. Use with severe caution.