Bí quyết xây dựng Dockerfile hiệu quả và dễ bảo trì

0 0 0

Người đăng: Gung Typical

Theo Viblo Asia

Một Dockerfile được xây dựng tốt là điều cần thiết để tạo ra các image Docker hiệu quả, an toàn và dễ bảo trì. Tuân theo các phương pháp hay nhất đảm bảo image của bạn gọn nhẹ, nhanh chóng trong quá trình build và dễ dàng quản lý.

1. Sử dụng Image nền tối giản

Bắt đầu với một image nền tối giản để giảm kích thước của image Docker cuối cùng. Ví dụ, thay vì sử dụng các image lớn như ubuntu hoặc debian, hãy cân nhắc sử dụng các image như alpine hoặc phiên bản slim có ít dependency hơn và dung lượng nhỏ hơn.

VD:

# Use a minimal base image (e.g., Alpine) for smaller image size
FROM node:16-alpine

Phương pháp này làm giảm kích thước tổng thể của image, điều này có lợi cho việc build nhanh hơn, tải lên registry dễ dàng hơn và giảm mức tiêu thụ tài nguyên trong thời gian chạy.

2. Sắp xếp các chỉ thị để tận dụng bộ nhớ Cache

Docker lưu trữ từng layer của image trong quá trình build. Để tối ưu hóa thời gian build, hãy đặt các chỉ thị ít thay đổi thường xuyên hơn ở đầu Dockerfile của bạn và các chỉ thị thay đổi thường xuyên hơn về phía cuối.

Phương pháp hay nhất:

  • Cài đặt các dependency trước.
  • Sao chép các file tĩnh (như package.json, requirements.txt, v.v.) sớm.
  • Sao chép mã nguồn của bạn ở cuối.

Chiến lược này tận dụng bộ nhớ cache layer của Docker, vì vậy nếu chỉ mã thay đổi, Docker không phải cài đặt lại các dependency, giúp tăng tốc độ build tiếp theo.

# Install dependencies first, as these change less frequently
COPY package.json /app/
WORKDIR /app
RUN npm install # Copy source code after installing dependencies
COPY . /app/

3. Tránh cài đặt các gói không cần thiết

Luôn đặt mục tiêu chỉ cài đặt các gói cần thiết để ứng dụng của bạn hoạt động. Việc cài đặt các công cụ hoặc dependency không cần thiết có thể làm tăng đáng kể kích thước image của bạn. Tránh cài đặt các tiện ích không cần thiết như curl, git hoặc vim trừ khi chúng cần thiết cho môi trường runtime của container.

# Only install necessary dependencies
RUN apk add --no-cache bash

Bằng cách sử dụng tùy chọn --no-cache, chúng ta ngăn Docker lưu trữ các file index gói, giúp tiết kiệm dung lượng.

4. Giảm số lượng Layer

Mỗi chỉ thị Dockerfile tạo ra một layer image mới. Càng nhiều layer thì image càng lớn và quá trình build càng chậm. Hãy cố gắng hợp nhất nhiều lệnh thành ít layer hơn.

Phương pháp hay nhất: Kết hợp các chỉ thị RUN nếu có thể. Ví dụ, thay vì chạy các lệnh RUN riêng biệt cho mỗi lần cài đặt gói, hãy kết hợp chúng thành một câu lệnh RUN duy nhất.

# Instead of running multiple RUN commands
RUN apt-get update && apt-get install -y \ curl \ vim \ git # Combine them into a single RUN command to reduce layers
RUN apt-get update && apt-get install -y curl vim git

5. Sử Dụng .dockerignore để loại trừ các file không cần thiết

Tương tự như .gitignore cho Git, .dockerignore được sử dụng để ngăn các file không cần thiết được sao chép vào image Docker của bạn, điều này có thể làm giảm kích thước image và cải thiện tốc độ build.

Phương pháp hay nhất: Tạo một file .dockerignore để loại trừ các file như:

  • .git/
  • node_modules/
  • *.log
  • Các file tạm thời
# .dockerignore
node_modules/
.git/
*.log
*.md

Bằng cách bỏ qua các file không cần thiết cho runtime của ứng dụng, bạn giảm thiểu kích thước image của mình và ngăn Docker sao chép các file không cần thiết trong quá trình build.

6. Tận dụng Multi-Stage Builds

Multi-stage builds cho phép bạn tách việc build ứng dụng của mình khỏi image cuối cùng, giúp bạn tạo ra các image nhỏ hơn và gọn gàng hơn. Bạn có thể sử dụng một stage để build ứng dụng (với các công cụ build) và một stage khác để sao chép các asset đã build vào một image runtime tối giản.

Phương pháp hay nhất:

  • Sử dụng một build stage để biên dịch mã, cài đặt dependency hoặc chạy thử nghiệm.
  • Sao chép các artifact kết quả vào một image cuối cùng nhỏ hơn.

VD:

