Chuyển đến nội dung chính

Hướng Dẫn Docker Compose: Đơn Giản Hóa Phát Triển Ứng Dụng Nhiều Container

Làm chủ Docker Compose để phát triển ứng dụng nhiều container hiệu quả. Tìm hiểu thực hành tốt nhất, mở rộng, điều phối và ví dụ thực tế.
Đã cập nhật 5 thg 10, 2026

Khám phá cùng AI

ChatGPTClaudePerplexity

Docker Compose đơn giản hóa việc quản lý các ứng dụng Docker nhiều container, giúp nhà phát triển viết và chạy ứng dụng phức tạp một cách nhẹ nhàng.

Các kỹ sư DevOps tầm trung, lập trình viên backend và nhà phát triển cloud-native, đặc biệt là những người làm việc với microservices hoặc kiến trúc đa dịch vụ, thường đối mặt với thách thức quản lý vô số container liên kết với nhau. Docker Compose giải quyết các phức tạp này, tinh gọn quy trình phát triển và kiểm thử. 

Trong bài viết này, bạn sẽ học mọi thứ cần thiết để sử dụng Docker Compose. Nếu bạn mới bắt đầu với Docker, hãy xem Hướng dẫn Docker cho Người Mới Bắt Đầu. 

Docker Compose là gì?

Docker Compose là công cụ được thiết kế để định nghĩa và điều phối các ứng dụng Docker nhiều container thông qua một tệp cấu hình YAML duy nhất. 

Với Compose, bạn có thể dễ dàng chỉ định services, networks, volumes, thiết lập môi trường và các phụ thuộc. Nó lý tưởng cho phát triển cục bộ, môi trường kiểm thử, tạo mẫu nhanh và các môi trường sản xuất nhỏ.

Các trường hợp sử dụng phổ biến của Docker Compose bao gồm tạo môi trường cục bộ phản chiếu hệ thống thực tế, như kiến trúc microservices. Bằng cách định nghĩa rõ ràng cách các thành phần tương tác, Compose mang lại tính nhất quán, dễ sử dụng và chu kỳ lặp nhanh hơn.

Bạn có thể thắc mắc vì sao không dùng Kubernetes. Trước hết, đó là giải pháp quá mức cần thiết cho các dự án nhỏ và kiểm thử cục bộ. Như bạn sẽ thấy trong hướng dẫn Kubernetes vs. Docker, Kubernetes phù hợp hơn để quản lý nhiều container trên các cụm. Khóa học Containerization and Virtualization with Docker and Kubernetes của chúng tôi đi sâu vào cách xây dựng và triển khai ứng dụng với Docker và Kubernetes. 

Vì sao sử dụng Docker Compose thay vì lệnh Docker thủ công?

Quản lý riêng lẻ nhiều container có thể nhanh chóng trở nên hỗn loạn do:

  • Thứ tự phụ thuộc phức tạp, 
  • Môi trường không nhất quán, và 
  • Vấn đề khả năng mở rộng. 

Với các lệnh thủ công, bạn có nguy cơ mắc lỗi do con người, trôi cấu hình và quy trình làm việc kém hiệu quả. 

Docker Compose giúp giải quyết những vấn đề này bằng cách định nghĩa tất cả dịch vụ ứng dụng và phụ thuộc trong một tệp YAML. Điều này mang lại tính nhất quán, khả năng mở rộng và quản lý phụ thuộc dễ dàng, giảm đáng kể sai sót và nâng cao năng suất.

Compose nhanh hơn so với tạo container và kết nối chúng thủ công. Hơn nữa, Compose tạo một mạng mặc định cho việc giao tiếp giữa tất cả container. Ngoài ra, nó quản lý volumes, đảm bảo tự động gắn lại khi thay thế dịch vụ hoặc khởi động lại. 

Bạn có thể học cách đóng gói (containerize) ứng dụng học máy với Docker và Kubernetes trong hướng dẫn Cách Đóng Gói Ứng Dụng Bằng Docker. 

Sự khác nhau giữa Docker và Docker Compose là gì?

