docker pull chỉ tải image có sẵn. Muốn tạo image riêng cho ứng dụng của bạn — cần Dockerfile. File cấu hình mô tả: base image nào, cài thư viện gì, copy file nào, chạy lệnh gì khi start.Build pipeline: Dockerfile → Image → Container
# Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]# requirements.txt
flask==3.1.0# app.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello(): return "Hello from Docker! 🐳"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)# Build image
docker build -t my-first-app .
# -t: tag name | .: context (thư mục hiện tại)
# Chạy container
docker run -d -p 5000:5000 --name my-app my-first-app
# Kiểm tra
curl localhost:5000
# Hello from Docker! 🐳FROM — Base image (VD: FROM node:20-alpine)WORKDIR — Thư mục làm việc (VD: WORKDIR /app)COPY — Copy file từ host vào image (VD: COPY . .)RUN — Chạy lệnh khi build (VD: RUN npm install)CMD — Lệnh mặc định khi container chạy (VD: CMD ["node", "index.js"])EXPOSE — Thông báo cổng container (chỉ documentation, vẫn cần -p)ENV — Biến môi trường mặc định (VD: ENV NODE_ENV=production)# ❌ Không tối ưu — cài lại deps mỗi khi sửa code
FROM node:20-alpine
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "index.js"]
# ✅ Tối ưu — tận dụng cache
FROM node:20-alpine
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm install # Cache: chỉ chạy lại khi package.json thay đổi
COPY . .
CMD ["node", "index.js"]my-flask-app với 3 file: app.py, requirements.txt, Dockerfiledocker build -t flask-app .docker images | grep flask — xem image vừa builddocker run -d -p 5000:5000 --name flask flask-apphttp://localhost:5000 — thấy Hello from Docker!app.py, build lại, chạy lại — thấy thay đổidocker logs flask — xem log1. Tại sao nên COPY package.json / requirements.txt trước code?
2. CMD khác gì so với RUN?