# Build stage
FROM node:16-alpine AS build
WORKDIR /app
COPY package.json package-lock.json /app/
RUN npm install
COPY . /app/
RUN npm run build # Final stage
FROM node:16-alpine
WORKDIR /app
COPY --from=build /app/dist /app/dist
CMD ["node", "dist/server.js"]

Trong ví dụ này, build stage cài đặt các dependency, chạy lệnh build và biên dịch ứng dụng. Final stage chỉ bao gồm các file đã build, dẫn đến một image nhỏ hơn nhiều.

7. Sử dụng thẻ phiên bản cụ thể cho các Image nền

Tránh sử dụng thẻ latest cho các image nền, vì nó có thể dẫn đến hành vi không thể đoán trước khi các image nền được cập nhật. Luôn chỉ định một phiên bản cố định để đảm bảo tính nhất quán giữa các bản build.

Phương pháp hay nhất:

  • Sử dụng các thẻ cụ thể (ví dụ: node:16-alpine thay vì node:alpine).
  • Nếu có thể, hãy sử dụng các phiên bản chính xác cho image nền để ngăn ngừa lỗi trong tương lai.
# Good practice: use a specific version tag for reproducibility
FROM node:16-alpine

8. Giảm thiểu việc sử dụng các chỉ thị RUN

Mỗi chỉ thị RUN thêm một layer mới vào image của bạn. Giảm thiểu số lượng chỉ thị RUN để giảm kích thước image và thời gian build. Thay vì chạy nhiều lệnh trong các chỉ thị RUN riêng biệt, hãy kết hợp chúng thành một lệnh duy nhất.

Phương pháp hay nhất: Kết hợp nhiều lệnh thành một câu lệnh RUN duy nhất bằng cách sử dụng && để xâu chuỗi chúng lại với nhau.

# Multiple RUN instructions (not ideal)
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y git # Combined RUN instruction (ideal)
RUN apt-get update && apt-get install -y curl git

9. Thiết lập người dùng không phải Root cho bảo mật

Chạy container với tư cách root là một rủi ro bảo mật. Bạn nên sử dụng người dùng không phải root bên trong container để giảm tác động của các lỗ hổng tiềm ẩn trong ứng dụng được container hóa.

Phương pháp hay nhất: Tạo và chuyển sang người dùng không phải root sau khi cài đặt các gói cần thiết.

# Create a non-root user and switch to that user
RUN adduser --disabled-password myuser
USER myuser

10. Thiết lập rõ ràng các biến môi trường

Thiết lập rõ ràng các biến môi trường trong Dockerfile bằng cách sử dụng chỉ thị ENV. Điều này có thể giúp cấu hình ứng dụng và làm cho nó dễ di chuyển hơn giữa các môi trường khác nhau.

# Set environment variables
ENV NODE_ENV production
ENV PORT 3000

Kết luận

Tuân theo các phương pháp hay nhất của Dockerfile là rất quan trọng để tạo ra các image Docker hiệu quả, dễ bảo trì và an toàn. Bằng cách sử dụng các image nền tối giản, giảm số lượng layer, loại trừ các file không cần thiết và làm theo các phương pháp được khuyến nghị khác, bạn có thể tạo các image Docker được tối ưu hóa, build nhanh hơn, kích thước nhỏ hơn và dễ quản lý hơn.

Ngoài ra, việc sử dụng multi-stage builds và người dùng không phải root có thể cải thiện cả bảo mật và hiệu suất. Bằng cách tuân thủ các phương pháp hay nhất này, bạn đảm bảo rằng image Docker của bạn hiệu quả, dễ di chuyển và nhất quán trên các môi trường khác nhau.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Cài đặt WSL / WSL2 trên Windows 10 để code như trên Ubuntu

Sau vài ba năm mình chuyển qua code trên Ubuntu thì thật không thể phủ nhận rằng mình đã yêu em nó. Cá nhân mình sử dụng Ubuntu để code web thì thật là tuyệt vời.

0 0 433

- vừa được xem lúc

Phần 1: Giới thiệu về Kubernetes

Kubernetes là gì. Trang chủ: https://kubernetes.io/. Ai cần Kubernetes.

0 0 100

- vừa được xem lúc

Docker: Chưa biết gì đến biết dùng (Phần 1- Lịch sử)

1. Vì sao nên sử dụng. . .

0 0 104

- vừa được xem lúc

Docker - những kiến thức cơ bản phần 1

Giới thiệu. Nếu bạn đang làm ở một công ty công nghệ thông tin, chắc rằng bạn đã được nghe nói về Docker.

0 0 78

- vừa được xem lúc

Docker: Chưa biết gì đến biết dùng (Phần 2 - Dockerfile)

1. Mở đầu.

0 0 67

- vừa được xem lúc

Docker: Chưa biết gì đến biết dùng (Phần 3: Docker-compose)

1. Mở đầu. . .

0 0 128