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