Đóng gói ứng dụng Python bằng Docker

“Trên máy tôi chạy được” là câu nói đùa quen thuộc của giới lập trình. Docker đóng gói cả ứng dụng lẫn môi trường vào một image, để nó chạy giống hệt nhau ở mọi nơi.

Dockerfile cơ bản

FROM python:3.12-slim

WORKDIR /app

# Copy requirements TRƯỚC để tận dụng cache
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

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

Thứ tự này rất quan trọng. Docker lưu cache theo từng lớp — vì requirements.txt hiếm khi đổi, bước cài thư viện được dùng lại và mỗi lần build sau chỉ mất vài giây thay vì vài phút.

Build và chạy

docker build -t ungdung-cua-toi .
docker run --rm -p 8000:8000 ungdung-cua-toi

Bỏ qua file không cần thiết

# .dockerignore
__pycache__/
*.pyc
.venv/
.git/
.env
tests/

Thiếu file này, image của bạn sẽ phình to và — nguy hiểm hơn — có thể chứa cả file .env với mật khẩu bên trong.

Multi-stage build cho image gọn

FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt

FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Không chạy bằng quyền root

RUN useradd -m ungdung
USER ungdung

Nhiều dịch vụ với docker compose

# compose.yaml
services:
  web:
    build: .
    ports: ["8000:8000"]
    environment:
      DATABASE_URL: postgresql://postgres:matkhau@db:5432/app
    depends_on: [db]

  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: matkhau
    volumes:
      - dulieu:/var/lib/postgresql/data

volumes:
  dulieu:
docker compose up -d
docker compose logs -f web

Vài điều nên nhớ

  • Ghim phiên bản image (python:3.12-slim), đừng dùng latest.
  • Truyền cấu hình qua biến môi trường, đừng nướng secret vào image.
  • Dữ liệu cần giữ lại phải nằm trong volume — container là thứ dùng xong bỏ đi.

Khi đã quen, bạn sẽ thấy việc dựng lại toàn bộ môi trường cho một dự án cũ chỉ còn là một câu lệnh.

Lên đầu trang