Trong khi Docker là nền tảng để xây dựng, chạy và quản lý container, Docker Compose là công cụ giúp dễ dàng định nghĩa và quản lý nhiều container bằng tệp YAML, chủ yếu là docker-compose.yml. 

Docker xử lý các container đơn lẻ, còn Docker Compose cho phép bạn xếp chúng thành một dịch vụ thống nhất. Ví dụ, một ứng dụng có backend, frontend, cơ sở dữ liệu, bộ nhớ đệm, v.v. 

Bạn có thể xây dựng và chạy container mà không cần Docker Compose. Tuy nhiên, gom mọi thứ vào một tệp docker-compose.yml sẽ giúp quản lý nhiều container dễ dàng hơn. Nó cũng cho phép khởi chạy ứng dụng trong bất kỳ môi trường nào chỉ với một lệnh. 

Hiểu Docker và Docker Compose rất quan trọng để bạn vượt qua các buổi phỏng vấn sắp tới. Hãy sẵn sàng bằng cách khám phá 26 Câu Hỏi Phỏng Vấn Docker Hàng Đầu và Đáp Án cho 2025. 

Những điều căn bản về Docker Compose

Trước khi đi vào chi tiết thực hành, việc hiểu các nguyên tắc cốt lõi và cú pháp của Docker Compose là cần thiết. Trước khi dùng Compose, hãy đảm bảo bạn đã cài Docker theo hướng dẫn trong Cài Đặt Docker trên Ubuntu: Từ Thiết Lập đến Container Đầu Tiên. 

Khung khái niệm

Docker Compose trừu tượng hóa sự phức tạp của điều phối container cho phát triển cục bộ và các triển khai đơn giản hơn. Với tệp Compose định dạng YAML, bạn khai báo các dịch vụ cần thiết, định nghĩa phụ thuộc, chỉ định networks, volumes, biến môi trường và nhiều hơn nữa. Compose quản lý hiệu quả việc khởi động, dừng, mở rộng và kết nối các dịch vụ này.

Cú pháp Compose cốt lõi

Docker Compose xoay quanh cú pháp YAML đơn giản. Các thành phần chính gồm:

  • services để định nghĩa các ứng dụng đóng gói trong container
  • images hoặc ngữ cảnh build để chỉ định container
  • ports để xuất dịch vụ
  • volumes để lưu trữ dữ liệu bền vững
  • networks để giao tiếp giữa các dịch vụ

Định nghĩa Dịch vụ và Kiến trúc Ứng dụng

Các tệp Compose biểu diễn các dịch vụ của ứng dụng và kết nối giữa chúng.

Định nghĩa services

Services là lõi của tệp Compose. Bạn có thể định nghĩa rõ ràng và đặt tên nhiều dịch vụ (như frontend web, cơ sở dữ liệu, dịch vụ bộ nhớ đệm), chỉ định phụ thuộc qua các từ khóa đơn giản như depends_on để kiểm soát thứ tự khởi động container.

Kiến thức cơ bản về mạng

Docker Compose tự động tạo các mạng mặc định để hỗ trợ giao tiếp giữa những dịch vụ được định nghĩa. Nhà phát triển cũng có thể chỉ định mạng tùy chỉnh khi cần để tăng cô lập hoặc đáp ứng yêu cầu mạng chi tiết.

Quản lý volumes

Volumes cho phép dữ liệu tồn tại vượt ngoài vòng đời container. Bạn có thể chỉ định volumes có tên hoặc gắn thư mục từ host vào container, đảm bảo cơ sở dữ liệu, log hoặc dữ liệu trạng thái khác được lưu bền vững.

Biến môi trường

Compose đơn giản hóa việc truyền biến môi trường và bí mật vào container một cách an toàn. Nó hỗ trợ khai báo trực tiếp dưới các dịch vụ và tham chiếu các biến được lưu trong tệp env bên cạnh tệp compose để giữ an toàn và tách biệt các giá trị nhạy cảm khỏi định nghĩa Docker.

Mở Rộng và Điều Phối với Docker Compose

Docker Compose cũng tinh gọn việc mở rộng và điều phối cơ bản, đặc biệt hữu ích cho các kịch bản kiểm thử tải nhanh hoặc đánh giá dịch vụ song song.

Mở rộng services

