Hướng dẫn sử dụng docker compose

  • June 26, 2021
  • 2727

Hướng dẫn sử dụng docker compose từ cơ bản đến nâng cao, giúp lập trình viên chỉ cần một command, có thể dễ dàng create và start toàn bộ các services phục vụ cho việc chạy ứng dụng.

Docker compose là gì?

Docker compose là một công cụ giúp định nghĩa và chạy multi-container cho các ứng dụng sử dụng docker. Docker compose sử dụng cú pháp YAML để định nghĩa các services, thường các service được định nghĩa trong file docker-compose.yml. Để chạy tất cả các ứng dụng được khai báo trong docker-compose.yml file chỉ cần truy cập vào thư mục chứa file docker-compose và sử dụng 1 command duy nhất docker-compose up -d

1. Create multi-container with docker compose

Định nghĩa một số service để khởi chạy dự án sử dụng laravel. Các service cần thiết để chạy 1 ứng dụng sử dụng laravel: nginx(web server), app(chứa code laravel), db(database), redis, minio(môi trường giả lập s3).

1.1 Định nghĩa các services với docker compose

Tạo file docker-compose.yml để định nghĩa các service


version: '3.4'

networks:
  backend:
    driver: bridge

services:
  nginx:
    image: nginx:1.19.2-alpine
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./docker/nginx/conf.d:/etc/nginx/conf.d
      - .:/var/www/
    links:
      - app
    depends_on:
      - app
    networks:
      - backend

  app:
    build:
      context: .
      dockerfile: docker/app/Dockerfile
    volumes:
      - .:/var/www/
    links:
      - db
      - redis
      - minio
    networks:
      - backend

  db:
    image: mysql:5.7
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci --skip-character-set-client-handshake
    ports:
      - "3389:3306"
    volumes:
- mysqldata:/var/lib/mysql - ./docker/mysql/init/init-databases.sql:/docker-entrypoint-initdb.d/init-databases.sql environment: MYSQL_DATABASE: laravel MYSQL_ROOT_PASSWORD: secret networks: - backend redis: image: redis:latest restart: always volumes: - ./docker/logs/redis:/var/log/redis ports: - "6379:6379" networks: - backend command: redis-server --appendonly yes minio: image: minio/minio ports: - "9000:9000" volumes: - ./docker/minio:/data tty: true networks: - backend environment: MINIO_ACCESS_KEY: minio MINIO_SECRET_KEY: minio123 MINIO_REGION_NAME: us-west-2 command: ["minio", "server", "/data"] volumes: mysqldata: driver: local

1.2 Giải thích các chỉ thị trong file docker compose

Giải thích một số chỉ thị hay dùng trong docker-compose.yml file

1. version

Version docker compose sử dụng, trong ví dụ trên mình dùng version 3.4


version: '3.4'

2. networks

Khai báo network sử dụng, network này sẽ được dùng trong các container, đảm bảo các container phải dùng chung 1 network thì mới có thể truy cập được đến nhau


// Khai báo một network có tên là backend, loại network là bridge
networks:
  backend:
    driver: bridge

3. services

Khai báo các service cần dùng cho ứng dụng, mỗi một server sẽ được chạy trong 1 container


services:
  nginx:

  app:
  ...

4. image

Khai báo docker image mà service dùng để build container


// Service nginx được build từ docker image nginx:1.19.2-alpine
image: nginx:1.19.2-alpine

5. ports

Chỉ định port của máy host và container


// Chỉ định port của host và container (HOST:CONTAINER)
// Truy cập vào port 81 của máy host đồng nghĩa với truy cập vào post 80 của container
ports:
      - 81:80

6. volumes

Mount data từ giữa container máy local, dữ liệu được link giữa máy của bạn và container, giúp không bị mất dữ liệu mỗi lân stop container


// Mount code từ thư mục cùng cấp với file docker-compose, vào trong thư mục /var/www của container
volumes:
      - .:/var/www/

8. links

Cho phép từ 1 service có thể giao tiếp với 1 hoặc nhiều service khác


app:
    // Từ service app có thể truy cập đến các service db, redis, minio
    links:
      - db
      - redis
      - minio

9. networks

Định nghĩa service sử dụng network nào, các container phải dùng chung 1 network mới có thể truy cập lẫn nhau được


// Service sử dụng network backend
networks:
      - backend

10. build

Dùng để build một server từ một docker file tự viết, service app được build từ docker file trong thư mục docker/app/Dockerfile


app:
    build:
      context: .
      dockerfile: docker/app/Dockerfile

11. command

Khai báo command cần thực thi, trong container khi server được chạy


db:
    image: mysql:5.7
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci --skip-character-set-client-handshake

12. environment

Khai báo biến môi trường cho container của db service


environment:
      MYSQL_DATABASE: laravel
      MYSQL_ROOT_PASSWORD: secret

2. Tạo các file dùng chung cho các service

Các file dùng để thiết lập ban đầu cho các service để trong thư mục docker cùng cấp với file docker-compose.yml
Create file docker/app/Dockerfile để build service app, chạy code laravel

FROM php:7.4-fpm AS prod
 
# Install system dependencies
RUN apt-get update && apt-get install -y \
    build-essential \
    mariadb-client \
    libpng-dev \
    libjpeg62-turbo-dev \
    libfreetype6-dev \
    libonig-dev \
    locales \
    libzip-dev \
    zip \
    jpegoptim optipng pngquant gifsicle \
    vim \
    unzip \
    git \
    curl \
    libsodium-dev \
    pkg-config

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd

# Get latest Composer
RUN curl -sS https://getcomposer.org/installer | \
    php -- --install-dir=/usr/local/bin --filename=composer

# Install php redis
RUN pecl install -o -f redis \
&&  rm -rf /tmp/pear \
&&  docker-php-ext-enable redis

# Set new UID for user www-data
RUN usermod -u 1000 www-data

# Set working directory
WORKDIR /var/www
COPY . .

Create file docker/nginx/conf.d/default.conf cấu hình giữa service nginx và service app


server {
    listen 80;
    index index.php index.html;

    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;

    root /var/www/public;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_hide_header X-Powered-By;
    }

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
}

Create file docker/mysql/init/init-databases.sql tạo các database khi service db được chạy


# Create databases
CREATE DATABASE IF NOT EXISTS `laravel`;
CREATE DATABASE IF NOT EXISTS `laravel_test`;

Như vậy phần định nghĩa các service đã xong, giờ chạy nó thôi nào

3. Các lệnh hay dùng trong docker compose

1. Bulid các service

Để buid các service được khai báo trong docker-compose.yml, Truy cập vào thư mục chứa file docker-compose.yml sau đó chạy lệnh.


docker-compose build

2. Chạy các service


docker-compose up

// Chạy ở chế độ background
docker-compose up -d

3. Stop service


// Stop các service, không bị mất dữ liệu
docker-compose stop

4. Start service


// Chạy các service bị stop
docker-compose start

5. Down service


// Các service sẽ bị down dữ liệu sẽ bị mất, phải chạy docker-compose up để chạy lại các service
docker-compose down

6. Truy cập vào service


// Truy cập vào service app
docker-compose exec app bash

Trên đây là toàn bộ các bước để định nghĩa khởi chạy các services với docker-compose hi vọng giúp ích cho mọi người