Docker Compose là gì?

Nếu ứng dụng Docker của bạn bao gồm nhiều hơn một container (ví dụ: máy chủ web và cơ sở dữ liệu chạy trong các container riêng biệt), việc xây dựng, chạy và kết nối các container từ các Dockerfile riêng biệt rất cồng kềnh và tốn thời gian. Docker Compose giải quyết vấn đề này bằng cách cho phép bạn sử dụng tệp YAML để xác định các ứng dụng đa container . Bạn có thể định cấu hình nhiều container tùy ý, cách chúng nên được xây dựng và kết nối, cũng như nơi lưu trữ dữ liệu. Khi tệp YAML hoàn tất, bạn có thể chạy một lệnh duy nhất để xây dựng, chạy và định cấu hình tất cả các container.

Hướng dẫn này sẽ giải thích cách docker-compose.ymlsắp xếp tệp và cách sử dụng tệp để tạo một số cấu hình ứng dụng cơ bản.

Ghi chú: Nhìn chung, các container trong ứng dụng được xây dựng bằng Docker Compose sẽ chạy trên cùng một máy chủ. Việc quản lý các container chạy trên các máy chủ khác nhau thường yêu cầu một công cụ bổ sung, chẳng hạn như Docker Swarm hoặc Kubernetes .

Trước khi bạn bắt đầu

Cài đặt Docker CE

Bạn sẽ cần một Linode đã cài đặt Docker CE để làm theo các bước trong hướng dẫn này.

Để cài đặt Docker CE (Phiên bản cộng đồng), hãy làm theo hướng dẫn trong một trong các hướng dẫn dưới đây:

Để xem hướng dẫn cài đặt cho các bản phân phối Linux hoặc hệ điều hành khác như Mac hoặc Windows, hãy tham khảo tài liệu chính thức của Docker tại đây: Cài đặt Docker Engine

Cài đặt Docker Compose

Docker Compose có sẵn trong các biến thể plugin và độc lập. Tuy nhiên, tài liệu chính thức của Docker ưu tiên plugin. Hơn nữa, plugin có cài đặt đơn giản và hoạt động tốt với các lệnh Docker Compose trước đây.

Các bước này cho thấy cách cài đặt plugin Docker Compose. Nếu bạn quan tâm đến việc cài đặt ứng dụng Docker Compose độc ​​lập, hãy làm theo hướng dẫn cài đặt chính thức của Docker .

Ghi chú

Nhiều hướng dẫn vẫn giữ nguyên định dạng lệnh độc lập Docker Compose, trông như sau:

docker-compose [command]

Hãy đảm bảo thay thế lệnh này bằng định dạng lệnh của plugin khi sử dụng phương pháp cài đặt này. Điều này thường chỉ có nghĩa là thay thế dấu gạch nối bằng một khoảng trắng, như trong:

docker compose [command]

1.Bật kho lưu trữ Docker cho trình quản lý gói của hệ thống. Kho lưu trữ thường đã được bật sau khi bạn cài đặt công cụ Docker. Hãy làm theo hướng dẫn liên quan của chúng tôi về cách cài đặt Docker để bật kho lưu trữ trên hệ thống của bạn.

2.Cập nhật trình quản lý gói của bạn và cài đặt plugin Docker Compose.

Trên hệ thống Debian và Ubuntu , hãy sử dụng các lệnh sau:

sudo apt update
sudo apt install docker-compose-plugin

Trên CentOS , Fedora và các bản phân phối dựa trên RPM khác, hãy sử dụng các lệnh sau:

sudo yum update
sudo yum install docker-compose-plugin

Cách sử dụng cơ bản

Phần này sẽ xem xét một ví dụ về tệp Docker Compose được lấy từ tài liệu chính thức của Docker .

1.Mở docker-compose.ymltrong trình soạn thảo văn bản và thêm nội dung sau:

version: '3'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data:

2.Lưu tệp và chạy Docker Compose từ cùng thư mục:

docker-compose up -d

