Danh sách bài viết trong series Sử dụng Docker từ cơ bản đến nâng cao
- Bài 1. Cơ Bản Docker: Hiểu Container và Vai Trò trong DevOps
- Bài 2. Docker Image: cách xây Dựng và tối Ưu
- Bài 3. Docker Networking: Kết Nối Container Hiệu Quả
- Bài 4. Docker Volume: Quản Lý Dữ Liệu Hiệu Quả cho Container
- Bài 5. Docker Compose: Điều Phối Multi-Container Hiệu Quả
- Bài 6. Docker Swarm: Orchestration Cơ Bản để Scale Container
- Bài 7. Docker Security: Bảo Mật Container Hiệu Quả
- Bài 8. Docker CI/CD: Tích Hợp Container vào Pipeline DevOps
- Bài 9. Docker Monitoring: Theo Dõi và Logging Container Hiệu Quả
- Bài 10. Docker resources: Tối Ưu và Debug Container Hiệu Quả
- Bài 11. Docker và Microservices: Thiết Kế Ứng Dụng Phân Tán
- Bài 12. Docker Registry: Tự Host và Quản Lý Image Hiệu Quả
- Bài 13. Docker với Cloud: Tích Hợp Container trên AWS ECS và GCP Cloud Run
Docker không chỉ là chạy container – nó bắt đầu từ Docker Image, “bản thiết kế” để tạo ra container. Trong DevOps, việc xây dựng image nhẹ, nhanh, và đáng tin cậy là yếu tố sống còn để tối ưu pipeline CI/CD. Trong bài thứ hai của series, chúng ta sẽ đi sâu vào Docker Image trong DevOps, đặc biệt tập trung vào Dockerfile chuyên sâu, cách build container hiệu quả, và kỹ thuật tối ưu image để giảm kích thước, tăng tốc độ. Hãy chuẩn bị để làm chủ nghệ thuật tạo image!
Docker Image Là Gì?
Định Nghĩa và Cấu Trúc
Docker Image là tập hợp các layer (lớp) chỉ đọc, chứa mã nguồn, thư viện, và cấu hình cần thiết để chạy ứng dụng trong container.
- Layer: Mỗi lệnh trong Dockerfile tạo một layer, được cache để tái sử dụng.
- Ví dụ: Image
nginx:alpine
gồm layer cơ bản (Alpine Linux) và layer Nginx.
DevOps: Image là “gói hàng” bạn build trong CI, push lên registry, và deploy trong CD.
Image vs Container
- Image: Template tĩnh, không chạy.
- Container: Instance động của image, chạy trên Docker Engine.
Thực tế: Một image Python có thể sinh ra hàng trăm container test trong pipeline.
Dockerfile Chuyên Sâu: Xây Dựng Image Từ Đầu
Cấu Trúc Dockerfile
Dockerfile là file script định nghĩa cách build image. Các lệnh chính:
- FROM: Base image khởi đầu.
FROM ubuntu:20.04
- RUN: Chạy lệnh trong image (cài package, update).
RUN apt update && apt install -y python3
- COPY: Sao chép file từ host vào image.
COPY app.py /app/
- WORKDIR: Đặt thư mục làm việc.
WORKDIR /app
- CMD: Lệnh mặc định khi container chạy.
CMD ["python3", "app.py"]
- EXPOSE: Công khai port (thông tin, không bind).
EXPOSE 8080
- ENV: Đặt biến môi trường.
ENV APP_ENV=production
DevOps: Dockerfile là “công thức” để đảm bảo môi trường nhất quán từ dev đến prod.
Layer Caching: Bí Mật Tăng Tốc Build
Docker cache layer để tránh chạy lại lệnh không thay đổi.
- Nguyên tắc: Thứ tự lệnh ảnh hưởng cache.
- Ví dụ sai:
FROM python:3.9 COPY . /app RUN pip install -r requirements.txt
COPY .
thay đổi → cacheRUN
bị phá, build chậm.
- Ví dụ đúng:
FROM python:3.9 RUN pip install -r requirements.txt COPY . /app
RUN
được cache nếurequirements.txt
không đổi.
DevOps: Tối ưu cache giảm thời gian build trong pipeline từ phút xuống giây.
Multi-Stage Build: Giảm Kích Thước Image
Multi-stage build dùng nhiều FROM
để tách build và runtime.
-
Ví dụ:
# Stage 1: Build FROM python:3.9 AS builder WORKDIR /app COPY requirements.txt . RUN pip install --user -r requirements.txt # Stage 2: Runtime FROM python:3.9-slim WORKDIR /app COPY --from=builder /root/.local /root/.local COPY app.py . CMD ["python3", "app.py"]
- Kết quả: Image chỉ chứa runtime, loại bỏ tool build (VD: giảm từ 900MB xuống 150MB).
DevOps: Image nhỏ hơn → push/pull nhanh hơn trong CI/CD.
Tối Ưu Image: Kỹ Thuật Nâng Cao
Chọn Base Image Nhẹ
- Alpine: ~5MB, nhỏ nhất.
- Slim: Cân bằng giữa nhỏ và đầy đủ (VD:
python:3.9-slim
~80MB). - Ví dụ:
FROM alpine:3.14 RUN apk add --no-cache python3
Gộp Lệnh RUN
- Giảm layer, giảm kích thước metadata:
RUN apt update && apt install -y python3 && apt clean
Xóa File Thừa
- Xóa cache package sau cài đặt:
RUN apt update && apt install -y python3 && rm -rf /var/lib/apt/lists/*
Dùng .dockerignore
- Loại file không cần (VD:
.git
,node_modules
):# .dockerignore .git *.md
DevOps: Image tối ưu giảm tải registry, tăng tốc deploy.
Thực Hành: Build Image Chuyên Sâu
Tạo Ứng Dụng Python
-
File
app.py
:from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return "Hello DevOps!" if __name__ == "__main__": app.run(host="0.0.0.0", port=8080)
- File
requirements.txt
:flask==2.0.1
Dockerfile Tối Ưu
# Stage 1: Build
FROM python:3.9-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# Stage 2: Runtime
FROM python:3.9-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY app.py .
ENV PATH=/root/.local/bin:$PATH
EXPOSE 8080
CMD ["python3", "app.py"]
Build và Test
- Build:
docker build -t myapp:latest .
- Chạy:
docker run -d -p 8080:8080 myapp:latest
- Test:
curl localhost:8080
- Kết quả: “Hello DevOps!”.
Kiểm Tra Kích Thước
docker images myapp:latest
- So sánh:
python:3.9
(~900MB) vsmyapp
(~150MB).
Debug tip:
- Build lỗi: Xem log
docker build -t myapp . --no-cache
. - Container không chạy: Check
docker logs <container-id>
.
Ứng Dụng trong DevOps
Microservices
- Mỗi service có Dockerfile riêng, tối ưu riêng (VD: web dùng
nginx:alpine
, API dùngpython:slim
).
Case study: Một team giảm kích thước image từ 1.2GB xuống 200MB với multi-stage, tăng tốc pipeline 3 lần.
Kết Luận
Docker Image trong DevOps là bước quan trọng để tạo container hiệu quả. Với Dockerfile chuyên sâu, từ layer caching, multi-stage build, đến kỹ thuật tối ưu image, bạn có thể xây dựng image nhẹ, nhanh cho CI/CD. Bài tiếp theo, chúng ta sẽ khám phá Docker Networking – cách kết nối container trong DevOps.