DEV Community

janak0ff
janak0ff

Posted on

Day 47: Docker Python App

A python app needed to be Dockerized, and then it needs to be deployed on App Server 1. We have already copied a requirements.txt file (having the app dependencies) under /python_app/src/ directory on App Server 1. Further complete this task as per details mentioned below:

  1. Create a Dockerfile under /python_app directory:

    • Use any python image as the base image.
    • Install the dependencies using requirements.txt file.
    • Expose the port 6100.
    • Run the server.py script using CMD.
  2. Build an image named nautilus/python-app using this Dockerfile.

  3. Once image is built, create a container named pythonapp_nautilus:
    - Map port 6100 of the container to the host port 8099.

  4. Once deployed, you can test the app using curl command on App Server 1.

curl http://localhost:8099/
Enter fullscreen mode Exit fullscreen mode

Introduction

Welcome to Day 47 of my 100 Days of DevOps journey! Today, we're going to Dockerize a Python Flask application. This is a common real-world scenario where you need to package a Python app into a container for consistent deployment across different environments.

What We'll Build Today

We have a simple Flask application that returns a welcome message. Our task is to:

  1. Create a Dockerfile to containerize the app
  2. Build a Docker image
  3. Deploy it as a running container
  4. Test the application

📋 Prerequisites

Before we begin, make sure you have:

  • Access to App Server 1 (stapp01)
  • Docker installed on the server
  • Basic understanding of Python and Flask

🔍 Understanding the Application

Application Structure

/python_app/
└── src/
    ├── requirements.txt
    └── server.py
Enter fullscreen mode Exit fullscreen mode

File 1: requirements.txt

flask
Enter fullscreen mode Exit fullscreen mode

This file lists all Python dependencies. Here, we only need Flask.

File 2: server.py – The Flask Application

from flask import Flask

# the all-important app variable:
app = Flask(__name__)

@app.route("/")
def hello():
    return "Welcome to xFusionCorp Industries!"

if __name__ == "__main__":
    app.config['TEMPLATES_AUTO_RELOAD'] = True
    app.run(host='0.0.0.0', debug=True, port=6100)
Enter fullscreen mode Exit fullscreen mode

Let's understand this code:

Line Explanation
from flask import Flask Import Flask framework
app = Flask(__name__) Create Flask application instance
@app.route("/") Define route for the root URL
def hello(): Function that runs when root URL is accessed
return "Welcome to xFusionCorp Industries!" Response sent to the browser
app.run(host='0.0.0.0', debug=True, port=6100) Run app on all interfaces, port 6100

🔧 Step-by-Step Dockerization

Step 1: SSH to App Server 1

First, let's connect to our server:

ssh tony@stapp01
# Password: Ir0nM@n
Enter fullscreen mode Exit fullscreen mode

Switch to root user for administrative tasks:

sudo su -
# Password: Ir0nM@n
Enter fullscreen mode Exit fullscreen mode

Step 2: Navigate to the Application Directory

cd /python_app

# Check the directory structure
ls -la
Enter fullscreen mode Exit fullscreen mode

Expected Output:

total 12
drwxr-xr-x 3 root root 4096 Aug 10 16:01 .
dr-xr-xr-x 1 root root 4096 Aug 10 16:04 ..
drwxr-xr-x 2 root root 4096 Aug 10 16:01 src
Enter fullscreen mode Exit fullscreen mode

Go into the src directory to see the files:

cd src
ls -la
Enter fullscreen mode Exit fullscreen mode

Expected Output:

-rw-r--r-- 1 root root 6 Aug 10 16:01 requirements.txt
-rw-r--r-- 1 root root 200 Aug 10 16:01 server.py
Enter fullscreen mode Exit fullscreen mode

Step 3: View the Application Files

# View requirements
cat requirements.txt
# Output: flask

# View the Python code
cat server.py
Enter fullscreen mode Exit fullscreen mode

Step 4: Create the Dockerfile

Go back to the /python_app directory:

