Back to blog

Docker Networks và Volumes Giải Thích Từ Đầu

dockernetworkingdevopscontainerstutorial
Docker Networks và Volumes Giải Thích Từ Đầu

Ở bài trước, bạn thấy rằng Node.js app có thể kết nối PostgreSQL bằng @db:5432 thay vì @localhost:5432. Điều đó hoạt động được nhờ Docker networking. Bạn cũng thấy rằng database data vẫn còn sau khi container restart — đó là nhờ volumes.

Bài này giải thích cả hai — container giao tiếp thế nào, và data được giữ lại như thế nào.


Phần 1: Docker Networks

Docker Network là gì?

Docker tạo ra một mạng ảo để các container có thể giao tiếp với nhau. Mặc định, container bị cô lập — không thể kết nối với nhau trừ khi cùng network.

Khi dùng Docker Compose, tất cả các service tự động được đặt vào một shared network mặc định. Đó là lý do tại sao các service có thể reference nhau bằng tên — không cần địa chỉ IP.

# Liệt kê tất cả network
docker network ls
 
# Xem chi tiết một network
docker network inspect bridge

Các Loại Network Driver

Docker hỗ trợ nhiều network driver cho các use case khác nhau:

DriverMô tả
bridgeMặc định — virtual network riêng biệt trên single host
hostContainer dùng trực tiếp network của host, không có isolation
noneContainer không có network
overlayKết nối container trên nhiều Docker host (Docker Swarm)

Với development local, bridge là thứ bạn sẽ dùng. Docker Compose dùng nó tự động.

Cách Container Giao Tiếp Với Nhau

Khi các container cùng network, chúng kết nối bằng tên container hoặc service như hostname. Docker tự resolve tên thành internal IP — bạn không cần biết IP thực.

# docker-compose.yml
services:
  app:
    build: .
    environment:
      - DATABASE_URL=postgres://admin:secret@db:5432/mydb  # "db" là tên service
    depends_on:
      - db
 
  db:
    image: postgres:16-alpine

Service app kết nối tới db qua hostname db. Docker xử lý DNS resolution nội bộ.

Tạo Network Thủ Công

Với docker run thông thường (không dùng Compose), bạn tự quản lý network:

# Tạo custom network
docker network create my-network
 
# Chạy container trên cùng network
docker run --network my-network --name app my-app
docker run --network my-network --name db postgres:16
 
# Gắn container đang chạy vào network
docker network connect my-network my-container

Custom Network trong Docker Compose

Để kiểm soát chi tiết hơn, bạn có thể định nghĩa explicit network trong Compose và gán service vào từng network cụ thể. Cách này giúp isolate các service khỏi nhau:

services:
  app:
    build: .
    networks:
      - frontend
      - backend
 
  db:
    image: postgres:16-alpine
    networks:
      - backend   # db chỉ nằm trong backend network
 
networks:
  frontend:
  backend:

Ở đây, db chỉ thuộc backend. Nếu bạn thêm một proxy service chỉ thuộc frontend, nó sẽ không thể reach db trực tiếp — một security boundary hữu ích.


Phần 2: Docker Volumes

Tại Sao Cần Volume?

Mặc định, data bên trong container bị mất khi container bị xóa. Container filesystem là ephemeral — nó chỉ tồn tại khi container còn sống.

Volume giải quyết điều này. Volume lưu data ngoài vòng đời của container, được Docker quản lý. Dù bạn xóa và tạo lại container, volume (và data trong đó) vẫn còn.

Volume dùng để lưu:

  • Database data (PostgreSQL, MySQL, MongoDB)
  • Uploaded files
  • Application logs
  • Bất kỳ data nào bạn không thể để mất
# Liệt kê tất cả volume
docker volume ls
 
# Xem chi tiết một volume
docker volume inspect my-volume
 
# Xóa một volume
docker volume rm my-volume
 
# Xóa tất cả volume không còn dùng
docker volume prune

Named Volume

Docker tự quản lý vị trí lưu trữ — bạn chỉ cần đặt tên. Lý tưởng cho data bền vững như database, nơi bạn không cần quan tâm đến path cụ thể trên host.

services:
  db:
    image: postgres:16-alpine
    volumes:
      - db_data:/var/lib/postgresql/data   # named volume
 
volumes:
  db_data:   # khai báo ở đây để Docker tạo và quản lý

Data trong db_data tồn tại sau docker compose down. Chỉ docker compose down -v mới xóa nó.

Bind Mount

Bind mount liên kết một thư mục hoặc file cụ thể từ máy host vào container. Thay đổi trên host được phản ánh ngay lập tức bên trong container — không cần rebuild.

Đây là pattern chuẩn cho development hot-reload:

services:
  app:
    build: .
    volumes:
      - .:/app              # Sync thư mục hiện tại vào /app
      - /app/node_modules   # Giữ nguyên node_modules của container

Dòng thứ hai — /app/node_modules — là một trick phổ biến. Nếu không có nó, bind mount của . sẽ ghi đè node_modules của container bằng của host (có thể không tồn tại hoặc khác nhau). Anonymous volume này đảm bảo container giữ node_modules của chính nó.

Với docker run:

docker run -v $(pwd):/app my-app

So Sánh Named Volume vs Bind Mount

Named VolumeBind Mount
Quản lý bởiDockerBạn
Path trên hostDocker tự quyếtBạn chỉ định
Use caseDatabase, persistent dataDevelopment, sync code
PerformanceTốtTốt (macOS có thể chậm hơn)

Kết Hợp Lại

Đây là Compose file hoàn chỉnh dùng cả custom network lẫn volume:

services:
  app:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - .:/app               # Bind mount cho hot-reload
      - /app/node_modules    # Giữ nguyên node_modules của container
    networks:
      - app-network
 
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: mydb
    volumes:
      - db_data:/var/lib/postgresql/data   # Persist database data
    networks:
      - app-network
 
volumes:
  db_data:
 
networks:
  app-network:
docker compose up -d
 
# Dừng container — data trong db_data volume vẫn còn
docker compose down
 
# Dừng container VÀ xóa volume — data mất luôn
docker compose down -v

Tóm Lại

✅ Docker network cho phép container giao tiếp — isolated mặc định, kết nối được khi cùng network
✅ Docker Compose tự động đặt tất cả service vào một network — kết nối qua tên service, không cần IP
✅ Dùng custom network trong Compose để isolate các service không nên nói chuyện với nhau
✅ Container data là ephemeral — volume giữ data tồn tại ngoài vòng đời container
✅ Named volume do Docker quản lý, lý tưởng cho database và persistent data
✅ Bind mount sync thư mục host vào container — hoàn hảo cho development hot-reload
✅ docker compose down xóa container; docker compose down -v xóa cả volume


Series: Lộ Trình Học Docker & Kubernetes
Previous: Docker Compose Cơ Bản
Next: Docker Networking & Volumes Deep Dive


Muốn đi sâu hơn? Bài tiếp theo cover Docker networking internals, overlay networks, production storage patterns, và nhiều hơn nữa.

📬 Đăng ký nhận bản tin

Nhận những bài viết mới nhất qua email mỗi tuần. Không spam, hủy đăng ký bất cứ lúc nào.

Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất cứ lúc nào.

💬 Comments

Đăng nhập để bình luận

Chúng tôi sẽ không đăng bất cứ điều gì mà không có sự cho phép của bạn.