Cờ "--scale" của Compose cho phép bạn nhanh chóng khởi chạy nhiều bản sao của dịch vụ. Điều này giúp các kịch bản kiểm thử như đánh giá cân bằng tải hoặc xử lý yêu cầu đồng thời trở nên đơn giản.

Ví dụ, mở rộng container ứng dụng Flask chỉ với một lệnh:

docker-compose up --scale flaskapp=4

Docker Compose so với Docker Swarm và Kubernetes

Trong khi Docker Compose vượt trội ở phát triển cục bộ và thiết lập quy mô nhỏ, nó bị hạn chế trong điều phối đa host ở quy mô sản xuất. Với các kịch bản phức tạp ở quy mô sản xuất trên nhiều host, những bộ điều phối mạnh mẽ hơn như Docker Swarm hoặc Kubernetes là phù hợp, vì chúng cung cấp cân bằng tải mạnh mẽ, tự phục hồi, mạng nâng cao và khả năng mở rộng lớn mà Compose không có.

Bài viết Docker Compose vs. Kubernetes của chúng tôi phân tích chi tiết hơn các khác biệt chính giữa Docker Compose và Kubernetes.  

Tính năng

Docker Compose

Docker Swarm

Kubernetes

Trường hợp sử dụng chính

Phát triển cục bộ, ứng dụng nhiều container đơn giản

Cụm sản xuất nhỏ đến vừa

Điều phối ở quy mô lớn, cấp độ sản xuất

Hỗ trợ đa host

Không hỗ trợ

Tích hợp sẵn

Hỗ trợ gốc

Khả năng mở rộng

Chỉ mở rộng thủ công

Vừa phải, với clustering tích hợp

Cao, thiết kế cho khối lượng lớn

Cân bằng tải

Không có bộ cân bằng tải tích hợp

Định tuyến nội bộ với cân bằng tải

Khám phá dịch vụ và cân bằng tải nâng cao

Tự phục hồi

Không tự phục hồi

Khởi động lại khi lỗi ở mức cơ bản

Tự khôi phục nâng cao và cập nhật cuốn chiếu

Mạng

Mạng bridge cơ bản

Mạng overlay giữa các node

Mô hình mạng phong phú (CNI)

Độ khó học

Dễ học

Độ phức tạp vừa phải

Cao, với nhiều thành phần và cấu hình

Tích hợp hệ sinh thái

Công cụ hạn chế

Công cụ CLI/GUI ở mức vừa

Hệ sinh thái phong phú (Helm, operators, v.v.)

Tài nguyên tiêu tốn

Tối thiểu

Nhẹ

Nặng hơn, cần nhiều tài nguyên hệ thống

Quản lý trạng thái

Không có nhận biết trạng thái tích hợp

Cơ bản qua Raft

Khai báo, quản lý trạng thái đầy đủ

Kiểu triển khai

Dựa trên YAML (docker-compose.yml)

YAML + CLI

YAML (Deployment, Service, v.v.)

Phù hợp nhất cho

Máy dev, pipeline CI, demo nhanh

Nhóm nhỏ, dịch vụ đơn giản trong prod

Ứng dụng phức tạp, microservices, hạ tầng doanh nghiệp

Kỹ Thuật Tối Ưu để Sử Dụng Compose Hiệu Quả

Sử dụng Docker Compose hiệu quả bao gồm tối ưu hóa quá trình build, thêm health check và quản lý tài nguyên dịch vụ. Phần này sẽ giúp bạn hiểu rõ hơn các kỹ thuật tối ưu này.

Chiến lược build hiệu quả

Sử dụng build nhiều giai đoạn trong Dockerfile giúp giảm kích thước image Docker, trong khi tận dụng cache build một cách rõ ràng sẽ tăng tốc đáng kể quá trình phát triển và CI.

Health check và chính sách khởi động lại

Compose cho phép bạn định nghĩa health check rõ ràng cho container để duy trì độ tin cậy của ứng dụng. Các chính sách khởi động lại giúp đảm bảo container lỗi sẽ tự động khởi động lại, tăng khả năng chống chịu.

Quản lý giới hạn tài nguyên

Thiết lập giới hạn CPU và bộ nhớ trực tiếp trong YAML của Compose giúp bạn kiểm soát phân bổ tài nguyên, tăng tính dự đoán và hiệu suất sử dụng tài nguyên.

Ví dụ đoạn cấu hình giới hạn tài nguyên:

services:
  flaskapp:
    image: flask
    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: 512M

Ví Dụ Thực Tiễn: Ứng Dụng Nhiều Container

Dưới đây là một ví dụ thực tế đơn giản gồm ứng dụng Python Flask kết hợp với Redis:

services:
  redis:
    image: redis:7
    container_name: redis
    ports:
      - "6379:6379"
    restart: always
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 30s
      timeout: 5s
      retries: 3
  web:
    build: .
    container_name: flask_app
    command: gunicorn app:app --worker-class gevent --bind 0.0.0.0:5000 --timeout 3000
    ports:
      - "5000:5000"
    depends_on:
      - redis
    environment:
      - REDIS_URL=redis://redis:6379/0
    env_file:
      - .env
    volumes:
      - ./shorts:/app/shorts
      - ./temp_uploads:/app/temp_uploads
      - ./uploads:/app/uploads
    restart: always

  worker:
    build: .
    container_name: celery_worker
    command: celery -A celery_worker.celery worker --loglevel=info
    depends_on:
      - redis
    environment:
      - REDIS_URL=redis://redis:6379/0
    env_file:
      - .env
    volumes:
      - ./shorts:/app/shorts
      - ./temp_uploads:/app/temp_uploads
      - ./uploads:/app/uploads
    restart: always

Tệp Docker Compose định nghĩa một ứng dụng nhiều container với ba dịch vụ:

  1. redis
  2. web (ứng dụng Flask với Gunicorn)
  3. worker (Celery worker)

Đối với dịch vụ redis:

  • Sử dụng image Redis 7 chính thức.
  • Đặt tên container là redis.
  • Ánh xạ cổng 6379 trong container sang 6379 trên host.
  • Luôn khởi động lại nếu gặp sự cố (restart: always).
  • Định nghĩa healthcheck chạy lệnh ping của redis-cli mỗi 30 giây, timeout sau 5 giây và thử lại 3 lần trước khi đánh dấu container không khỏe.

Đối với dịch vụ web:

  • Build image từ thư mục hiện tại (build: .).
  • Đặt tên container là flask_app.
  • Chạy lệnh gunicorn app:app với worker gevent, bind 0.0.0.0:5000, timeout dài 3000 giây
  • Ánh xạ cổng 5000 của container sang 5000 trên host.
  • Khai báo phụ thuộc vào dịch vụ redis, đảm bảo Redis khởi động trước.
  • Thiết lập biến môi trường REDIS_URL trỏ đến container Redis nội bộ.
  • Nạp thêm biến môi trường từ tệp .env.
  • Gắn ba thư mục cục bộ vào container:
    • ./shorts vào /app/shorts,
    • ./temp_uploads vào /app/temp_uploads 
    • ./uploads vào /app/uploads
  • Cấu hình luôn khởi động lại nếu gặp sự cố.

Đối với dịch vụ worker:

  • Cũng build image từ thư mục hiện tại (build: .), dùng lại cùng Dockerfile với dịch vụ web.
  • Đặt tên container: celery_worker.
  • Chạy lệnh celery -A celery_worker.celery worker --loglevel=info để khởi động Celery worker xử lý tác vụ nền.
  • Khai báo phụ thuộc vào dịch vụ redis, đảm bảo Redis khởi động trước.
  • Thiết lập cùng biến môi trường REDIS_URL để kết nối tới broker Redis.
  • Nạp các biến môi trường khác từ tệp .env.
  • Gắn cùng ba thư mục như dịch vụ web, cho phép cả ứng dụng web và worker chia sẻ tệp và nội dung tải lên.
  • Cấu hình luôn khởi động lại nếu gặp sự cố.

Khám phá thêm ý tưởng dự án Docker trong hướng dẫn 10 Ý Tưởng Dự Án Docker của chúng tôi. 

Xây Dựng và Chạy Ứng Dụng Nhiều Container