cd /python_app
Enter fullscreen mode Exit fullscreen mode

Create the Dockerfile:

vi Dockerfile
Enter fullscreen mode Exit fullscreen mode

Dockerfile Content:

# Use python image as base
FROM python:3.9-slim

# Set working directory inside container
WORKDIR /app

# Copy requirements.txt and install dependencies
COPY src/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy the application code
COPY src/ .

# Expose port 6100
EXPOSE 6100

# Run the server.py script
CMD ["python", "server.py"]
Enter fullscreen mode Exit fullscreen mode

📖 Understanding the Dockerfile

Instruction Explanation
FROM python:3.9-slim Base image – lightweight Python 3.9
WORKDIR /app Create and switch to /app directory in container
COPY src/requirements.txt . Copy requirements file to container
RUN pip install --no-cache-dir -r requirements.txt Install Flask dependency
COPY src/ . Copy all application code to container
EXPOSE 6100 Document that the app listens on port 6100
CMD ["python", "server.py"] Command to run when container starts

Step 5: Build the Docker Image

docker build -t nautilus/python-app /python_app/
Enter fullscreen mode Exit fullscreen mode

Let's break down this command:

  • docker build – Build an image from a Dockerfile
  • -t nautilus/python-app – Tag the image with name nautilus/python-app
  • /python_app/ – Build context (where Dockerfile is located)

Build Process Output:

[+] Building 8.0s (10/10) FINISHED
 => [internal] load build definition from Dockerfile
 => [internal] load metadata for docker.io/library/python:3.9-slim
 => [1/5] FROM docker.io/library/python:3.9-slim
 => [2/5] WORKDIR /app
 => [3/5] COPY src/requirements.txt .
 => [4/5] RUN pip install --no-cache-dir -r requirements.txt
 => [5/5] COPY src/ .
 => exporting to image
 => => naming to docker.io/nautilus/python-app
Enter fullscreen mode Exit fullscreen mode

Step 6: Verify the Image

# List all images
docker images

# Filter for our image
docker images | grep nautilus
Enter fullscreen mode Exit fullscreen mode

Expected Output:

nautilus/python-app   latest    c47a882442ec   30 seconds ago   180MB
Enter fullscreen mode Exit fullscreen mode

Step 7: Create and Run the Container

docker run -d --name pythonapp_nautilus -p 8099:6100 nautilus/python-app
Enter fullscreen mode Exit fullscreen mode

Understanding this command:

  • docker run – Create and start a container
  • -d – Run in background (detached mode)
  • --name pythonapp_nautilus – Name the container
  • -p 8099:6100 – Map host port 8099 to container port 6100
  • nautilus/python-app – The image to use

Step 8: Verify the Container is Running

docker ps | grep pythonapp_nautilus
Enter fullscreen mode Exit fullscreen mode

Expected Output:

ab657a0c3818   nautilus/python-app   "python server.py"   5 seconds ago   Up 4 seconds   0.0.0.0:8099->6100/tcp   pythonapp_nautilus
Enter fullscreen mode Exit fullscreen mode

Step 9: Test the Application

curl http://localhost:8099/
Enter fullscreen mode Exit fullscreen mode

Expected Output:

Welcome to xFusionCorp Industries!
Enter fullscreen mode Exit fullscreen mode

🔍 Additional Verification Commands

Check Container Logs

docker logs pythonapp_nautilus
Enter fullscreen mode Exit fullscreen mode

Expected Output:

 * Serving Flask app 'server'
 * Debug mode: on
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:6100
Enter fullscreen mode Exit fullscreen mode

Check Container Details

# Detailed container information
docker inspect pythonapp_nautilus

# Port mapping
docker port pythonapp_nautilus
# Output: 6100/tcp -> 0.0.0.0:8099
Enter fullscreen mode Exit fullscreen mode

Get Shell Inside Container

# Enter container shell
docker exec -it pythonapp_nautilus /bin/bash

