Hệ quả bảo mật và Biện pháp giảm thiểu rủi ro
Mặc dù build arguments mang lại sự linh hoạt, chúng cũng tiềm ẩn rủi ro bảo mật mà bạn cần hiểu rõ để giữ image Docker an toàn.
Các hướng rò rỉ tham số
Build arguments không riêng tư như bạn nghĩ. Giá trị của build args có thể rò rỉ qua nhiều kênh mà nhiều lập trình viên bỏ qua. Đầu tiên, lịch sử image Docker hiển thị tất cả build args của bạn, nghĩa là bất kỳ ai có quyền truy cập image đều có thể chạy docker history để xem các giá trị dùng lúc build, bao gồm thông tin nhạy cảm như API key hoặc token.
docker history flaskapp:dev

Hình 4 - Docker history
Các layer trung gian cũng có thể làm rò rỉ build args. Ngay cả khi bạn dùng build đa giai đoạn và không copy layer chứa thông tin nhạy cảm, giá trị build arg vẫn tồn tại trong bộ nhớ đệm layer trên máy build. Điều này có nghĩa bất kỳ ai có quyền truy cập Docker daemon trên máy chủ build đều có thể trích xuất thông tin này.
Log của CI/CD cũng là một rủi ro đáng kể khác. Hầu hết hệ thống CI/CD ghi lại toàn bộ lệnh build, bao gồm mọi build arg truyền trên dòng lệnh.
Ví dụ, toàn bộ lệnh này, bao gồm API_KEY, sẽ hiển thị trong log CI/CD:
docker build --build-arg API_KEY=secret123 -t myapp:latest .
Các log này thường được truy cập bởi nhiều lập trình viên hơn hoặc thậm chí lưu trữ trên hệ thống bên thứ ba, làm tăng bề mặt phơi lộ của các giá trị nhạy cảm.
Các lựa chọn thay thế an toàn
Với thông tin nhạy cảm, bạn nên dùng tính năng secrets của Docker BuildKit thay vì build args. BuildKit cho phép bạn mount secrets trong quá trình build mà không lưu chúng trong image cuối cùng hoặc lịch sử.
Dưới đây là ví dụ Dockerfile sử dụng secrets của Docker BuildKit:
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
# Use secret mount instead of build arg
RUN --mount=type=secret,id=api_key \
cat /run/secrets/api_key > api_key.txt
EXPOSE 5000
CMD ["python", "app.py"]
Để build image này với secret, trước tiên tạo tệp api_key.txt:
echo "my-secret-api-key" > api_key.txt
Sau đó build image kèm secret:
DOCKER_BUILDKIT=1 docker build \
--secret id=api_key,src=api_key.txt \
-t flaskapp:secure .

Hình 5 - Build image với BuildKit secrets
Với cấu hình cần có khi runtime, biến môi trường vẫn là cách tiếp cận ưu tiên. Chúng có thể được đặt khi khởi chạy container mà không bị nhúng vào image:
# Set environment variables at runtime
docker run -e API_KEY=secret123 -p 5000:5000 flaskapp:latest
Để xử lý an toàn cấu hình nhạy cảm trong sản xuất, hãy cân nhắc dùng các nền tảng điều phối container như Kubernetes, nền tảng này cung cấp phương thức bảo mật như Secrets để quản lý thông tin nhạy cảm. Docker Swarm cũng có khả năng tương tự với quản lý secrets.
> Docker không phải nền tảng container duy nhất. Đọc về Podman để xem công cụ nào phù hợp hơn với bạn.
Hãy nhớ nguyên tắc: dùng build args cho cấu hình lúc build không nhạy cảm, dùng BuildKit secrets cho nhu cầu nhạy cảm lúc build, và dùng biến môi trường hoặc secrets của nền tảng điều phối cho cấu hình lúc runtime.
Tích hợp với Hệ sinh thái Container
Giờ khi đã nắm vững cơ bản, hãy khám phá cách tận dụng build arguments trong hệ sinh thái Docker rộng hơn và các công cụ build hiện đại.
Docker Compose
Docker Compose giúp bạn dễ dàng định nghĩa và chia sẻ build arguments trên các ứng dụng đa container.
Nếu muốn thực hành theo, dưới đây là cấu trúc dự án hoàn chỉnh cho hai dịch vụ Flask đơn giản:
flask-project/
├── docker-compose.yml # Main compose configuration
├── .env # Environment variables for compose
├── web/
│ ├── Dockerfile # Web service Dockerfile
│ ├── app.py # Flask application
│ └── requirements.txt # Python dependencies
├── api/
│ ├── Dockerfile # API service Dockerfile
│ ├── app.py # API Flask application
│ └── requirements.txt # API dependencies
Tôi sẽ lướt nhanh nội dung từng tệp:
web/app.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
return render_template("index.html", title="Flask Web App")
@app.route("/about")
def about():
return "About page - Web Service"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=True)
web/requirements.txt
flask==3.1.0
web/Dockerfile
# Web service Dockerfile
ARG PYTHON_VERSION=3.13
FROM python:${PYTHON_VERSION}-slim
# Redeclare the build arg to use it after FROM
ARG PYTHON_VERSION
ARG ENVIRONMENT=production
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV FLASK_ENV=${ENVIRONMENT}
WORKDIR /app
# Copy and install requirements
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Create a simple template folder and file if not exists
RUN mkdir -p templates && \
echo "<html><body><h1>Hello from Web Service</h1><p>Python version: ${PYTHON_VERSION}</p><p>Environment: ${ENVIRONMENT}</p></body></html>" > templates/index.html
EXPOSE 5000
CMD ["python", "app.py"]
api/app.py
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/api/health")
def health():
return jsonify({"status": "healthy"})
@app.route("/api/data")
def get_data():
return jsonify(
{"message": "Hello from the API service", "items": ["item1", "item2", "item3"]}
)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True)
api/requirements.txt
flask==3.1.0
api/Dockerfile
ARG PYTHON_VERSION=3.13
FROM python:${PYTHON_VERSION}-slim
# Redeclare the build arg to use it after FROM
ARG PYTHON_VERSION
ARG ENVIRONMENT=production
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV FLASK_ENV=${ENVIRONMENT}
WORKDIR /app
# Copy and install requirements
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Add metadata label based on build args
LABEL python.version="${PYTHON_VERSION}" \
app.environment="${ENVIRONMENT}"
EXPOSE 8000
CMD ["python", "app.py"]
.env
PYTHON_VERSION=3.10
ENVIRONMENT=development
docker-compose.yml
services:
web:
build:
context: ./web
dockerfile: Dockerfile
args:
PYTHON_VERSION: ${PYTHON_VERSION:-3.13}
ENVIRONMENT: ${ENVIRONMENT:-development}
ports:
- "5000:5000"
depends_on:
- api
api:
build:
context: ./api
dockerfile: Dockerfile
args:
PYTHON_VERSION: ${PYTHON_VERSION:-3.13}
ENVIRONMENT: ${ENVIRONMENT:-production}
ports:
- "8000:8000"
Tóm lại, đây là cách rất đơn giản để khởi chạy hai ứng dụng trong các môi trường cách ly, đồng thời, với một bộ build args cụ thể.
Bạn có thể dùng lệnh này để chạy thiết lập đa container:
docker compose up --build

Hình 6 - Build args với Docker Compose
Sau vài giây, bạn sẽ thấy cả hai dịch vụ đều đang chạy:

Hình 7 - Build args với Docker Compose (2)
Thiết lập trên khá dài dòng với những ứng dụng đơn giản như thế này, nhưng bạn đã nắm được bức tranh lớn—build arguments được đặt trong tệp compose và được tham chiếu trong từng Dockerfile.
Ngoài ra, bạn cũng có thể truyền giá trị biến từ môi trường của mình vào build args, rất tiện cho pipeline CI/CD:
services:
web:
build:
context: .
args:
- PYTHON_VERSION=${PYTHON_VERSION:-3.10}
Và để ghi đè các giá trị này khi chạy docker-compose, bạn có thể dùng biến môi trường:
PYTHON_VERSION=3.10 docker-compose up --build
Cách làm này giúp bạn duy trì bản dựng nhất quán trong toàn đội trong khi vẫn linh hoạt khi cần.
Tính năng của BuildKit
BuildKit, công cụ build hiện đại của Docker, tăng tốc quy trình build với các tính năng khiến việc dùng build args mạnh mẽ hơn nữa. Khi bật BuildKit (bằng cách đặt DOCKER_BUILDKIT=1), bạn mở khóa một vài khả năng mới.
Inline cache cải thiện hiệu năng build bằng cách tận dụng cache của image từ xa. Bạn có thể chỉ định image nguồn để dùng làm cache với cờ --cache-from, và BuildKit sẽ thông minh sử dụng các layer của image đó:
DOCKER_BUILDKIT=1 docker build \
--build-arg PYTHON_VERSION=3.10 \
--cache-from flaskapp:dev \
-t flaskapp:latest .
Một tính năng giá trị khác của BuildKit là deterministic outputs, đảm bảo các bản dựng có thể tái tạo. Điều này rất quan trọng khi bạn muốn có đúng cùng một image bất kể thời điểm hay nơi build:
# Build with deterministic output
DOCKER_BUILDKIT=1 docker build \
--build-arg PYTHON_VERSION=3.10 \
--build-arg BUILD_DATE=2025-05-01 \
--output type=docker,name=flaskapp:stable \
.
Tính năng che giấu secret trong log của BuildKit bảo vệ thông tin nhạy cảm trong quá trình build.
Không giống build args thông thường, vốn xuất hiện trong log build, BuildKit tự động ẩn giá trị của secrets:
# Create a file with the API key
echo "my-api-key-value" > ./api-key.txt
# Build with secret (value won't appear in logs)
DOCKER_BUILDKIT=1 docker build \
--secret id=api_key,src=./api-key.txt \
-t flaskapp:secure .
Trong Dockerfile, bạn sẽ truy cập secret này như sau:
RUN --mount=type=secret,id=api_key \
cat /run/secrets/api_key > /app/config/api_key.txt
Các tính năng của BuildKit phối hợp với build args để tạo nên hệ thống build an toàn, hiệu quả và có thể tái tạo, phù hợp với hầu như mọi quy trình container hóa.
Thực tiễn tốt nhất cho Doanh nghiệp
Triển khai Docker build arguments trên các đội lớn đòi hỏi cách tiếp cận tiêu chuẩn hóa, ít nhất là nếu bạn muốn giảm nhầm lẫn và tối đa hóa lợi ích về bảo mật và hiệu năng.
Khi áp dụng build args trong môi trường doanh nghiệp, hãy bắt đầu với việc xác thực tham số hợp lý.
Luôn cung cấp giá trị mặc định hợp lý cho mọi build argument để đảm bảo bản dựng không thất bại bất ngờ khi tham số không được truyền. Bạn cũng nên thêm các kiểm tra xác thực trong Dockerfile để đảm bảo các build arg quan trọng đáp ứng yêu cầu của bạn.
Ví dụ sau xác thực phiên bản Python:
ARG PYTHON_VERSION=3.9
# Validate Python version
RUN if [[ ! "$PYTHON_VERSION" =~ ^3\.[0-9]+$ ]]; then \
echo "Invalid Python version: ${PYTHON_VERSION}. Must be 3.x"; \
exit 1; \
fi
Tối ưu hóa cache layer là yếu tố then chốt để giảm thời gian build trong pipeline CI/CD.
Sắp xếp các chỉ thị trong Dockerfile để tối đa hóa cache hit bằng cách đặt nội dung ít thay đổi (như cài đặt phụ thuộc) trước nội dung thường xuyên thay đổi (như mã ứng dụng).
Khi dùng build args có thể thay đổi thường xuyên, hãy đặt chúng sau các thao tác ổn định để tránh làm mất hiệu lực toàn bộ cache:
FROM python:3.13-slim
WORKDIR /app
# Dependencies change less frequently - good cache utilization
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Build args that might change often come AFTER stable operations
ARG BUILD_NUMBER
ARG COMMIT_SHA
# Now these args won't invalidate the dependency cache
Quản lý metadata thông qua build args giúp cải thiện khả năng truy vết và tuân thủ. Dùng build args để đưa metadata lúc build vào nhãn (labels):
ARG BUILD_DATE
ARG VERSION
ARG COMMIT_SHA
ARG BUILD_URL
LABEL org.opencontainers.image.created="${BUILD_DATE}" Can you please provide me with access to this document?
org.opencontainers.image.version="${VERSION}" \
org.opencontainers.image.revision="${COMMIT_SHA}" \
org.opencontainers.image.url="${BUILD_URL}"
Các nhãn tiêu chuẩn hóa này tuân theo đặc tả của Open Container Initiative (OCI), nghĩa là image của bạn sẽ tương thích với nhiều công cụ quản lý container khác nhau.
Tài liệu thường bị xem nhẹ, nhưng lại rất quan trọng để áp dụng trong doanh nghiệp.
Hãy tạo một mục README rõ ràng ghi lại tất cả build args hiện có, mục đích, giá trị mặc định và ví dụ sử dụng. Ghi rõ build arg nào là bắt buộc và tùy chọn, và ghi chú mọi tương tác giữa các tham số. Cân nhắc thêm thông tin này vào tệp cấu hình pipeline CI/CD dưới dạng chú thích để giúp lập trình viên hiểu giá trị nào họ cần cung cấp:
# Example documented CI configuration
build_job:
script:
# BUILD_NUMBER: Unique identifier for this build (required)
# ENVIRONMENT: Target deployment environment [dev|staging|prod] (required)
# PYTHON_VERSION: Python version to use (optional, default: 3.9)
- docker build
--build-arg BUILD_NUMBER=${CI_PIPELINE_ID}
--build-arg ENVIRONMENT=${DEPLOY_ENV}
--build-arg PYTHON_VERSION=${PYTHON_VERSION:-3.9}
-t myapp:${CI_PIPELINE_ID} .
Để áp dụng ở cấp độ doanh nghiệp thực sự, hãy cân nhắc triển khai một schema cho build argument có thể phân phiên bản và xác thực. Cách làm này cho phép bạn phát triển cấu hình build theo thời gian trong khi vẫn duy trì tương thích ngược.
Phân tích so sánh: Build Args vs. Biến môi trường
Nếu bạn muốn tạo các Docker image an toàn và linh hoạt theo thực tiễn tốt nhất, bạn phải hiểu khi nào nên dùng build arguments và khi nào dùng biến môi trường.
Dưới đây là bảng tham chiếu nhanh:
|
Tính năng |
Build arguments |
Biến môi trường |
|
Khả dụng |
Chỉ khả dụng trong lúc build image |
Khả dụng cả khi build và khi container chạy |
|
Tồn tại |
Không được lưu trong image cuối (trừ khi chuyển rõ ràng sang |
Được lưu trong image và khả dụng cho container đang chạy |
|
Bảo mật |
Hiển thị trong lịch sử image với docker history |
Không hiện trong lịch sử image nhưng có thể được truy cập bởi tiến trình trong container |
|
Mục đích sử dụng |
Phù hợp cho cấu hình lúc build như phiên bản, đường dẫn build, cờ trình biên dịch |
Phù hợp cho cấu hình lúc runtime như chuỗi kết nối, cờ tính năng, mức log |
|
Khai báo |
Định nghĩa bằng chỉ thị |
Định nghĩa bằng chỉ thị |
|
Giá trị mặc định |
Có thể cung cấp giá trị mặc định: |
Có thể cung cấp giá trị mặc định: |
|
Phạm vi |
Theo từng giai đoạn build, phải khai báo lại sau mỗi |
Khả dụng trên mọi giai đoạn build và được kế thừa bởi image con |
|
Cách ghi đè |
|
|
Điểm khác biệt chính nằm ở thời điểm và mục đích. Build args cấu hình chính quá trình build, trong khi biến môi trường cấu hình ứng dụng khi chạy. Ví dụ, bạn sẽ dùng build arg để chọn base image (ARG PYTHON_VERSION=3.10), còn dùng biến môi trường để cho ứng dụng biết cổng cần lắng nghe (ENV PORT=8080).
Xét về bảo mật, build args rủi ro cao hơn với thông tin nhạy cảm vì chúng tồn tại trong lịch sử image.
Hãy cân nhắc quy trình sau để xử lý các loại cấu hình khác nhau:
# Build-time configuration (non-sensitive)
ARG PYTHON_VERSION=3.13
FROM python:${PYTHON_VERSION}-slim
# Build-time secrets (use BuildKit secrets)
RUN --mount=type=secret,id=build_key \
cat /run/secrets/build_key > /tmp/key && \
# Use the secret for build operations
rm /tmp/key
# Runtime configuration (non-sensitive)
ENV LOG_LEVEL=info
# Runtime secrets (should be injected at runtime, not here)
# This would be provided at runtime with:
# docker run -e API_KEY=secret123 myimage
Trong thực tế, một mẫu phổ biến là chuyển một số build args thành biến môi trường khi chúng cần khả dụng lúc runtime:
ARG APP_VERSION=1.0.0
# Make the version available at runtime
ENV APP_VERSION=${APP_VERSION}
Với ứng dụng doanh nghiệp, sự tách bạch này cho phép các đội khác nhau quản lý những khía cạnh khác nhau của vòng đời ứng dụng. Nhóm DevOps có thể chỉnh build args cho quá trình tạo image, trong khi đội vận hành có thể điều chỉnh biến môi trường khi triển khai mà không cần rebuild image.
Tổng kết về Docker Build Args
Docker build args không chỉ là một tính năng kỹ thuật khác - chúng là công cụ chủ lực để tạo image hoạt động nhất quán giữa đội ngũ và các môi trường.
Tôi đã hướng dẫn cách dùng chúng trong các dự án Python đơn giản, đồng thời vẫn bảo vệ thông tin nhạy cảm. Bạn cũng đã thấy cách tích hợp build args với các công cụ như Docker Compose.
Hãy xem build args như nền móng của chiến lược container hóa linh hoạt. Bắt đầu nhỏ bằng cách tham số hóa phiên bản Python trong dự án tiếp theo. Khi đã quen, hãy thử thêm logic điều kiện cho các môi trường khác nhau. Chẳng mấy chốc, bạn sẽ tạo được các bản dựng đa giai đoạn tinh vi mà đội ngũ có thể tùy biến mà không cần sửa Dockerfile.
Sẵn sàng tìm hiểu sâu hơn? Các khóa học từ DataCamp dưới đây là điểm dừng chân tiếp theo tốt nhất:
Câu hỏi thường gặp
Docker build arguments là gì?
Docker build arguments (build args) là các biến bạn truyền vào quy trình build của Docker và chỉ khả dụng trong lúc tạo image. Chúng cho phép bạn tùy biến Dockerfile mà không cần chỉnh sửa, giúp quá trình build container linh hoạt và có thể tái sử dụng hơn. Hãy coi chúng như các tham số bạn có thể điều chỉnh mỗi lần build image, rất phù hợp để xử lý các môi trường hoặc cấu hình khác nhau.
Build args khác gì với biến môi trường trong Docker?
Build args chỉ tồn tại trong lúc tạo image, trong khi biến môi trường tồn tại trong container đang chạy. Build args được định nghĩa với chỉ thị ARG và truyền qua cờ --build-arg khi build, nên lý tưởng cho việc như chọn base image hoặc đặt cấu hình lúc build. Biến môi trường, được định nghĩa với ENV, được thiết kế cho cấu hình runtime mà ứng dụng của bạn cần khi chạy.
Những lo ngại bảo mật nào cần chú ý khi dùng Docker build args?
Build args không riêng tư như nhiều lập trình viên tưởng—giá trị của chúng hiển thị trong lịch sử image và log CI/CD. Không bao giờ dùng build args cho thông tin nhạy cảm như API key hoặc mật khẩu vì bất kỳ ai có quyền truy cập image đều có thể xem các giá trị này. Với dữ liệu nhạy cảm, hãy dùng Docker BuildKit secrets, vốn không lưu trong image cuối cùng hay lịch sử.
Làm sao truyền build args qua pipeline CI/CD như GitHub Actions?
Hầu hết nền tảng CI/CD hỗ trợ Docker build args thông qua tệp cấu hình. Trong GitHub Actions, bạn có thể truyền build args trong YAML workflow bằng tham số build-args dưới docker/build-push-action. Bạn có thể tham chiếu biến môi trường, secrets của repository, hoặc giá trị hardcode tùy nhu cầu bảo mật. Điều này cho phép bạn tự động hóa build với các cấu hình khác nhau dựa trên nhánh, môi trường, hoặc biến CI khác.
Có giới hạn bao nhiêu build args trong một Dockerfile không?
Không có giới hạn kỹ thuật cứng về số lượng build args, nhưng quá nhiều sẽ khiến Dockerfile khó hiểu và khó bảo trì. Với dự án khoa học dữ liệu, hãy tập trung tham số hóa các biến quan trọng như phiên bản Python, lựa chọn framework, hoặc cấu hình tập dữ liệu. Nếu bạn có hơn 8–10 build args, hãy cân nhắc tách Dockerfile thành các tệp nhỏ, tập trung hơn hoặc dùng Docker Compose để quản lý độ phức tạp.

Bạn đang chật vật vì các bản dựng Docker không nhất quán giữa các thành viên trong nhóm? Build arguments có thể là thứ bạn cần. Đây là giải pháp phổ biến để tạo các Docker image linh hoạt và tiêu chuẩn hóa. Chúng cho phép bạn truyền giá trị vào quy trình build mà không phải hardcode, giúp Dockerfile của bạn dễ mang đi và dễ bảo trì hơn.
Docker build args giải quyết những vấn đề thường gặp, chẳng hạn như xử lý các base image khác nhau, phiên bản package, hoặc thiết lập cấu hình giữa các môi trường.
Tài liệu chính thức của Docker khuyến nghị dùng build args để tham số hóa quá trình build thay vì lạm dụng biến môi trường. Chúng đặc biệt hữu ích trong pipeline CI/CD, nơi bạn cần tạo image với cấu hình khác nhau từ cùng một Dockerfile.
> Mới làm quen với Docker và containers? Hãy làm theo hướng dẫn này để bắt kịp nhanh chóng.
Trong bài viết này, tôi sẽ chỉ cho bạn cách dùng Docker build arguments để xây dựng quy trình container hóa hiệu quả, an toàn và linh hoạt hơn.
Giới thiệu về Docker Build Args
Build arguments (hay build args) là các biến mà bạn truyền cho Docker tại thời điểm build, và chỉ khả dụng trong quá trình tạo image.
Khác với biến môi trường tồn tại trong container khi chạy, build args chỉ tồn tại trong ngữ cảnh lệnh
docker buildvà biến mất khi image đã được tạo. Chúng hoạt động tương tự tham số hàm, cho phép bạn truyền các giá trị khác nhau mỗi lần build image.Trường hợp sử dụng chính của build args xoay quanh việc tạo Dockerfile linh hoạt, tái sử dụng.
Bạn có thể dùng build args để chỉ định các base image khác nhau (như chuyển giữa Alpine hoặc Debian), đặt phiên bản ứng dụng mà không cần sửa Dockerfile, hoặc cấu hình các thiết lập lúc build như máy chủ proxy hay URL repository. Tính linh hoạt này rất hữu ích trong pipeline CI/CD nơi bạn có thể build cùng một Dockerfile với các tham số khác nhau tùy mục tiêu triển khai.
Build args tỏa sáng khi bạn cần tùy biến bản dựng mà không phải duy trì nhiều biến thể Dockerfile. Chúng giúp bạn tuân thủ nguyên tắc DRY (Don't Repeat Yourself) bằng cách tập trung hóa logic cấu hình container nhưng vẫn cho phép tùy biến.
Chúng cũng hoàn hảo để xử lý khác biệt giữa môi trường phát triển, kiểm thử và sản xuất mà chỉ nên ảnh hưởng đến cách image được build, không ảnh hưởng đến cách container chạy.
Giờ bạn đã biết build args là gì, hãy xem cách sử dụng chúng.
Định nghĩa và Sử dụng Build Arguments
Bây giờ, hãy bắt tay vào khía cạnh thực hành của việc triển khai build arguments. Giả định bạn đã cài đặt và cấu hình Docker.
Cú pháp cơ bản và phạm vi
Bạn có thể khai báo build arguments trong Dockerfile bằng chỉ thị
ARG, có thể đặt trước hoặc sau chỉ thịFROM, tùy bạn cần dùng chúng khi nào. Đây là cú pháp cơ bản:Bạn có thể cung cấp giá trị khi build image bằng cờ
--build-arg:Hình 1 - Build args cơ bản trong Docker
Phạm vi (scope) của build args tuân theo các quy tắc quan trọng cần nắm rõ. Các arg được khai báo trước chỉ thị
FROMchỉ khả dụng trướcFROMvà phải được khai báo lại sau đó nếu bạn cần dùng tiếp.Điều này xảy ra vì mỗi chỉ thị
FROMbắt đầu một giai đoạn build mới với phạm vi riêng. Hành vi này gần như bắt buộc bạn phải ghi nhớ, đặc biệt trong các bản dựng đa giai đoạn (multi-stage).Kỹ thuật khai báo nâng cao
Hãy tạo một ứng dụng Flask "Hello World" hoàn chỉnh sử dụng build args để hỗ trợ các cấu hình khác nhau:
> Tìm hiểu cách đóng gói (containerize) một ứng dụng bằng Docker.
Trước tiên, tạo một ứng dụng Flask đơn giản (
app.py):Đồng thời, hãy tạo tệp
requirements.txt:Giờ hãy tạo Dockerfile sử dụng build args cho cấu hình linh hoạt:
> Dockerfile ở trên trông có vẻ khá phức tạp? Học Docker từ đầu với hướng dẫn của chúng tôi.
Để build image này cho môi trường phát triển với phiên bản Python cụ thể, bạn có thể chạy từ Terminal:
Hình 2 - Build args trong một ứng dụng Python cơ bản
Trong các bản dựng đa giai đoạn, build args cần được xử lý đặc biệt. Dưới đây là ví dụ đầy đủ cho thấy cách truyền tham số qua nhiều giai đoạn với ứng dụng Flask của chúng ta:
Giờ bạn có thể build với phiên bản Python và môi trường cụ thể:
Hình 3 - Build args trong các bản dựng đa giai đoạn
Tóm lại, cách tiếp cận này cho phép bạn duy trì cấu hình nhất quán trên mọi giai đoạn build.
Build arguments được định nghĩa sẵn
Docker cung cấp một số build args định nghĩa sẵn mà bạn có thể dùng mà không cần khai báo trước. Bao gồm:
HTTP_PROXYvàHTTPS_PROXY: Hữu ích khi build trong môi trường doanh nghiệp có máy chủ proxy.FTP_PROXY: Tương tự HTTP proxy nhưng cho kết nối FTP.NO_PROXY: Chỉ định các host nên bỏ qua proxy.BUILD_DATEvàVCS_REF: Thường dùng cho metadata và quản lý phiên bản image.Các arg định sẵn này rất tiện khi bạn build image trong môi trường có cấu hình mạng cụ thể. Ví dụ, trong mạng doanh nghiệp với yêu cầu proxy nghiêm ngặt, bạn có thể dùng:
Cách làm này giữ cho Dockerfile của bạn có tính di động nhưng vẫn hoạt động được trong môi trường bị hạn chế.