Mở đầu
Docker là một nền tảng giúp đơn giản hóa quá trình triển khai và quản lý ứng dụng bằng cách sử dụng công nghệ container. Containers cho phép bạn chạy ứng dụng trong các tiến trình được cách ly tài nguyên, mang lại sự ổn định và bảo mật cao hơn. Mặc dù có điểm tương đồng với máy ảo (Virtual Machine), nhưng containers nhẹ hơn, linh hoạt hơn và tận dụng tốt hơn tài nguyên hệ thống và phụ thuộc nhiều hơn vào hệ điều hành của máy chủ.
Nếu bạn đang muốn bắt đầu với Docker trên Ubuntu, thì đây chính là bài viết dành cho bạn. Trong hướng dẫn này, mình sẽ cùng bạn từng bước cài đặt Docker Community Edition (CE) phiên bản miễn phí, phổ biến nhất của Docker.
Không chỉ đơn thuần là cài đặt, bạn sẽ được thực hành các thao tác cơ bản như:
- Làm quen với containers và images.
- Tạo và quản lý containers (bắt đầu, dừng, xoá).
- Tự tạo Docker image từ những thay đổi trong container.
- Đẩy image lên Docker Hub (hoặc repository riêng của bạn).
Bên cạnh đó, mình cũng sẽ hướng dẫn bạn cách:
- Cài Docker có hỗ trợ GPU (nếu bạn dùng cho AI/ML).
- Xử lý một số lỗi phổ biến trong quá trình sử dụng.
- Và chia sẻ vài mẹo bảo mật để bạn yên tâm khi dùng Docker trong dự án thực tế.
Trước khi bắt đầu, bạn cần chuẩn bị gì?
Để quá trình cài đặt Docker diễn ra suôn sẻ, hãy đảm bảo bạn đáp ứng một vài điều kiện sau:
- Một máy chủ Ubuntu đã được cấu hình cơ bản, bao gồm:
- Người dùng không phải root nhưng có quyền
sudo
. - Tường lửa (firewall) đã được thiết lập theo hướng dẫn khởi tạo server của Ubuntu.
- Người dùng không phải root nhưng có quyền
- Một tài khoản Docker Hub bạn có thể đăng ký miễn phí tại https://hub.docker.com để lưu trữ và chia sẻ các Docker image sau này.
Khi mọi thứ đã sẵn sàng, chúng ta hãy cùng bắt đầu hành trình cài đặt Docker trên Ubuntu.
Bước 1: Cài đặt Docker trên Ubuntu
Mặc dù Ubuntu đã cung cấp sẵn gói cài đặt Docker trong kho lưu trữ của mình, nhưng phiên bản đó thường không phải là mới nhất.
Để đảm bảo chúng ta sử dụng phiên bản Docker mới nhất với đầy đủ tính năng và bản vá bảo mật, mình sẽ hướng dẫn bạn cài đặt Docker trực tiếp từ kho lưu trữ chính thức của Docker.
Quy trình sẽ gồm các bước:
- Thêm nguồn chứa gói Docker chính thức vào hệ thống.
- Thêm khóa GPG để xác thực các tệp cài đặt, đảm bảo chúng an toàn và đáng tin cậy.
- Tiến hành cài đặt Docker từ nguồn mới này.
Trước khi cài đặt bất kỳ phần mềm mới nào, việc đầu tiên chúng ta nên làm là cập nhật danh sách các gói của hệ thống. Điều này giúp đảm bảo mọi thứ đều mới nhất và tránh lỗi trong quá trình cài đặt.
sudo apt update
Tiếp theo, chúng ta cần cài đặt một số gói phụ trợ. Những gói này cho phép apt
có thể giao tiếp và lấy các gói phần mềm thông qua giao thức HTTPS một giao thức an toàn và bảo mật hơn.
sudo apt install apt-transport-https ca-certificates curl software-properties-common
Để đảm bảo các gói cài đặt Docker mà chúng ta tải về là hợp lệ và chưa bị thay đổi, chúng ta cần thêm khóa GPG chính thức của Docker vào hệ thống.
curl -fsSL <https://download.docker.com/linux/ubuntu/gpg> | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
Sau khi đã thêm khóa GPG, bước tiếp theo là thêm kho lưu trữ chính thức của Docker vào danh sách nguồn của apt. Điều này giúp hệ thống nhận biết và cài đặt Docker trực tiếp từ nguồn đáng tin cậy.
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] <https://download.docker.com/linux/ubuntu> $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Bây giờ chúng ta cần cập nhật lại danh sách gói một lần nữa để hệ thống nhận diện được nguồn mới vừa thêm vào.
sudo apt update
Lệnh này sẽ quét tất cả các nguồn phần mềm (bao gồm kho Docker mới) và cập nhật thông tin về các gói phần mềm khả dụng. Trước khi tiến hành cài đặt, chúng ta cần đảm bảo rằng apt
sẽ lấy Docker từ kho lưu trữ chính thức của Docker, chứ không phải từ kho mặc định của Ubuntu (vì kho mặc định có thể chứa phiên bản cũ hơn).
apt-cache policy docker-ce
Bạn sẽ thấy kết quả đầu ra tương tự như thế này (lưu ý rằng số phiên bản Docker có thể khác tuỳ thời điểm):
docker-ce:
Installed: (none)
Candidate: 5:20.10.14~3-0~ubuntu-jammy
Version table:
5:20.10.14~3-0~ubuntu-jammy 500
500 <https://download.docker.com/linux/ubuntu> jammy/stable amd64 Packages
5:20.10.13~3-0~ubuntu-jammy 500
500 <https://download.docker.com/linux/ubuntu> jammy/stable amd64 Packages
Lưu ý rằng docker-ce
chưa được cài đặt trên hệ thống của bạn (bạn sẽ thấy “Installed: (none)”). Tuy nhiên, thông tin (candidate) cho chúng ta biết phiên bản cài đặt từ kho lưu trữ chính thức của Docker dành cho Ubuntu, điều này có nghĩa là bạn sẽ cài đặt phiên bản mới nhất từ Docker chứ không phải phiên bản cũ hơn từ kho lưu trữ mặc định của Ubuntu.
Giờ thì chúng ta đã sẵn sàng để cài đặt Docker từ kho lưu trữ chính thức! Để cài đặt Docker Engine, chỉ cần chạy lệnh sau trong terminal:
sudo apt install docker-ce
Đợi quá trình cài đặt hoàn tất, Docker sẽ tự động được khởi động và thiết lập để bắt đầu mỗi khi hệ thống khởi động lại.
Để kiểm tra xem Docker có đang chạy không, bạn chỉ cần chạy lệnh sau:
sudo systemctl status docker
Output● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2022-04-01 21:30:25 UTC; 22s ago
TriggeredBy: ● docker.socket
Docs: <https://docs.docker.com>
Main PID: 7854 (dockerd)
Tasks: 7
Memory: 38.3M
CPU: 340ms
CGroup: /system.slice/docker.service
└─7854 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Sau khi cài đặt Docker, bạn không chỉ có dịch vụ Docker (daemon) mà còn có công cụ dòng lệnh docker
, hay còn gọi là Docker client. Công cụ này cho phép bạn tương tác với Docker và quản lý các container, images, networks và volumes. Với Docker client, bạn có thể dễ dàng thực hiện các lệnh để xây dựng, chạy và quản lý containers của mình từ terminal. Chúng ta sẽ cùng tìm hiểu cách sử dụng các lệnh Docker trong phần sau của hướng dẫn này.
Bước 2: Thực thi lệnh Docker mà không cần sudo
Theo mặc định, lệnh docker
chỉ có thể được thực thi bởi người dùng root hoặc bởi những người dùng đã được thêm vào nhóm docker
, nhóm này được tạo tự động trong quá trình cài đặt Docker. Nếu bạn cố gắng chạy lệnh docker
mà không sử dụng sudo
hoặc không thuộc nhóm docker
, bạn sẽ nhận được thông báo lỗi giống như sau:
Outputdocker: Cannot connect to the Docker daemon. Is the docker daemon running on this host?.
See 'docker run --help'.
Tuy nhiên, nếu bạn không muốn luôn phải thêm sudo
vào mỗi lệnh Docker, bạn có thể thêm người dùng của mình vào nhóm docker
. Điều này sẽ cho phép bạn chạy các lệnh Docker mà không cần quyền root.
sudo usermod -aG docker $USER
Để áp dụng quyền truy cập mới sau khi thêm người dùng vào nhóm docker
, bạn cần phải đăng xuất khỏi hệ thống và đăng nhập lại.
su - ${USER}
Để xác nhận rằng người dùng của bạn đã được thêm thành công vào nhóm docker
, bạn có thể sử dụng lệnh sau:
groups $USER
Lệnh này sẽ hiển thị tất cả các nhóm mà người dùng hiện tại thuộc về. Nếu bạn thấy docker
trong danh sách nhóm, điều này có nghĩa là người dùng đã được thêm vào nhóm docker thành công.
Phần còn lại của bài viết này giả định rằng bạn đang chạy lệnh docker
với quyền của người dùng đã được thêm vào nhóm docker
. Bây giờ, chúng ta sẽ cùng tìm hiểu một số lệnh cơ bản của Docker để bắt đầu sử dụng công cụ này. Docker cung cấp một bộ lệnh mạnh mẽ giúp bạn quản lý containers, images, networks, và volumes.
Bước 3: Sử dụng Lệnh Docker
Việc sử dụng Docker bao gồm việc truyền cho Docker một chuỗi các tùy chọn và lệnh, theo sau là các đối số cần thiết. Cú pháp của lệnh Docker có dạng như sau:
docker [OPTIONS] COMMAND [ARGUMENTS...]
- OPTIONS: Các tùy chọn này có thể điều chỉnh cách thức lệnh được thực thi, chẳng hạn như chế độ tương tác, hạn chế tài nguyên, hoặc chỉ định các cài đặt cụ thể.
- COMMAND: Đây là lệnh chính mà Docker sẽ thực thi, chẳng hạn như
run
,ps
,build
,stop
, v.v. - ARGUMENTS: Các đối số sẽ xác định thêm chi tiết cho lệnh, ví dụ như tên image, ID container, hoặc các tệp cấu hình.
Để xem danh sách đầy đủ các subcommands (lệnh con) mà Docker hỗ trợ, bạn có thể chạy lệnh sau:
docker --help
Output attach Attach local standard input, output, and error streams to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive
history Show the history of an image
images List images
import Import the contents from a tarball to create a filesystem image
info Display system-wide information
inspect Return low-level information on Docker objects
kill Kill one or more running containers
load Load an image from a tar archive or STDIN
login Log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
Để xem các tùy chọn có sẵn cho một lệnh cụ thể, hãy nhập:
docker docker-subcommand --help
Để xem thông tin toàn hệ thống về Docker, hãy sử dụng:
docker info
Hãy cùng khám phá một số lệnh này. Chúng ta sẽ bắt đầu từ việc làm việc với Docker images. Images trong Docker là các bản sao chỉ đọc (read-only) của một môi trường chứa phần mềm và các tệp cần thiết để chạy một ứng dụng trong container.
Bước 4: Làm Việc Với Docker Images
Trong bước này, chúng ta sẽ tìm hiểu chi tiết hơn về cách làm việc với Docker images. Docker images là cơ sở để tạo ra các container, và bạn sẽ cần hiểu cách quản lý chúng để tối ưu hóa quá trình phát triển và triển khai ứng dụng.
Docker containers được xây dựng từ Docker images. Mặc định, Docker sẽ tải các images này từ Docker Hub, một registry Docker được quản lý bởi Docker, công ty đứng sau dự án Docker. Docker Hub là nơi lưu trữ chính thức các Docker images và là một nguồn tài nguyên phong phú cho nhiều ứng dụng và hệ điều hành Linux.
Điều đặc biệt về Docker Hub là bất kỳ ai cũng có thể lưu trữ Docker images của mình trên đó, giúp chia sẻ với cộng đồng hoặc giữa các nhóm phát triển. Chính vì vậy, hầu hết các ứng dụng phổ biến và các bản phân phối Linux mà bạn cần sử dụng đều có sẵn dưới dạng Docker images trên Docker Hub.
Để kiểm tra xem bạn có thể truy cập và tải Docker images từ Docker Hub hay không, bạn có thể chạy lệnh sau:
docker run hello-world
OutputUnable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:bfea6278a0a267fad2634554f4f0c6f31981eea41c553fdf5a83e95a41d40c38
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
Khi Docker không thể tìm thấy image hello-world
trên máy tính của bạn, nó đã tự động tải image này từ Docker Hub, là kho lưu trữ mặc định của Docker. Docker Hub là nơi chứa hàng triệu Docker images, từ các ứng dụng phổ biến đến các hệ điều hành, giúp bạn dễ dàng tải và sử dụng chúng.
Sau khi image được tải về, Docker tiếp tục tạo một container từ image đó và chạy ứng dụng bên trong container. Ứng dụng này sau đó hiển thị thông điệp xác nhận rằng Docker đã được cài đặt và hoạt động bình thường. Bạn có thể tìm kiếm hình ảnh có sẵn trên Docker Hub bằng cách sử dụng lệnh docker với lệnh con search. Ví dụ, để tìm kiếm hình ảnh Ubuntu, hãy nhập:
docker search ubuntu
Tập lệnh sẽ thu thập Docker Hub và trả về danh sách tất cả các hình ảnh có tên khớp với chuỗi tìm kiếm. Trong trường hợp này, đầu ra sẽ tương tự như sau:
OutputNAME DESCRIPTION STARS OFFICIAL AUTOMATED
ubuntu Ubuntu is a Debian-based Linux operating sys… 14048 [OK]
websphere-liberty WebSphere Liberty multi-architecture images … 283 [OK]
ubuntu-upstart DEPRECATED, as is Upstart (find other proces… 112 [OK]
neurodebian NeuroDebian provides neuroscience research s… 88 [OK]
open-liberty Open Liberty multi-architecture images based… 51 [OK]
...
Trong cột OFFICIAL, một ký hiệu OK cho thấy đây là một image được xây dựng và hỗ trợ bởi công ty đứng sau dự án. Những images này thường được đảm bảo về chất lượng và độ tin cậy, vì chúng được duy trì và cập nhật thường xuyên. Khi bạn đã xác định được image mà mình muốn sử dụng, bạn có thể tải nó về máy tính của mình bằng cách sử dụng lệnh docker pull
. Ví dụ, để tải image Ubuntu, bạn chỉ cần chạy:
docker pull ubuntu
OutputUsing default tag: latest
latest: Pulling from library/ubuntu
e0b25ef51634: Pull complete
Digest: sha256:9101220a875cee98b016668342c489ff0674f247f6ca20dfc91b91c0f28581ae
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
Khi một Docker image đã được tải về, bạn có thể sử dụng lệnh docker run
để tạo và chạy một container từ image đó. Như bạn đã thấy trong ví dụ với hello-world
, nếu Docker không tìm thấy image trên máy tính của bạn khi bạn sử dụng lệnh docker run
, Docker sẽ tự động tải image từ Docker Hub trước khi tạo container và chạy nó. Để xem những hình ảnh đã được tải xuống máy tính của bạn, hãy nhập:
docker images
OutputREPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 1d622ef86b13 3 weeks ago 73.9MB
hello-world latest bf756fb1ae65 4 months ago 13.3kB
Như bạn sẽ thấy trong phần sau của hướng dẫn này, các Docker images mà bạn sử dụng để chạy containers có thể được chỉnh sửa và sử dụng để tạo ra những Docker images mới. Quá trình này cho phép bạn tùy chỉnh container của mình, thêm vào các phần mềm, cấu hình, hoặc tệp cần thiết, rồi từ đó tạo một image mới.
Sau khi đã tạo được một image mới, bạn có thể tải (hay “push” theo thuật ngữ kỹ thuật) image này lên Docker Hub hoặc các Docker registry khác để chia sẻ với người khác hoặc sử dụng lại trên các máy chủ khác. Quá trình tạo và push một image giúp bạn dễ dàng tái sử dụng và triển khai các container tương tự trên các môi trường khác nhau mà không cần phải cấu hình lại mọi thứ từ đầu.
Bước 5: Chạy Docker Container
Ở bước trên, bạn đã chạy một container hello-world
, đây chỉ là một ví dụ đơn giản nhằm xác nhận rằng Docker đang hoạt động đúng. Container này chạy một lần, in ra thông báo kiểm tra và sau đó tự động thoát. Mặc dù hữu ích trong việc kiểm tra ban đầu, nhưng container thực tế có thể mạnh mẽ hơn rất nhiều.
Trên thực tế, Docker containers có thể duy trì trạng thái hoạt động, chạy các ứng dụng nền (background services), hoặc thậm chí cung cấp một môi trường tương tác giống như cách bạn làm việc với một máy ảo. Tuy nhiên, điểm đặc biệt là container nhẹ hơn rất nhiều so với máy ảo truyền thống, sử dụng ít tài nguyên hơn và khởi động gần như tức thì.
Chúng ta sẽ cùng khám phá cách khởi tạo một container có thể tương tác, nơi bạn có thể gõ lệnh và thao tác trực tiếp bên trong môi trường đó tương tự như khi bạn SSH vào một máy chủ Linux thực thụ.
Bây giờ, hãy cùng thử chạy một container tương tác bằng cách sử dụng image Ubuntu mới nhất. Khi kết hợp hai tùy chọn -i
và -t
, bạn sẽ có quyền truy cập vào shell bên trong container.
docker run -it ubuntu
- Giải thích
i
(interactive): giữ cho kết nối đầu vào (stdin) mở, cho phép bạn nhập lệnh vào container.t
(tty): cấp cho bạn một terminal ảo bên trong container.
Khi chạy lệnh này, bạn sẽ thấy dấu nhắc shell giống như đang sử dụng một phiên bản Ubuntu thực thụ. Tại đây, bạn có thể cài đặt phần mềm, thay đổi file, hoặc làm bất kỳ điều gì bạn vẫn làm với một máy Linux thông thường.
Output
root@d9b100f2f636:/#
Trong trường hợp này, d9b100f2f636
là ID của container đang chạy. Đây là một mã định danh duy nhất mà Docker gán cho container, giúp bạn dễ dàng theo dõi và quản lý nó sau này.
Khi đã vào bên trong container, bạn có thể chạy bất kỳ lệnh nào giống như đang thao tác trên một máy chủ Ubuntu thực thụ. Một điểm tiện lợi là bạn không cần dùng sudo
, vì mặc định bạn đang hoạt động với quyền root trong container.
Ví dụ, để cập nhật danh sách gói phần mềm bên trong container, chỉ cần chạy:
root@d9b100f2f636:/# apt update
Sau đó cài đặt bất kỳ ứng dụng nào vào đó. Hãy cài đặt Node.js:
root@d9b100f2f636:/# apt install nodejs
Lệnh trên cài đặt Node.js trong container từ kho lưu trữ Ubuntu chính thức. Khi quá trình cài đặt hoàn tất, hãy xác minh rằng Node.js đã được cài đặt:
root@d9b100f2f636:/# node -v
Output
v12.22.9
Một điều quan trọng cần ghi nhớ khi làm việc với Docker container là: mọi thay đổi bạn thực hiện bên trong container chỉ ảnh hưởng đến chính container đó.
Điều này có nghĩa là:
- Nếu bạn cài đặt phần mềm, sửa file cấu hình, hoặc tạo thư mục mới trong container thì tất cả các thay đổi đó sẽ không ảnh hưởng đến hệ thống máy chủ đang chạy Docker.
- Mỗi container giống như một môi trường tách biệt, độc lập hoàn toàn với hệ điều hành chính.
Vì tính chất cô lập này, bạn có thể tự tin thử nghiệm, thay đổi và thậm chí phá hỏng mọi thứ bên trong container mà không lo làm hỏng hệ thống thật. Nếu container gặp sự cố, bạn chỉ cần xóa nó và tạo mới lại từ image ban đầu là xong.
Sau khi bạn đã hoàn tất các thao tác bên trong container, bạn có thể dễ dàng thoát ra và quay lại hệ thống máy chủ chính bằng cách gõ:
exit
Bây giờ, chúng ta đã biết cách tạo và làm việc bên trong một container, chúng ta hãy cùng khám phá cách quản lý các container đang hoạt động hoặc đã dừng trên hệ thống.
Bước 6: Quản Lý Docker Containers
Sau một thời gian sử dụng Docker, hệ thống của bạn có thể sẽ có rất nhiều container, bao gồm cả container đang chạy và container đã dừng. Để kiểm tra các container đang hoạt động, bạn chỉ cần sử dụng lệnh sau:
docker ps
Bạn sẽ thấy kết quả tương tự như sau:
Output
CONTAINER ID IMAGE COMMAND CREATED
Trong quá trình thực hành ở bài hướng dẫn này, bạn đã khởi tạo hai container: một từ image hello-world
và một từ image ubuntu
. Mặc dù cả hai container này đã dừng hoạt động, nhưng chúng vẫn còn tồn tại trên hệ thống của bạn. Để xem danh sách tất cả container bao gồm cả những container đã thoát, bạn dùng lệnh sau:
docker ps -a
OutputCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1c08a7a0d0e4 ubuntu "bash" About a minute ago Exited (0) 7 seconds ago dazzling_taussig
587000e49d53 hello-world "/hello" 5 minutes ago Exited (0) 5 minutes ago adoring_kowalevski
Để xem container mới nhất bạn đã tạo, hãy truyền lệnh -l vào đó:
docker ps -l
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1c08a7a0d0e4 ubuntu "bash" 3 minutes ago Exited (0) 2 minutes ago dazzling_taussig
Khi một container đã dừng, bạn không cần tạo lại từ đầu. Bạn hoàn toàn có thể khởi động lại container đó bằng lệnh docker start
, theo sau là ID hoặc tên của container.
Ví dụ, để khởi động lại container Ubuntu có ID là 1c08a7a0d0e4
, bạn chỉ cần chạy lệnh sau:
docker start 1c08a7a0d0e4
Container sẽ khởi động và bạn có thể sử dụng docker ps để xem trạng thái của nó:
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1c08a7a0d0e4 ubuntu "bash" 6 minutes ago Up 8 seconds dazzling_taussig
Khi bạn không còn cần container hoạt động nữa, bạn có thể dừng nó lại bằng lệnh:
docker stop <container_id_or_name>
Thay vì sử dụng Container ID, bạn cũng có thể dùng tên container là tên mà Docker tự động gán nếu bạn không chỉ định lúc tạo. Trong ví dụ này, container có tên là dazzling_taussig
, vì vậy bạn có thể dừng nó bằng lệnh:
docker stop dazzling_taussig
Khi bạn đã xác định rằng một container không còn cần thiết nữa, bạn có thể xóa nó khỏi hệ thống bằng lệnh:
docker rm <container_id_or_name>
Có 1 mẹo nhỏ khi bạn khởi chạy một container mới bằng lệnh docker run đó là
bạn có thể chủ động đặt tên cho container thay vì để Docker tự sinh tên ngẫu nhiên. Điều này giúp dễ quản lý và thao tác sau này. Sử dụng tuỳ chọn --name
, cú pháp như sau:
docker run --name my_ubuntu_container ubuntu
Ngoài ra, nếu chỉ cần chạy container tạm thời (ví dụ như để test hoặc chạy một tác vụ ngắn hạn), bạn có thể dùng tuỳ chọn --rm
. Tùy chọn này sẽ đảm bảo container tự động xóa sau khi dừng, giúp hệ thống của bạn không bị lộn xộn bởi các container không còn dùng đến:
docker run --rm ubuntu
Một trong những tính năng mạnh mẽ của Docker là khả năng biến container thành image, từ đó bạn có thể dùng để tạo ra các container mới với cùng trạng thái, cấu hình và dữ liệu. Chúng ta cùng đi tìm hiểu ở bước sau.
Bước 7: Commit Container Docker Thành Image
Khi bạn làm việc với một Docker container tạo file mới, chỉnh sửa cấu hình, cài đặt phần mềm tất cả các thay đổi này chỉ tồn tại bên trong container đó. Bạn có thể tạm dừng container, khởi động lại nó, và các thay đổi vẫn được giữ nguyên. Tuy nhiên, nếu bạn xóa container bằng lệnh:
docker rm <container_id_or_name>
thì toàn bộ thay đổi sẽ biến mất vĩnh viễn. Để tránh mất công làm lại, bạn có thể lưu lại trạng thái hiện tại của container bằng cách commit nó thành một image mới. Điều này tương tự như tạo một snapshot cho máy ảo.
docker commit my_temp_container my_saved_image
Sau đó, bạn có thể tạo các container mới dựa trên image đó bất cứ lúc nào, mang lại sự linh hoạt và khả năng tái sử dụng cho quá trình phát triển và triển khai ứng dụng.
Sau khi đã tạo một Docker image từ container của bạn, bước tiếp theo là chia sẻ nó với người khác. Điều này cho phép đồng đội, cộng đồng hoặc các hệ thống khác có thể dễ dàng tạo container từ image bạn đã cấu hình sẵn.
Bước 8: Đẩy hình ảnh Docker vào kho lưu trữ Docker
Bạn có một image tùy chỉnh từ container, bước tiếp theo hợp lý là chia sẻ nó, có thể chỉ với một vài người bạn, hoặc công khai với cả thế giới qua Docker Hub hay một Docker registry riêng mà bạn đang sử dụng. Để đẩy hình ảnh lên Docker Hub hoặc Docker registry nào khác, bạn phải có tài khoản ở đó. Để đẩy hình ảnh của bạn, trước tiên hãy đăng nhập vào Docker Hub.
docker login -u docker-registry-username
Lưu ý: Nếu tên người dùng trên Docker Registry (ví dụ: Docker Hub) khác với username cục bộ bạn dùng để tạo image, bạn phải tag lại image với tên tài khoản registry trước khi thực hiện đẩy image lên.
Ví dụ: Giả sử bạn tạo image cục bộ dưới tên sammy, nhưng tài khoản Docker Hub của bạn là dockerhubuser
, bạn cần tag lại như sau:
docker tag ubuntu-nodejs dockerhubuser/ubuntu-nodejs
Lúc này, bạn có thể đẩy image đã tag lên Docker Hub bằng lệnh:
docker push dockerhubuser/ubuntu-nodejs
Trong bài thực hành username local là sammy cũng với user docker hub nên chúng ta chỉ cần thực hiện câu lệnh sau để đẩy image.
docker push sammy/ubuntu-nodejs
Quá trình này có thể mất một thời gian để hoàn tất khi tải hình ảnh lên, nhưng khi hoàn tất, đầu ra sẽ như thế này:
OutputThe push refers to a repository [docker.io/sammy/ubuntu-nodejs]
e3fbbfb44187: Pushed
5f70bf18a086: Pushed
a3b5c80a4eba: Pushed
7f18b442972b: Pushed
3ce512daaf78: Pushed
7aae4540b42d: Pushed
...
Sau khi bạn đã đẩy image lên Docker Hub (hoặc một registry khác), bạn có thể dễ dàng tải image đó xuống bất kỳ máy nào khác có Docker được cài đặt.
docker pull sammy/ubuntu-nodejs
Tiếp theo nếu bạn đang phát triển hoặc triển khai các ứng dụng đòi hỏi hiệu suất tính toán cao như trí tuệ nhân tạo (AI), học sâu (deep learning) hoặc xử lý ảnh/video, thì việc sử dụng GPU trong container Docker là một lợi thế cực kỳ lớn. Thay vì chỉ dựa vào CPU, bạn có thể tận dụng toàn bộ sức mạnh phần cứng GPU để tăng tốc quá trình huấn luyện mô hình, inference, hoặc tính toán ma trận khối lượng lớn.
Cài đặt Docker với hỗ trợ GPU
Để cài Docker với GPU support, bạn sẽ cần thực hiện quy trình hơi khác so với việc cài đặt Docker thông thường. Lý do là vì việc sử dụng GPU trong container đòi hỏi thêm driver, runtime và một số cấu hình bổ sung để Docker có thể giao tiếp với tài nguyên GPU của máy chủ. Dưới đây là các bước chi tiết giúp bạn thiết lập Docker với GPU support trên hệ điều hành Ubuntu:
Bước 1: Cài Đặt NVIDIA Driver
Docker sử dụng GPU thông qua NVIDIA driver đã được cài đặt sẵn trên hệ thống. Do đó, trước tiên bạn cần đảm bảo đã cài đúng phiên bản driver phù hợp cho GPU của bạn.
Bạn có thể kiểm tra driver hiện tại bằng lệnh:
nvidia-smi
Nếu chưa cài driver, bạn có thể cài thông qua lệnh:
sudo apt install nvidia-driver-525
sudo reboot
*Lưu ý: Thay số 525
bằng phiên bản driver mới nhất tương thích với GPU của bạn. Bạn có thể tìm thấy hướng dẫn cài đặt trên trang web NVIDIA. https://www.nvidia.com/en-us/drivers/.*
Bước 2: Cài Đặt NVIDIA Container Toolkit
NVIDIA Container Toolkit là công cụ giúp Docker container truy cập GPU. Làm theo các bước sau để cài đặt:
# Thiết lập biến môi trường
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
# Thêm GPG key
curl -s -L <https://nvidia.github.io/nvidia-docker/gpgkey> | \\
sudo gpg --dearmor -o /usr/share/keyrings/nvidia-docker.gpg
# Thêm repository cho NVIDIA Docker
curl -s -L <https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list> | \\
sed 's#https://#deb [signed-by=/usr/share/keyrings/nvidia-docker.gpg] https://#' | \\
sudo tee /etc/apt/sources.list.d/nvidia-docker.list
# Cập nhật hệ thống và cài nvidia-docker2
sudo apt update
sudo apt install -y nvidia-docker2
# Khởi động lại Docker daemon
sudo systemctl restart docker
Bước 3: Kiểm Tra GPU Trong Container
Sau khi hoàn tất cài đặt, bạn hãy chạy container thử nghiệm để xác minh GPU đã hoạt động:
docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi
Nếu lệnh này trả về thông tin GPU như tên card, bộ nhớ, trạng thái driver, thì bạn đã cài đặt thành công Docker với GPU support. Để biết thêm thông tin về cách cài đặt và sử dụng Docker có hỗ trợ GPU, hãy tham khảo các tài nguyên sau:
Khi triển khai Docker trong môi trường thực tế đặc biệt là môi trường production, bảo mật phải là một ưu tiên hàng đầu. Mặc dù Docker mang lại sự tiện lợi và linh hoạt trong việc quản lý ứng dụng, nhưng nếu không được cấu hình đúng cách, nó có thể trở thành điểm yếu nghiêm trọng trong hệ thống của bạn. Chúng ta sẽ cùng tìm hiểu những thực tiễn bảo mật tốt nhất để bảo vệ hệ thống Docker, hạn chế các nguy cơ từ bên trong và bên ngoài.
Những Thực Tiễn Bảo Mật Cần Thiết Khi Triển Khai Docker
Bảo mật Docker Engine rất quan trọng để đảm bảo rằng các container và hệ thống máy chủ của bạn được bảo vệ khỏi các lỗ hổng tiềm ẩn. Sau đây là một số biện pháp thực hành tốt nhất cần tuân theo:
Sử dụng nguyên tắc quyền tối thiểu:
- Nguyên tắc đặc quyền tối thiểu (Least Privilege) có nghĩa là container chỉ nên được cấp những quyền tối thiểu cần thiết để thực hiện nhiệm vụ của nó. Điều này giúp giảm khả năng container bị lợi dụng để thực hiện các hành động độc hại trên hệ thống.
Chạy container với user không phải root
- Mặc định, Docker chạy container với quyền
root
bên trong. Đây là một lỗ hổng bảo mật tiềm ẩn nếu container bị khai thác.
Cập nhật Docker thường xuyên
- Một trong những cách đơn giản nhất để giữ an toàn là đảm bảo Docker Engine luôn được cập nhật phiên bản mới nhất.
Kích hoạt Docker Content Trust (DCT)
- Docker Content Trust cho phép xác minh tính toàn vẹn của image thông qua chữ ký số. Điều này đảm bảo image bạn kéo về là hợp lệ, không bị thay đổi hoặc giả mạo.
Hạn chế mở cổng mạng không cần thiết
- Việc mở quá nhiều port khi chạy container là điều không nên. Hãy chỉ expose đúng port cần thiết.
Bây giờ bạn làm việc với nhiều container, việc quản lý từng container một bằng tay sẽ trở nên phức tạp và tốn thời gian. Đây là lúc Docker Compose phát huy tác dụng. Nó cho phép bạn định nghĩa, cấu hình và chạy nhiều container chỉ với một file cấu hình duy nhất.
Sử dụng Docker Compose
Docker Compose giúp đơn giản hóa việc triển khai và quản lý các ứng dụng phức tạp bao gồm nhiều container. Dưới đây là một số lợi ích nổi bật:
Dễ Dàng Định Nghĩa Ứng Dụng
Bạn có thể định nghĩa toàn bộ kiến trúc ứng dụng chỉ trong một file YAML (docker-compose.yml
). Trong file này, bạn có thể khai báo:
- Các dịch vụ cần thiết (ví dụ: web, database, cache…).
- Volume cho dữ liệu.
- Mạng riêng giữa các container.
- Biến môi trường và tham số khởi tạo.
Tự Động Hóa Việc Khởi Động
Chỉ với một lệnh đơn giản:
docker compose up
Toàn bộ hệ thống container sẽ được khởi động đồng bộ và đúng thứ tự phụ thuộc.
Quản Lý Nhiều Môi Trường
Bạn có thể dùng cùng một file docker-compose.yml
cho nhiều môi trường (development, staging, production), chỉ cần tùy chỉnh biến môi trường hoặc override qua file docker-compose.override.yml
.
Dễ Dàng Bảo Trì và Mở Rộng
Vì cấu trúc file Compose rõ ràng, bạn dễ dàng thêm dịch vụ mới, thay đổi cấu hình, hoặc cập nhật phiên bản container chỉ bằng cách chỉnh sửa YAML và chạy lại.
Hỗ Trợ Cho CI/CD
Docker Compose rất phù hợp để tích hợp vào các quy trình CI/CD, nhờ khả năng tái tạo nhanh môi trường ứng dụng giống nhau trên nhiều máy khác nhau (local, test, cloud…).
Sau một thời gian sử dụng, bạn có thể muốn gỡ bỏ Docker khỏi hệ thống vì nhiều lý do: dọn dẹp môi trường phát triển, cài đặt lại từ đầu hoặc chuyển sang môi trường khác.
Gỡ Cài Đặt Docker Trên Ubuntu
Xóa các gói Docker là một phần thiết yếu trong việc duy trì hệ thống của bạn và đảm bảo rằng bạn đã cài đặt phiên bản Docker mới nhất. Sau đây là một số bước cần thực hiện:
Bước 1: Gỡ Bỏ Các Gói Docker
Chạy lệnh sau để gỡ toàn bộ các gói liên quan đến Docker:
sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Lệnh purge
sẽ xóa cả gói lẫn các file cấu hình liên quan.
Bước 2: Xóa Dữ Liệu Docker Còn Lưu Trữ
Mặc dù bạn đã gỡ các gói, dữ liệu Docker (container, images, volumes…) vẫn còn nằm trong hệ thống. Để xóa sạch, hãy chạy:
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
Lưu ý: Hành động này là không thể khôi phục, nên hãy đảm bảo bạn đã sao lưu dữ liệu nếu cần.
Bước 3: Kiểm Tra Docker Đã Được Gỡ Thành Công
Bạn có thể xác minh bằng cách chạy:
docker --version
Nếu hệ thống trả về thông báo lỗi kiểu như "command not found"
, nghĩa là Docker đã được gỡ bỏ hoàn toàn. Vậy là bạn đã hoàn tất việc dọn dẹp Docker khỏi hệ thống.
Qua các phần trên, chúng ta đã cùng nhau khám phá gần như toàn bộ hành trình làm việc với Docker từ quá trình cài đặt, sử dụng lệnh cơ bản, quản lý container và image, cho đến các chủ đề nâng cao như Docker Compose, GPU support và các thực hành bảo mật. Việc làm chủ Docker không chỉ giúp bạn triển khai ứng dụng nhanh chóng và linh hoạt hơn mà còn mở ra cánh cửa để tiếp cận các mô hình triển khai hiện đại như microservices hay CI/CD pipelines.
Tổng kết
Sau hành trình khám phá Docker từ cơ bản đến nâng cao, bạn đã nắm trong tay những kiến thức nền tảng vững chắc để làm chủ công cụ container mạnh mẽ này. Từ việc cài đặt Docker trên Ubuntu, thao tác với container và image, đến sử dụng Docker Compose để triển khai ứng dụng đa thành phần mỗi bước đều giúp bạn tiến gần hơn đến một quy trình phát triển phần mềm hiện đại và linh hoạt. Bên cạnh đó, bạn cũng đã tìm hiểu cách bật hỗ trợ GPU để phục vụ các tác vụ tính toán chuyên sâu, áp dụng các thực hành bảo mật để bảo vệ hệ thống, và biết cách dọn dẹp Docker khi không còn sử dụng. Docker không chỉ giúp đơn giản hóa việc phát triển và triển khai ứng dụng mà còn là nền tảng để bạn tiến xa hơn với CI/CD, DevSecOps và Kubernetes. Nếu bạn đã đọc đến đây, xin chúc mừng bạn đã sẵn sàng ứng dụng Docker vào các dự án thực tế. Hãy tiếp tục tìm hiểu về Dockerfile nâng cao, triển khai CI/CD pipelines, hoặc mở rộng sang Kubernetes để nâng tầm kỹ năng của mình.