# Inside container, you can check:
ls -la
python --version
exit
Enter fullscreen mode Exit fullscreen mode

📝 Complete Commands Summary

# SSH to App Server 1
ssh tony@stapp01
# Password: Ir0nM@n

# Switch to root
sudo su -
# Password: Ir0nM@n

# Navigate to directory
cd /python_app

# Create Dockerfile
cat > Dockerfile << 'EOF'
# Use python image as base
FROM python:3.9-slim

# Set working directory inside container
WORKDIR /app

# Copy requirements.txt and install dependencies
COPY src/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy the application code
COPY src/ .

# Expose port 6100
EXPOSE 6100

# Run the server.py script
CMD ["python", "server.py"]
EOF

# Build the image
docker build -t nautilus/python-app /python_app/

# Create and run container
docker run -d --name pythonapp_nautilus -p 8099:6100 nautilus/python-app

# Verify
docker ps | grep pythonapp_nautilus

# Test
curl http://localhost:8099/
Enter fullscreen mode Exit fullscreen mode

📊 Architecture Diagram

┌─────────────────────────────────────────────────────────────┐
│                      App Server 1                           │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐   │
│  │            pythonapp_nautilus Container              │   │
│  │                                                      │   │
│  │  ┌────────────────────────────────────────────┐     │   │
│  │  │         Flask Application                   │     │   │
│  │  │         (server.py)                        │     │   │
│  │  │         Port: 6100                         │     │   │
│  │  └────────────────────────────────────────────┘     │   │
│  │                                                      │   │
│  │  Docker Image: nautilus/python-app                   │   │
│  └──────────────────────────────────────────────────────┘   │
│                          │                                  │
│                          ▼                                  │
│                Port Mapping: 8099:6100                     │
│                          │                                  │
│                          ▼                                  │
│           curl http://localhost:8099/                      │
│                                                             │
│           Response: "Welcome to xFusionCorp Industries!"   │
└─────────────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

🎯 Key Concepts Explained

What is a Dockerfile?

A Dockerfile is a text file with instructions on how to build a Docker image. Think of it as a recipe:

  • Base Image: The starting point (like using a pre-made pizza crust)
  • Instructions: What to add and how to prepare (adding toppings)
  • Expose: What port the app uses (like the serving window)
  • CMD: What to run when the container starts (like turning on the oven)

Why Use python:3.9-slim?

  • python:3.9-slim is a lightweight version
  • It contains only what's necessary to run Python
  • Smaller image size → faster downloads and less storage

Port Mapping Explained

Host Port → Container Port
  8099    →     6100
Enter fullscreen mode Exit fullscreen mode
  • The app runs on port 6100 inside the container
  • We access it on port 8099 from outside
  • This prevents port conflicts if multiple containers use the same port

✅ Task Summary

Requirement Status Command/File
Create Dockerfile /python_app/Dockerfile
Use Python base image FROM python:3.9-slim
Install dependencies pip install -r requirements.txt
Expose port 6100 EXPOSE 6100
Run server.py CMD ["python", "server.py"]
Build image docker build -t nautilus/python-app
Create container pythonapp_nautilus
Port mapping 8099:6100
Application accessible curl http://localhost:8099/

🔧 Troubleshooting Common Issues

Issue 1: Dockerfile Not Found

Error: open Dockerfile: no such file or directory
Solution: Make sure Dockerfile is in the correct directory (/python_app)

Issue 2: Port Already in Use

Error: port is already allocated
Solution: Use a different host port or stop the conflicting container

Issue 3: Flask Not Found

Error: ModuleNotFoundError: No module named 'flask'
Solution: Check that requirements.txt contains flask and pip install ran successfully


🎉 You Did It!

You've successfully Dockerized a Python Flask application! This is exactly how real-world applications are containerized and deployed in production.

What You Learned:

  1. ✅ How to write a Dockerfile for Python applications
  2. ✅ How to build Docker images
  3. ✅ How to run containers with port mapping
  4. ✅ How to test containerized applications

Top comments (0)