Tại sao Dockerfile của bạn cần được “khám sức khỏe”?
Ngày đầu sờ vào Docker, mình cứ nghĩ đơn giản: hễ docker build ra image và docker run thấy app lên là xong phim. Thú thật, lúc đó mình toàn “xào nấu” Dockerfile bằng cách copy-paste từ StackOverflow hoặc mấy bài blog từ đời Tống. Kết quả là gì? Một con app Node.js đơn giản mà image nặng tới 1.2GB, build mất cả 5 phút, và chứa đầy lỗ hổng bảo mật mà mình chẳng hề hay biết.
Bước ngoặt đến khi mình nâng cấp toàn bộ hệ thống từ Docker Compose v1 lên v2. Quá trình này vô tình “bóc trần” đống Dockerfile cũ nát. Mình phát hiện nhiều image vẫn dùng base image lỗi thời (Debian Buster thay vì Bullseye/Bookworm), cài package mà quên dọn cache, hoặc tệ nhất là cho container chạy quyền root vô tội vạ. Đó là lúc mình cầu cứu Hadolint.
Hadolint không chỉ đơn thuần là công cụ kiểm tra cú pháp. Nó soi xét từng dòng code để đảm bảo bạn đang tuân thủ các “Best Practices” của Docker. Điểm ăn tiền nhất là nó tích hợp sẵn Shellcheck để bắt lỗi các câu lệnh shell bên trong chỉ thị RUN. Viết Dockerfile mà thiếu Hadolint cũng giống như code JavaScript mà không có ESLint vậy – bạn đang tự rước họa vào thân khi lên production.
4 lợi ích sát sườn khi dùng Hadolint
- Ép cân cho Image: Nó sẽ nhắc bạn xóa cache
/var/lib/apt/lists/*hoặc dùng Multi-stage build. Mình từng giảm được một image Python từ 850MB xuống còn 120MB nhờ sửa theo Hadolint. - Vá lỗ hổng bảo mật: Cảnh báo ngay khi bạn dùng quyền root hoặc cài những package thừa thãi tạo điều kiện cho hacker.
- Đồng nhất phong cách: Cả team sẽ viết Dockerfile theo một chuẩn chung, không còn mỗi người một kiểu “mắm muối” khác nhau.
- Chặn lỗi ngớ ngẩn: Phát hiện việc dùng tag
latest– một sai lầm chết người khiến app chạy ngon ở staging nhưng lăn đùng ra chết ở production.
Cách mang Hadolint về máy
Việc cài đặt Hadolint nhanh tới mức bạn chưa kịp pha xong tách cafe đã xong rồi.
1. Chạy nhanh bằng Docker
Lười cài đặt vào máy thật? Hãy dùng chính Docker để kiểm tra Dockerfile của bạn:
docker run --rm -i hadolint/hadolint < Dockerfile
2. Cài đặt trực tiếp cho MacOS/Linux
Dân dùng Mac thì cứ brew cho rảnh tay:
brew install hadolint
Với Linux, bạn tải bản binary trực tiếp từ GitHub Releases chỉ với 2 dòng lệnh:
sudo wget -O /usr/local/bin/hadolint https://github.com/hadolint/hadolint/releases/latest/download/hadolint-Linux-x86_64
sudo chmod +x /usr/local/bin/hadolint
3. “Vũ khí” tối thượng cho VS Code
Mình khuyên anh em Junior nên cài ngay extension Hadolint. Nó sẽ gạch chân đỏ những chỗ chưa chuẩn ngay khi bạn đang gõ. Cảm giác như có một ông Senior dày dạn kinh nghiệm ngồi cạnh nhắc bài, giúp bạn lên trình cực nhanh mà không cần đọc hết đống tài liệu khô khan.
Cấu hình và sử dụng thực tế
Hadolint trả về các mã lỗi bắt đầu bằng DL (Docker Lint) hoặc SC (ShellCheck). Đừng hoảng khi thấy một danh sách dài dằng dặc, hãy giải quyết từng cái một.
Kiểm tra Dockerfile đầu tiên
Thử chạy lệnh này với file bạn vừa viết:
hadolint Dockerfile
Nếu bạn thấy thông báo DL3008 warning: Pin versions in apt-get install, nghĩa là bạn cần ghi rõ phiên bản package (ví dụ: python3=3.10.6-1) thay vì để nó tự chọn bản mới nhất.
Tùy biến theo ý thích
Đôi khi một vài quy tắc quá khắt khe so với dự án nhỏ. Bạn có thể tạo file .hadolint.yaml ở thư mục gốc để tắt chúng đi:
# .hadolint.yaml
ignored:
- DL3008 # Bỏ qua yêu cầu ghi rõ version package cho nhanh
- DL3015 # Không cần nhắc --no-install-recommends nữa
override:
error:
- DL3001 # Nâng cấp cảnh báo này thành lỗi bắt buộc phải sửa
3 quy tắc “vàng” không được quên
Dựa trên kinh nghiệm của mình, đây là những thứ Hadolint sẽ cứu bạn khỏi những bàn thua trông thấy:
- Fix cứng version: Tuyệt đối tránh
FROM node:latest. Hãy dùngFROM node:18.16.0-alpine. - Dọn dẹp hiện trường: Luôn kết hợp
apt-get installvà xóa cache trong cùng một câu lệnhRUNđể không làm phình layer. - Ưu tiên WORKDIR: Đừng dùng
RUN cd /app, hãy dùngWORKDIR /app. Lệnh này đảm bảo các chỉ thị sau đó luôn nằm đúng chỗ.
Tự động hóa: Đưa Hadolint vào CI/CD
Đừng đợi đến lúc build lỗi mới sửa. Hãy biến Hadolint thành một chốt chặn tự động.
Tích hợp GitHub Actions
Chỉ cần thêm vài dòng này vào workflow, bất kỳ ai trong team push một cái Dockerfile “tệ” lên là hệ thống sẽ từ chối ngay lập tức.
name: Lint Dockerfile
on: [push, pull_request]
jobs:
hadolint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run Hadolint
uses: hadolint/[email protected]
with:
dockerfile: Dockerfile
Từ ngày áp dụng Hadolint, mình không còn phải lo lắng về việc image phình to bất thường hay lỗi vặt do shell script gây ra. Image sạch thì build nhanh, deploy mượt, mà sếp nhìn vào cũng thấy sự chuyên nghiệp của mình trong đó. Hãy lôi cái Dockerfile cũ của bạn ra chạy thử ngay đi, mình cam đoan bạn sẽ bất ngờ vì độ “đỏ lòm” của nó đấy!

