Lint Dockerfile với Hadolint
Cập nhật gần nhất: 16/02/2024
Hello các bạn lại là mình đây 👋👋
Cuối tuần các bạn có đi đâu không?.......Không thì mở blog của mình ra đọc nhé, đọc cho mình cảm thấy blog của mình đỡ ế 🤣🤣🤣🤣
Tiếp tục với series học Docker, ở bài này ta sẽ cùng nhau setup Hadolint để lint Dockerfile đảm bảo là project của chúng ta luôn có 1 Dockerfile chuẩn sạch đẹp nhé
Mình hứa đây sẽ là 1 trong những bài ngắn và "tàu nhanh" nhất trong cả series.
Triển thôi nào 🚀🚀🚀
Giới thiệu vỡ lòng chút
Ở thời điểm hiện tại, gần như bất kì ngôn ngữ (hay script) nào bạn viết, C, C++, Java, javascript, Ruby, YAML, ... thì đều có linter cả. Dockerfile cũng không ngoại lệ.
Linter sẽ giúp chúng ta kiểm tra xem code ta viết có theo 1 chuẩn nào đó xác định không, có lỗi gì không, có biến nào khai báo xong quên không dùng không, .... ti tỉ thứ trên đời.
Ở bài này ta sẽ setup Hadolint để check Dockerfile: cải thiện + tìm ra các lỗi trước khi build và chạy image nhé
Setup
Đầu tiên ta tạo 1 folder mới tên là: test-hadolint
nhé (hoặc tên là gì cũng được tuỳ các bạn )
Trong đó ta tạo 1 file Dockerfile:
FROM debian
RUN export node_version="0.10" \
&& apt-get update && apt-get -y install nodejs="$node_verion"
COPY package.json usr/src/app
RUN cd /usr/src/app \
&& npm install node-static
EXPOSE 80000
CMD ["npm", "start"]
Ở trên như các bạn thấy ta FROM
từ image debian
(cùng họ hàng với Ubuntu), sau đó cài nodeJS và start app lên. Giờ ta thử lint Dockerfile xem nó có lỗi gì nhé.
Thật sự là với sự ra đời của Docker thì ta chẳng cần phải mất công cài đặt bất kì thứ gì vào máy nữa: mysql, redis,... và cả Hadolint. Đơn giản là ta chạy image của Hadolint -> xong.
Các bạn chạy cho mình command sau, ở trong folder test-hadolint
của chúng ta nhé:
docker run --rm -i hadolint/hadolint < Dockerfile
Ta thấy in ra như sau:
Như ở trên ta thấy báo 1 số lỗi như:
- Warning (cảnh báo): nên luôn thêm tag cho image FROM, hiện tại ta không nói gì thì mặc định là
latest
, nhưng latest ở năm 2022 là v11, nhưng 2030 có thể là v50 rồi. Do vậy để viết Dockerfile mà 10 năm sau vẫn chạy thì nhớ để tag nhé các bạn - Info (kiểu đề xuất, gợi ý cho mình, còn không thì cũng không sao)
- Error (có lỗi hoặc thứ gì đó không hợp lệ): ở đây ta EXPOSE port 80000 trong khi port cho phép là 0 -> 65535
Từ những thông tin này ta có thể update để có 1 Dockerfile tốt hơn, rõ ràng hơn, không gặp lỗi (ở hiện tại hoặc tương lai), 10 năm sau vẫn chạy 💪💪💪
Ngoài ra Hadolint cũng cho ta thêm 1 số option khác để custom những rule để check, ignore error, format output,.... Các bạn có thể check ở đây nhé.
Hết!
.
.
.
.
.
Ủa gì mà nhạt dữ vậy, đã mất công viết thì vết cái gì cho "ra dẻ" tí đi chứ?😂😂😂.
Oke thì ra dẻ 😎
Tích hợp với CICD
Ở trên như các bạn thấy là ta đang chạy Hadolint ở local, tự chạy, nhưng ở trong 1 project nhiều người, sẽ khó để đảm bảo là anh em luôn chạy Lint trước khi commit, và kể cả anh em có chạy thì có đảm bảo là anh em sẽ fix những lỗi in ra hay không. Hay anh em giả vờ "mắt không thấy tai không nghe" 🙃🙃
Để đảm bảo là ta luôn check thì ta nên có 1 công cụ check tự động mọi commit đẩy lên git, và tất nhiên giải pháp đầu tiên ta nghĩ tới là dùng CICD rồi.
Hadolint có sẵn Hadolin Action nên ở bài này ta sẽ dùng Github nhé
Vẫn ở trong folder test-hadolint
các bạn tạo cho mình 1 folder tên là .github
, bên trong đó tạo tiếp 1 folder tên là workflows
, bên trong workflows
thì ta tạo file lint-dockerfile.yml
với nội dung như sau:
name: Lint Dockerfile
on: [push]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: hadolint/hadolint-action@v2.0.0
with:
dockerfile: Dockerfile
Oke tiếp theo ta lên Github tạo repo tên là test-hadolint
, public hay private đều được nhé. Và sau đó ta commit code ở local lên, mở terminal ở folder test-hadolint
của chúng ta ở local và chạy lần lượt các command sau:
git init
git remote add origin https://github.com/maitrungduc1410/test-hadolint.git
git add .
git commit -m "first commit"
git push -u origin master
ở trên đoạn add origin là username của mình, các bạn thay tên github username của các bạn vào nhé
Ngay sau khi push, ta lên Github sẽ thấy Action bắt đầu chạy:
Click vào job đang chạy đó để xem chi tiết ta thấy như sau:
Như ở trên các bạn thấy rằng khi chạy Hadolint thì cũng cho ta kết quả tương tự nhưng pipeline bị lỗi, vì mặc định Hadolint action sẽ cho fail cả pipeline nếu bất kì check nào bị failed, không cần biết đó là error, warning hay info. Mình thấy cái default check này cũng ổn rồi, vì những thứ mà hadolint nói với chúng ta cũng toàn là thứ cần fix cả
Nếu các bạn không muốn Hadolint làm fail cả pipeline thì các bạn update lại như sau:
name: Lint Dockerfile
on: [push]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: hadolint/hadolint-action@v2.0.0
with:
dockerfile: Dockerfile
no-fail: true # ---->>> thêm vào đây
Sau đó ta commit lại code:
git add .
git commit -m "ci: ignore hadolint if failed"
git push origin master
Sau đó ta quay trở lại github, check job mới nhất sẽ thấy success, mặc dù Hadolint check thấy có lỗi:
Hadolint Action cũng cho ta cấu hình các options giống như lúc chạy ở local, các bạn có thể xem thêm ở đây nhé.
Thường thì mình sẽ cho fail luôn cả action, vì Dockerfile là file quan trọng, ta dùng nó để build cả app chạy cho production nên mọi thứ phải chuẩn chỉ
Tí quên
Ở Github action ta đang để là on: [push]
tức là mọi commit từ mọi branch push lên thì action sẽ đều chạy nhưng bởi vì ở đây ta chỉ lint Dockerfile, nên ta sẽ không muốn chạy đi chạy lại action này trong trường hợp không có gì thay đổi cả, nên ta update lại 1 chút như sau nhé:
name: Lint Dockerfile
on:
push:
paths:
- Dockerfile
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: hadolint/hadolint-action@v2.0.0
with:
dockerfile: Dockerfile
no-fail: true
Sau đó ta commit tiếp nhé:
git add .
git commit -m "ci: only run action if Dockerfile changed"
git push origin master
Sau đó ta quay trở lại Github để chắc chắn là không có job nào vừa được chạy:
Oke ổn rồi đó, từ giờ thì chỉ khi nào ta đổi Dockerfile thì action mới chạy lại. Phần này là bài tập về nhà các bạn tự làm nhé (thử tạo thêm file mới xong commit lên xem, rồi sau đó thử update Dockerfile nữa )
Chấm hết
Hi vọng qua bài này ta đã có thêm 1 tool hữu ích để có thêm cải thiện Dockerfile của chúng ta thêm nữa. Có 1 Dockerfile tốt cũng là giúp app của chúng ta khi được build và deploy cũng sẽ chạy tốt hơn.
Mong là bài nãy vẫn đủ "tàu nhanh" không quá dài với các bạn 😊
Thân ái chào tạm biệt, hẹn gặp lại các bạn ở những bài sau 👋👋
All rights reserved