Xin chào cộng đồng DevOps và các lập trình viên trên hành trình khám phá Docker! Chào mừng trở lại với chuỗi bài viết “Roadmap Docker“. Ở các bài trước, chúng ta đã cùng tìm hiểu về Container là gì, sự khác biệt giữa Container, VM và Bare Metal, đi sâu hơn vào Docker và tiêu chuẩn OCI. Để làm việc hiệu quả với Docker, việc thành thạo giao diện dòng lệnh (command line) là cực kỳ quan trọng. Chúng ta cũng đã có bài giới thiệu về các kỹ năng cốt lõi về Linux cần thiết. Hôm nay, chúng ta sẽ đi sâu vào các lệnh shell cụ thể không thể thiếu khi bạn làm việc với Docker, từ những thao tác cơ bản đến cách kết hợp sức mạnh của shell để quản lý môi trường Docker một cách hiệu quả.
Là một DevOps Engineer, đặc biệt là khi mới bắt đầu, bạn sẽ dành rất nhiều thời gian làm việc trong terminal. Docker được thiết kế để điều khiển chủ yếu qua dòng lệnh. Việc hiểu và sử dụng linh hoạt các lệnh shell tiêu chuẩn, kết hợp với lệnh docker
, sẽ giúp bạn tự động hóa công việc, xử lý lỗi nhanh chóng và quản lý tài nguyên hệ thống một cách chuyên nghiệp hơn.
Mục lục
Các Lệnh Docker Cơ Bản: Nền Tảng Của Mọi Thao Tác
Trước khi đi sâu vào cách kết hợp với shell, chúng ta cần nắm vững các lệnh Docker cốt lõi. Đây là “bảng chữ cái” mà bạn sẽ sử dụng hàng ngày:
docker run
: Chạy một container mới từ một image. Đây có lẽ là lệnh được dùng nhiều nhất. Bạn có thể cấu hình rất nhiều thứ khi chạy, từ cổng (ports), volume, mạng (networks) cho đến biến môi trường (environment variables).docker ps
: Liệt kê các container đang chạy. Thêm cờ-a
(hoặc--all
) để xem tất cả các container, bao gồm cả những cái đã dừng.docker images
: Liệt kê các image Docker có sẵn trên hệ thống của bạn.docker build
: Xây dựng (build) một image Docker từ Dockerfile. Lệnh này đọc hướng dẫn từ Dockerfile và tạo ra một image sẵn sàng để chạy.docker stop <container_id_or_name>
: Dừng một container đang chạy một cách nhẹ nhàng (gửi tín hiệu SIGTERM).docker kill <container_id_or_name>
: Dừng một container một cách đột ngột (gửi tín hiệu SIGKILL).docker rm <container_id_or_name>
: Xóa một container đã dừng.docker rmi <image_id_or_name>
: Xóa một image Docker. Cẩn thận khi xóa các image mà container đang sử dụng.docker exec -it <container_id_or_name> <command>
: Thực thi một lệnh bên trong một container đang chạy. Thường dùng để truy cập shell bên trong container (ví dụ:docker exec -it my-container bash
).docker logs <container_id_or_name>
: Xem nhật ký (logs) của một container.docker system prune
: Xóa các tài nguyên Docker không sử dụng (container đã dừng, network không dùng, image không gắn tag, cache build). Rất hữu ích để giải phóng dung lượng đĩa.
Những lệnh này là xương sống. Nhưng sức mạnh thực sự đến khi bạn kết hợp chúng với các công cụ shell tiêu chuẩn.
Các Lệnh Shell Cần Thiết Kết Hợp Với Docker
Môi trường terminal Linux (bash, zsh, v.v.) cung cấp hàng trăm lệnh và công cụ nhỏ nhưng vô cùng mạnh mẽ. Khi làm việc với Docker, một số lệnh shell trở thành “người bạn đồng hành” không thể thiếu:
1. Di Chuyển và Xem Nội Dung: cd
, ls
, pwd
Mặc dù đơn giản, các lệnh này rất quan trọng khi bạn làm việc với Dockerfile hoặc các tệp cấu hình Docker Compose. Lệnh docker build
luôn được thực thi trong ngữ cảnh (context) của thư mục hiện tại hoặc thư mục bạn chỉ định. Vì vậy, biết mình đang ở đâu và có những tệp nào là bước đầu tiên.
# Di chuyển đến thư mục chứa Dockerfile
cd /path/to/your/app
# Xem nội dung thư mục để kiểm tra Dockerfile, source code, v.v.
ls -l
# Xác nhận đường dẫn hiện tại (ngữ cảnh build)
pwd
2. Lọc và Tìm Kiếm: grep
Lệnh grep
là công cụ lọc văn bản dựa trên mẫu (pattern) cực kỳ mạnh mẽ. Khi output của các lệnh Docker trở nên dài dòng (ví dụ: danh sách hàng trăm container hoặc image), grep
giúp bạn tìm thấy thông tin cần thiết một cách nhanh chóng.
# Tìm container có tên chứa "webserver" trong danh sách container đang chạy
docker ps | grep webserver
# Tìm image có tên "my-app" và tag "latest"
docker images | grep "my-app.*latest"
# Tìm lỗi trong log của một container
docker logs my-container | grep "ERROR"
Ký tự |
(pipe) chuyển output của lệnh bên trái thành input cho lệnh bên phải. Đây là một trong những kỹ thuật shell cơ bản và mạnh mẽ nhất.
3. Xử lý Tệp và Chuỗi: cat
, echo
cat
thường dùng để hiển thị nội dung tệp. echo
dùng để in chuỗi ra terminal. Chúng có ích khi bạn cần xem nhanh nội dung tệp cấu hình, Dockerfile, hoặc tạo nhanh một chuỗi để truyền vào lệnh khác.
# Xem nhanh nội dung Dockerfile
cat Dockerfile
# In một chuỗi và pipe nó vào một lệnh khác (ví dụ: ghi vào tệp)
echo "VERSION=1.0" > .env
4. Biến Môi Trường: export
Biến môi trường rất phổ biến trong các ứng dụng hiện đại và cấu hình Docker. Lệnh export
trong shell giúp bạn định nghĩa các biến môi trường mà có thể được sử dụng bởi các lệnh sau đó, bao gồm cả lệnh docker build
(với --build-arg
) hoặc docker run
(với -e
hoặc đọc từ tệp .env
).
# Định nghĩa biến môi trường trong session hiện tại
export APP_PORT=8080
# Sử dụng biến môi trường trong lệnh docker run
docker run -p $APP_PORT:80 my-web-app
# Sử dụng biến môi trường khi build (kết hợp với --build-arg trong Dockerfile)
export BUILD_VERSION="v1.2.3"
docker build --build-arg VERSION=$BUILD_VERSION -t my-image:$BUILD_VERSION .
Lệnh export
đặc biệt quan trọng khi làm việc với Docker Compose, nơi các biến môi trường trong tệp .env
(nếu có) hoặc shell hiện tại có thể ghi đè các giá trị trong tệp docker-compose.yml
. Điều này giúp bạn dễ dàng tùy chỉnh cấu hình cho các môi trường khác nhau (dev, staging, prod) mà không cần sửa trực tiếp tệp docker-compose.yml
.
# Ví dụ tệp .env
# DB_HOST=localhost
# DB_PORT=5432
# Ví dụ docker-compose.yml sử dụng biến
# services:
# db:
# image: postgres
# ports:
# - "${DB_PORT}:5432"
# environment:
# POSTGRES_HOST: ${DB_HOST}
# Chạy docker-compose, nó sẽ đọc biến từ .env HOẶC từ môi trường shell
export DB_PORT=6543 # Biến này sẽ ghi đè giá trị trong .env nếu có
docker-compose up -d
Hiểu cách quản lý biến môi trường là kỹ năng then chốt, như chúng ta đã đề cập trong bài về Người Dùng, Nhóm và Quyền Hạn trong Linux (liên quan đến quyền truy cập tệp .env
) và các bài về quản lý cấu hình ứng dụng.
5. Chuỗi Lệnh và Điều Kiện: ;
, &&
, ||
Các ký tự này cho phép bạn thực thi nhiều lệnh trên cùng một dòng terminal:
;
: Thực thi các lệnh theo trình tự, bất kể lệnh trước có thành công hay không.&&
: Thực thi lệnh tiếp theo CHỈ KHI lệnh trước thành công (exit code là 0). Rất hữu ích cho các workflow phụ thuộc.||
: Thực thi lệnh tiếp theo CHỈ KHI lệnh trước thất bại (exit code khác 0). Thường dùng để cung cấp hành động dự phòng.
# Dừng container, sau đó xóa nó (bất kể dừng thành công hay không)
docker stop my-container ; docker rm my-container
# Build image, và CHỈ KHI build thành công thì mới chạy container
docker build -t my-image . && docker run -d my-image
# Dừng container, NẾU thất bại thì hiển thị lỗi
docker stop my-container || echo "Không thể dừng container my-container"
6. Sử dụng Output Làm Argument: Command Substitution ($(...)
hoặc ` “) và xargs
Đây là một kỹ thuật cực kỳ mạnh mẽ để tự động hóa các tác vụ lặp đi lặp lại trên nhiều container hoặc image.
- Command Substitution: Sử dụng
$(command)
(cú pháp hiện đại, nên dùng) hoặc “` `command` “` để thay thế output chuẩn của một lệnh vào dòng lệnh khác làm argument. xargs
: Đọc các mục từ input chuẩn (thường từ pipe|
) và thực thi một lệnh khác với các mục đó làm argument. Rất hiệu quả khi xử lý danh sách dài.
# Dừng tất cả container đang chạy bằng cách lấy ID từ docker ps -q (chỉ ID)
docker stop $(docker ps -q)
# Xóa tất cả container đã dừng
docker rm $(docker ps -aq -f "status=exited")
# Xóa tất cả image không gắn tag (dangling images)
docker rmi $(docker images -f "dangling=true" -q)
# --- Sử dụng xargs (thường an toàn hơn và xử lý danh sách dài tốt hơn) ---
# Dừng tất cả container đang chạy
docker ps -q | xargs docker stop
# Xóa tất cả container đã dừng (hoặc tất cả container -aq)
docker ps -aq -f "status=exited" | xargs docker rm
# Xóa tất cả image không gắn tag
docker images -f "dangling=true" -q | xargs docker rmi
# Lưu ý: Khi dùng xargs với lệnh xóa, bạn có thể thêm -I {} hoặc -P để kiểm soát cách xử lý argument, nhưng với Docker ID/Name thì cú pháp đơn giản thường hoạt động tốt.
Kỹ thuật này cho phép bạn thực hiện các tác vụ quản lý tài nguyên Docker hàng loạt một cách hiệu quả, tránh việc phải copy/paste từng ID một.
7. Truy cập Shell Bên Trong Container: docker exec
Mặc dù docker exec
là lệnh của Docker, nó thường được dùng để chạy các lệnh shell bên trong container. Cờ -it
là viết tắt của -i
(interactive – tương tác) và -t
(pseudo-TTY – cấp phát terminal ảo), cho phép bạn tương tác với shell bên trong container như thể đang ssh vào một máy ảo.
# Truy cập shell bash bên trong container 'my-container'
docker exec -it my-container bash
# Nếu container không có bash, thử sh
docker exec -it my-container sh
# Thực thi một lệnh đơn giản bên trong container
docker exec my-container ls /app
Đây là lệnh không thể thiếu để debug ứng dụng chạy trong container, kiểm tra cấu hình, logs, hoặc chạy các script cài đặt/khởi động thủ công.
Sức Mạnh Tổng Hợp: Các Kịch Bản Phức Tạp Hơn
Khi đã nắm vững các lệnh cơ bản, bạn có thể kết hợp chúng để tạo ra các workflow phức tạp hơn.
# Ví dụ: Dừng và xóa container cũ, build image mới, và chạy container mới
docker stop my-web-app && docker rm my-web-app && \
docker build -t my-web-app:latest . && \
docker run -d --name my-web-app -p 80:80 my-web-app:latest
# Ví dụ: Tìm container bị lỗi (restart count > 0) và kiểm tra log của nó
docker ps -a --filter "status=restarting" --filter "restartcount=1" -q | \
xargs -I {} sh -c 'echo "--- Logs for {} ---" && docker logs {} && echo ""'
# Lệnh trên hơi phức tạp, nó dùng xargs để chạy một đoạn script shell ('sh -c') cho mỗi ID container tìm được.
# Script đó sẽ in header, hiển thị log, và in dòng trống để phân tách.
Việc tạo các script shell (các tệp .sh
) chứa chuỗi các lệnh này là cách phổ biến để tự động hóa các tác vụ lặp đi lặp lại, ví dụ như quá trình triển khai (deployment) đơn giản.
Tổng Kết Các Lệnh Quan Trọng
Để tiện theo dõi, đây là bảng tóm tắt một số lệnh Docker và shell quan trọng cùng cách kết hợp chúng:
Lệnh Docker Chính | Mục Đích | Lệnh Shell Thường Dùng Kèm | Ví Dụ Kết Hợp |
---|---|---|---|
docker ps / docker images |
Liệt kê container / image | grep , | (pipe), -q (cờ của Docker để chỉ in ID) |
docker ps -a | grep "my-app" docker images -q | grep "ubuntu" |
docker stop / docker rm / docker rmi |
Dừng / Xóa container / Xóa image | $(...) , xargs , -q , -a , -f (filter) |
docker stop $(docker ps -q) docker ps -aq -f "status=exited" | xargs docker rm docker images -f "dangling=true" -q | xargs docker rmi |
docker build |
Xây dựng image | cd , pwd , export , && |
cd /path/to/dockerfile && docker build . export VERSION=2.0 && docker build --build-arg VER=$VERSION -t my-image:$VERSION . |
docker run |
Chạy container | -e , -p , -v (cờ của Docker sử dụng cú pháp shell/OS), $(...) , && |
export PORT=8000 && docker run -p $PORT:80 my-app docker build -t my-image . && docker run my-image |
docker logs |
Xem nhật ký container | grep , | (pipe), Redirection (> , >> ) |
docker logs my-container | grep "error" docker logs my-container > container.log |
docker exec |
Thực thi lệnh bên trong container | -it (cờ của Docker), các lệnh shell bên trong container |
docker exec -it my-container bash docker exec my-container env |
Vượt Xa Cơ Bản: Mẹo Thêm Cho Người Dùng Docker
- Biến môi trường trong Docker Compose: Nhớ rằng Docker Compose có thể đọc biến từ shell hoặc tệp
.env
. Sử dụngexport
hoặc tạo tệp.env
là cách hiệu quả để quản lý cấu hình môi trường. - Aliases và Functions: Để tiết kiệm thời gian, bạn có thể tạo alias hoặc function trong tệp cấu hình shell của mình (ví dụ:
~/.bashrc
hoặc~/.zshrc
) cho các lệnh Docker phức tạp thường dùng. Ví dụ:alias dpsa="docker ps -a"
. - Kiểm tra Exit Code: Sau khi thực thi một lệnh Docker hoặc shell, bạn có thể kiểm tra giá trị của biến môi trường
$?
. Giá trị 0 thường báo hiệu thành công, giá trị khác 0 là lỗi. Điều này rất quan trọng khi viết script. - Công cụ quản lý Package: Đừng quên các lệnh quản lý package như
apt
,yum
/dnf
,apk
mà chúng ta đã tìm hiểu trong bài “Roadmap Docker: Package Managers 101“. Bạn sẽ thường xuyên dùng chúng bên trong Dockerfile (với lệnhRUN
) hoặc khi debug bên trong container (vớidocker exec
) để cài đặt công cụ hoặc thư viện cần thiết.
Kết Luận
Làm việc với Docker hiệu quả không chỉ là biết các lệnh docker
, mà còn là việc tận dụng sức mạnh và sự linh hoạt của môi trường shell Linux. Các lệnh cơ bản như grep
, xargs
, $(...)
, export
, &&
, ||
khi kết hợp với các lệnh Docker sẽ biến bạn từ người dùng Docker thông thường thành một kỹ sư DevOps có khả năng tự động hóa, gỡ lỗi và quản lý môi trường container một cách chuyên nghiệp.
Hãy dành thời gian thực hành các ví dụ trong bài viết này. Thử nghiệm với các cờ (flag) khác nhau của lệnh docker
và kết hợp chúng với các công cụ shell. Bạn sẽ thấy năng suất làm việc của mình tăng lên đáng kể.
Chặng đường trong “Roadmap Docker” vẫn còn tiếp tục. Trong các bài tiếp theo, chúng ta sẽ khám phá sâu hơn về Dockerfile, Docker Compose, mạng trong Docker, và nhiều chủ đề nâng cao khác. Đừng quên xem lại các bài viết trước về Linux cơ bản, Package Managers, và Người dùng và Quyền hạn trong Linux vì chúng là nền tảng vững chắc cho mọi thứ chúng ta làm với Docker.
Chúc bạn học tốt và hẹn gặp lại trong các bài viết tiếp theo!
“`