DEV Community

Aisalkyn Aidarova
Aisalkyn Aidarova

Posted on

Docker Lab 2: Build and Run a Python Web Application in Docker

Goal

In this lab, students will learn how to:

  • Build a Docker image from a Python application.
  • Understand why developers use base images.
  • Install application dependencies.
  • Run a Python web server inside a container.
  • Access the application from a browser.
  • See how DevOps engineers package backend applications.

Real DevOps Scenario

Imagine a Python developer finishes building a REST API.

Without Docker, every server must have:

  • Python installed
  • pip installed
  • Required libraries installed
  • Correct Python version

This often causes problems.

Example:

Developer Laptop
Python 3.12
Flask 3.0

↓

Production Server

Python 3.9
Flask missing

↓

Application fails
Enter fullscreen mode Exit fullscreen mode

Docker solves this problem by packaging everything together.


Step 1: Create the Project Folder

mkdir docker-python-lab
cd docker-python-lab
Enter fullscreen mode Exit fullscreen mode

Step 2: Create the Application

Create app.py

touch app.py
Enter fullscreen mode Exit fullscreen mode

Open it:

nano app.py
Enter fullscreen mode Exit fullscreen mode

Paste:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return "<h1>Hello from Python inside Docker!</h1>"

@app.route("/about")
def about():
    return "<h2>This application is running inside a Docker container.</h2>"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)
Enter fullscreen mode Exit fullscreen mode

Save.


Step 3: Create Requirements File

touch requirements.txt
Enter fullscreen mode Exit fullscreen mode

Open:

nano requirements.txt
Enter fullscreen mode Exit fullscreen mode

Add:

Flask==3.0.3
Enter fullscreen mode Exit fullscreen mode

Save.


Why do we need requirements.txt?

Developers use this file to list all Python packages required by the application.

Instead of manually installing software, Docker reads this file and installs everything automatically.


Step 4: Create Dockerfile

touch Dockerfile
Enter fullscreen mode Exit fullscreen mode

Paste:

FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 5000

CMD ["python", "app.py"]
Enter fullscreen mode Exit fullscreen mode

Explain Every Line

FROM

FROM python:3.12-slim
Enter fullscreen mode Exit fullscreen mode

Downloads a lightweight Python image.

Instead of installing Python ourselves, Docker already has it prepared.


WORKDIR

WORKDIR /app
Enter fullscreen mode Exit fullscreen mode

Creates and switches into the /app directory inside the container.

Every command after this runs from there.


COPY

COPY requirements.txt .
Enter fullscreen mode Exit fullscreen mode

Copies only the requirements file first.

This improves Docker caching because dependencies usually change less often than the application code.


RUN

RUN pip install --no-cache-dir -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

Installs Flask inside the image.


COPY

COPY . .
Enter fullscreen mode Exit fullscreen mode

Copies the rest of the application files.


EXPOSE

EXPOSE 5000
Enter fullscreen mode Exit fullscreen mode

The Flask application listens on port 5000.


CMD

CMD ["python","app.py"]
Enter fullscreen mode Exit fullscreen mode

Runs the application when the container starts.


Step 5: Build Image

docker build -t python-app:v1 .
Enter fullscreen mode Exit fullscreen mode

Step 6: Check Images

docker images
Enter fullscreen mode Exit fullscreen mode

Expected:

python-app
python
Enter fullscreen mode Exit fullscreen mode

Step 7: Run Container

docker run -d -p 5000:5000 --name python-container python-app:v1
Enter fullscreen mode Exit fullscreen mode

Step 8: Open Browser

Visit:

http://localhost:5000
Enter fullscreen mode Exit fullscreen mode

You should see:

Hello from Python inside Docker!
Enter fullscreen mode Exit fullscreen mode

Try:

http://localhost:5000/about
Enter fullscreen mode Exit fullscreen mode

Step 9: View Logs

docker logs python-container
Enter fullscreen mode Exit fullscreen mode

Step 10: Enter the Container

docker exec -it python-container bash
Enter fullscreen mode Exit fullscreen mode

Inside the container:

pwd
ls
python --version
pip list
Enter fullscreen mode Exit fullscreen mode

Exit:

exit
Enter fullscreen mode Exit fullscreen mode

Step 11: Stop and Remove

docker stop python-container
docker rm python-container
Enter fullscreen mode Exit fullscreen mode

What Students Learned

  • How Docker packages Python applications.
  • Why requirements.txt is important.
  • What WORKDIR, COPY, RUN, and CMD do.
  • How backend applications are containerized.

Docker Lab 3: Multi-Container Application with Docker Compose

Goal

Students will learn:

  • Why applications often have multiple services.
  • What Docker Compose is.
  • How containers communicate.
  • How DevOps engineers run full environments locally.

Real DevOps Scenario

A real application rarely consists of one container.

For example:

Browser
   │
   ▼
Frontend (React)
   │
   ▼
Backend API (Python)
   │
   ▼
Database (PostgreSQL)
Enter fullscreen mode Exit fullscreen mode

Managing each container separately becomes difficult.

Docker Compose lets us define the entire environment in one file.


Step 1: Create the Project

mkdir docker-compose-lab
cd docker-compose-lab
Enter fullscreen mode Exit fullscreen mode

Step 2: Create index.html

<!DOCTYPE html>
<html>
<head>
    <title>Docker Compose Lab</title>
</head>
<body>
    <h1>Docker Compose is Working!</h1>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Step 3: Create Dockerfile

FROM nginx:latest

COPY index.html /usr/share/nginx/html/

EXPOSE 80
Enter fullscreen mode Exit fullscreen mode

Step 4: Create docker-compose.yml

version: "3.9"

services:

  website:
    build: .
    container_name: mywebsite

    ports:
      - "8080:80"
Enter fullscreen mode Exit fullscreen mode

Explain the Compose File

version

Defines the Compose file format.


services

Lists all containers in the application.

Right now we only have one.

Later you can add:

  • frontend
  • backend
  • database
  • redis
  • rabbitmq

build

build: .
Enter fullscreen mode Exit fullscreen mode

Build the image from the current directory.


container_name

Names the container.


ports

8080:80
Enter fullscreen mode Exit fullscreen mode

Maps your laptop's port 8080 to port 80 inside the container.


Step 5: Start Everything

docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Compose will:

  1. Build the image.
  2. Create the container.
  3. Start the container.

Step 6: Check Running Containers

docker ps
Enter fullscreen mode Exit fullscreen mode

Step 7: Open Browser

http://localhost:8080
Enter fullscreen mode Exit fullscreen mode

You should see:

Docker Compose is Working!
Enter fullscreen mode Exit fullscreen mode

Step 8: View Logs

docker compose logs
Enter fullscreen mode Exit fullscreen mode

Step 9: Stop Everything

docker compose down
Enter fullscreen mode Exit fullscreen mode

This removes the container created by Docker Compose.


What Students Learned

Students now understand that:

  • Docker manages individual containers.
  • Docker Compose manages multiple containers together using a single configuration file.
  • In real DevOps environments, Compose is commonly used by developers for local testing, while orchestration platforms such as Kubernetes are used in production.

Top comments (0)