❤️ AZDIGI chính thức cập nhật hệ thống blog mới hoàn chỉnh. Tuy nhiên có thể một số bài viết bị sai lệch hình ảnh, hãy ấn nút Báo cáo bài viết ở cuối bài để AZDIGI cập nhật trong thời gian nhanh nhất. Chân thành cám ơn.
Ở Bài 1, mình đã giới thiệu Docker là gì, tại sao nó quan trọng, và cách nó thay đổi hoàn toàn việc triển khai ứng dụng trên VPS. Nếu bạn chưa đọc, mình khuyên bạn nên quay lại đọc trước để nắm được các khái niệm nền tảng như container, image, Docker Engine.

Bài này, mình sẽ cùng bạn cài đặt Docker và Docker Compose trên VPS Ubuntu 24.04: từng bước một, trên một VPS thực tế. Cuối bài, bạn sẽ có một môi trường Docker sẵn sàng để chạy bất kỳ ứng dụng nào.
Yêu cầu trước khi bắt đầu
Để thực hành theo bài này, bạn cần:
- Một VPS chạy Ubuntu 24.04 LTS (hoặc 22.04 cũng được, các bước tương tự)
- Quyền root hoặc user có quyền sudo
- Kết nối SSH vào VPS
VPS mình dùng trong bài viết này có cấu hình như sau:
- OS: Ubuntu 24.04.3 LTS
- Kernel: 6.8.0-88-generic
- RAM: 3.8 GB
- Disk: 36 GB
Bước 1: Cập nhật hệ thống
Trước khi cài bất kỳ phần mềm nào, việc đầu tiên luôn là cập nhật danh sách package và nâng cấp các gói hiện có. Điều này đảm bảo hệ thống của bạn có các bản vá bảo mật mới nhất và tránh xung đột dependency khi cài Docker.
sudo apt update && sudo apt upgrade -y
Output sẽ trông giống như thế này:
Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Hit:2 http://archive.ubuntu.com/ubuntu noble-updates InRelease
Hit:3 http://archive.ubuntu.com/ubuntu noble-backports InRelease
Hit:4 http://security.ubuntu.com/ubuntu noble-security InRelease
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Bước 2: Cài đặt Docker Engine từ repository chính thức
Đây là phần quan trọng nhất của bài viết, và mình muốn giải thích tại sao chúng ta làm theo cách này.
Tại sao không dùng apt install docker.io?
Nếu bạn chạy sudo apt install docker.io, Ubuntu sẽ cài Docker từ repository mặc định của distro. Vấn đề là:
- Phiên bản cũ: Repository của Ubuntu thường đi sau vài phiên bản so với Docker chính thức. Bạn có thể nhận Docker 24.x trong khi bản mới nhất đã là 27.x.
- Thiếu plugin: Bản từ Ubuntu không đi kèm Docker Compose plugin (v2) và Buildx: hai công cụ mà bạn sẽ cần rất nhiều.
- Cập nhật chậm: Các bản vá bảo mật từ Docker Inc. phải đợi Ubuntu đóng gói lại, có thể mất vài tuần đến vài tháng.
Vì vậy, cách đúng đắn là cài từ repository chính thức của Docker. Bạn sẽ luôn có phiên bản mới nhất, đầy đủ tính năng, và nhận cập nhật bảo mật nhanh nhất.
Gỡ bỏ phiên bản Docker cũ (nếu có)
Trước tiên, hãy đảm bảo hệ thống không có phiên bản Docker cũ nào gây xung đột:
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
Nếu VPS mới tinh chưa cài gì, lệnh này sẽ báo “package not installed”, hoàn toàn bình thường, không ảnh hưởng gì.
Cài đặt các package cần thiết
Docker cần một số công cụ để tải và xác thực package từ repository bên ngoài:
sudo apt-get install -y ca-certificates curl
Thêm Docker GPG key
GPG key dùng để xác thực rằng các package bạn tải về thực sự đến từ Docker Inc., không bị ai chỉnh sửa hay giả mạo. Đây là bước bảo mật quan trọng.
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
Thêm Docker repository
Tiếp theo, thêm repository chính thức của Docker vào danh sách source của APT:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Lệnh này tự động detect kiến trúc CPU (amd64, arm64,…) và codename của Ubuntu (noble cho 24.04) để tạo đúng source list. Sau đó cập nhật lại danh sách package:
sudo apt-get update
Bạn sẽ thấy dòng mới từ download.docker.com xuất hiện trong output:
Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Hit:2 http://archive.ubuntu.com/ubuntu noble-updates InRelease
Hit:3 http://archive.ubuntu.com/ubuntu noble-backports InRelease
Hit:4 http://security.ubuntu.com/ubuntu noble-security InRelease
Get:5 https://download.docker.com/linux/ubuntu noble InRelease [48.8 kB]
Get:6 https://download.docker.com/linux/ubuntu noble/stable amd64 Packages [13.6 kB]
Fetched 62.4 kB in 1s (62.4 kB/s)
Reading package lists... Done
Cài đặt Docker Engine
Bây giờ là lúc cài Docker! Chúng ta sẽ cài cả bộ gồm 5 package:
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Giải thích từng package:
- docker-ce: Docker Engine (Community Edition): phần core chạy container
- docker-ce-cli: Công cụ dòng lệnh
dockermà bạn gõ hàng ngày - containerd.io: Container runtime cấp thấp, quản lý vòng đời của container
- docker-buildx-plugin: Plugin build image nâng cao, hỗ trợ multi-platform
- docker-compose-plugin: Docker Compose v2: chạy multi-container bằng file YAML
Quá trình cài đặt sẽ mất khoảng 1-2 phút tuỳ tốc độ mạng của VPS.
Bước 3: Kiểm tra Docker đã cài thành công
Sau khi cài xong, hãy kiểm tra phiên bản Docker:
docker version
Output sẽ hiển thị cả phiên bản Client và Server:
Client: Docker Engine - Community
Version: 29.3.0
API version: 1.54
Go version: go1.25.7
Git commit: 5927d80
Built: Thu Mar 5 14:25:48 2026
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 29.3.0
API version: 1.54 (minimum version 1.40)
Go version: go1.25.7
Git commit: 83bca51
Built: Thu Mar 5 14:25:48 2026
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v2.2.2
GitCommit: 301b2dac98f15c27117da5c8af12118a041a31d9
runc:
Version: 1.3.4
GitCommit: v1.3.4-0-gd6d73eb8
docker-init:
Version: 0.19.0
GitCommit: de40ad0
Nếu bạn thấy cả phần Client và Server như trên, Docker đã được cài đặt và đang chạy bình thường. 🎉
Bạn cũng có thể kiểm tra thông tin chi tiết hơn về Docker Engine:
docker info
Lệnh này sẽ hiển thị nhiều thông tin hữu ích: số container đang chạy, storage driver, kernel version, tổng RAM,… Rất tiện để debug khi gặp vấn đề.
Bước 4: Cấu hình chạy Docker không cần sudo
Mặc định, Docker yêu cầu quyền root để chạy. Nghĩa là mỗi lần gõ lệnh docker, bạn phải thêm sudo phía trước. Điều này khá bất tiện và cũng không phải best practice.
Giải pháp là thêm user hiện tại vào group docker. Khi đó, Docker daemon sẽ cho phép user này giao tiếp với nó mà không cần sudo.
sudo groupadd docker
sudo usermod -aG docker $USER
Dòng đầu tiên tạo group docker (nếu chưa có, có thể sẽ báo “group already exists”, không sao cả). Dòng thứ hai thêm user hiện tại vào group đó.
Để thay đổi có hiệu lực, bạn cần đăng xuất và đăng nhập lại SSH session. Hoặc nhanh hơn, chạy:
newgrp docker
Từ giờ, bạn có thể chạy docker mà không cần sudo.
Bước 5: Chạy container đầu tiên
Thời khắc đáng nhớ đây! Hãy chạy container đầu tiên trên VPS của bạn:
docker run hello-world
Output sẽ như sau:
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
17eec7bbc9d7: Pull complete
Digest: sha256:85404b3c53951c3ff5d40de0972b1bb21fafa2e8daa235355baf44f33db9dbdd
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.
(amd64)
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 an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
Dòng “Hello from Docker!” cho thấy mọi thứ hoạt động hoàn hảo. Hãy cùng phân tích những gì vừa xảy ra:
- Docker không tìm thấy image
hello-worldtrên máy → tự động tải từ Docker Hub - Tạo một container mới từ image đó
- Chạy chương trình bên trong container → in ra thông báo
- Container hoàn thành công việc và tự tắt
Toàn bộ quá trình này diễn ra trong vài giây. Đó chính là sức mạnh của Docker, bạn vừa tải, tạo và chạy một container mà không cần cài đặt hay cấu hình gì thêm.
Bước 6: Kiểm tra Docker Compose
Docker Compose là công cụ giúp bạn định nghĩa và quản lý nhiều container cùng lúc bằng một file YAML. Ví dụ: bạn muốn chạy WordPress + MySQL + Redis thì chỉ cần một file docker-compose.yml và một lệnh duy nhất.
Vì chúng ta đã cài docker-compose-plugin ở trên, Docker Compose v2 đã sẵn sàng. Kiểm tra phiên bản:
docker compose version
Docker Compose version v5.1.0
Lưu ý: Docker Compose v2 sử dụng lệnh docker compose (không có dấu gạch ngang). Nếu bạn từng dùng Docker Compose v1, lệnh cũ là docker-compose (có dấu gạch ngang). V2 nhanh hơn, tích hợp trực tiếp vào Docker CLI, và là phiên bản được Docker khuyến nghị sử dụng.
Bước 7: Một số lệnh Docker cơ bản
Trước khi kết thúc, mình giới thiệu vài lệnh Docker mà bạn sẽ dùng thường xuyên nhất.
Xem các container đang chạy
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Hiện tại không có container nào đang chạy, đúng rồi, vì container hello-world đã tự tắt sau khi in xong thông báo.
Để xem tất cả container (kể cả đã dừng), thêm flag -a:
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago quirky_morse
Bạn có thể thấy container hello-world đã chạy và thoát với mã 0 (thành công).
Xem danh sách image đã tải
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest 85404b3c5395 2 months ago 25.9kB
Image hello-world chỉ nặng 25.9 KB, siêu nhẹ, vì nó chỉ chứa một chương trình nhỏ để in thông báo. Trong thực tế, image của các ứng dụng như Nginx, WordPress, MySQL sẽ nặng từ vài chục đến vài trăm MB.
Kiểm tra trạng thái Docker service
sudo systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: enabled)
Active: active (running) since Fri 2025-03-14 02:00:00 UTC; 5min ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 12345 (dockerd)
Tasks: 10
Memory: 92.5M
CPU: 1.234s
CGroup: /system.slice/docker.service
└─12345 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Trạng thái active (running) và enabled nghĩa là Docker đang chạy và sẽ tự khởi động cùng hệ thống khi VPS reboot.
📚 Serie Docker từ A đến Z
- Bài 1: Docker là gì? Tại sao nên dùng Docker trên VPS
- Bài 2: Cài đặt Docker và Docker Compose trên VPS Ubuntu (đang đọc)
- Bài 3: Làm quen với Docker – Các lệnh cơ bản cần biết
- Bài 4: Docker Image & Dockerfile – Tự tạo Image riêng
- Bài 5: Docker Volume & Network – Quản lý dữ liệu và mạng
- Bài 6: Docker Compose là gì? Cài đặt và cú pháp cơ bản
- Bài 7: Deploy WordPress + MySQL + phpMyAdmin bằng Docker Compose
- Bài 8: Deploy LEMP Stack (Nginx + PHP-FPM + MariaDB) bằng Docker Compose
- Bài 9: Biến môi trường & file .env trong Docker Compose
- Bài 10: Reverse Proxy với Nginx Proxy Manager + SSL tự động
- Bài 11: Deploy ứng dụng Node.js / Python với Docker Compose
- Bài 12: Backup & Restore dữ liệu Docker Volume
- Bài 13: Monitoring Docker với Portainer, Uptime Kuma và cAdvisor
- Bài 14: Docker Logging – Quản lý log hiệu quả
- Bài 15: Bảo mật Docker trên VPS
- Bài 16: CI/CD đơn giản – Auto deploy với Webhook + Docker Compose
- Bài 17: Docker Compose trong thực tế – Tổng hợp project mẫu
Tổng kết
Vậy là xong! Bạn đã hoàn thành việc cài đặt Docker và Docker Compose trên VPS Ubuntu 24.04. Tổng kết lại những gì đã làm:
- ✅ Cập nhật hệ thống Ubuntu
- ✅ Cài Docker Engine từ repository chính thức (không dùng bản mặc định của Ubuntu)
- ✅ Cấu hình chạy Docker không cần sudo
- ✅ Chạy container đầu tiên thành công
- ✅ Xác nhận Docker Compose v2 hoạt động
- ✅ Làm quen với các lệnh cơ bản:
docker ps,docker images,docker version
Giờ VPS của bạn đã sẵn sàng để chạy bất kỳ ứng dụng Docker nào rồi.
Ở Bài 3, mình sẽ cùng bạn triển khai ứng dụng web đầu tiên bằng Docker, một website thực tế với Nginx. Bạn sẽ học cách quản lý container, map port, mount volume, và hiểu rõ hơn cách Docker hoạt động trong thực tế. Hẹn gặp bạn ở bài tiếp theo! 🚀
👈 Bài trước: Docker là gì? Tại sao nên dùng Docker trên VPS
👉 Bài tiếp: Làm quen với Docker – Các lệnh cơ bản cần biết
Về tác giả
Thạch Phạm
Đồng sáng lập và Giám đốc điều hành của AZDIGI. Có hơn 15 năm kinh nghiệm trong phổ biến kiến thức liên quan đến WordPress tại thachpham.com, phát triển website và phát triển hệ thống.