EQVPS

Cách triển khai một stack Docker Compose trên VPS

Triển khai một stack đa container trên VPS với Docker Compose: viết docker-compose.yml, giữ bí mật trong .env, đưa nó lên với khởi-động-lại-sau-reboot, và chỉ publish những cổng bạn thực sự muốn. Ví dụ sao chép-dán với một web app, cơ sở dữ liệu và reverse proxy.

Docker Compose mô tả một stack đa container trong một file và chạy nó bằng một lệnh. Đây là hướng dẫn triển khai; trước tiên hãy cài Docker nếu bạn chưa. Về một stack chuyên cho agent AI (agent + vector DB + Redis), xem docker-compose cho agent AI.

1. Một stack: app + cơ sở dữ liệu + reverse proxy

# /opt/stack/docker-compose.yml
services:
  app:
    image: your/app:latest
    restart: unless-stopped
    env_file: [.env]
    depends_on: [db]
    # no ports: — reached only through the proxy below

  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes: ["pg:/var/lib/postgresql/data"]   # internal only

  caddy:                                        # HTTPS automatically
    image: caddy:2
    restart: unless-stopped
    ports: ["80:80", "443:443"]                 # the only public entrypoint
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data

volumes: { pg: {}, caddy_data: {} }

Bí mật sống trong .env, không bao giờ trong file compose:

# /opt/stack/.env  (chmod 600, git-ignored)
DB_PASSWORD=a-long-random-string

Một Caddyfile tối giản proxy tên miền của bạn tới app và tự lấy HTTPS:

app.yourdomain.com {
  reverse_proxy app:8080
}

2. Đưa nó lên

cd /opt/stack
docker compose up -d
docker compose ps
docker compose logs -f app

restart: unless-stopped trên mỗi dịch vụ + Docker bật lúc boot = stack tự trở lại sau một reboot.

3. Lệnh hằng ngày

docker compose pull && docker compose up -d   # update images
docker compose down                            # stop the stack
docker compose restart app                     # restart one service

Phần người ta hay làm sai: cổng bị phơi bày

Docker publish cổng qua iptables, nên một container với ports: ["5432:5432"] có thể truy cập được từ internet ngay cả sau một tường lửa UFW bạn tưởng đã đóng. Chỉ publish duy nhất điểm vào công khai (proxy trên 80/443); giữ cơ sở dữ liệu và cache trên mạng compose hoặc ràng buộc vào 127.0.0.1. Bất cứ thứ gì phục vụ lưu lượng web đều cần một gói IP riêng; ghép với một tường lửa UFW.

Về cả một stack sau một IP, xem tự lưu trữ nhiều dịch vụ. Root trong khoảng một phút, NVMe, không KYC, thanh toán bằng crypto.

FAQ

Làm sao triển khai một stack Docker Compose trên VPS?

Cài Docker với plugin Compose, viết một docker-compose.yml mô tả từng dịch vụ, giữ bí mật trong một .env bị git bỏ qua, rồi docker compose up -d. Đặt restart: unless-stopped trên mỗi dịch vụ và bật Docker lúc boot để stack sống sót qua reboot. Ví dụ dưới đây chạy một web app, Postgres và một reverse proxy Caddy.

Bí mật để ở đâu — trong file compose?

Không. Để chúng trong một file .env (chmod 600, bị git bỏ qua) và tham chiếu là ${VAR} trong compose, hoặc dùng Docker secrets. Đừng bao giờ commit mật khẩu hay khóa API vào docker-compose.yml — một file lộ với thông tin đăng nhập còn hiệu lực là lỗi kinh điển.

Stack có trở lại sau một reboot không?

Chỉ khi bạn bảo nó. Đặt restart: unless-stopped (hoặc always) trên mỗi dịch vụ và bật Docker lúc boot (systemctl enable docker). Khi đó docker compose up -d sống sót qua reboot và khởi động lại các container bị crash.

Những cổng nào bị phơi bày?

Chỉ những gì bạn publish với ports:. Ràng buộc các dịch vụ nội bộ (cơ sở dữ liệu, cache) vào mạng compose hoặc 127.0.0.1 và chỉ publish điểm vào công khai — thường là một reverse proxy trên 80/443. Docker publish qua iptables, nên một dòng ports: vô tình có thể truy cập được từ internet ngay cả sau UFW.

Bạn có yêu cầu giấy tờ hay thẻ không?

Không. Một email để đăng ký, thanh toán bằng USDC hoặc USDT — không giấy tờ, không thẻ. Root trong khoảng một phút.

Bình luận

Chưa có bình luận nào. Hãy là người đầu tiên.

Để lại bình luận

Bình luận được kiểm duyệt trước khi hiển thị.