Cài Docker trên Cloud Server Ubuntu: Hướng dẫn từ cài đặt đến chạy container đầu tiên
Docker giúp đóng gói ứng dụng cùng thư viện và môi trường chạy vào container, nhờ đó quá trình triển khai giữa máy cá nhân, staging và production nhất quán hơn. Thay vì cài trực tiếp từng phiên bản PHP, Node.js, Nginx, Redis hoặc database lên Cloud Server, đội ngũ có thể quản lý các thành phần này bằng image, container và file Docker Compose.
Tuy nhiên, cài Docker thành công chưa có nghĩa Cloud Server đã sẵn sàng cho production. Người vận hành còn phải xử lý quyền người dùng, firewall, port, dữ liệu lâu dài, log rotation, chính sách tự khởi động và backup.
Bài viết này hướng dẫn cài Docker Engine trên Cloud Server sử dụng Ubuntu, kiểm tra Docker Compose, chạy container đầu tiên và hoàn thiện những cấu hình cần thiết trước khi triển khai ứng dụng thực tế.
Phạm vi bài viết: hướng dẫn sử dụng kho phần mềm chính thức của Docker trên Ubuntu 64-bit. Nên kiểm tra phiên bản Ubuntu đang được Docker hỗ trợ trước khi triển khai trên production.
1. Docker trên Cloud Server hoạt động như thế nào?
Khi cài Docker trên Cloud Server, hệ thống thường có các thành phần chính:
Người quản trị
|
v
Docker CLI
|
v
Docker Engine
|
|-- Container 1: Nginx
|-- Container 2: Backend API
|-- Container 3: Redis
`-- Container 4: Database
Trong đó:
- Docker Engine chịu trách nhiệm tạo và quản lý container.
- Docker CLI cung cấp các câu lệnh như
docker run,docker psvàdocker logs. - containerd quản lý vòng đời container ở tầng thấp hơn.
- Docker Buildx hỗ trợ quá trình build image.
- Docker Compose plugin giúp khai báo và vận hành nhiều container thông qua file YAML.
Khi cài từ kho chính thức, các package thường gồm docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin và docker-compose-plugin.
2. Khi nào nên cài Docker trên Cloud Server?
Docker phù hợp khi hệ thống cần:
- Triển khai ứng dụng theo môi trường đồng nhất.
- Chạy nhiều service trên cùng một Cloud Server.
- Tách biệt dependency giữa các ứng dụng.
- Đóng gói application thành image.
- Tự động hóa quy trình CI/CD.
- Dễ dàng rollback về image cũ.
- Triển khai Nginx, Redis, database hoặc worker độc lập.
- Chuẩn bị kiến trúc trước khi chuyển sang Kubernetes.
Ví dụ, một ứng dụng API có thể được tổ chức như sau:
Internet
|
v
Nginx Container
|
v
Backend API Container
|
|-- Redis Container
`-- PostgreSQL Container
Dù chạy trong container, các service vẫn sử dụng CPU, RAM, ổ đĩa và network của Cloud Server. Docker không tạo thêm tài nguyên vật lý và cũng không tự giải quyết tình trạng máy chủ thiếu tài nguyên.
3. Điều kiện chuẩn bị trước khi cài Docker
Bạn cần chuẩn bị:
- Một Cloud Server đang chạy Ubuntu 64-bit.
- Tài khoản có quyền
sudo. - Kết nối SSH tới máy chủ.
- Kết nối Internet để tải package và image.
- Dung lượng ổ đĩa còn đủ.
- Bản backup nếu máy chủ đang chạy ứng dụng.
- Danh sách các port đang sử dụng.
Kiểm tra phiên bản hệ điều hành:
cat /etc/os-release
Kiểm tra kiến trúc CPU:
dpkg --print-architecture
Kiểm tra dung lượng ổ đĩa:
df -h
Kiểm tra RAM:
free -m
Kiểm tra CPU:
nproc
Trong production, nên kiểm tra cả các service và port đang hoạt động trước khi thay đổi hệ thống:
sudo ss -tulpn
4. Kết nối SSH tới Cloud Server
Từ máy cá nhân, kết nối tới Cloud Server bằng:
ssh username@server_ip
Ví dụ:
ssh ubuntu@203.0.113.10
Trường hợp sử dụng SSH Key:
ssh -i ~/.ssh/cloud-server-key ubuntu@203.0.113.10
Sau khi đăng nhập, kiểm tra người dùng hiện tại:
whoami
Kiểm tra quyền sudo:
sudo -v
Không nên thực hiện toàn bộ quá trình bằng tài khoản root nếu không thực sự cần thiết. Một tài khoản quản trị có quyền sudo giúp giới hạn phạm vi sử dụng đặc quyền trong các tác vụ thông thường.
5. Cập nhật package trên Ubuntu
Trước khi thêm kho Docker, cập nhật danh sách package:
sudo apt update
Cài các bản cập nhật hiện có:
sudo apt upgrade -y
Kiểm tra xem hệ thống có yêu cầu khởi động lại hay không:
test -f /var/run/reboot-required && cat /var/run/reboot-required
Nếu máy chủ đang chạy dịch vụ production, không nên reboot ngay mà chưa kiểm tra:
- Ứng dụng có tự khởi động lại không.
- Database có được shutdown đúng cách không.
- Có maintenance window hay chưa.
- Có snapshot hoặc backup gần nhất không.
6. Gỡ các package có thể xung đột
Ubuntu có thể đã cài các package Docker từ nguồn khác. Nên gỡ các package xung đột trước khi cài Docker Engine từ kho chính thức.
sudo apt remove $(dpkg --get-selections \
docker.io \
docker-compose \
docker-compose-v2 \
docker-doc \
docker-buildx \
podman-docker \
containerd \
runc | cut -f1)
Nếu các package trên chưa tồn tại, apt có thể thông báo không có package cần gỡ.
Thao tác gỡ package không tự động xóa image, container, volume và network đang được lưu trong /var/lib/docker. Nếu đây là máy chủ đã từng chạy Docker, cần kiểm tra dữ liệu cũ trước khi tiếp tục.
sudo ls -la /var/lib/docker 2>/dev/null
Không xóa thư mục này nếu chưa xác định rõ dữ liệu bên trong có còn cần sử dụng hay không.
7. Thêm GPG key chính thức của Docker
Cài các package cần thiết:
sudo apt update
sudo apt install -y ca-certificates curl
Tạo thư mục lưu key:
sudo install -m 0755 -d /etc/apt/keyrings
Tải GPG key chính thức:
sudo curl -fsSL \
https://download.docker.com/linux/ubuntu/gpg \
-o /etc/apt/keyrings/docker.asc
Cho phép apt đọc key:
sudo chmod a+r /etc/apt/keyrings/docker.asc
GPG key giúp hệ thống xác minh package được lấy từ kho Docker đã khai báo.
8. Thêm Docker repository vào Ubuntu
Tạo file nguồn phần mềm:
sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
Cập nhật lại package index:
sudo apt update
Kiểm tra package Docker có được nhận diện hay không:
apt-cache policy docker-ce
Nếu repository được cấu hình đúng, kết quả sẽ hiển thị phiên bản Docker có thể cài đặt từ download.docker.com.
Với môi trường cần duy trì lâu dài, nên dùng repository chính thức thay vì installation script không kiểm soát phiên bản.
9. Cài Docker Engine và Docker Compose
Cài các package:
sudo apt install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
Các thành phần được cài gồm:
| Package | Vai trò |
|---|---|
docker-ce |
Docker Engine |
docker-ce-cli |
Giao diện dòng lệnh Docker |
containerd.io |
Container runtime |
docker-buildx-plugin |
Build image nâng cao |
docker-compose-plugin |
Chạy Docker Compose |
10. Kiểm tra trạng thái Docker
Kiểm tra Docker service:
sudo systemctl status docker
Nếu service chưa chạy:
sudo systemctl start docker
Kiểm tra trạng thái ngắn gọn:
sudo systemctl is-active docker
Kết quả mong đợi:
active
Kiểm tra Docker version:
sudo docker version
Kiểm tra thông tin Docker Engine:
sudo docker info
Có thể chủ động bật Docker và containerd khi máy chủ khởi động:
sudo systemctl enable docker.service
sudo systemctl enable containerd.service
11. Chạy container kiểm tra hello-world
Chạy image kiểm tra:
sudo docker run hello-world
Docker sẽ thực hiện các bước:
- Tìm image
hello-worldtrên máy chủ. - Tải image nếu chưa tồn tại.
- Tạo container.
- Chạy container.
- In thông báo xác nhận.
- Kết thúc container.
Kiểm tra container đã tạo:
sudo docker ps -a
Kiểm tra image:
sudo docker images
Xóa container thử nghiệm đã dừng:
sudo docker container prune
Lệnh trên có thể xóa tất cả container đã dừng, vì vậy cần kiểm tra kỹ trước khi xác nhận.
12. Cấu hình chạy Docker không cần sudo
Mặc định, Docker socket thuộc quyền quản lý của root. Vì vậy, người dùng thường phải thêm sudo trước câu lệnh Docker.
Thêm tài khoản hiện tại vào nhóm docker:
sudo usermod -aG docker $USER
Áp dụng nhóm mới trong phiên hiện tại:
newgrp docker
Hoặc đăng xuất SSH rồi đăng nhập lại.
Kiểm tra:
docker run hello-world
Nếu câu lệnh chạy mà không cần sudo, quyền đã được áp dụng.
Cảnh báo bảo mật: thành viên của nhóm
dockercó thể có quyền tương đương root trên máy chủ. Không nên thêm tài khoản không đáng tin cậy vào nhóm này.
Kiểm tra thành viên nhóm Docker:
getent group docker
Nếu gặp lỗi quyền tại ~/.docker/config.json, có thể sửa ownership:
sudo chown "$USER":"$USER" "$HOME/.docker" -R
sudo chmod g+rwx "$HOME/.docker" -R
13. Kiểm tra Docker Compose
Docker Compose hiện được sử dụng dưới dạng plugin với cú pháp:
docker compose
Kiểm tra phiên bản:
docker compose version
Cú pháp mới có khoảng trắng:
docker compose up -d
Không nên tiếp tục phụ thuộc vào bản standalone cũ:
docker-compose up -d
Nếu Compose chưa được cài:
sudo apt update
sudo apt install -y docker-compose-plugin
14. Chạy container Nginx đầu tiên
Tạo một Nginx container:
docker run -d \
--name nginx-demo \
--restart unless-stopped \
-p 8080:80 \
nginx:alpine
Ý nghĩa các tham số:
| Tham số | Ý nghĩa |
|---|---|
-d |
Chạy container ở chế độ nền |
--name nginx-demo |
Đặt tên container |
--restart unless-stopped |
Tự khởi động lại trừ khi bị dừng thủ công |
-p 8080:80 |
Ánh xạ port 8080 của host tới port 80 của container |
nginx:alpine |
Image được sử dụng |
Kiểm tra container:
docker ps
Kiểm tra từ bên trong máy chủ:
curl http://127.0.0.1:8080
Kiểm tra log:
docker logs nginx-demo
Theo dõi log liên tục:
docker logs -f nginx-demo
Dừng container:
docker stop nginx-demo
Khởi động lại:
docker start nginx-demo
Xóa container:
docker rm -f nginx-demo
15. Cẩn thận khi publish port Docker
Câu lệnh:
docker run -p 8080:80 nginx
có thể khiến port 8080 được truy cập từ bên ngoài nếu firewall và mạng của Cloud Server cho phép.
Nếu container chỉ được Nginx trên host truy cập, nên bind vào localhost:
docker run -d \
--name backend-api \
-p 127.0.0.1:3000:3000 \
backend-api:latest
Khi đó port chỉ lắng nghe trên 127.0.0.1:
sudo ss -tulpn | grep 3000
Không nên tắt cơ chế Docker quản lý iptables nếu chưa có thiết kế network thay thế.
16. Chạy Nginx bằng Docker Compose
Tạo thư mục dự án:
sudo mkdir -p /opt/nginx-demo
sudo chown "$USER":"$USER" /opt/nginx-demo
cd /opt/nginx-demo
Tạo file compose.yaml:
services:
web:
image: nginx:alpine
container_name: nginx-demo
restart: unless-stopped
ports:
- "127.0.0.1:8080:80"
Khởi chạy:
docker compose up -d
Kiểm tra:
docker compose ps
Xem log:
docker compose logs
Theo dõi log:
docker compose logs -f
Dừng và xóa container, network của project:
docker compose down
Cập nhật image:
docker compose pull
docker compose up -d
Xem cấu hình Compose sau khi được phân tích:
docker compose config
Lệnh này hữu ích để phát hiện lỗi indentation, biến môi trường thiếu hoặc cấu hình YAML không hợp lệ.
17. Cấu hình container tự khởi động sau khi reboot
Các restart policy phổ biến:
| Chính sách | Hành vi |
|---|---|
no |
Không tự restart |
on-failure |
Restart khi process kết thúc với mã lỗi |
always |
Luôn restart |
unless-stopped |
Restart trừ khi container bị dừng thủ công |
Chạy container với restart policy:
docker run -d \
--name redis \
--restart unless-stopped \
redis:alpine
Cập nhật container đang chạy:
docker update --restart unless-stopped redis
Kiểm tra restart policy:
docker inspect \
--format '{{.HostConfig.RestartPolicy.Name}}' \
redis
Với Docker Compose:
services:
redis:
image: redis:alpine
restart: unless-stopped
Không nên kết hợp restart policy của Docker với một process manager trên host để cùng quản lý một container.
18. Dữ liệu trong container được lưu ở đâu?
Nếu ứng dụng ghi dữ liệu trực tiếp vào writable layer của container, dữ liệu có thể mất khi container bị xóa và tạo lại.
Với dữ liệu cần duy trì lâu dài, nên sử dụng:
- Named volume.
- Bind mount.
- Hệ thống lưu trữ bên ngoài.
- Managed database.
- Object Storage tùy loại dữ liệu.
Tạo volume:
docker volume create app-data
Kiểm tra:
docker volume ls
Chạy container sử dụng volume:
docker run -d \
--name nginx-volume-demo \
-v app-data:/usr/share/nginx/html \
nginx:alpine
Kiểm tra volume:
docker volume inspect app-data
Ví dụ Compose:
services:
database:
image: postgres:alpine
restart: unless-stopped
environment:
POSTGRES_DB: app
POSTGRES_USER: app_user
POSTGRES_PASSWORD: change-this-password
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
postgres-data:
Không nên đặt mật khẩu production trực tiếp trong file Compose được lưu vào Git.
19. Cấu hình log rotation cho Docker
Docker mặc định sử dụng logging driver json-file. Nếu container tạo nhiều log và không có rotation, file log có thể tiếp tục tăng kích thước và làm đầy ổ đĩa Cloud Server.
Kiểm tra logging driver:
docker info --format '{{.LoggingDriver}}'
Phương án 1: Sử dụng logging driver local
Tạo hoặc chỉnh sửa file:
sudo mkdir -p /etc/docker
sudo nano /etc/docker/daemon.json
Nội dung:
{
"log-driver": "local"
}
Kiểm tra JSON:
python3 -m json.tool /etc/docker/daemon.json
Khởi động lại Docker:
sudo systemctl restart docker
Phương án 2: Giới hạn json-file
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
Cấu hình mới chỉ áp dụng cho các container được tạo sau khi Docker daemon được restart. Container hiện tại cần được tạo lại để nhận cấu hình mới.
Kiểm tra dung lượng Docker:
docker system df
Kiểm tra dung lượng thư mục Docker:
sudo du -sh /var/lib/docker
20. Các câu lệnh Docker thường dùng
Quản lý container
docker ps
docker ps -a
docker stop container_name
docker start container_name
docker restart container_name
docker rm container_name
docker rm -f container_name
Quản lý image
docker images
docker pull nginx:alpine
docker rmi image_name
Kiểm tra container
docker logs container_name
docker inspect container_name
docker stats
docker exec -it container_name sh
docker exec -it container_name bash
Quản lý network
docker network ls
docker network inspect bridge
Quản lý volume
docker volume ls
docker volume inspect volume_name
21. Những lỗi thường gặp khi cài Docker
Lỗi không tìm thấy package docker-ce
Thông báo:
Package docker-ce has no installation candidate
Kiểm tra:
cat /etc/apt/sources.list.d/docker.sources
ls -l /etc/apt/keyrings/docker.asc
sudo apt update
Nguyên nhân thường liên quan đến repository chưa được thêm đúng, codename hệ điều hành không phù hợp hoặc GPG key không thể đọc.
Lỗi không kết nối được Docker daemon
Thông báo:
Cannot connect to the Docker daemon
Kiểm tra:
sudo systemctl status docker
sudo systemctl start docker
sudo journalctl -u docker --since "30 minutes ago"
sudo cat /etc/docker/daemon.json
Một lỗi cú pháp JSON trong daemon.json có thể khiến Docker không khởi động.
Lỗi permission denied với Docker socket
Thông báo có thể chứa:
permission denied while trying to connect to the Docker daemon socket
Kiểm tra nhóm:
groups
Thêm người dùng:
sudo usermod -aG docker $USER
newgrp docker
Lỗi port đã được sử dụng
Thông báo:
port is already allocated
Kiểm tra port:
sudo ss -tulpn | grep :8080
Kiểm tra container:
docker ps --format "table {{.Names}}\t{{.Ports}}"
Có thể đổi port host:
docker run -p 8081:80 nginx:alpine
Lỗi không còn dung lượng ổ đĩa
Thông báo:
no space left on device
Kiểm tra:
df -h
df -i
docker system df
Liệt kê container, image và volume trước khi dọn:
docker ps -a
docker images
docker volume ls
Lệnh dọn tài nguyên không sử dụng:
docker system prune
Không nên chạy thêm tùy chọn --volumes nếu chưa xác định rõ các volume không còn chứa dữ liệu cần thiết.
Container liên tục restart
Kiểm tra:
docker ps -a
docker logs --tail 200 container_name
docker inspect --format '{{.State.ExitCode}}' container_name
docker inspect --format '{{.HostConfig.RestartPolicy.Name}}' container_name
Không nên chỉ đặt restart: always để che giấu lỗi ứng dụng. Cần xác định nguyên nhân process bên trong container bị dừng.
22. Cập nhật Docker Engine
Cập nhật package index:
sudo apt update
Xem các package Docker có thể nâng cấp:
apt list --upgradable 2>/dev/null | grep -E 'docker|containerd'
Nâng cấp:
sudo apt install \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
Với production, nên thử nghiệm bản nâng cấp trên staging trước khi cập nhật máy chủ đang vận hành.
Trước khi nâng cấp:
- Kiểm tra release note.
- Backup dữ liệu.
- Kiểm tra volume.
- Lưu file Compose.
- Kiểm tra image đang sử dụng.
- Chuẩn bị rollback.
- Chọn maintenance window phù hợp.
23. Checklist cài Docker trên Cloud Server
Trước khi cài
- Đã kiểm tra phiên bản Ubuntu và kiến trúc CPU.
- Có tài khoản
sudo. - Đã kiểm tra dung lượng ổ đĩa.
- Đã kiểm tra CPU và RAM.
- Đã ghi lại các port đang sử dụng.
- Đã backup ứng dụng và dữ liệu hiện tại.
- Đã xác định server là development, staging hay production.
Trong khi cài
- Đã gỡ package xung đột.
- Đã thêm GPG key chính thức.
- Đã thêm Docker repository.
- Đã cài Docker Engine.
- Đã cài Buildx.
- Đã cài Docker Compose plugin.
- Đã chạy thành công
hello-world. - Đã kiểm tra Docker service.
Cấu hình sau cài đặt
- Đã xác định có cho phép chạy Docker không cần
sudohay không. - Đã kiểm tra rủi ro của nhóm
docker. - Đã bật restart policy cho container.
- Đã cấu hình dữ liệu bằng volume hoặc storage bên ngoài.
- Đã cấu hình log rotation.
- Đã kiểm tra port publish.
- Đã kiểm tra firewall.
- Đã bind service nội bộ vào
127.0.0.1khi phù hợp. - Đã thiết lập monitoring CPU, RAM và ổ đĩa.
- Đã có phương án backup volume và database.
Trước khi triển khai production
- Không lưu mật khẩu trực tiếp trong image.
- Không dùng image tag không kiểm soát cho quá trình release.
- Đã thiết lập health check.
- Đã giới hạn CPU và RAM nếu cần.
- Đã kiểm tra container tự chạy lại sau reboot.
- Đã thử restore dữ liệu.
- Đã kiểm tra log và alert.
- Đã cập nhật hệ điều hành và package bảo mật.
- Chỉ mở các port cần thiết.
- Có tài liệu rollback.
Kết luận
Cài Docker trên Cloud Server Ubuntu gồm nhiều bước hơn việc chạy một installation script. Với hệ thống cần vận hành lâu dài, nên sử dụng repository chính thức để cài Docker Engine, CLI, containerd, Buildx và Docker Compose plugin.
Sau khi cài, cần tiếp tục kiểm tra quyền người dùng, restart policy, port publishing, firewall, volume và log rotation. Đây là những phần dễ bị bỏ qua nhưng có thể dẫn đến rò rỉ port, mất dữ liệu hoặc đầy ổ đĩa khi container chạy liên tục.
Với ứng dụng nhỏ, một Cloud Server có thể chạy Nginx, backend, Redis và database bằng Docker Compose. Khi workload tăng, cần tiếp tục theo dõi CPU, RAM, Disk I/O, network và tách các thành phần có tải lớn sang tài nguyên độc lập.
Gợi ý bước tiếp theo
Khi cần triển khai ứng dụng container trên hạ tầng có thể chủ động CPU, RAM, SSD và băng thông, bạn có thể tham khảo giải pháp Cloud Server của Bizfly Cloud.
All Rights Reserved