Chạy container không cần root với Podman thay Docker

SSH vào VPS, bạn vừa cài Docker xong thì nhận ra daemon Docker chạy với quyền root. Chỉ cần một container bị lỗ hổng, kẻ tấn công có thể leo thang lên toàn bộ máy chủ. Đó là rủi ro mà nhiều sysadmin chấp nhận trong nhiều năm. Podman sinh ra để giải quyết chính vấn đề này: chạy container ở chế độ rootless, tiến trình container thuộc về user thường, không phải root. Bài này hướng dẫn bạn cài Podman trên Ubuntu 24.04 LTS, chuyển workflow từ Docker sang Podman và cấu hình để container tự khởi động cùng hệ thống bằng systemd.
Tóm tắt nhanh
- Podman là giải pháp thay thế Docker, không cần daemon chạy nền, hỗ trợ rootless container từ phiên bản 4.0.
- Câu lệnh Podman tương thích phần lớn với Docker:
podman run,podman ps,podman buildthay chodocker .... - Container rootless của Podman mặc định dùng slirp4netns cho mạng, cần mở port bằng flag
-pnhư Docker. - Podman tích hợp systemd qua
podman generate systemdhoặc quadlet (file.container), giúp container chạy như service khi reboot.
Yêu cầu trước khi bắt đầu
- Một VPS chạy Ubuntu 24.04 LTS (bài này cũng áp dụng được cho Debian 12, AlmaLinux 9 với lệnh tương ứng).
- User sudo non-root để cài đặt và chạy container.
- Hiểu cơ bản về container và lệnh Docker (nếu bạn đã quen Docker thì chuyển sang Podman rất nhanh).
- Port cần thiết cho container, ví dụ 8080 cho web, mở trên firewall nếu dùng ufw hoặc firewalld.
Vì sao nên chuyển từ Docker sang Podman?
Docker dùng kiến trúc client-server. Một daemon dockerd chạy với quyền root, nhận lệnh từ client và quản lý toàn bộ container. Nếu daemon bị khai thác, attacker có quyền root trên host. Podman không có daemon trung tâm. Mỗi tiến trình podman hoạt động độc lập, container chạy dưới user hiện tại nhờ cơ chế user namespace của Linux kernel. Khi bạn chạy podman run với user thường, tiến trình trong container ánh xạ sang một UID khác trên host, thường là UID rất lớn (ví dụ 100000+). Kể cả khi container bị chiếm quyền, kẻ tấn công cũng chỉ có quyền của user thường đó, không phải root.
Podman tương thích với chuẩn OCI (Open Container Initiative), nghĩa là image từ Docker Hub chạy được bình thường. Lệnh podman được thiết kế để thay thế trực tiếp docker: podman pull, podman build, podman network đều có. Nếu bạn đã viết file docker-compose.yml, dùng podman-compose hoặc podman play kube để chạy. Với một VPS dùng để chạy vài container nhỏ, bỏ daemon Docker giúp giảm một phần bộ nhớ và loại bỏ một tiến trình chạy quyền root.
Có một điểm cần nói rõ: Docker cũng hỗ trợ rootless mode từ bản 19.03, nhưng cách triển khai phức tạp hơn, cần cài thêm slirp4netns, fuse-overlayfs và phải khởi động daemon theo user. Podman làm điều này mặc định, không cấu hình thêm. Với người mới hoặc người muốn đơn giản, Podman dễ tiếp cận hơn.
Bước 1 - Cài đặt Podman trên Ubuntu 24.04
Podman có trong kho lưu trữ chính thức của Ubuntu 24.04. Cập nhật package và cài đặt:
sudo apt update
sudo apt install podman -y
Kiểm tra phiên bản đã cài:
podman --version
Output mong đợi dạng podman version 4.9.3 hoặc mới hơn. Bản 4.x hỗ trợ đầy đủ rootless container và quadlet. Nếu bạn dùng AlmaLinux 9, lệnh cài là sudo dnf install podman.
Sau khi cài, kiểm tra xem user hiện tại có chạy container được không. Lệnh sau chạy container hello-world:
podman run hello-world
Nếu lần đầu chạy, Podman sẽ tải image về. Bạn thấy thông báo giới thiệu Podman hoạt động đúng. Không cần thêm user vào nhóm nào, không cần logout/login lại. Đây là khác biệt lớn so với Docker, nơi bạn phải thêm user vào nhóm docker để tránh lỗi permission denied.
Bước 2 - Cấu hình container rootless và mạng
Container rootless của Podman không có quyền tạo network bridge như Docker. Mặc định Podman dùng slirp4netns, một tiến trình user-space giả lập mạng TCP/IP. Container có IP riêng trong dải 10.0.2.0/24, nhưng không truy cập trực tiếp từ ngoài. Muốn expose port, bạn dùng flag -p giống Docker:
podman run -d --name web -p 8080:80 nginx
Lệnh này chạy container Nginx, map port 8080 trên host vào port 80 trong container. Kiểm tra bằng:
curl -I http://localhost:8080
Kết quả trả về HTTP/1.1 200 OK từ Nginx. Lưu ý, port dưới 1024 (như 80, 443) cần quyền root. Nếu bạn muốn container lắng nghe port 80, phải dùng sudo podman run hoặc cấu hình sysctl net.ipv4.ip_unprivileged_port_start=80. Cách đơn giản nhất là dùng port trên 1024 và đặt reverse proxy Nginx trước mặt, việc này cũng tốt hơn cho bảo mật.
Kiểm tra container đang chạy:
podman ps
Output hiện CONTAINER ID, IMAGE, COMMAND, CREATED, STATUS, PORTS, NAMES giống Docker. Dừng và xóa container:
podman stop web
podman rm web
Bước 3 - Chuyển workflow Docker Compose sang Podman
Nếu bạn đã quen viết docker-compose.yml, không cần chuyển hẳn sang Podman ngay. Cài podman-compose bằng pip hoặc package manager:
sudo apt install podman-compose -y
File cấu hình giữ nguyên cú pháp. Ví dụ file docker-compose.yml chạy Nginx và Redis:
version: "3.8"
services:
web:
image: nginx:latest
ports:
- "8080:80"
redis:
image: redis:7-alpine
Chạy bằng lệnh:
podman-compose up -d
podman-compose đọc file và tạo container qua Podman. Kiểm tra:
podman ps
Bạn thấy hai container web và redis đang chạy. Lưu ý podman-compose có một số hạn chế so với Docker Compose v2, ví dụ không hỗ trợ đầy đủ biến môi trường trong file .env ở một số phiên bản. Với cấu hình phức tạp, dùng podman play kube hoặc quadlet sẽ ổn định hơn.
Nếu bạn muốn dùng Docker Compose thật sự, có thể cài plugin docker-compose riêng và trỏ nó tới Podman bằng socket. Nhưng cách này rườm rà. Với hầu hết dự án, podman-compose đủ dùng.
Bước 4 - Chạy Podman như service với systemd (quadlet)
Container chạy bằng podman run sẽ tắt khi bạn logout hoặc VPS reboot. Podman cung cấp cơ chế quadlet, cho phép bạn mô tả container bằng file .container và systemd quản lý vòng đời. Đây là cách "chuẩn" để chạy container production trên Podman.
Đầu tiên tạo thư mục cho quadlet của user:
mkdir -p ~/.config/containers/systemd
Tạo file web.container:
nano ~/.config/containers/systemd/web.container
Nội dung file:
[Unit]
Description=Nginx container
[Container]
Image=docker.io/library/nginx:latest
PublishPort=8080:80
[Service]
Restart=always
[Install]
WantedBy=default.target
Reload systemd và kích hoạt service:
systemctl --user daemon-reload
systemctl --user enable --now web.service
Kiểm tra trạng thái:
systemctl --user status web.service
Quan trọng: service user chỉ chạy khi bạn đăng nhập. Để container chạy từ khi VPS boot mà không cần đăng nhập, kích hoạt "lingering" cho user:
sudo loginctl enable-linger $USER
Sau lệnh này, container Nginx tự khởi động cùng hệ thống và tự restart nếu crash. Đây là cách đáng tin cậy hơn nhiều so với việc chạy container trong screen hay tmux.
So sánh Podman và Docker
| Tiêu chí | Podman | Docker |
|---|---|---|
| Kiến trúc | Daemonless, mỗi lệnh độc lập | Client-server, daemon chạy nền |
| Rootless container | Hỗ trợ mặc định, dễ dùng | Có nhưng cấu hình phức tạp hơn |
| Bảo mật | Container chạy dưới user thường, giảm rủi ro leo thang | Daemon chạy root, rủi ro cao hơn nếu bị khai thác |
| Tương thích Docker Hub | Có, chuẩn OCI | Có |
| Docker Compose | Dùng podman-compose hoặc quadlet | Hỗ trợ chính thức |
| Hệ sinh thái và tài liệu | Mạnh, cộng đồng đang phát triển | Rất lớn, nhiều tài liệu hơn |
Nhìn vào bảng trên, Podman thắng ở khía cạnh bảo mật và đơn giản khi chạy rootless. Docker vẫn mạnh hơn về hệ sinh thái công cụ xung quanh, đặc biệt là Docker Compose và các tích hợp CI/CD. Với một VPS cá nhân chạy vài container, mình nghiêng về Podman. Với môi trường doanh nghiệp có sẵn pipeline Docker, việc chuyển đổi cần cân nhắc chi phí.
Xử lý lỗi thường gặp
Lỗi "cannot re-exec process" khi chạy rootless
Lỗi này thường do thiếu slirp4netns hoặc user namespace bị giới hạn. Cài thêm package:
sudo apt install slirp4netns fuse-overlayfs -y
Nếu vẫn lỗi, kiểm tra xem kernel có bật user namespace không:
cat /proc/sys/user/max_user_namespaces
Nếu kết quả là 0, bật lên:
sudo sysctl -w user.max_user_namespaces=15000
Để áp dụng lâu dài, thêm dòng user.max_user_namespaces=15000 vào /etc/sysctl.conf rồi chạy sudo sysctl -p.
Container không truy cập được internet
Kiểm tra cấu hình DNS trong file /etc/containers/containers.conf hoặc dùng flag --dns khi chạy:
podman run -d --dns 8.8.8.8 --name test alpine sleep 3600
Nếu mạng chính có vấn đề, kiểm tra slirp4netns có chạy không:
ps aux | grep slirp4netns
Thiếu tiến trình này nghĩa là chưa cài slirp4netns hoặc cài chưa đúng.
Lỗi "unable to find user namespace" trên AlmaLinux
Trên RHEL/AlmaLinux, cần bật quyền cho user namespace:
sudo sysctl -w kernel.unprivileged_userns_clone=1
Thêm vào /etc/sysctl.conf để giữ sau reboot.
Câu hỏi thường gặp
Podman có tương thích hoàn toàn với Docker không?
Phần lớn lệnh và image tương thích. Image từ Docker Hub chạy bình thường vì Podman tuân theo chuẩn OCI. Lệnh cơ bản như run, build, ps giống nhau. Khác biệt nằm ở khía cạnh nâng cao: Docker Compose dùng plugin riêng, Podman dùng podman-compose hoặc quadlet.
Podman có an toàn hơn Docker không?
Về thiết kế, có. Container rootless của Podman chạy dưới user thường, không phải root. Nếu container bị tấn công, phạm vi ảnh hưởng bị giới hạn. Docker chạy daemon với quyền root, nếu daemon bị lỗ hổng, rủi ro là toàn bộ host.
Tôi có thể chạy Podman trên VPS Windows Server không?
Podman có bản cho Windows nhưng hoạt động trong môi trường WSL2 hoặc máy ảo Linux. Trên Windows Server, Docker Desktop vẫn là lựa chọn phổ biến hơn. Nếu bạn cần container trên Windows, cân nhắc dùng VPS Windows với WSL2, còn nếu ưu tiên rootless container, dùng VPS Linux sẽ thuận tiện hơn nhiều.
Podman có hỗ trợ Kubernetes không?
Có. Lệnh podman play kube cho phép chạy file YAML của Kubernetes bằng Podman. Đây là cách chuyển từ Docker sang Kubernetes mà không cần thay đổi nhiều. Tuy nhiên, nếu bạn cần một cluster đầy đủ, hãy dùng k3s hoặc Kubernetes thật sự, không phải Podman.
Chạy Podman trên VPS có ngốn RAM không?
Ít hơn Docker vì không có daemon chạy nền. Mỗi container vẫn cần RAM riêng nhưng Podman không chiếm thêm bộ nhớ cho tiến trình quản lý. Với VPS 2GB RAM, bạn có thể chạy 3-4 container nhỏ như Nginx, Redis, Postgres mà không lo thiếu bộ nhớ. Nếu cần dung lượng lớn hơn, hãy xem các gói VPS giá rẻ với 4GB hoặc 8GB RAM.
Làm sao để cài Podman trên Ubuntu 20.04?
Ubuntu 20.04 đã hết hạn hỗ trợ chuẩn từ tháng 4 năm 2025. Bạn nên nâng cấp lên Ubuntu 24.04 LTS để có phiên bản Podman mới và nhận bản vá bảo mật. Podman trên Ubuntu 20.04 bản cũ có nhiều lỗi liên quan rootless container, không nên dùng cho production.
Bài viết liên quan
- Cách cài Docker trên VPS Ubuntu chi tiết từ A đến Z
- Chạy nhiều site trên 1 VPS với Docker và Nginx proxy
- Quản lý container với Portainer trên VPS
- Cài đặt Kubernetes nhẹ k3s trên VPS Ubuntu 24.04


