Vì sao cần Docker ngay? — Nghe Docker hoài mà chưa dùng
Bạn đã nghe về Docker từ đồng nghiệp, trên các trang công nghệ, và có lẽ đã tự hỏi “Docker là gì mà ai cũng nói đến?”. Docker hứa hẹn đơn giản hóa việc đóng gói, phân phối và chạy ứng dụng. Tuy nhiên, việc bắt đầu có thể khiến bạn bối rối.
Bài viết này sẽ đưa bạn từ con số 0, giúp bạn cài đặt Docker và chạy container đầu tiên chỉ trong vài phút.
- 📦 Đóng gói ứng dụng: Đảm bảo ứng dụng chạy nhất quán ở mọi môi trường.
- 🚀 Triển khai nhanh: Giảm thời gian thiết lập, tăng tốc độ đưa sản phẩm ra thị trường.
- ☁️ Di chuyển dễ dàng: Chuyển ứng dụng giữa các máy chủ, cloud mà không lo xung đột.
- 🧪 Môi trường thử nghiệm: Tạo các môi trường cô lập để test code, tính năng mới.
- 💡 Hiểu rõ hơn: Nắm bắt cách Docker hoạt động, tối ưu hóa quy trình làm việc.
1. Cài đặt Docker trên Ubuntu — Bước đầu tiên
Tóm gọn: Cài đặt Docker trên Ubuntu rất đơn giản bằng cách sử dụng kho lưu trữ chính thức của Docker, đảm bảo bạn luôn có phiên bản mới nhất và ổn định.
1.1. Chuẩn bị hệ thống
Trước khi cài đặt, hãy cập nhật danh sách gói và nâng cấp các gói hiện có trên hệ thống của bạn. Điều này giúp đảm bảo bạn đang sử dụng các phiên bản phần mềm mới nhất và tránh các xung đột tiềm ẩn.
sudo apt update
sudo apt upgrade -y
1.2. Gỡ bỏ các phiên bản Docker cũ (nếu có)
Nếu bạn đã từng cài đặt Docker trên hệ thống này trước đây, hãy gỡ bỏ các phiên bản cũ để tránh xung đột.
sudo apt remove docker docker-engine docker.io containerd runc
1.3. Cài đặt các gói cần thiết
Cài đặt các gói phụ trợ để cho phép apt sử dụng một kho lưu trữ qua HTTPS.
sudo apt install apt-transport-https ca-certificates curl software-properties-common -y
1.4. Thêm Docker GPG key chính thức
Thêm khóa GPG của Docker để xác minh tính toàn vẹn của các gói bạn tải về.
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
1.5. Thêm Docker repository
Thêm kho lưu trữ Docker chính thức vào danh sách nguồn apt của bạn.
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
1.6. Cài đặt Docker Engine
Cập nhật lại danh sách gói sau khi thêm repository mới và cài đặt Docker.
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y
💡 Mẹo: Lệnh
docker-compose-plugingiúp bạn sử dụngdocker compose(thay vìdocker-compose) để quản lý nhiều container cùng lúc.
1.7. Kiểm tra cài đặt Docker
Sau khi cài đặt, hãy kiểm tra xem Docker đã chạy thành công chưa bằng lệnh hello-world.
sudo docker run hello-world
Output mẫu:
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2004b797f867: Pull complete
Digest: sha256:f47066b903350036888476932a0a5365c46c313b3693c02757061248f46276f4
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run our tutorial at https://www.docker.com/101-tutorial
2. Quản lý tiến trình Docker — Khởi động, dừng, kiểm tra
Tóm gọn: Docker là một dịch vụ chạy ngầm (daemon). Bạn cần biết cách quản lý dịch vụ này để đảm bảo Docker luôn sẵn sàng hoạt động.
2.1. Kiểm tra trạng thái dịch vụ Docker
Xem Docker daemon có đang chạy hay không.
sudo systemctl status docker
Output mẫu:
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2024-05-20 10:30:00 UTC; 1 day 2h ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 1234 (dockerd)
Tasks: 45
Memory: 150.5M
CPU: 1min 10.500s
CGroup: /system.slice/docker.service
└─1234 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
May 20 10:30:00 ubuntu systemd[1]: Starting Docker Application Container Engine...
May 20 10:30:01 ubuntu dockerd[1234]: time="2024-05-20T10:30:01.123456789Z" level=info msg="Starting up"
May 20 10:30:01 ubuntu dockerd[1234]: time="2024-05-20T10:30:01.987654321Z" level=info msg="Loading container state from ..."
...
active (running): Dịch vụ Docker đang hoạt động.enabled: Dịch vụ sẽ tự động khởi động khi máy chủ reboot.
2.2. Khởi động dịch vụ Docker
Nếu Docker chưa chạy, bạn có thể khởi động nó.
sudo systemctl start docker
2.3. Dừng dịch vụ Docker
Để dừng Docker daemon.
sudo systemctl stop docker
2.4. Khởi động lại dịch vụ Docker
Thường dùng khi bạn thay đổi cấu hình Docker.
sudo systemctl restart docker
2.5. Kích hoạt Docker tự khởi động cùng hệ thống
Đảm bảo Docker luôn chạy sau mỗi lần máy chủ khởi động lại.
sudo systemctl enable docker
2.6. Vô hiệu hóa Docker tự khởi động
Nếu bạn không muốn Docker tự khởi động.
sudo systemctl disable docker
⚠️ Cảnh báo: Việc dừng dịch vụ Docker sẽ làm tất cả các container đang chạy bị dừng theo.
3. Chạy container đầu tiên — nginx trên Ubuntu
Tóm gọn: Container là “đơn vị” chạy của Docker, giống như một máy ảo siêu nhẹ. Chúng ta sẽ chạy một web server Nginx trong container.
3.1. Tải image Nginx
Docker Hub là kho lưu trữ các image (mẫu để tạo container). Lệnh docker pull sẽ tải image về máy bạn.
sudo docker pull nginx:latest
nginx: Tên của image.:latest: Tag chỉ định phiên bản, ở đây là phiên bản mới nhất.
3.2. Chạy container Nginx ở chế độ nền (detached mode)
Lệnh docker run sẽ tạo và khởi động một container từ image đã tải.
sudo docker run --name my-nginx-container -d -p 8080:80 nginx:latest
--name my-nginx-container: Đặt tên cho container để dễ quản lý.-d: Chạy container ở chế độ nền (detached mode). Nếu không có cờ này, terminal của bạn sẽ bị “khóa” bởi container.-p 8080:80: Ánh xạ cổng. Cổng80bên trong container sẽ được truy cập qua cổng8080trên máy chủ Ubuntu của bạn.nginx:latest: Image dùng để tạo container.
3.3. Kiểm tra container đang chạy
Xem danh sách các container đang hoạt động.
sudo docker ps
Output mẫu:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
abcdef123456 nginx:latest "/docker-entrypoint.…" 5 seconds ago Up 4 seconds 0.0.0.0:8080->80/tcp my-nginx-container
CONTAINER ID: Mã định danh duy nhất của container.IMAGE: Image đã sử dụng để tạo container.STATUS: Trạng thái hiện tại (Up X seconds/minutes).PORTS: Các cổng được ánh xạ. Bạn thấy0.0.0.0:8080->80/tcpnghĩa là cổng 80 của container được mở ra cổng 8080 của máy chủ trên tất cả các interface mạng (0.0.0.0).NAMES: Tên bạn đã đặt cho container.
3.4. Truy cập web server Nginx
Mở trình duyệt web và truy cập vào địa chỉ http://<IP_MA_MAY_CHU_UBUNTU>:8080. Nếu bạn đang chạy trên máy local, hãy dùng http://localhost:8080.
Bạn sẽ thấy trang chào mừng mặc định của Nginx.
3.5. Dừng container Nginx
Sử dụng tên hoặc ID của container để dừng nó.
sudo docker stop my-nginx-container
3.6. Xóa container Nginx
Sau khi dừng, bạn có thể xóa container nếu không cần dùng nữa.
sudo docker rm my-nginx-container
💡 Mẹo: Nếu bạn muốn xóa cả container đang chạy, hãy dùng cờ
-f(force):sudo docker rm -f my-nginx-container. Tuy nhiên, nên dừng hẳn rồi mới xóa để an toàn hơn.
4. Hiểu về Image và Container — Hai khái niệm cốt lõi
Tóm gọn: Image là bản thiết kế, còn Container là bản thực thi của thiết kế đó. Hiểu rõ sự khác biệt giúp bạn sử dụng Docker hiệu quả.
4.1. Image là gì?
Image là một tập tin chỉ đọc (read-only) chứa các chỉ dẫn để tạo ra một container. Nó bao gồm hệ điều hành cơ bản, ứng dụng, thư viện, biến môi trường, và các file cấu hình cần thiết.
- Tính bất biến: Một khi image được tạo ra, nó không thay đổi.
- Layered filesystem: Image được xây dựng từ nhiều lớp (layers). Mỗi lệnh trong Dockerfile tạo ra một lớp mới. Điều này giúp tiết kiệm dung lượng và tăng tốc độ build/pull image.
4.2. Container là gì?
Container là một môi trường thực thi có thể chạy được, được tạo ra từ một image. Nó là một tiến trình độc lập, có hệ thống file, mạng, và các tài nguyên riêng.
- Trạng thái: Container có trạng thái (đang chạy, đã dừng, đã xóa).
- Ghi dữ liệu: Dữ liệu ghi vào container (ví dụ: log, file tải lên) sẽ bị mất khi container bị xóa, trừ khi bạn sử dụng Volume hoặc Bind Mount.
4.3. Tải và quản lý Images
Xem danh sách các image đã tải về máy.
sudo docker images
Output mẫu:
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest abcdef123456 3 weeks ago 142MB
hello-world latest fedcba987654 6 months ago 13.3kB
REPOSITORY: Tên của image.TAG: Phiên bản của image.IMAGE ID: Mã định danh duy nhất của image.CREATED: Thời gian image được tạo.SIZE: Kích thước của image.
4.4. Xóa Image
Nếu bạn không cần một image nữa, hãy xóa nó để giải phóng dung lượng đĩa.
sudo docker rmi nginx:latest
rmi: Viết tắt của “remove image”.- Bạn không thể xóa một image nếu có container nào đó đang sử dụng nó.
💡 Mẹo: Để xóa tất cả các image không còn được sử dụng bởi container nào, bạn có thể dùng lệnh:
sudo docker image prune -a.
5. Chạy container với tùy chỉnh — Tùy biến Nginx
Tóm gọn: Container có thể được tùy chỉnh sâu hơn bằng cách mount thư mục từ máy chủ vào container, cho phép bạn thay đổi cấu hình hoặc lưu trữ dữ liệu.
5.1. Tạo thư mục cấu hình Nginx trên máy chủ
Tạo một thư mục trên máy chủ Ubuntu để chứa file cấu hình Nginx tùy chỉnh của bạn.
sudo mkdir -p /home/ubuntu/nginx-config
5.2. Tạo file cấu hình Nginx tùy chỉnh
Tạo một file default.conf trong thư mục vừa tạo. File này sẽ ghi đè cấu hình mặc định của Nginx bên trong container.
sudo nano /home/ubuntu/nginx-config/default.conf
Dán nội dung sau vào file:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /hello {
return 200 'Hello from VSIS.NET!\n';
add_header Content-Type text/plain;
}
}
Lưu và thoát nano (Ctrl + X, Y, Enter).
5.3. Chạy container Nginx với Bind Mount
Sử dụng cờ -v để “mount” thư mục cấu hình từ máy chủ vào thư mục /etc/nginx/conf.d bên trong container.
sudo docker run --name my-custom-nginx -d -p 8081:80 -v /home/ubuntu/nginx-config:/etc/nginx/conf.d nginx:latest
-v /home/ubuntu/nginx-config:/etc/nginx/conf.d: Đây là bind mount. Nó liên kết thư mục/home/ubuntu/nginx-configtrên máy chủ với thư mục/etc/nginx/conf.dbên trong container. Bất kỳ file nào trong thư mục máy chủ sẽ xuất hiện trong thư mục container, và ngược lại.
5.4. Kiểm tra cấu hình tùy chỉnh
Truy cập http://localhost:8081 (hoặc IP máy chủ của bạn). Bạn sẽ thấy trang mặc định của Nginx (vì chúng ta đã cấu hình root /usr/share/nginx/html).
Tiếp theo, truy cập http://localhost:8081/hello.
Bạn sẽ thấy dòng chữ “Hello from VSIS.NET!”. Điều này chứng tỏ file cấu hình tùy chỉnh của bạn đã được Nginx trong container nhận diện và sử dụng.
5.5. Xóa container tùy chỉnh
sudo docker stop my-custom-nginx
sudo docker rm my-custom-nginx
💡 Mẹo: Bind mount rất hữu ích cho việc phát triển, cho phép bạn chỉnh sửa code hoặc cấu hình trên máy chủ và thấy ngay sự thay đổi trong container mà không cần build lại image.
6. Pitfalls & lỗi thường gặp
Tóm gọn: Dù Docker khá dễ dùng, bạn vẫn có thể gặp một số lỗi phổ biến khi mới bắt đầu.
6.1. Lỗi “permission denied” khi chạy lệnh Docker
Vấn đề: Khi bạn chạy lệnh docker ps hoặc docker run mà không có sudo, bạn có thể gặp lỗi “permission denied”.
Nguyên nhân: Theo mặc định, tiến trình Docker daemon chạy với quyền root, và chỉ người dùng root mới có quyền truy cập nó.
Cách khắc phục:
1. Sử dụng sudo: Luôn chạy các lệnh Docker với sudo (ví dụ: sudo docker ps).
2. Thêm user vào nhóm docker: Để tránh phải gõ sudo mỗi lần, bạn có thể thêm user của mình vào nhóm docker.
bash
sudo usermod -aG docker $USER
Sau đó, bạn cần đăng xuất và đăng nhập lại để thay đổi có hiệu lực.
> ⚠️ Cảnh báo: Thêm user vào nhóm docker tương đương với việc cấp cho user đó quyền root, vì họ có thể chạy các container có quyền truy cập hệ thống file gốc. Hãy cân nhắc kỹ về bảo mật.
6.2. Cổng (Port) đã bị sử dụng
Vấn đề: Lỗi “Bind for 0.0.0.0:8080 failed: port is already allocated” khi chạy docker run.
Nguyên nhân: Cổng bạn muốn ánh xạ trên máy chủ (ví dụ: 8080) đã có một tiến trình khác đang sử dụng.
Cách khắc phục:
1. Tìm tiến trình đang chiếm cổng:
bash
sudo netstat -tulnp | grep 8080
Hoặc trên các hệ thống mới hơn:
bash
sudo ss -tulnp | grep 8080
2. Dừng tiến trình đó: Sử dụng PID (Process ID) tìm được để dừng tiến trình (ví dụ: sudo kill <PID>).
3. Chọn cổng khác: Thay đổi cổng ánh xạ trong lệnh docker run sang một cổng chưa được sử dụng (ví dụ: -p 8082:80).
6.3. Container không khởi động hoặc dừng ngay lập tức
Vấn đề: Container chạy rồi báo Exited (0) ... hoặc Exited (1) ....
Nguyên nhân: Lệnh chính được định nghĩa trong image hoặc khi bạn chạy docker run đã thực thi xong và thoát. Với hello-world, đó là hành vi mong muốn. Với các ứng dụng khác, nó có thể là lỗi.
Cách khắc phục:
1. Kiểm tra log của container:
bash
sudo docker logs <container_name_or_id>
Log sẽ cho bạn biết lý do tại sao container bị thoát.
2. Chạy container ở chế độ foreground: Bỏ cờ -d trong lệnh docker run để xem trực tiếp output và lỗi.
bash
sudo docker run --name my-debug-container -p 8080:80 nginx:latest
Sau khi debug xong, bạn có thể thêm cờ -d để chạy ở chế độ nền.
3. Kiểm tra lệnh CMD/ENTRYPOINT trong Dockerfile: Nếu bạn tự build image, hãy đảm bảo lệnh khởi động ứng dụng của bạn chạy liên tục.
6.4. Image không tìm thấy (Image not found)
Vấn đề: Lỗi “Error response from daemon: pull access denied for
Nguyên nhân:
1. Tên image hoặc tag bị gõ sai.
2. Image đó không tồn tại trên Docker Hub hoặc kho lưu trữ bạn đang truy cập.
3. Image là riêng tư (private) và bạn chưa đăng nhập.
Cách khắc phục:
1. Kiểm tra chính tả: Đảm bảo tên image và tag là chính xác.
2. Tìm kiếm trên Docker Hub: Truy cập hub.docker.com để tìm kiếm image.
3. Đăng nhập Docker: Nếu là image private, dùng sudo docker login và nhập thông tin tài khoản Docker Hub của bạn.
7. Key Takeaways
- Docker giúp đóng gói, phân phối và chạy ứng dụng một cách nhất quán trên mọi môi trường.
- Image là bản thiết kế, Container là bản thực thi của ứng dụng.
- Cài đặt Docker trên Ubuntu có thể thực hiện dễ dàng qua
apttừ kho lưu trữ chính thức. - Lệnh
docker runlà công cụ cơ bản để tạo và khởi động container, với các tùy chọn quan trọng như-d,-p,-v,--name. - Bind mount (
-v) cho phép chia sẻ thư mục giữa máy chủ và container, rất hữu ích cho việc phát triển và tùy chỉnh cấu hình.
8. FAQ
8.1. Docker có phải là máy ảo không?
Không. Docker sử dụng công nghệ container hóa, chia sẻ nhân hệ điều hành với máy chủ. Máy ảo ảo hóa toàn bộ phần cứng và chạy hệ điều hành riêng. Container nhẹ hơn, khởi động nhanh hơn và tốn ít tài nguyên hơn máy ảo.
8.2. Tôi cần phiên bản Ubuntu nào để cài Docker?
Docker hỗ trợ hầu hết các phiên bản Ubuntu LTS (Long Term Support) gần đây, bao gồm Ubuntu 22.04 LTS (Jammy Jellyfish) và Ubuntu 24.04 LTS (Noble Numbat). Nên sử dụng phiên bản LTS để có sự ổn định.
8.3. Làm sao để xem tất cả các container (cả đang chạy và đã dừng)?
Sử dụng cờ -a với lệnh docker ps:
sudo docker ps -a
8.4. Docker có an toàn không?
Docker cung cấp một lớp cô lập giữa các container và giữa container với hệ thống máy chủ. Tuy nhiên, bảo mật của Docker còn phụ thuộc vào cách bạn cấu hình, quản lý image và quyền truy cập. Việc thêm user vào nhóm docker cần được thực hiện cẩn thận.
8.5. Tôi có thể chạy nhiều container cùng lúc không?
Chắc chắn rồi! Đó là một trong những lợi thế lớn nhất của Docker. Bạn có thể chạy nhiều container độc lập trên cùng một máy chủ. Để quản lý phức hợp nhiều container, bạn có thể tìm hiểu về Docker Compose.
Cần VPS chạy Docker?
Bạn đã sẵn sàng khám phá sức mạnh của Docker nhưng chưa có môi trường phù hợp? Tại VSIS.NET, chúng tôi cung cấp các giải pháp VPS cấu hình mạnh mẽ, tối ưu cho việc triển khai và quản lý Docker.
Với VPS tại VSIS.NET, bạn có thể dễ dàng cài đặt Docker, thử nghiệm các ứng dụng container hóa và xây dựng hạ tầng hiện đại.
Khám phá ngay các gói VPS tại vsis.net/vps!