Điều này sẽ xây dựng và chạy các container dbvà wordpress. Giống như khi chạy một container duy nhất với docker run-dcờ sẽ khởi động các container ở chế độ tách biệt.

Bây giờ bạn có một container WordPress và container MySQL đang chạy trên máy chủ của mình. Điều hướng đến 192.0.8.1:8000/wordpresstrong trình duyệt web để xem ứng dụng WordPress mới cài đặt của bạn. Bạn cũng có thể sử dụng docker psđể khám phá thêm cấu hình kết quả:

docker ps

4.Dừng lại và loại bỏ các thùng chứa:

docker-compose down

Soạn thảo cú pháp tập tin

Một docker-compose.ymltập tin được sắp xếp thành bốn phần:

Chỉ thịSử dụng
phiên bảnChỉ định phiên bản cú pháp tệp Compose. Hướng dẫn này sẽ sử dụng Phiên bản 3 trong suốt quá trình.
dịch vụTrong Docker, dịch vụ là tên gọi của “Container in production” . Phần này định nghĩa các container sẽ được khởi động như một phần của phiên bản Docker Compose.
mạng lướiPhần này được sử dụng để cấu hình mạng cho ứng dụng của bạn. Bạn có thể thay đổi cài đặt của mạng mặc định, kết nối với mạng bên ngoài hoặc xác định mạng dành riêng cho ứng dụng.
khối lượngGắn đường dẫn được liên kết trên máy chủ mà container có thể sử dụng.

Phần lớn hướng dẫn này sẽ tập trung vào việc thiết lập container bằng cách sử dụng servicesphần này. Sau đây là một số chỉ thị phổ biến được sử dụng để thiết lập và cấu hình container:

Chỉ thịSử dụng
imageĐặt hình ảnh sẽ được sử dụng để xây dựng container. Sử dụng chỉ thị này giả định rằng hình ảnh được chỉ định đã tồn tại trên máy chủ hoặc trên Docker Hub .
buildCó thể sử dụng lệnh này thay cho image. Chỉ định vị trí của Dockerfile sẽ được sử dụng để xây dựng container này.
dbTrong trường hợp tệp Dockercompose ví dụ, dblà một biến cho vùng chứa mà bạn sắp xác định.
restartYêu cầu container khởi động lại nếu hệ thống khởi động lại.
volumesGắn một đường dẫn được liên kết trên máy chủ có thể được container sử dụng
environmentXác định các biến môi trường sẽ được truyền vào lệnh chạy Docker.
depends_onĐặt một dịch vụ làm phụ thuộc cho vùng chứa được xác định theo khối hiện tại
portÁnh xạ một cổng từ container tới máy chủ theo cách sau:host:container
linksLiên kết dịch vụ này với bất kỳ dịch vụ nào khác trong tệp Docker Compose bằng cách chỉ định tên của chúng tại đây.

Có nhiều chỉ thị cấu hình khác. Xem tham chiếu Compose File để biết chi tiết.

Quan trọng: Ví dụ docker-compose.ymltrên sử dụng environmentchỉ thị để lưu trữ mật khẩu người dùng MySQL trực tiếp trong tệp YAML để nhập vào vùng chứa dưới dạng biến môi trường. Điều này không được khuyến khích đối với thông tin nhạy cảm trong môi trường sản xuất. Thay vào đó, thông tin nhạy cảm có thể được lưu trữ trong một .envtệp riêng (không được kiểm tra trong kiểm soát phiên bản hoặc công khai) và truy cập từ bên trong docker-compose.ymlbằng cách sử dụng env_filechỉ thị.

Xây dựng một ứng dụng từ đầu

Tạo một docker-compose.ymltệp theo từng phần để minh họa các bước xây dựng ứng dụng đa vùng chứa.

Định nghĩa một dịch vụ đơn giản:

1.Tạo một mục mới docker-compose.ymltrong trình soạn thảo văn bản và thêm nội dung sau:

version: '3'

services:
  distro:
    image: alpine
    restart: always
    container_name: Alpine_Distro
    entrypoint: tail -f /dev/null

Mỗi mục trong servicesphần sẽ tạo một vùng chứa riêng khi docker-composechạy. Tại thời điểm này, phần chứa một vùng chứa duy nhất dựa trên bản phân phối Alpine chính thức:

  • Chỉ thị này restartđược sử dụng để chỉ ra rằng container phải luôn khởi động lại (ví dụ như sau khi gặp sự cố hoặc khởi động lại hệ thống).
  • Chỉ thị này container_nameđược sử dụng để ghi đè tên vùng chứa được tạo ngẫu nhiên và thay thế bằng tên dễ nhớ và dễ làm việc hơn.
  • Các container Docker thoát theo mặc định nếu không có tiến trình nào đang chạy trên chúng. tail -flà một tiến trình đang diễn ra, vì vậy nó sẽ chạy vô thời hạn và ngăn container dừng lại. Mặc định entrypointbị ghi đè để container tiếp tục chạy.

2.Đưa thùng chứa của bạn lên:

docker-compose up -d

3.Kiểm tra trạng thái container của bạn:

docker ps

Đầu ra sẽ giống như sau:

CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS              PORTS               NAMES
967013c36a27        alpine              "tail -f /dev/null"   3 seconds ago       Up 

4.Đem thùng chứa xuống:

docker-compose down

Thêm dịch vụ bổ sung

Từ đây, bạn có thể bắt đầu xây dựng hệ sinh thái container. Bạn có thể xác định cách chúng hoạt động cùng nhau và giao tiếp.

1.Mở lại docker-compos.ymlvà thêm databasedịch vụ bên dưới:

version: '3'

services:
  distro:
    image: alpine
    container_name: Alpine_Distro
    restart: always
    entrypoint: tail -f /dev/null

  database:
    image: postgres:latest
    container_name: postgres_db
    volumes:
      - ../dumps:/tmp/
    ports:
      - "5432:5432"

Hiện nay có hai dịch vụ được xác định:

  • Phân phối
  • Cơ sở dữ liệu

Dịch vụ Distro giống như trước. Máy chủ cơ sở dữ liệu chứa các hướng dẫn cho một container postgres và các chỉ thị: volumes: - ../dumps:/tmpvà ports:-"5432:5432", chỉ thị đầu tiên ánh xạ /dumpsthư mục containerd vào thư mục cục bộ của chúng tôi /tmp. Chỉ thị thứ hai ánh xạ các cổng container vào các cổng của máy chủ cục bộ.

2.Kiểm tra các container đang chạy:

docker ps

Lệnh này hiển thị trạng thái của các container, ánh xạ cổng, tên và lệnh cuối cùng đang chạy trên chúng. Điều quan trọng cần lưu ý là container postgres đọc “docker-entrypoint…” bên dưới các lệnh. Tập lệnh Postgres Docker Entrypoint là thứ cuối cùng khởi chạy khi container khởi động.

CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                    NAMES
ecc37246f6ef        postgres:latest     "docker-entrypoint..."   About a minute ago   Up About a minute   0.0.0.0:5432->5432/tcp   postgres_db
35dab3e712d6        alpine              "tail -f /dev/null"      About a minute ago 

3.Đem cả hai thùng chứa xuống:

docker-compose down

Thêm dịch vụ nginx

1.Thêm một container nginx để ứng dụng của bạn có thể phục vụ các trang web:

version: '3'

services:
  distro:
    image: alpine
    container_name: Alpine_Distro
    restart: always
    entrypoint: tail -f /dev/null

  database:
    image: postgres:latest
    container_name: postgres_db
    volumes:
      - ../dumps:/tmp/
    ports:
      - "5432:5432"
  web:
    image: nginx:latest
    container_name: nginx
    volumes:
      - ./mysite.template:/etc/nginx/conf.d/mysite.template
    ports:
      - "8080:80"
    environment:
      - NGINX_HOST=example.com
      - NGINX_port=80
    links:
      - database:db
      - distro

Tệp này docker-composechứa một số chỉ thị mới: environment và links . Chỉ thị đầu tiên thiết lập các tùy chọn mức thời gian chạy trong vùng chứa. linkstạo một mạng lưới phụ thuộc giữa các vùng chứa. Vùng chứa nginx phụ thuộc vào hai vùng chứa kia để thực thi. Ngoài ra, các vùng chứa tương ứng sẽ có thể truy cập được tại tên máy chủ được chỉ định bởi bí danh. Trong trường hợp này, lệnh ping dbtừ webvùng chứa sẽ truy cập được databasedịch vụ. Mặc dù bạn không cần linkschỉ thị để các vùng chứa giao tiếp với nhau, nhưng linkscó thể đóng vai trò là biện pháp phòng ngừa khi khởi động ứng dụng docker-compose.

2.Khởi động Docker Compose và kiểm tra trạng thái của container:

docker-compose up -d
 docker ps

Đầu ra sẽ tương tự như sau:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
55d573674e49        nginx:latest        "nginx -g 'daemon ..."   3 minutes ago       Up 3 minutes        0.0.0.0:8080->80/tcp     nginx
ad9e48b2b82a        alpine              "tail -f /dev/null"      3 minutes ago       Up 3 minutes                                 Alpine_Distro
736cf2f2239e        postgres:latest     "docker-entrypoint..."   3 minutes ago       

3.Kiểm tra nginx bằng cách điều hướng đến địa chỉ IP công khai của Linode, cổng 8080trong trình duyệt (ví dụ 192.0.2.0:8080). Bạn sẽ thấy trang đích nginx mặc định được hiển thị.

Lưu trữ dữ liệu liên tục

Không nên lưu trữ dữ liệu PostgreSQL trực tiếp bên trong một container. Container Docker được coi là tạm thời: container của ứng dụng của bạn được xây dựng từ đầu khi chạy docker-compose upvà bị hủy khi chạy docker-compose down. Ngoài ra, bất kỳ sự cố hoặc khởi động lại bất ngờ nào trên hệ thống của bạn sẽ khiến bất kỳ dữ liệu nào được lưu trữ trong container bị mất.

Vì những lý do này, điều quan trọng là phải thiết lập một ổ đĩa cố định trên máy chủ mà các vùng chứa cơ sở dữ liệu sẽ sử dụng để lưu trữ dữ liệu.

1.Thêm một volumesphần docker-compose.ymlvà chỉnh sửa databasedịch vụ để tham chiếu đến tập:

version: '3'

services:
  distro:
    image: alpine
    container_name: Alpine_Distro
    restart: always
    entrypoint: tail -f /dev/null

  database:
    image: postgres:latest
    container_name: postgres_db
    volumes:
      - data:/var/lib/postgresql
    ports:
      - "5432:5432"
  web:
    image: nginx:latest
    container_name: nginx
    volumes:
      - ./mysite.template:/etc/nginx/conf.d/mysite.template
    ports:
      - "8080:80"
    environment:
      - NGINX_HOST=example.com
      - NGINX_port=80
    links:
      - database:db
      - distro
volumes:
  data:
    external: true

2.external: trueyêu cầu Docker Compose sử dụng một khối lượng dữ liệu ngoài đã tồn tại trước đó. Nếu không có khối lượng nào được đặt tên data, việc khởi động ứng dụng sẽ gây ra lỗi. Tạo khối lượng:

docker volume create --name=data

3.Khởi động ứng dụng như trước:

docker-compose up -d

Các bước tiếp theo

Docker Compose là một công cụ mạnh mẽ để sắp xếp các bộ container có thể hoạt động cùng nhau. Những thứ như ứng dụng hoặc môi trường phát triển có thể sử dụng Docker-compose. Kết quả là một môi trường có thể định cấu hình và mô-đun hóa có thể triển khai ở bất kỳ đâu.

Nguồn: https://www.linode.com/docs/guides/how-to-use-docker-compose/