Cơ bản về Docker CLI: Nắm vững Quản lý Images, Containers, Volumes và Networks

Chào mừng bạn trở lại với loạt bài “Roadmap Docker”! Trong các bài viết trước, chúng ta đã cùng nhau tìm hiểu Container Là Gì và Vì Sao Mỗi Lập Trình Viên Nên Tìm Hiểu, phân biệt sự khác nhau giữa Container, Máy ảo (VM) và Bare Metal, và nắm bắt Hiểu về Docker và Tiêu chuẩn OCI. Chúng ta cũng đã trang bị những kiến thức nền tảng quan trọng về Linux, Package Managers, Người dùng, Nhóm và Quyền hạn, cũng như các Lệnh Shell Cần Thiết và cách Sử dụng Shell Script để Tự động hóa. Sau khi đã Hướng dẫn Cài đặt Docker thành công, bước tiếp theo và cũng là quan trọng nhất, chính là làm quen với giao diện dòng lệnh (CLI) của Docker. Đây là công cụ quyền năng giúp bạn tương tác trực tiếp với Docker Engine, quản lý toàn bộ vòng đời của các thành phần Docker.

Bài viết này sẽ đi sâu vào những lệnh Docker CLI cơ bản nhất để quản lý bốn đối tượng chính: Images, Containers, Volumes và Networks. Nắm vững các lệnh này là chìa khóa để bạn bắt đầu hành trình làm việc hiệu quả với Docker.

Docker CLI: Cửa ngõ tương tác

Giao diện dòng lệnh Docker (Docker CLI) là cách chính để bạn ra lệnh cho Docker daemon (Docker Engine) thực hiện các tác vụ như tải image, chạy container, tạo mạng hay quản lý dữ liệu. Cú pháp chung thường là docker [lệnh] [đối tượng] [tùy chọn].

Ví dụ:

docker run ubuntu echo "Xin chao Docker"

Ở đây:

  • docker: Gọi chương trình Docker CLI.
  • run: Là lệnh (command) để chạy một container mới.
  • ubuntu: Là đối tượng (image name) mà chúng ta muốn chạy container từ đó.
  • echo "Xin chao Docker": Là đối số (arguments) – lệnh sẽ được thực thi bên trong container.

Bây giờ, chúng ta hãy đi sâu vào cách quản lý từng loại đối tượng.

Quản lý Docker Images

Image là nền tảng của container. Nó là một khuôn mẫu tĩnh, chỉ đọc, chứa mã ứng dụng, thư viện, phụ thuộc và cấu hình cần thiết để ứng dụng chạy. Hiểu về Sử Dụng Các Image Bên Thứ Ba An Toàn và Hiệu Quả và cách các Dockerfile hoạt động là rất quan trọng, nhưng trước hết, hãy nắm vững các lệnh CLI cơ bản để làm việc với chúng.

Tải Image về máy (Pulling Images)

Lệnh docker pull được sử dụng để tải image từ một registry (mặc định là Docker Hub) về máy tính của bạn.

docker pull <image_name>[:<tag>]

Trong đó, image_name là tên của image (ví dụ: ubuntu, nginx, mysql) và tag là phiên bản cụ thể của image (mặc định là latest nếu không chỉ định). Việc Gắn Tag cho Docker Image một cách hợp lý là rất quan trọng.

docker pull ubuntu:20.04
docker pull nginx

Lệnh đầu tiên tải image Ubuntu phiên bản 20.04, lệnh thứ hai tải image Nginx với tag latest.

Liệt kê các Image có sẵn (Listing Images)

Sử dụng lệnh docker images hoặc docker image ls để xem danh sách các image đã được tải về máy.

docker images

Kết quả sẽ hiển thị các cột như:

  • REPOSITORY: Tên của image.
  • TAG: Phiên bản của image.
  • IMAGE ID: ID duy nhất của image. Đây là cách nhận dạng chính xác một image.
  • CREATED: Thời gian image được tạo.
  • SIZE: Kích thước của image.

Kiểm tra chi tiết Image (Inspecting Images)

Lệnh docker image inspect cung cấp thông tin chi tiết về cấu hình, metadata, lịch sử xây dựng của một image. Rất hữu ích cho việc gỡ lỗi hoặc hiểu rõ hơn về image.

docker image inspect <image_id_or_name>

Ví dụ:

docker image inspect ubuntu:20.04

Lệnh này trả về một đối tượng JSON chứa rất nhiều thông tin.

Xóa Image (Removing Images)

Để giải phóng dung lượng đĩa, bạn có thể xóa các image không cần thiết bằng lệnh docker image rm hoặc docker rmi.

docker image rm <image_id_or_name>

Ví dụ:

docker image rm ubuntu:20.04

Lưu ý: Bạn không thể xóa một image nếu có bất kỳ container nào đang sử dụng nó. Bạn cần dừng và xóa các container đó trước, hoặc sử dụng tùy chọn -f (force) để buộc xóa (không khuyến khích dùng -f trong môi trường production).

docker image rm -f ubuntu:20.04

Quản lý Docker Containers

Container là một phiên bản đang chạy (hoặc đã dừng) của một image. Đây là nơi ứng dụng của bạn thực sự hoạt động, biệt lập với hệ thống host và các container khác nhờ vào các kỹ thuật như Namespaces, cgroups, và UnionFS.

Chạy Container (Running Containers)

Lệnh docker run là lệnh được sử dụng phổ biến nhất. Nó thực hiện hai bước: tạo một container mới từ một image, và sau đó chạy nó. Chúng ta đã có bài viết chi tiết về Chạy Container với docker run – Hướng dẫn cho người mới bắt đầuTùy Chọn Cấu Hình Thời Gian Chạy cho Container Docker, hãy xem lại để hiểu rõ hơn các tùy chọn.

docker run <image_name> [<command>]

Một số tùy chọn phổ biến:

  • -d: Chạy container ở chế độ “detached” (chạy ngầm trong nền).
  • -p host_port:container_port: Ánh xạ cổng từ host vào container.
  • -v host_path:container_path hoặc -v volume_name:container_path: Gắn volume hoặc bind mount dữ liệu. (Tham khảo thêm về Lưu trữ Dữ liệu Bền vững trong DockerVolume Mounts và Bind Mounts).
  • --name <container_name>: Đặt tên dễ nhớ cho container.
  • -it: Kết hợp -i (interactive) và -t (pseudo-TTY) để tương tác với container qua shell. Rất hữu ích khi bạn muốn chạy container và ngay lập tức vào bên trong để gỡ lỗi.
  • --rm: Tự động xóa container khi nó dừng.

Ví dụ:

# Chạy một container Nginx ở chế độ ngầm, ánh xạ cổng 8080 trên host tới cổng 80 trên container và đặt tên là my-nginx
docker run -d -p 8080:80 --name my-nginx nginx

# Chạy một container Ubuntu và mở shell tương tác bên trong
docker run -it ubuntu bash

Liệt kê các Container (Listing Containers)

Lệnh docker ps hoặc docker container ls hiển thị danh sách các container đang chạy.

docker ps

Kết quả bao gồm:

  • CONTAINER ID: ID duy nhất của container.
  • IMAGE: Image mà container được tạo từ đó.
  • COMMAND: Lệnh khởi động container.
  • CREATED: Thời gian container được tạo.
  • STATUS: Trạng thái hiện tại (Up, Exited, Created, etc.).
  • PORTS: Thông tin ánh xạ cổng.
  • NAMES: Tên của container (do bạn đặt hoặc Docker tự tạo).

Để hiển thị cả các container đã dừng, thêm tùy chọn -a:

docker ps -a

Bắt đầu, Dừng, Khởi động lại Container (Start, Stop, Restart)

Các lệnh này quản lý trạng thái chạy của container:

docker start <container_id_or_name>
docker stop <container_id_or_name>
docker restart <container_id_or_name>

Ví dụ:

docker stop my-nginx
docker start my-nginx

Tạm dừng và Tiếp tục Container (Pause, Unpause)

Lệnh pause tạm dừng tất cả các tiến trình trong một container mà không dừng container. Lệnh unpause sẽ tiếp tục các tiến trình đó.

docker pause <container_id_or_name>
docker unpause <container_id_or_name>

Kiểm tra chi tiết Container (Inspecting Containers)

Tương tự như image, docker container inspect cung cấp thông tin sâu về cấu hình runtime của container, bao gồm network settings, mounted volumes, state, etc.

docker container inspect <container_id_or_name>

Xem nhật ký Container (Viewing Logs)

Ứng dụng bên trong container thường ghi log ra standard output (stdout) và standard error (stderr). Lệnh docker logs cho phép bạn xem các log này.

docker logs <container_id_or_name>

Một số tùy chọn hữu ích:

  • -f: Theo dõi log theo thời gian thực (follow).
  • --tail <number>: Chỉ hiển thị N dòng log cuối cùng.
docker logs -f my-nginx

Thực thi lệnh bên trong Container (Executing Commands)

Lệnh docker exec cho phép bạn chạy một lệnh mới bên trong một container đang chạy. Điều này rất hữu ích để gỡ lỗi hoặc thực hiện các tác vụ quản trị bên trong container.