Docker Compose cung cấp bộ công cụ trực quan cho các tác vụ container thường nhật:

Build images

Dùng docker compose build để tạo images theo Dockerfile bạn định nghĩa. Chúng tôi trình bày thêm về xây dựng Docker image trong hướng dẫn Cách Học Docker Từ Con Số 0: Hướng Dẫn Cho Chuyên Gia Dữ Liệu. 

Chạy services

Sử dụng docker compose up  để khởi chạy tất cả dịch vụ được định nghĩa trong tệp compose. Để chạy nền, dùng docker compose up -d. Khóa học Introduction to Docker của chúng tôi đi sâu hơn về chạy container ở chế độ nền. 

Xem container đang chạy

Để xem các container đang hoạt động và trạng thái của chúng, dùng docker compose ps để liệt kê tất cả dịch vụ đang chạy.

Dừng services

Dùng docker compose down để dừng các dịch vụ đang chạy. 

Xem log

Dùng docker compose logs để kiểm tra log. Bạn có thể chỉ định một container để xem log bằng docker logs container_name. Để stream log, dùng docker compose -f container_name. 

Hướng dẫn 18 Lệnh Docker Hàng Đầu để Build, Chạy và Quản Lý Containers của chúng tôi phân tích thêm các lệnh Docker để bạn tự tin quản lý ứng dụng trên nhiều môi trường. 

Các Trường Hợp Nâng Cao với Docker Compose 

Quy trình Compose có thể thích ứng với các thiết lập phát triển phức tạp hơn hoặc cấu hình môi trường khác nhau.

Cấu hình đa môi trường

Nhiều tệp Compose hoặc tệp ghi đè giúp thiết lập các môi trường khác nhau (phát triển, kiểm thử, sản xuất). Điều này giữ cho định nghĩa dễ bảo trì và dễ đọc, cho phép chỉnh sửa nhanh mà không làm rối cấu hình.

Quản lý phụ thuộc

Trong khi depends_on xử lý thứ tự khởi động cơ bản, các kịch bản phức tạp có thể tích hợp script khởi tạo (như "wait-for-it"), đảm bảo container chỉ khởi động sau khi thỏa các điều kiện cụ thể, chẳng hạn cơ sở dữ liệu sẵn sàng.

Tích hợp với CI/CD

Compose tích hợp dễ dàng vào quy trình tích hợp liên tục, tự động hóa thiết lập môi trường hoàn chỉnh cho kiểm thử. Các nền tảng như GitLab CI và GitHub Actions cung cấp cách tiếp cận gốc hoặc đơn giản để tích hợp Compose, tinh gọn kiểm thử tự động.

Thực hành tốt nhất và Thách thức thường gặp

Bạn có thể tránh các lỗi thường gặp và xây dựng cấu hình dễ bảo trì bằng cách tổ chức và cấu trúc định nghĩa Compose một cách cẩn trọng.

Tổ chức Tệp Compose

Giữ cho tệp Compose rõ ràng và mô-đun. Với dự án đơn giản, một tệp là đủ, nhưng với ứng dụng lớn hơn, hãy cân nhắc tách cấu hình thành nhiều tệp Compose bằng tính năng override. Điều này cho phép:

  • Phân tách hợp lý các thành phần (ví dụ, docker-compose.backend.yml, docker-compose.frontend.yml)
  • Tùy biến môi trường cục bộ vs. sản xuất dễ dàng hơn
  • Tinh gọn kiểm soát phiên bản và cộng tác, vì thay đổi đối với một dịch vụ không ảnh hưởng toàn bộ tệp

Dùng tên dịch vụ có ý nghĩa và thụt lề nhất quán để tệp dễ đọc và theo dõi.

Cạm bẫy tiềm ẩn

