Vấn đề khi có nhiều container cần phối hợp
Chạy một container đơn lẻ với podman run thì đơn giản. Rắc rối bắt đầu khi ứng dụng cần 3–4 container phối hợp nhau — web app, database, cache, reverse proxy. Network phải tạo tay. Thứ tự khởi động phải canh đúng. Biến môi trường phải truyền đúng chỗ, volume phải mount đồng bộ. Deploy lần đầu thì xong được. Lần thứ hai, hoặc chuyển sang máy khác, là mất nửa buổi.
Mình dùng Fedora làm máy development chính đã 2 năm — khá hài lòng với tốc độ cập nhật package, Podman thường đi trước các distro khác cả vài tháng. Nhưng chính vì Fedora đẩy Podman thay Docker, nhiều người gặp câu hỏi thực tế: file docker-compose.yml cũ giờ chạy thế nào?
Bốn cách để orchestrate nhiều container trên Fedora
Cách 1: Giữ nguyên Docker Compose
Cài Docker Engine lên Fedora vẫn được, không ai cấm. Docker Compose chạy bình thường, file compose không cần đụng vào.
Nhưng có vài điểm khó chịu. Docker daemon cần chạy root — cộng thêm một systemd service riêng phải quản lý. Fedora cũng không còn ship Docker trong repo chính thức, tức là mỗi lần nâng Fedora version phải kiểm tra lại repo Docker riêng. Mình từng gặp Docker daemon crash sau khi upgrade Fedora 38 → 39 vì xung đột cgroup v2 — mất gần 2 tiếng mới debug ra nguyên nhân.
Cách 2: Podman Pods — native nhưng verbose
Podman hỗ trợ khái niệm “pod” — nhóm container dùng chung network namespace, tương tự Kubernetes pod. Bạn tạo pod rồi add container vào:
podman pod create --name myapp -p 8080:80
podman run -d --pod myapp nginx
podman run -d --pod myapp postgres:15
Vấn đề là không có file config nào để version control. Muốn tái tạo lại stack phải gõ lại toàn bộ lệnh từ đầu. Nếu bạn đã quen workflow khai báo kiểu docker-compose.yml, cách này sẽ cảm giác như thụt lùi.
Cách 3: Quadlet — systemd-native cho production
Từ Podman 4.4+ (Fedora 38+), Quadlet cho phép viết file .container và .pod trong ~/.config/containers/systemd/, systemd tự generate unit file. Rất production-ready, tích hợp tốt với journalctl và restart policy đầy đủ.
Nhưng để dùng được Quadlet, bạn phải học cú pháp mới từ đầu — khác hoàn toàn với docker-compose.yml. Nếu đang có 10–15 project dùng compose file, migrate hết sang Quadlet không phải việc một buổi.
Cách 4: Podman Compose — điểm cân bằng thực dụng
Podman Compose là tool Python chạy file docker-compose.yml bằng Podman backend thay vì Docker. Không cần daemon root, hỗ trợ rootless hoàn toàn, cú pháp giữ nguyên so với Docker Compose.
So sánh bốn approach
| Approach | Rootless | Tương thích compose file | Systemd integration | Learning curve |
|---|---|---|---|---|
| Docker Compose | ❌ Root daemon | ✅ 100% | Thủ công | Thấp |
| Podman Pods | ✅ | ❌ Cú pháp khác | Thủ công | Trung bình |
| Quadlet | ✅ | ❌ Cần migrate | ✅ Native | Cao |
| Podman Compose | ✅ | ✅ ~90% | Có thể wrap | Thấp |
Podman Compose không hỗ trợ 100% spec — một số tính năng như extends, profiles phức tạp, hay một số deploy option có thể thiếu. Nhưng cho 90% use case thông thường, nó chạy ổn mà không cần sửa gì.
Cài đặt Podman Compose trên Fedora
Fedora có Podman Compose trong repo chính thức từ Fedora 36+:
sudo dnf install podman-compose
podman-compose --version
Nếu muốn version mới nhất từ PyPI:
pip install --user podman-compose
Triển khai thực tế: Web app + PostgreSQL + Redis
Tạo cấu trúc project
mkdir ~/myapp && cd ~/myapp
mkdir -p app nginx/conf.d
Viết docker-compose.yml
version: '3.8'
services:
web:
image: python:3.11-slim
working_dir: /app
volumes:
- ./app:/app:Z
command: python -m http.server 8000
depends_on:
- db
- cache
environment:
- DATABASE_URL=postgresql://user:password@db:5432/mydb
- REDIS_URL=redis://cache:6379
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
volumes:
- pgdata:/var/lib/postgresql/data
cache:
image: redis:7-alpine
command: redis-server --save 60 1
nginx:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
depends_on:
- web
volumes:
pgdata:
File cấu hình nginx
# nginx/conf.d/default.conf
server {
listen 80;
location / {
proxy_pass http://web:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Các lệnh cơ bản
# Khởi động toàn bộ stack
podman-compose up -d
# Xem log real-time
podman-compose logs -f
# Kiểm tra trạng thái
podman-compose ps
# Dừng và xóa container (giữ volume)
podman-compose down
# Dừng và xóa cả volume data
podman-compose down -v
Những điểm dễ vấp khi chạy rootless trên Fedora
Volume mount và SELinux
Fedora chạy SELinux enforcing theo mặc định. Khi mount thư mục host vào container, phải thêm label :Z (relabel riêng cho container này) hoặc :z (shared giữa nhiều container):
volumes:
- ./app:/app:Z # Relabel riêng cho container này
- ./config:/etc/app:z # Shared — nhiều container cùng đọc
Thiếu label này là nguyên nhân số một của lỗi “Permission denied” khi chạy Podman trên Fedora. Container start xong xuôi, log sạch bóng, nhưng app bên trong cứ báo lỗi đọc file — SELinux đang chặn ở background mà không có dòng log nào rõ ràng.
Port dưới 1024
Rootless container không bind được port nhỏ hơn 1024 theo mặc định. Cho môi trường dev, dùng port cao hơn là đủ. Nếu thực sự cần port 80/443:
# Hạ ngưỡng port cho user thường (cần root một lần)
echo "net.ipv4.ip_unprivileged_port_start=80" | sudo tee /etc/sysctl.d/99-podman-ports.conf
sudo sysctl --system
Tự động start khi reboot
Podman Compose không tích hợp systemd sẵn như Quadlet, nhưng có thể wrap bằng user service:
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/myapp.service << 'EOF'
[Unit]
Description=My App Stack
After=default.target
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=%h/myapp
ExecStart=/usr/bin/podman-compose up -d
ExecStop=/usr/bin/podman-compose down
TimeoutStartSec=0
[Install]
WantedBy=default.target
EOF
systemctl --user enable --now myapp.service
# Cho service chạy khi user chưa đăng nhập
loginctl enable-linger $USER
Khi nào nên chuyển sang Quadlet
Podman Compose phù hợp cho development và staging. Còn production trên Fedora Server? Quadlet là câu chuyện khác hẳn: log thẳng vào systemd journal, dependency management qua unit files, restart tự động không cần script wrapper bên ngoài.
Tin vui là từ Fedora 40, có tool podlet tự động convert file compose sang Quadlet:
sudo dnf install podlet
podlet compose docker-compose.yml
Nó generate ra file .container và .network sẵn dùng, giúp migrate mà không phải viết lại từ đầu.
Tổng kết
Cho môi trường development trên Fedora, Podman Compose là điểm khởi đầu hợp lý nhất. Rootless, không cần daemon, chạy được 90% file compose hiện tại mà không sửa gì. Khi project lớn lên và cần độ ổn định production — restart policy đàng hoàng, journald, dependency graph — thì Quadlet mới đáng đầu tư. Lúc đó, podlet lo phần convert, bạn chỉ cần review lại output là xong.

