Giới thiệu Docker Compose

Hôm nay mình sẽ giới thiệu một chút về Docker Compose – giúp chúng ta điều chỉnh và chạy multiple containers với nhau.

Lưu ý: Compose không dành cho mục đích lên Production.

Khi nào cần phải sử dụng Docker Compose?

Một vài cases mà bạn sẽ cần dùng Docker compose:

  • Dựng development environment: Provision các local database instance, message queue đi kèm các services.
  • Automated testing environment: Setup các services hỗ trợ cho việc automation testing, ví dụ như setup cả bộ Report Portal bao gồm cả Web server, API gateway và MongDB trong bài viết này: https://toilatester.blog/2018/11/20/huong-dan-setup-report-portal-voi-docker-compose/
  • Single host deployment: Setting cho việc deploy lên 1 host cố định – use case này thì mình thấy khá hiếm

Với tester tụi mình thì sẽ sử dụng chủ yếu với mục đích 1 và 2: Provision môi trường cho ứng dụng để chạy automate test và setup những service phục vụ cho việc testing. Single host deployment có thể sử dụng để setup sau này khi dùng trong Docker clusters với Docker Swarm hay Kubernetes.

Vậy Docker Compose là cái gì và dùng làm sao?

Ok, đi qua một chút lý thuyết. Theo định nghĩa dịch từ nguyên gốc trang chủ của Docker, chúng ta có:

Compose (mình dùng từ này cho gọn nha) là một công cụ giúp xác định và chạy ứng dụng với nhiều container.

Tài liệu chính thức của Docker

Đơn giản hơn thì, Compose gần 2 phần:

  • Một file docker-compose.yaml: Chứa các configuration cho tất cả các containter cần chạy
  • Sử dụng command line để điều khiển các containers này (run,stop, restart)

Chúng ta cùng thử bằng cách tạo một file docker-compose.yaml với nội dung như sau:

Bước 1: Tạo docker-compose.yaml

mkdir tester
cd tester
touch docker-compose.yaml

Bước 2: Thêm vào trong file với nội dung sau:

version: '3.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
       WORDPRESS_DB_NAME: wordpress
volumes:
    db_data: {}

Giải thích một chút về configuration của file trên:

  • Xác định những containers cần chạy như các services, ở đây chúng ta có 2 container sẽ được chạy là MySQL và WordPress.
  • services.db: Config của service db, ở đây ta có Docker image MySQL với tag 5.7, có volumes được nối vào db_data volume, restart bất cứ lúc nào nếu container bị chết giữa đường và truyền vào một số environment variable như MYSQL_ROOT_PASSWORD, MYSQL_ROOT_USER,etc.
  • services.wordpress: Ở đây container WordPress cần database phải được setup trước, do đó ta dùng tag depends_on: db (db là tên service ở đầu, đại diện cho MySQL containers). Image được chọn là wordpress với tag latest. Port được bind ra máy chủ là 8000 với port 80 trong container. Tương tự ta có thể truyền vào một số env var ở đây giống với db.
  • volumes: Khởi tạo những volumes có sẵn trên máy chủ để sử dụng, bạn có thể truyền path vào hoặc để {} tức default volume driver tức local dir nơi bạn cài Docker

Chi tiết hơn về các viết docker-compose file: https://docs.docker.com/compose/compose-file/

Okie, vậy là chúng ta đã xong thao tác đầu tiên: define docker-compose.yaml file là một file chứa configuration của một website WordPress đơn giản bao gồm Web server và MySQL database

Bây giờ cùng nhảy vào Terminal / Command prompt nào.

Start containers:

docker-compose up

Bạn sẽ thấy Docker pull image về nếu trên máy chưa có sẵn, và kết quả sau khi chạy xong:

Creating tester_db_1 ... done
Creating tester_wordpress_1 ... done
Attaching to dockertest_db_1, dockertest_wordpress_1
db_1         | Initializing database
db_1         | 2019-04-20T10:50:55.360633Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
db_1         | 2019-04-20T10:50:56.517342Z 0 [Warning] InnoDB: New log files created, LSN=45790
db_1         | 2019-04-20T10:50:56.578672Z 0 [Warning] InnoDB: Creating foreign key constraint system tables
...
và một đống log của MySQL lẫn WordPress

Thử mở browser và vào localhost:8000 chúng ta sẽ có giao diện install wizard của WordPress.

Nhấn Ctrl + C để stop container: (Compose sẽ dọn cho bạn một cách nhẹ nhàng và từ tốn, hạn chế nhấn Ctrl + C nhiều lần để force quá trình hủy diệt này nha)

Gracefully stopping… (press Ctrl+C again to force)
 Killing tester_wordpress_1  … done
 Killing tester_db_1         … done

Chúng ta cũng có thể chạy containers như background services bằng cờ -d, lúc này bạn sẽ không thấy log dài nữa mà thay vào đó là 1 vài info báo rằng containers đã chạy:

docker-compose up -d
 Starting dockertest_db_1 … done
 Starting dockertest_wordpress_1 … done

Cũng test thử với docker ps:

docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
0d0f499733b4        wordpress:latest    "docker-entrypoint.s…"   12 minutes ago      Up 47 seconds       0.0.0.0:8000->80/tcp   tester_wordpress_1
6ad79cd95bb4        mysql:5.7           "docker-entrypoint.s…"   12 minutes ago      Up 49 seconds       3306/tcp, 33060/tcp    tester_db_1

Để dọn dẹp những “background services” này có nhiều cách, nhưng tốt nhất vẫn là dùng docker-compose down:

docker-compose down
Stopping tester_wordpress_1 ... done
Stopping tester_db_1        ... done
Removing tester_wordpress_1 ... done
Removing tester_db_1        ... done
Removing network tester_default

Chúng ta cũng có thể scale số lượng của từng containers cho từng service với cờ --scale:

docker-compose up -d --scale db=2

Creating network "tester_default" with the default driver
Creating tester_db_1 ... done
Creating tester_db_2 ... done
Creating tester_wordpress_1 ... done

Bên trên là một vài thao tác cơ bản với Docker Compose, tới đây thì bạn có thể thử một số ví dụ trên mạng và ví dụ trên trang chủ của Docker.

Một vài thứ hay ho có thể áp dụng:

  • Nếu không xác định, sẽ có một tầng Default Network được khởi tạo khi chạy, tầng này đóng vai trò như một subnet chứa các containers, và có thể giải các tên miền thành các Container IP. Như ở ví dụ trên ta sẽ thấy WordPress được truyền vào biến Database Host là `db:3306` ở đây Compose network sẽ giải `db` ra thành Container IP của MySQL và gọi tới container này.
  • Tương tự với Network, Volumes cũng được khởi tạo. Và bạn có thể gọi tên Volume trong configuration của từng services.
  • Có thể define việc build từ Dockerfile ra image trước khi sử dụng image đó, khá là tiện lợi trong quá trình development.

Đó là một số tóm gọn và Docker Compose và cách sử dụng, nếu có câu hỏi thêm, các bạn có thể thoái mải comment ở dưới nhen ^^.

Leave a comment