Lưu ý những sai sót thường gặp sau:

  • Dùng thẻ latest cho images: Điều này gây khó đoán, vì phiên bản image thực tế có thể thay đổi theo thời gian. Luôn ghim phiên bản image rõ ràng (ví dụ, postgres:15.1) để đảm bảo nhất quán giữa các môi trường.
  • Hard-code bí mật: Không bao giờ đưa dữ liệu nhạy cảm (ví dụ, API key, mật khẩu) trực tiếp vào tệp Compose. Thay vào đó, dùng biến môi trường, tệp .env (loại trừ khỏi kiểm soát phiên bản), hoặc công cụ quản lý bí mật như Docker Secrets để xử lý an toàn.
  • Định nghĩa dịch vụ quá phức tạp: Tránh nhồi nhét quá nhiều logic hoặc quá nhiều trách nhiệm vào một container. Tuân thủ nguyên tắc một trách nhiệm, ưu tiên sự đơn giản khi có thể.
  • Bỏ qua cấu hình mạng rõ ràng: Hãy định nghĩa mạng tùy chỉnh trong Compose thay vì phụ thuộc vào hành vi mặc định. Điều này cho phép kiểm soát tốt hơn giao tiếp giữa dịch vụ, giảm xung đột cổng và cải thiện ranh giới bảo mật.

Bằng cách áp dụng các thực hành này, quy trình làm việc dựa trên Compose của bạn sẽ vững chắc hơn, an toàn hơn và dễ bảo trì hơn trong môi trường cộng tác hoặc đang phát triển.

Kết luận

Docker Compose đơn giản hóa đáng kể việc xây dựng, quản lý và vận hành các ứng dụng nhiều container cho nhà phát triển. Định nghĩa rõ ràng dựa trên YAML, điều phối dễ dàng và khả năng mở rộng trực quan khiến nó trở nên vô giá cho các kịch bản phát triển cục bộ và kiến trúc triển khai đơn giản. Mặc dù các bộ điều phối nâng cao như Docker Swarm và Kubernetes phù hợp hơn với khối lượng công việc sản xuất quy mô lớn, Compose vẫn là điểm khởi đầu thiết yếu để hiểu các nguyên lý điều phối container và cải thiện quy trình làm việc của nhà phát triển.

Khám phá các khóa học Docker của chúng tôi để học:

Câu hỏi thường gặp về Docker Compose

Docker Compose khác gì so với Docker Swarm hoặc Kubernetes?

Docker Compose lý tưởng cho phát triển cục bộ và kiểm thử quy mô nhỏ. Với điều phối cấp sản xuất có tính năng như tự mở rộng và tự phục hồi, Docker Swarm và Kubernetes phù hợp hơn.

Docker Compose có quản lý phụ thuộc giữa services không?

Có, Compose cho phép bạn định nghĩa phụ thuộc với chỉ thị depends_on. Các script hỗ trợ bên ngoài như wait-for-it có thể dùng để kiểm soát chính xác hơn, chẳng hạn chờ cơ sở dữ liệu sẵn sàng.

Làm thế nào để quản lý nhiều môi trường bằng Docker Compose?

Bạn có thể dùng nhiều tệp Compose (ví dụ, docker-compose.yml và docker-compose.prod.yml) và ghi đè cấu hình theo môi trường bằng cờ -f khi chạy lệnh.

Docker Compose có hỗ trợ health check và chính sách khởi động lại không?

Có, Docker Compose hỗ trợ health check cho container và chính sách khởi động lại, cho phép bạn tăng độ bền vững của dịch vụ trong phát triển và kiểm thử.


Derrick Mwiti's photo
Author
Derrick Mwiti
Chủ đề
Docker
Kỹ thuật Dữ liệu

Các khóa học hàng đầu trên DataCamp

Lộ trình

Container hóa và ảo hóa với Docker và Kubernetes

13 giờ
Hãy khám phá sức mạnh của Docker và Kubernetes. Khóa học tương tác này sẽ giúp bạn xây dựng và triển khai ứng dụng trong các môi trường hiện đại.
Xem chi tiếtRight Arrow
Bắt Đầu Khóa Học
Xem thêmRight Arrow
Liên quan

blog

Claude Opus 4.6: Tính năng, Điểm chuẩn, Bài kiểm tra thực hành và hơn thế nữa

Mô hình mới nhất của Anthropic dẫn đầu ở mã hóa tác tử và lập luận phức tạp. Thêm vào đó, nó có cửa sổ ngữ cảnh 1M.
Matt Crabtree's photo

Matt Crabtree

10 phút

Xem ThêmXem Thêm