0

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 psdocker 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-plugindocker-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:

  1. Tìm image hello-world trên máy chủ.
  2. Tải image nếu chưa tồn tại.
  3. Tạo container.
  4. Chạy container.
  5. In thông báo xác nhận.
  6. 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 docker có 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 sudo hay 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.1 khi 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

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí