Docker và Docker Compose

Sê-ri 60 bài đi từ image và layer tới BuildKit, mạng, lưu trữ và Compose nhiều tầng. Mọi khẳng định đều kèm số đo chạy thật.

60/60 phần đã đăng Docker
1 Một container tốn thêm 0,38 MB và 260 ms — nhưng chạy 100 cái song song chỉ mất 43 ms mỗi cái: đo cái giá thật của Docker thay vì tin lời quảng cáo Mở đầu sê-ri Docker: đo thời gian khởi động, bộ nhớ và mật độ container trên máy thật, vì sao đo tuần tự chỉ ra độ trễ chứ không phải năng lực, và vì sao trên macOS bạn vẫn đang chạy một máy ảo. 21/08/2025 · 10 phút đọc 2 Image chứa 50 MB dữ liệu báo cáo là 4,0 MB và chiếm 66,1 MB đĩa — lệch mười sáu lần Layer là gì, lệnh nào sinh ra layer, vì sao mười image chỉ tốn dung lượng của một, và vì sao docker images nói dối bạn theo hai cách. 22/08/2025 · 8 phút đọc 3 docker stop ai cũng bảo cho 10 giây ân hạn — máy tôi đo được 1, và app có trạng thái mất dữ liệu Vòng đời một container: sáu trạng thái, chuyện gì xảy ra ở mỗi bước, lớp ghi tốn bao nhiêu, và vì sao đừng bao giờ tin vào thời gian ân hạn mặc định. 23/08/2025 · 9 phút đọc 4 Kiểm thử xong myapp:1.4.2 rồi triển khai, cụm chạy hai phiên bản khác nhau dưới cùng một cái tên: tag là con trỏ ghi đè được, digest mới là danh tính Dựng registry thật rồi đẩy đè lên chính một tag. Đo chuyện xảy ra với máy đã pull, vì sao digest mới là thứ đáng tin, latest không phải mới nhất, và --pull=always tốn 1 665 ms. 24/08/2025 · 9 phút đọc 5 Bốn lệnh Dockerfile làm khác hẳn cái tên của chúng: EXPOSE không mở cổng, ARG lộ bí mật Mỗi lệnh Dockerfile thật sự sinh ra gì: dạng shell so với exec, COPY so với ADD, EXPOSE không mở cổng, VOLUME rò rỉ volume, và ARG lộ bí mật. 25/08/2025 · 9 phút đọc 6 Đổi một dòng mã, build lại nhanh gấp tám lần — hoặc chậm y như cũ, tuỳ bạn xếp COPY ở đâu Đo cache của layer: thứ tự COPY quyết định thời gian build, touch không phá cache, và vì sao tách apt-get update ra dòng riêng vừa làm image to hơn vừa cài gói cũ. 26/08/2025 · 8 phút đọc 7 .dockerignore không giúp build nhanh hơn — nó giúp cache đừng chết mỗi lần bạn git commit Đo build context với BuildKit: 150 B dù thư mục dự án 28 MB, và chỗ .dockerignore thật sự đáng giá là cache chứ không phải tốc độ truyền. 27/08/2025 · 8 phút đọc 8 ENTRYPOINT dạng shell nuốt sạch tham số người dùng, không một dòng lỗi — và một chữ exec cứu mã thoát Bốn tổ hợp ENTRYPOINT và CMD, đo hành vi thật của từng cái, và một dòng exec quyết định container của bạn thoát với mã 0 hay 137. 28/08/2025 · 8 phút đọc 9 Máy chủ Go 86 MB xuống còn 1,9 MB — 45 lần, chỉ vì thôi vác cả xưởng đi theo tệp nhị phân Đo multi-stage build trên một ứng dụng Go thật: dung lượng, số layer, thời gian build, cái giá của scratch, và vì sao tầng không ai dùng tới bị bỏ qua hoàn toàn. 29/08/2025 · 8 phút đọc 10 Alpine ít gói hơn Debian sáu lần, nhưng số lệnh cho kẻ tấn công chỉ ít hơn 24% Đo năm image nền trên cùng một ứng dụng: dung lượng, số gói, số lệnh có sẵn. Vì sao dung lượng nhỏ không đồng nghĩa với bề mặt tấn công nhỏ. 30/08/2025 · 8 phút đọc 11 Đổi từ glibc sang musl, cùng một chương trình cấp phát bộ nhớ chậm đi 209 lần ở 8 luồng Ba khác biệt thật giữa musl và glibc: cấp phát bộ nhớ đa luồng, wheel Python, và ngăn xếp luồng 128 KB so với 8 MB — một trong ba đủ để đảo ngược quyết định chọn image nền. 31/08/2025 · 9 phút đọc 12 Sáu image phổ biến đều chạy bằng root — và cái cớ 'phải root để nghe cổng 80' đã hết hiệu lực Sáu image phổ biến đều chạy bằng root. Đo root trong container làm được gì, cái gì hỏng khi chuyển sang non-root, và bốn cách vá quyền volume — một cách không chạy. 01/09/2025 · 9 phút đọc 13 ARG so với ENV: một biến rỗng đi vào lệnh RUN, cài nhầm phiên bản, không một dòng lỗi Luật phạm vi của ARG và ENV trong multi-stage, ba nơi bí mật rò rỉ, tác động lên cache, và vì sao HTTP_PROXY không còn hoạt động như tài liệu cũ mô tả. 02/09/2025 · 8 phút đọc 14 Container báo unhealthy nhưng Docker không khởi động lại — HEALTHCHECK là cái báo khói, không phải bình chữa cháy Đo vòng đời trạng thái healthcheck, công thức độ trễ phát hiện, chi phí CPU theo tần suất, và ai thật sự phản ứng khi container báo hỏng. 03/09/2025 · 8 phút đọc 15 Image không nhãn tự khai là do đội NGINX bảo trì — và 1 337 byte đủ để truy ngược container về đúng commit Đo chi phí của nhãn, tác động lên cache, cách truy vết ngược một container, và vì sao image của bạn đang mang tên người khác. 04/09/2025 · 7 phút đọc 16 Đổi một chữ trong dòng FROM tiết kiệm 300 MB; gộp các lệnh RUN tiết kiệm đúng 0 Đo từng cách giảm dung lượng image một cách độc lập trên cùng một ứng dụng Python 419 MB, rồi xếp hạng theo số megabyte thật sự tiết kiệm được. 05/09/2025 · 8 phút đọc 17 Ba tầng không phụ thuộc nhau: builder cũ mất 11 giây, BuildKit mất 3,6 — vì một cái đọc cả công thức trước Đo A/B hai bộ máy build của Docker trên cùng Dockerfile: context, tầng song song, tầng bị bỏ qua, và tính năng builder cũ không có. 06/09/2025 · 8 phút đọc 18 Thêm một dòng vào requirements.txt: 12,2 giây thay vì 45–65 — nhờ giữ lại thùng đồ, không phải sản phẩm Đo --mount=type=cache trên pip: 12,2 giây so với 45–65 giây. Kèm công thức cho npm, Maven, apt, Go và một cái bẫy đo đạc. 07/09/2025 · 8 phút đọc 19 Máy CI chưa từng thấy dự án dựng xong trong 6,2 giây thay vì 64 — nhờ cache nằm ở nơi khác Đo cache dùng chung giữa các máy build: registry cache và local cache, mode=min so với mode=max, và cái giá dung lượng của từng lựa chọn. 08/09/2025 · 8 phút đọc 20 Dựng ảnh amd64 trên máy Mac: biên dịch chéo mất 3,4 giây, mô phỏng QEMU mất 42,7 — chậm gấp 12,6 lần Dựng ảnh cho amd64 và arm64 bằng buildx: hai cách làm, chênh lệch thời gian thật, cấu trúc của ảnh đa kiến trúc, và giới hạn --load đã biến mất. 09/09/2025 · 8 phút đọc 21 COPY rồi rm token: docker history sạch, filesystem sạch, mà bí mật vẫn nằm nguyên trong layer Đo bốn cách đưa bí mật vào lúc build và tìm chuỗi bí mật ở bốn chỗ. Chỉ một cách sạch hoàn toàn — và bí mật không tham gia vào khoá cache. 10/09/2025 · 8 phút đọc 22 requirements.txt của tôi ghi 2 dòng, ảnh Docker thật chạy 13 gói Python — SBOM liệt kê hết, và lúc có CVE tôi grep thay vì mở từng container Bật SBOM và provenance cho ảnh Docker: chi phí thật 3,98%, 130 thành phần được liệt kê, và digest image nền được ghi lại để build lặp lại được kể cả khi tag đã trỏ đi nơi khác. 11/09/2025 · 8 phút đọc 23 Ba lệnh sleep 3 y hệt nhau: xếp thành chuỗi mất 10,2 giây, xếp độc lập chỉ 3,7 Đo ba hình dạng đồ thị phụ thuộc trong Dockerfile, giới hạn song song thật, và cơ chế khử trùng lặp khiến việc lặp lại một bước không tốn gì. 12/09/2025 · 8 phút đọc 24 Hai bước chiếm 94,5% thời gian build — và chúng không phải chỗ người ta hay ngồi tối ưu Dùng --progress=plain để đo thời gian từng bước build, xếp hạng chỗ tốn nhất, và kiểm chứng bằng cách sửa đúng chỗ đó rồi đo lại. 13/09/2025 · 8 phút đọc 25 Container bị giới hạn nửa nhân, 64 MB — nhưng nproc vẫn báo 16 nhân và meminfo báo 16 GB Đo --cpus và --memory: giới hạn có tác dụng thật, nhưng container không nhìn thấy chúng. Kèm cách phân biệt mã thoát 137 do OOM với 137 do hết giờ dừng. 14/09/2025 · 9 phút đọc 26 Cùng container nửa nhân: JVM cấu hình cho 1 nhân, Node vẫn fork 16 worker rồi OOM Đo JVM và Node dưới giới hạn tài nguyên của Docker: cái nào đọc đúng, cái nào đọc sai, và hai kiểu chết hoàn toàn khác nhau khi hết bộ nhớ. 15/09/2025 · 8 phút đọc 27 Vì sao container không chịu tắt trong 5 giây rồi mất 382 bản ghi: PID 1 phớt lờ tín hiệu, và một cờ sửa nhanh gấp 47 lần PID 1 mang ngữ nghĩa tín hiệu riêng của nhân Linux. Đo hậu quả khi app của bạn là PID 1, đo 20 tiến trình zombie, và đo chính xác bao nhiêu bản ghi bị mất khi dừng ẩu. 16/09/2025 · 7 phút đọc 28 on-failure:5 nghe như có bảo hiểm, thực ra là 'hỏng lần thứ sáu thì tắt vĩnh viễn' Bốn chính sách restart, khoảng nghỉ nhân đôi đo được từng lần, và ba chuyện restart policy không làm mà nhiều người tưởng nó làm. 17/09/2025 · 9 phút đọc 29 Container in 60 MB log, tệp trên đĩa 97 MB, còn Docker báo 4 kB — chỗ đĩa biến mất mà không lệnh nào thấy Đo hệ số phồng của json-file, so với driver local có xoay vòng và nén sẵn, và vì sao lệnh đếm dung lượng của Docker không nhìn thấy log. 18/09/2025 · 8 phút đọc 30 Bật --read-only, ba trong bốn image chết ngay — nhưng mỗi cái chỉ cần đúng vài đường ghi Đo cái gì gãy khi bật read-only, tìm tập tmpfs nhỏ nhất cho nginx và postgres, và đo tmpfs ăn vào giới hạn bộ nhớ. 19/09/2025 · 8 phút đọc 31 nginx chạy tốt với 3 trong 14 quyền của root — và --privileged gỡ ba lớp phòng thủ chứ không phải một Đo từng capability một, đo bộ lọc seccomp tách khỏi capability, và phát hiện --privileged tắt luôn seccomp. 20/09/2025 · 8 phút đọc 32 Docker rootless nuốt trọn --memory 64m mà không một dòng cảnh báo — giới hạn chỉ là cái biển vẽ Dựng song song hai daemon rootful và rootless rồi đo build, khởi động, thông lượng. Chênh lệch hiệu năng gần bằng 0; chỗ mất mát nằm ở nơi khác. 21/09/2025 · 8 phút đọc 33 bridge chậm hơn host 18%, nghe ghê — nhưng đó là 14 micro giây, nhỏ hơn một truy vấn CSDL tầm thường iperf3 qua bridge, host, none và overlay. Số liệu thật, cùng lý do vì sao chênh lệch hiệu năng thường không phải thứ đáng lo nhất. 22/09/2025 · 9 phút đọc 34 Deploy xong, JVM vẫn gọi vào IP của container đã chết suốt 24 giây — vì nó nhớ số cũ Đo DNS nội bộ của Docker: độ trễ phân giải, round-robin theo bí danh, và cái bẫy cache khiến ứng dụng gọi vào container đã biến mất. 23/09/2025 · 9 phút đọc 35 Bật ufw rồi mà container vẫn lộ ra Internet: hai luật tường lửa y hệt, một cái vô dụng Vì sao gói tin tới cổng Docker không bao giờ chạm chuỗi iptables INPUT, cái giá 93 MB cho 20 cổng publish, và hai cách vá đã đo tận nơi. 24/09/2025 · 8 phút đọc 36 Hai container cùng mạng nói với nhau: đi thẳng 47 µs, vòng qua cổng publish 84 µs Đo độ trễ hỏi-đáp thật giữa các container: bridge, host, cùng container, qua -p. Và một phát hiện 3 lần biến mất khi chạy lại. 25/09/2025 · 8 phút đọc 37 host.docker.internal phân giải được, trả 200 — và đi tới hoàn toàn sai máy Đo cùng một cái tên trên hai nền tảng. Nó trỏ đi đâu, cần cờ gì, và trường hợp nó im lặng gọi nhầm sang máy khác. 26/09/2025 · 7 phút đọc 38 Container nằm trên hai mạng cùng lúc — nhưng nó tuyệt đối không làm cầu cho ai đi nhờ Dựng ba tầng trên hai mạng rồi đo đủ 12 chiều gọi. Mạng internal, tắt giao tiếp nội mạng, và vì sao container hai mạng không làm cầu nối. 27/09/2025 · 8 phút đọc 39 Mã 200 đã về, thân rỗng, kết nối treo — thủ phạm là một cây cầu thấp bị gỡ mất biển báo Mã 200 đã về, thân rỗng, kết nối treo tới hết giờ. Đo lại từ đầu vì sao MTU lệch chỉ gây hoạ khi ICMP bị chặn. 28/09/2025 · 9 phút đọc 40 Ba container hỏng ba kiểu, một mã lỗi duy nhất — cái thang tách chúng ra từng bậc Dựng sẵn bốn container hỏng theo bốn kiểu rồi chạy thang chẩn đoán. Kèm cách gỡ lỗi container distroless không có shell. 29/09/2025 · 8 phút đọc 41 Gắn volume rỗng vào nginx thì cấu hình mặc định còn nguyên, gắn thư mục rỗng thì mất sạch: ba kiểu lưu trữ Docker và chỗ chúng cư xử ngược nhau Ba kiểu lưu trữ của Docker: cái gì sống sót khi xoá container, ai sở hữu tệp, vì sao volume rỗng được nạp mồi còn bind mount thì che thẳng, và vì sao -v với --mount không tương đương. 30/09/2025 · 9 phút đọc 42 Trên Mac, bind mount stat 3.000 tệp chậm gấp 87 lần volume — nhưng ghi tuần tự thì ngang nhau Đo tệp nhỏ, siêu dữ liệu và fsync trên hai nền tảng. Kèm hai lời khuyên phổ biến bị số đo bác bỏ. 01/10/2025 · 9 phút đọc 43 Tệp do container tạo ra lại thuộc về root và bạn không xoá nổi: nhân Linux chỉ ghi một con số, còn cái tên là chuyện của mỗi bên Vì sao build trong container xong thì tệp trên máy chủ thuộc về root và bạn không sửa được, bốn cách vá đã đo, và cái bẫy khi dùng --user với một uid không có tên. 02/10/2025 · 8 phút đọc 44 Tôi tar nóng một volume PostgreSQL đang ghi giữa chừng rồi khôi phục — nó chạy, 0 dòng hỏng, nhưng con số dừng ở một mốc tôi không chọn Ba cách sao lưu volume, đo thời gian và dung lượng từng cách. Phép thử cái bẫy sao lưu nóng cho kết quả ngược lời đồn — và ba lý do thật sự khiến nó vẫn nguy hiểm. 03/10/2025 · 10 phút đọc 45 docker image prune báo thu hồi 0 B — nhưng vùng lớn nhất vẫn còn nguyên ở chỗ khác Dựng một hệ thống bừa bộn rồi chạy từng lệnh prune, đo dung lượng thật thu hồi được sau mỗi lệnh. Hai cái bẫy lộ ra ngay. 04/10/2025 · 8 phút đọc 46 Ba cách hỏi Docker chiếm bao nhiêu đĩa cho ba con số: 420, 217 và 294 MB — chỉ một đúng Ba cách đếm cùng một ổ đĩa cho ba con số. Đo xem cái nào đúng, chênh lệch nằm ở đâu, và vì sao ba image 64 MB chỉ tốn thêm 33 byte. 05/10/2025 · 7 phút đọc 47 Bốn container cùng ghi một tệp: một cách mở giữ trọn 200.000 dòng, một cách mất 70% mà không báo lỗi Bốn container cùng ghi một tệp trên volume chung. Đo O_APPEND, seek+write, ghi có bộ đệm, và các cách chia sẻ dữ liệu khác. 06/10/2025 · 8 phút đọc 48 Xoá 2.000 tệp trên ổ mạng chậm hơn 142 lần: cái giá của mỗi vòng đi–về, và ba lần tôi cố làm hỏng dữ liệu mà không được Dựng máy chủ NFS thật, gắn thẳng vào container Docker rồi đo từng loại thao tác. Vì sao siêu dữ liệu trả giá đắt còn luồng byte thì không, và ba phép thử tính đúng đắn mà lời đồn bảo sẽ hỏng. 07/10/2025 · 9 phút đọc 49 up -d chạy lại khi không đổi gì mất 0,17 giây và không đụng gì — vì Compose so trạng thái, không thi hành lệnh Dựng một hệ hai dịch vụ, đo thời gian lên xuống, và xem Compose thật sự tạo ra những gì đằng sau một lệnh up. 08/10/2025 · 7 phút đọc 50 depends_on chỉ thấy 'đèn nguồn đã sáng' — ứng dụng vẫn trượt kết nối 97 lần trong 5 giây Đo chính xác khoảng thời gian dịch vụ đã lên mà chưa phục vụ được, và vì sao lời giải thích phổ biến về nó lại sai. 09/10/2025 · 7 phút đọc 51 1.20 rụng thành 1.2, và .env không tự vào container: đo bốn lớp biến môi trường trong Compose So sánh .env, environment:, env_file: và ENV trong Dockerfile: đo thật thứ tự ghi đè bằng Docker Compose v5.4, và vì sao .env không tự nhét biến vào container. 26/08/2026 · 8 phút đọc 52 8080 và 8081 cùng mở: đo cách nhiều tệp Docker Compose gộp lại, và chỗ danh sách bị cộng dồn Đo thật cách docker-compose.override.yml và -f nhiều tệp gộp vào nhau trên Compose v5.4: scalar bị ghi đè, còn ports, environment và profiles lại cộng dồn. 26/08/2026 · 9 phút đọc 53 172.19 khác 172.20, nhưng volume thì sống: đo phạm vi dự án Compose và cái gì còn lại sau down Đo thật trên Compose v5.4.0: network/volume tự sinh mang tên <project>_<tên>, hai project cách ly hoàn toàn, volume vẫn sống sót qua down trừ khi thêm -v. 26/08/2026 · 10 phút đọc 54 11, 12, 7: đo cách DNS round robin của Docker chia tải giữa các replica trong Compose Scale một service lên 3 replica bằng docker compose up --scale, rồi đo thật xem 30 request HTTP chia cho từng container như thế nào, và vì sao giữ kết nối lại phá vỡ việc chia tải đó. 13/10/2025 · 9 phút đọc 55 0,05 giây so với 7,52 giây: đo healthcheck và depends_on condition trong Compose Đo thật trên Docker Compose v5.4.0: healthcheck và depends_on condition service_healthy khiến app đợi thêm 7,52 giây thay vì khởi động ngay sau 0,05 giây. 26/08/2026 · 7 phút đọc 56 Gắn một tệp vào container: nội dung đổi đúng, mà bộ nạp lại không bao giờ chạy Đo bốn vòng lặp sửa mã trong Compose, từ 1,02 giây tới không bao giờ. Kèm nguyên nhân đo được ở tầng inode. 14/10/2025 · 8 phút đọc 57 Mặc định của Compose: sau khi máy chủ reboot, container nằm im và website biến mất Đo hành vi thật của từng chính sách restart khi daemon khởi động lại, và đo chính xác thời gian gián đoạn khi cập nhật bằng up -d. 15/10/2025 · 7 phút đọc 58 compose watch không gắn gì vào container — nó chép tệp, và thế là thoát sạch cái bẫy mtime Đo ba action của compose watch, so với vòng lặp bind mount cũ, và xem vì sao nó không dính cái bẫy mtime. 16/10/2025 · 8 phút đọc 59 Base image đầy đủ có 56 lỗ hổng nghiêm trọng, bản alpine có 0 — và một dòng FROM là toàn bộ khác biệt Đo số CVE theo base image, đo cái mà máy quét bắt được và bỏ sót, và đo xem ghim digest ngăn được chuyện gì — ba lớp phòng thủ, không lớp nào đọc mã bạn viết. 17/10/2025 · 8 phút đọc 60 Chín điều kiểm trước khi lên sản xuất — và điều thứ chín là cái tôi suýt quên Gom mọi con số đã đo thành một script kiểm chạy được, thử trên hai hệ thống, và những kết quả đi ngược trực giác nhất. 18/10/2025 · 11 phút đọc