Cài Docker + Portainer trên VPS quản lý 5 container có UI

Chia sẻ bài viết

Mục lục
Cài Docker + Portainer trên VPS quản lý 5 container có UI
TL;DR
  • Portainer là web UI quản lý Docker, miễn phí Community Edition cho VPS.
  • Cài Docker rồi chạy 1 container Portainer trong 5 phút.
  • UI cho deploy stack từ Compose, restart container, xem log realtime, monitor RAM/CPU.
  • Bảo mật: chỉ expose qua reverse proxy + basic auth + IP whitelist.
  • VPS 2GB chạy thoải mái Portainer + 5-10 container service.

Dev solo quản lý 5-10 Docker container qua SSH + docker ps + docker logs là cực hình. Portainer cho UI web đẹp, click 1 nút restart container, xem log scroll realtime, deploy stack Compose nguyên cái. Cài 5 phút, dùng hằng ngày tiết kiệm hàng giờ.

Portainer Community Edition miễn phí cho mọi feature core. Edition Business chỉ thêm RBAC enterprise, OIDC SSO - dev solo không cần. Bài này hướng dẫn cài CE trên Cloud VPS 2GB Ubuntu 24.04, security tốt bằng reverse proxy.

1. Cài Docker trên Ubuntu 24.04

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker

# Verify
docker --version
docker compose version

2. Cài Portainer CE

# Tạo volume lưu data Portainer
docker volume create portainer_data

# Run Portainer
docker run -d 
  -p 127.0.0.1:9000:9000 
  -p 127.0.0.1:9443:9443 
  --name portainer 
  --restart=always 
  -v /var/run/docker.sock:/var/run/docker.sock 
  -v portainer_data:/data 
  portainer/portainer-ce:latest

docker ps

Chú ý: bind port chỉ vào 127.0.0.1 (localhost), không expose ra public. Truy cập qua reverse proxy ở bước 4.

3. Setup admin lần đầu

# SSH tunnel từ máy local
ssh -L 9000:127.0.0.1:9000 user@vps-ip

# Trên browser local truy cập http://localhost:9000
# Tạo username admin và password mạnh (12+ ký tự)
# Choose "Get Started" -> Local Docker environment

Sau khi setup admin, đóng SSH tunnel. Tiếp theo expose qua reverse proxy với SSL + basic auth.

4. Cài Caddy reverse proxy + SSL + basic auth

sudo apt install -y caddy

# Tạo bcrypt hash cho basic auth password
caddy hash-password
# Nhập password 2 lần, copy output dạng JDJh...

sudo nano /etc/caddy/Caddyfile
portainer.yourdomain.com {
    # Basic auth
    basicauth {
        admin JDJhJDE0J...your-bcrypt-hash
    }

    # IP whitelist (optional, dùng IP văn phòng/nhà)
    @blocked {
        not remote_ip 1.2.3.4 5.6.7.8
    }
    respond @blocked "Forbidden" 403

    reverse_proxy 127.0.0.1:9000
}

sudo systemctl reload caddy

Trỏ DNS portainer.yourdomain.com -> IP VPS. Caddy auto cấp Let Encrypt SSL trong 30s. Truy cập https://portainer.yourdomain.com - basic auth popup trước, đúng password mới vào được Portainer login.

5. UI tour: dashboard, container, stack

  • Dashboard: số container running, image, volume, network.
  • Containers: list mọi container, click vào xem log, exec shell, stats CPU/RAM.
  • Images: list image đã pull, prune unused.
  • Stacks: deploy nhiều container từ Docker Compose YAML, manage chung.
  • Networks: tạo bridge network để container giao tiếp internal.
  • Volumes: manage persistent data.

6. Deploy stack từ Compose qua UI

Stacks -> Add Stack -> Web editor. Paste docker-compose.yml:

services:
  postgres:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: example
    volumes:
      - pg-data:/var/lib/postgresql/data

  redis:
    image: redis:7
    restart: unless-stopped
    command: redis-server --maxmemory 200mb --maxmemory-policy allkeys-lru

  app:
    image: myapp:latest
    restart: unless-stopped
    ports:
      - "127.0.0.1:3000:3000"
    environment:
      DATABASE_URL: postgres://postgres:example@postgres:5432/myapp
      REDIS_URL: redis://redis:6379
    depends_on:
      - postgres
      - redis

volumes:
  pg-data:

Click Deploy the stack. Portainer pull image, tạo container, start theo thứ tự depends_on. 1 phút sau stack chạy đầy đủ.

7. Xem log real-time

Click container name -> tab Logs. Mặc định show 100 dòng cuối, auto-refresh mỗi giây. Có thể filter timestamp, search keyword. Tiện hơn ssh + docker logs -f -t nhiều.

8. Exec shell vào container

Click container -> Console -> Connect. Chọn shell (/bin/bash hoặc /bin/sh). Mở terminal web trực tiếp trong browser, không cần ssh. Tiện debug nhanh:

# Trong shell container
ls /app
cat /etc/hostname
ps aux
env | grep DATABASE

9. Monitor stats CPU/RAM/Network

Click container -> Stats. Biểu đồ realtime cho CPU%, Memory MB, Network I/O. Phát hiện container ngốn tài nguyên bất thường.

Dashboard tổng cũng có graph overview cho tất cả container.

10. Auto update container với Watchtower

# Deploy Watchtower qua Portainer Stack
services:
  watchtower:
    image: containrrr/watchtower:latest
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      WATCHTOWER_CLEANUP: "true"
      WATCHTOWER_SCHEDULE: "0 0 4 * * *"   # mỗi 4h
      WATCHTOWER_LABEL_ENABLE: "true"

Container có label com.centurylinklabs.watchtower.enable=true sẽ tự được update mỗi 4 tiếng khi có image mới.

11. Backup Portainer data

# Backup volume portainer_data
docker run --rm 
  -v portainer_data:/data 
  -v $(pwd):/backup 
  alpine tar -czf /backup/portainer-$(date +%F).tar.gz /data

# Restore khi cần
docker run --rm 
  -v portainer_data:/data 
  -v $(pwd):/backup 
  alpine tar -xzf /backup/portainer-2026-07-07.tar.gz -C /

12. Best practices bảo mật Portainer

  • Không expose port 9000/9443 ra public, chỉ qua reverse proxy.
  • Basic auth Caddy thêm 1 lớp trước Portainer login.
  • IP whitelist nếu chỉ access từ văn phòng/nhà.
  • Enable 2FA cho user admin trong Portainer settings.
  • Backup volume portainer_data hàng tuần lên S3.
  • Update Portainer image định kỳ (có security patch).
  • Đừng chia sẻ docker.sock với container không trust được - tương đương root host.
Cloud VPS cho vibe coder

Quản lý Docker container qua UI - không cần SSH mỗi lần

Cloud VPS TND sẵn AlmaLinux 9, Ubuntu 22/24, Debian 12/13. SSD CEPH, snapshot 1-click, backup hằng ngày, network 200Mbps trong nước. Cài Docker + Portainer trong 10 phút, manage 5-10 container thoải mái với VPS 2GB.

Xem 8 cấu hình Cloud VPS →

Bảo mật giao diện quản lý, phần quan trọng nhất

ViệcVì sao bắt buộc
Đặt sau lớp phân luồng có chứng chỉ bảo mậtTruy cập không mã hóa là lộ mật khẩu quản trị
Thêm một lớp xác thực nữa trước giao diệnGiao diện quản lý container tương đương quyền quản trị toàn máy
Không mở cổng quản lý ra internetChỉ cho vào qua mạng riêng hoặc qua lớp phân luồng
Đặt mật khẩu quản trị ngay lần đầuCó cửa sổ thời gian rất ngắn để đặt; bỏ lỡ là phải dựng lại
Rà lại quyền của người dùng phụNgười có quyền chạy container là người có quyền vào máy

Điểm cần hiểu rõ: ai vào được giao diện quản lý container là chạy được container với quyền cao nhất, tức là chiếm được cả máy chủ. Đây không phải một bảng điều khiển thông thường.

Kiểm sau khi dựng

# 1. Cong nao dang mo ra ngoai
ss -ltnp | grep -v 127.0.0.1

# 2. Giao dien quan ly co bi lo ra internet khong
curl -sI https://IP-MAY-CHU:9443 --max-time 5 | head -3
# nen khong ket noi duoc tu ngoai, chi vao duoc qua lop phan luong

# 3. Chung chi bao mat da cap chua
curl -sI https://quanly.tenmien.vn | head -5

# 4. Container nao dang chay voi quyen cao
docker ps
docker inspect $(docker ps -q) | grep -i privileged

# 5. Dung luong: nhat ky va anh cu la hai thu lam day o
docker system df
du -sh /var/lib/docker/containers/*/*-json.log 2>/dev/null | sort -h | tail -5

Về công cụ tự cập nhật container

Nghe tiện nhưng cần cân nhắc: tự động kéo bản mới nhất nghĩa là một ngày nào đó bản mới có thay đổi phá vỡ tương thích và dịch vụ của bạn chết lúc 3 giờ sáng mà không ai chạm vào gì. Với dịch vụ quan trọng, nên tắt tự cập nhật và cập nhật theo lịch tháng có sao lưu trước.

Ba thói quen giữ cụm container sống lâu

  • Đặt giới hạn bộ nhớ và giới hạn kích thước nhật ký cho mọi dịch vụ. Không đặt thì một dịch vụ đi hoang kéo cả máy xuống.
  • Giữ tệp khai báo trong kho mã nguồn. Dựng lại được toàn bộ máy là bản sao lưu quan trọng nhất mà không tốn dung lượng.
  • Dọn ảnh và vùng lưu trữ mồ côi định kỳ, vì chúng chiếm chỗ rất nhanh.

FAQ

Portainer CE có giới hạn gì so với Business?

CE đủ mọi feature core: stack, container, image, volume, network, log, stats. Business thêm: RBAC nhiều role, OIDC SSO, Kubernetes namespace isolation, support. Dev solo và team nhỏ dùng CE thoải mái.

Portainer ăn nhiều RAM không?

Khoảng 50-80MB RAM khi idle, lên 150MB khi xem stats realtime nhiều container. Không đáng kể trên VPS 2GB.

Có thể quản lý nhiều VPS từ 1 Portainer không?

Có. Cài Portainer Edge Agent trên VPS khác, register vào Portainer chính. Quản lý multi-host từ 1 UI duy nhất. Tiết kiệm overhead.

Stack deploy qua UI có save file Compose ở đâu?

Trong volume portainer_data, file dạng JSON metadata. Để backup chuẩn, export stack từ UI (Download) thành file YAML local + commit git.

Có app mobile cho Portainer không?

Không có native app. Web UI responsive khá tốt trên Safari/Chrome mobile. Có app cộng đồng "Containers" iOS dùng Portainer API.

Có nên dùng Portainer cho production critical app không?

Được nếu basic auth + 2FA + IP whitelist + audit log. Cho enterprise critical thì cân nhắc Portainer Business hoặc K8s + ArgoCD GitOps để có audit trail tốt hơn.