Cài đặt Portainer quản lý Docker qua UI — hết nhớ lệnh, hết sợ nhầm

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

Mỗi ngày gõ lệnh Docker — rồi cũng tới lúc mệt

Nếu bạn đang chạy vài chục container trên VPS, chắc đã quen với cái vòng lặp quen thuộc: SSH vào server, gõ docker ps -a, nhìn một đống container, rồi mò mẫm đọc log từng cái. Xong rồi docker inspect để kiểm tra network, volume… Mỗi thao tác nhỏ cũng phải mở terminal.

Mình từng ở giai đoạn đó. Lúc đầu chỉ có 5–6 container, nhớ lệnh được. Nhưng khi stack lên 20–30 container — Nginx, PHP-FPM, MySQL, Redis, n8n, Gitea — CLI bắt đầu thành gánh nặng. Nhất là lúc debug lúc 2 giờ sáng, ngón tay gõ nhầm tên container mà mắt không còn nhìn rõ.

Tại sao CLI Docker không đủ cho môi trường thực tế

Vấn đề không phải là CLI Docker yếu. Ngược lại, CLI rất mạnh — nhưng nó đòi hỏi bạn nhớ chính xác tên container, tên volume, cú pháp lệnh. Một số điểm đau thực tế:

  • Khó tổng quan: docker stats hiển thị real-time nhưng không lưu lịch sử, không có graph.
  • Khó chia sẻ quyền: Nếu cần để đồng nghiệp xem logs, bạn phải tạo SSH key cho họ — rủi ro không cần thiết.
  • Thao tác hay nhầm: docker rm nhầm container đang chạy xảy ra thường xuyên hơn bạn nghĩ.
  • Không thấy network topology: Khó biết container nào đang kết nối với network nào chỉ qua CLI.

Tới lúc đó mình bắt đầu tìm giải pháp — cần cái gì đó ngồi trên Docker Engine, để không phải mở terminal cho mọi thao tác nhỏ.

Các lựa chọn quản lý Docker qua giao diện

Lazydocker — terminal UI đơn giản

Không muốn cài web UI? Lazydocker là lựa chọn nhẹ nhất. Chạy ngay trong terminal, không cần cổng mạng, không cần reverse proxy. Nhược điểm: vẫn phải SSH vào server, không truy cập từ xa được dễ dàng.

Rancher — nặng, dành cho Kubernetes

Rancher mạnh nhưng thiết kế chủ yếu cho Kubernetes cluster. Nếu chỉ dùng standalone Docker, cài Rancher là overkill — tốn RAM, cấu hình phức tạp, dựng lên mất cả buổi.

Portainer CE — điểm ngọt giữa đơn giản và đủ dùng

Portainer Community Edition là thứ mình dùng liên tục 2 năm nay và chưa thấy lý do để đổi. Cài bằng Docker, truy cập qua web browser, hỗ trợ quản lý container/image/volume/network đầy đủ. Đặc biệt là phần quản lý Docker Compose stack trực tiếp trên UI — deploy mà không cần SSH vào server.

Cài đặt Portainer — cách làm đúng để không đau đầu sau này

Yêu cầu trước khi cài

  • Docker Engine đã cài (phiên bản 20.10 trở lên)
  • Docker Compose v2 (plugin tích hợp, không phải standalone v1)
  • VPS/server mở port 9443 (HTTPS) hoặc 9000 (HTTP)

Chuẩn bị thư mục và file Compose

Mình luôn cài Portainer bằng Docker Compose — dễ update, dễ backup, dễ migrate hơn chạy docker run thuần túy. Một điểm cần lưu ý: dùng docker compose (v2, không có dấu gạch ngang), không phải docker-compose cũ. Nhanh hơn, tích hợp tốt hơn với Docker Engine hiện đại, và docker-compose v1 đã chính thức end-of-life từ tháng 7/2023.

mkdir -p /opt/portainer && cd /opt/portainer

Tạo file compose.yml với nội dung sau:

services:
  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    restart: unless-stopped
    ports:
      - "9443:9443"
      - "8000:8000"   # tunnel agent (tùy chọn)
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data

volumes:
  portainer_data:

Khởi chạy Portainer

docker compose up -d

Kiểm tra container đã chạy chưa:

docker compose ps

Khoảng 10–15 giây sau, truy cập https://<IP-server>:9443 từ browser. Lần đầu sẽ thấy form tạo tài khoản admin — điền thông tin và đăng nhập.

Lưu ý: Portainer dùng self-signed certificate — browser sẽ cảnh báo không tin tưởng. Bạn có thể bấm “Advanced → Proceed” để bỏ qua, hoặc cấu hình reverse proxy với Let’s Encrypt sau (khuyến nghị cho production).

Bảo mật ban đầu — đừng bỏ qua bước này

Sau khi tạo tài khoản admin, làm ngay mấy việc sau trước khi dùng:

  1. Đặt mật khẩu đủ mạnh — ít nhất 12 ký tự, có số và ký tự đặc biệt.
  2. Tắt quyền truy cập không cần thiết: Settings → Authentication → tắt “Allow non-admin users to access the local environment” nếu chỉ có bạn dùng.
  3. Giới hạn IP bằng firewall: Chỉ cho IP của bạn truy cập port 9443.
# Chỉ cho IP cụ thể truy cập Portainer
ufw allow from 203.0.113.10 to any port 9443
ufw deny 9443
ufw reload

Tips thực chiến sau khi cài xong

Quản lý Docker Compose stack từ UI

Tính năng mình dùng nhiều nhất. Vào Stacks → Add stack, paste nội dung compose.yml của service muốn deploy — Portainer sẽ quản lý nó như một unit. Khi cần update image mới, bấm “Pull and redeploy” là xong. Không cần SSH vào server, không cần nhớ lệnh.

Xem logs real-time không cần nhớ tên container

Click vào container → tab Logs → tick “Auto-refresh logs”. Tiện hơn nhiều so với gõ docker logs -f --tail 100 ten-container-rat-dai mỗi lần debug.

Exec vào container từ browser

Container → tab Console → Connect. Terminal mở ngay trong browser, không cần thêm cửa sổ SSH. Hữu ích khi cần kiểm tra nhanh file config bên trong container mà không muốn mở thêm session.

Backup volume dễ hơn

Vào Volumes, bạn thấy rõ volume nào đang được dùng bởi container nào. Script backup volume nhanh:

# Backup volume portainer_data ra file tar
docker run --rm \
  -v portainer_data:/source \
  -v /backup:/dest \
  alpine tar czf /dest/portainer_data_$(date +%Y%m%d).tar.gz -C /source .

Update Portainer không mất dữ liệu

Vì cài bằng Compose và dữ liệu lưu trong named volume, update rất an toàn:

cd /opt/portainer
docker compose pull
docker compose up -d

Cấu hình reverse proxy với Nginx cho production

Server đã có Nginx? Nên đặt Portainer sau reverse proxy để dùng HTTPS thật thay vì self-signed certificate:

server {
    listen 443 ssl;
    server_name portainer.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/portainer.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/portainer.yourdomain.com/privkey.pem;

    location / {
        proxy_pass https://localhost:9443;
        proxy_ssl_verify off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Sau đó bỏ phần ports trong compose.yml — port 9443 sẽ không expose ra ngoài nữa, chỉ Nginx nội bộ kết nối được.

Khi nào không nên dùng Portainer

Portainer không phải câu trả lời cho tất cả. Vài trường hợp nên cân nhắc kỹ:

  • Môi trường CI/CD tự động: Pipeline deploy không cần UI — dùng CLI hoặc Docker API trực tiếp đơn giản hơn và ít phụ thuộc hơn.
  • Server có yêu cầu bảo mật cao: Mount /var/run/docker.sock cho Portainer container nghĩa là Portainer có quyền root trên host. Môi trường production nghiêm ngặt nên dùng Portainer Agent thay vì mount socket trực tiếp.
  • Kubernetes cluster: Portainer hỗ trợ K8s nhưng Lens hoặc k9s phù hợp hơn cho môi trường Kubernetes thuần.

Với VPS cá nhân hoặc team nhỏ chạy standalone Docker, Portainer là lựa chọn đáng cài nhất. Đầu tư một buổi thiết lập, đổi lại là không còn phải gõ lệnh dài mỗi ngày — mình thấy đó là deal khá tốt.

Share: