Vấn đề thực tế: Quản lý hàng chục Container qua terminal
Hồi mới dùng Docker, hầu như ai cũng bắt đầu bằng vài lệnh quen thuộc: docker run, docker ps hay docker logs. Mọi chuyện vẫn rất êm đẹp nếu trên VPS chỉ chạy một con Nginx tĩnh và một web app Node.js nhẹ nhàng.
Thế nhưng, dự án phình to lên là câu chuyện khác hẳn. Bạn phải kéo thêm MySQL, Redis, Celery worker và RabbitMQ. Một đêm nọ, khách báo website dính lỗi 502 Bad Gateway. Bạn vội vàng SSH vào máy chủ.
Lúc này, chuỗi thao tác quen thuộc bắt đầu: gõ docker ps -a để lùng container chết. Màn hình tuôn ra một bảng text rối rắm. Bạn phải căng mắt tìm hash ID, copy-paste vào docker logs -f [id] để đọc log, rồi lại nhảy sang docker inspect kiểm tra IP mạng nội bộ.
Chưa kể, lệnh docker stats trên terminal hẹp nhảy số liên tục rất khó theo dõi. Chỉ một phút lơ đễnh gõ nhầm lệnh xóa container dữ liệu production là bạn có thể thức trắng đêm để khôi phục backup.
Vì sao dòng lệnh (CLI) thuần dần trở thành rào cản?
CLI Docker sinh ra để phục vụ script tự động hóa và pipeline CI/CD. Tuy nhiên, khi cần debug nóng hoặc kiểm tra trạng thái hàng ngày, dòng lệnh bộc lộ ba phiền toái rõ rệt:
- Khó nắm bức tranh tổng thể: CLI hiển thị tuần tự từng dòng. Khi server chạy tầm 15–20 container, bạn không thể biết ngay dịch vụ nào đang chiếm 80% RAM, volume nào bị mồ côi hay port nào đang xung đột.
- Mất thời gian xử lý sự cố: Để nhảy vào shell của container, bạn phải nhớ tên hoặc ID rồi gõ
docker exec -it [id] /bin/sh. Muốn tải log gửi cho đồng nghiệp phân tích cũng phải qua vài bước pipe lệnh phức tạp. Lúc hệ thống gặp sự cố, mỗi phút mò mẫm đều khiến thời gian downtime kéo dài thêm. - Rủi ro về phân quyền: Thao tác với Docker CLI thường đòi hỏi user nằm trong group
docker(quyền tương đương root). Nếu cấp quyền này cho tester hoặc junior dev chỉ để họ đọc log, nguy cơ ai đó chạy nhầmdocker rm -flà hoàn toàn có thật.
Các phương án quản trị Docker phổ biến hiện nay
Tùy theo quy mô hạ tầng, anh em sysadmin thường cân nhắc ba hướng đi sau:
- Dùng Bash Script kết hợp Alias: Ví dụ tạo alias
dps='docker ps --format ...'. Cách này nhanh gọn, ít tốn tài nguyên. Dù vậy, đây chỉ là giải pháp tạm thời, vẫn phụ thuộc hoàn toàn vào terminal và chỉ tiện cho cá nhân người cấu hình. - Lên hẳn Kubernetes hoặc Rancher: Lựa chọn chuẩn chỉ cho hệ thống phân tán hàng chục node. Nhưng nếu bạn chỉ vận hành 1–2 con VPS (2 vCPU, 4GB RAM), dựng K8s sẽ ngốn sạch tài nguyên cho control plane trước khi kịp chạy ứng dụng chính.
- Dựng Portainer CE trên nền Docker Engine: Đây là điểm cân bằng lý tưởng. Bản thân Portainer chỉ là một container nhẹ (ngốn chưa tới 100MB RAM), kết nối trực tiếp vào Docker socket để biến toàn bộ thao tác gõ lệnh thành giao diện web trực quan.
Hướng dẫn cài đặt chi tiết trên Ubuntu 24.04 LTS (Noble Numbat)
Dưới đây là quy trình cài đặt Docker Engine bản chuẩn từ Docker repository và dựng Portainer CE ổn định nhất.
Bước 1: Gỡ gói cũ và cài Docker Engine chính thức
Kho apt mặc định của Ubuntu 24.04 có sẵn gói docker.io. Tuy nhiên, gói này thường cập nhật chậm tính năng mới. Hãy dọn sạch các gói cũ trước:
sudo apt remove -y docker.io docker-doc docker-compose podman-docker containerd runc
sudo apt update
sudo apt install -y ca-certificates curl gnupg
Tạo thư mục keyring và tải GPG key chuẩn từ Docker:
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 repository của Docker vào danh sách nguồn apt:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
Cài đặt trọn bộ Docker Engine, CLI, containerd cùng Compose plugin:
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Xác nhận Docker service đã tự kích hoạt và đang chạy:
sudo systemctl status docker --no-pager
Bước 2: Phân quyền Docker không cần sudo
Mặc định, bạn phải kèm sudo trước mỗi lệnh Docker. Để thao tác thuận tiện hơn, hãy thêm user hiện tại vào group docker:
sudo usermod -aG docker $USER
newgrp docker
Kiểm tra ngay bằng container thử nghiệm:
docker run --rm hello-world
Nếu terminal in ra dòng chữ “Hello from Docker!”, môi trường Docker Engine của bạn đã hoàn tất.
Bước 3: Khởi chạy Portainer Community Edition
Đầu tiên, tạo một volume riêng biệt. Volume này giữ lại dữ liệu tài khoản, thiết lập môi trường và lịch sử cấu hình mỗi khi bạn update Portainer:
docker volume create portainer_data
Tiến hành chạy container Portainer CE:
docker run -d \
-p 8000:8000 \
-p 9443:9443 \
--name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest
Ý nghĩa các tham số cần nhớ:
-p 9443:9443: Cổng HTTPS để bạn vào giao diện quản trị trên trình duyệt.-p 8000:8000: Cổng kết nối TCP dành cho Edge Agent nếu sau này bạn quản lý nhiều máy chủ từ xa.--restart=always: Đảm bảo Portainer tự chạy lại khi server reboot hoặc service crash.-v /var/run/docker.sock:/var/run/docker.sock: Gắn socket của Docker daemon từ host vào container để Portainer nhận diện và điều khiển các container khác.
Mình đã chạy thử cấu hình này trên cả VPS 2GB RAM lẫn máy chủ staging Ubuntu 24.04. Toàn bộ tiến trình hoạt động trơn tru, không gặp lỗi tương thích AppArmor hay kẹt network bridge nào.
Bước 4: Tạo tài khoản admin và cấu hình ban đầu
Mở trình duyệt và truy cập theo đường dẫn:
https://<IP_SERVER_CUA_BAN>:9443
Vì Portainer dùng SSL tự ký (self-signed cert), trình duyệt sẽ hiện cảnh báo bảo mật. Bạn chỉ cần bấm Advanced (Nâng cao) rồi chọn Proceed / Tiếp tục truy cập.
Tại giao diện khởi tạo, hãy tạo mật khẩu cho tài khoản admin (yêu cầu tối thiểu 12 ký tự). Lưu ý: Portainer có cơ chế khóa bảo mật sau 5 phút. Nếu quá thời gian này bạn chưa tạo mật khẩu, hãy chạy lệnh docker restart portainer trên terminal để reset bộ đếm.
Sau khi đăng nhập thành công, chọn môi trường local. Bạn sẽ thấy ngay bảng điều khiển trung tâm:
- Danh sách Container: Phân loại rõ ràng trạng thái Running, Stopped hoặc Unhealthy kèm nút Start/Stop/Restart ngay bên cạnh.
- Logs real-time: Có sẵn ô tìm kiếm từ khóa lỗi, tự động cuộn dòng mà không cần nhớ cú pháp
grep. - Console: Mở ngay shell
/bin/shhoặc/bin/bashvào trong container trực tiếp trên tab trình duyệt. - Stats: Theo dõi biểu đồ CPU, RAM, Network I/O cập nhật theo từng giây của từng container.
Kinh nghiệm vận hành thực tế cần lưu ý
Sau khi đưa Portainer vào sử dụng thực tế trên server public, bạn nên áp dụng ngay hai biện pháp này:
- Bảo vệ cổng 9443: Đừng mở toang cổng này ra Internet. Hãy dùng UFW chặn lại và chỉ whitelist IP tĩnh của bạn (
sudo ufw allow from <IP_CUA_BAN> to any port 9443 proto tcp). Nếu dùng domain, hãy trỏ qua Nginx Proxy Manager hoặc Cloudflare Tunnel có xác thực hai lớp (2FA). - Dọn rác định kỳ (Dangling Images & Volumes): Mỗi lần build code mới, Docker thường để lại các image không tên (dangling). Vào mục Images, lọc danh sách Unused và nhấn nút Remove. Thao tác click chuột đơn giản này thường giúp server giải phóng từ 10GB đến 30GB dung lượng ổ cứng bị lãng phí.