docker exec <container_id_or_name> <command>

Ví dụ, để mở một shell bên trong container my-nginx:

docker exec -it my-nginx bash

(Lưu ý container Nginx dựa trên Alpine Linux, nên shell mặc định thường là sh hoặc ash thay vì bash).

Xóa Container (Removing Containers)

Để xóa một hoặc nhiều container đã dừng:

docker container rm <container_id_or_name> [<container_id_or_name>...]

Ví dụ:

docker container rm my-nginx my-old-container

Để xóa container đang chạy, bạn cần dừng nó trước hoặc sử dụng tùy chọn -f (force):

docker container rm -f my-nginx

Lưu ý -f sẽ gửi tín hiệu SIGKILL tới tiến trình chính trong container.

Quản lý Docker Volumes

Theo mặc định, dữ liệu trong container là tạm thời (ephemeral) và sẽ mất khi container bị xóa. Volume là cách ưu tiên để lưu trữ dữ liệu bền vững (persistent data) trong Docker, độc lập với vòng đời của container. Chúng ta đã thảo luận chi tiết về Lưu trữ Dữ liệu Bền vững trong Docker và sự khác biệt giữa Volume Mounts và Bind Mounts.

Tạo Volume (Creating Volumes)

Bạn có thể tạo volume được đặt tên (named volume) bằng lệnh docker volume create.

docker volume create <volume_name>

Ví dụ:

docker volume create my-app-data

Volume này sau đó có thể được gắn (mount) vào một hoặc nhiều container.

Liệt kê các Volume (Listing Volumes)

Sử dụng docker volume ls để xem danh sách các volume có sẵn trên hệ thống Docker host.

docker volume ls

Kết quả thường chỉ hiển thị tên (DRIVERVOLUME NAME).

Kiểm tra chi tiết Volume (Inspecting Volumes)

Lệnh docker volume inspect hiển thị thông tin chi tiết về một volume, bao gồm cả đường dẫn vật lý của nó trên hệ thống host.

docker volume inspect <volume_name>

Ví dụ:

docker volume inspect my-app-data

Bạn sẽ thấy mục Mountpoint, cho biết đường dẫn thực tế trên host nơi dữ liệu của volume được lưu trữ.

Gắn Volume vào Container (Mounting Volumes)

Như đã đề cập trong phần Container, volume được gắn vào container khi chạy bằng tùy chọn -v trong lệnh docker run.

docker run -d -v my-app-data:/app/data --name my-app my-app-image

Lệnh này gắn volume my-app-data vào đường dẫn /app/data bên trong container my-app.

Xóa Volume (Removing Volumes)

Để xóa một volume không còn sử dụng:

docker volume rm <volume_name>

Ví dụ:

docker volume rm my-app-data

Bạn chỉ có thể xóa một volume nếu không có container nào đang sử dụng nó. Để xóa volume cùng với container, bạn có thể sử dụng tùy chọn -v khi xóa container (docker rm -v), nhưng phương pháp này chỉ xóa các volume ẩn danh (anonymous volumes), không phải named volumes.

Để xóa các volume không còn được sử dụng bởi bất kỳ container nào, bạn có thể dùng lệnh docker volume prune. Lệnh này sẽ hỏi xác nhận trước khi xóa.

docker volume prune

Quản lý Docker Networks

Docker networking cho phép các container giao tiếp với nhau và với thế giới bên ngoài. Docker tạo các network mặc định (như bridge, host, none) và cho phép bạn tạo các network tùy chỉnh. Hiểu rõ cách network hoạt động là quan trọng để thiết kế các ứng dụng đa container hiệu quả.

Liệt kê các Network (Listing Networks)

Sử dụng lệnh docker network ls để xem danh sách các network có sẵn.

docker network ls

Bạn sẽ thấy ít nhất ba network mặc định: bridge, host, và none. Network bridge là network mặc định cho các container mới nếu không chỉ định.

Kiểm tra chi tiết Network (Inspecting Networks)

Lệnh docker network inspect cung cấp thông tin chi tiết về một network cụ thể, bao gồm cả subnet, gateway, và danh sách các container đang kết nối đến network đó.

docker network inspect <network_id_or_name>

Ví dụ:

docker network inspect bridge

Thông tin về các container kết nối rất hữu ích khi gỡ lỗi kết nối giữa các container.

Tạo Network (Creating Networks)

Bạn nên tạo custom network cho các ứng dụng đa container của mình. Điều này cung cấp sự cô lập tốt hơn và cho phép các container tham chiếu nhau bằng tên host (DNS Service Discovery).

docker network create [<options>] <network_name>

Loại network phổ biến nhất để bắt đầu là bridge:

docker network create my-app-network

Kết nối Container vào Network (Connecting Containers)

Khi chạy container mới, bạn chỉ định network bằng tùy chọn --network trong lệnh docker run.

docker run -d --network my-app-network --name app-container my-app-image
docker run -d --network my-app-network --name db-container my-db-image

Bây giờ, app-container có thể kết nối đến db-container bằng hostname db-container và ngược lại.

Bạn cũng có thể kết nối một container đang chạy vào một network bằng lệnh docker network connect.

docker network connect my-app-network <container_id_or_name>

Ngắt kết nối Container khỏi Network (Disconnecting Containers)

Để ngắt kết nối một container khỏi một network:

docker network disconnect <network_id_or_name> <container_id_or_name>

Ví dụ:

docker network disconnect bridge my-nginx

Xóa Network (Removing Networks)

Để xóa một network tùy chỉnh:

docker network rm <network_id_or_name>

Ví dụ:

docker network rm my-app-network

Bạn chỉ có thể xóa network nếu không có container nào đang sử dụng nó.

Bảng Tóm tắt các Lệnh Quản lý Cơ bản

Để tiện tham khảo, đây là bảng tổng hợp các lệnh cơ bản để quản lý Images, Containers, Volumes và Networks:

Đối tượng Liệt kê (List) Kiểm tra chi tiết (Inspect) Xóa (Remove) Tạo (Create) / Chạy (Run)
Image docker images hoặc docker image ls docker image inspect <id/name> docker image rm <id/name> docker pull <name> (Tải) / docker build (Xây dựng từ Dockerfile)
Container docker ps (đang chạy) / docker ps -a (tất cả) docker container inspect <id/name> docker container rm <id/name> docker run <image>
Volume docker volume ls docker volume inspect <name> docker volume rm <name> / docker volume prune docker volume create <name>
Network docker network ls docker network inspect <id/name> docker network rm <id/name> docker network create <name>

Các Lệnh Hệ thống và Dọn dẹp Hữu ích

Khi làm việc với Docker, hệ thống của bạn có thể tích tụ nhiều image, container, volume, network không còn sử dụng. Docker cung cấp các lệnh để quản lý và dọn dẹp chúng.

Xem dung lượng sử dụng (Disk Usage)

Lệnh docker system df cung cấp cái nhìn tổng quan về dung lượng đĩa mà Docker đang sử dụng, phân loại theo Images, Containers, Local Volumes và Build Cache.

docker system df

Dọn dẹp tài nguyên không sử dụng (Pruning)

Lệnh docker system prune là một công cụ mạnh mẽ để dọn dẹp các tài nguyên không còn sử dụng (dangling) hoặc không được tham chiếu (unused) trên hệ thống Docker.

docker system prune

Lệnh này sẽ xóa:

  • Tất cả container đã dừng.
  • Tất cả network không được sử dụng bởi ít nhất một container.
  • Tất cả image dangling (không có tag và không được sử dụng bởi bất kỳ container nào).
  • Tất cả build cache.

Bạn có thể thêm tùy chọn --volumes để xóa cả các volume không sử dụng.

docker system prune --volumes

Hãy cẩn thận khi sử dụng lệnh này, đặc biệt với tùy chọn --volumes, để tránh xóa nhầm dữ liệu quan trọng.

Kết luận

Làm chủ Docker CLI là bước đầu tiên và quan trọng nhất trên con đường trở thành một kỹ sư DevOps thành thạo Docker. Các lệnh cơ bản để quản lý Images, Containers, Volumes và Networks mà chúng ta đã khám phá trong bài viết này chính là nền tảng cho mọi thao tác phức tạp hơn sau này.

Hãy dành thời gian thực hành các lệnh này trên máy tính của bạn. Thử kéo các image khác nhau, chạy container từ chúng với các tùy chọn khác nhau, tạo và gắn volume, xây dựng các network tùy chỉnh và kết nối container vào đó. Đừng ngần ngại sử dụng docker inspect để hiểu sâu hơn về cấu hình của từng đối tượng.

Sau khi đã vững vàng với các khái niệm và lệnh cơ bản này, bạn đã sẵn sàng để tiến xa hơn trong “Roadmap Docker”. Các bài viết tiếp theo sẽ đưa bạn đến với việc Viết Dockerfile Tốt Hơn để đóng gói ứng dụng của bạn, hiểu về Docker Caching, Tối Ưu Kích Thước Image và Tăng Cường Bảo Mật, và cuối cùng là quản lý các ứng dụng phức tạp hơn với Docker Compose. Chúc bạn thành công trên hành trình khám phá Docker!

Chỉ mục