メモ〜Docker-composeとは

Docker-composeとは
-
複数のコンテナからなるサービスを効率的に作成するための設定ファイル、およびそれを実行するためのコマンド。

一つのサービスは複数のコンテナからなる場合がほとんどであり、例えばWordPressでブログを運用する場合にはWordPress用と記事を保管するMySQLようで最低でも2つのコンテナが必要になる。

この場合、本来であれば

- コンテナを収容する`Dockerネットワーク`を作成する。
- WordPressとDockerそれぞれのコンテナを作成する。
- 両者を作成済みのネットワークに追加する。
- WordPressとMySQLで使用する環境変数を設定する。

などの作業が必要になり、その都度ターミナルコマンドを発行することになる。

しかしこの手順を`docker-compose.yml`というファイルに記述して実行することで一連の処理が自動で行われるので、サービスを効率的に構築することができる。

Docker-composeを利用したサービス構築の手順
-

- Linux用のdocker-composeのインストール
- docker-compose.ymlの作成
- docker-compose.ymlの実行

Linux用のdockercomposeのインストール
-
windows, macに関してはdocker desktopをインストールした時点でdocker-composeが実行可能になりますが、linuxに関してだけは別途でインストールが必要です。

```shell:docker-composeのインストール
% sudo curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# curlは指定したurlにアクセスするためのコマンド
# 書式はcurl url -o アウトプットの出力先
# -Lはリダイレクトがある場合にそちらに遷移するためのオプション
# 上記例では、指定したurlもしくはそのリダイレクト先からdocker-composeのファイルをダウンロードして
# /usr/local/bin/docker-composeに保存している
```

```shell:実行権限の付与
% sudo chmod +x /usr/local/bin/docker-compose
# chmodはコマンドの権限を操作するためのコマンド
# 上記例では全てのユーザーにdocker-composeの実行権限を付与(+x)している
```

docker-compose.ymlの作成・実行
-

```yml
version: '3.3'

services:
 httpd:
  image: httpd:2.4.43
  ports:
   - "80:80"
```

上記のようにファイルを作成し

```shell
% docker-compose up [-d] # -dをつけるとバックグラウンドで実行される
```
と唱えると`httpd:2.3.43`というイメージをもとにしたコンテナ(apacheサーバー）が作成され、ホストOSの80番ポートへのアクセスがapacheの80番ポートに転送されるようになる

docker-compose.ymlの解説
-
docker-compose.ymlとは、ネットワークに所属するコンテナの設定を記述していくためのファイル
。

このファイル内では一つ一つのコンテナをサービスと呼んでおり、

```yml
services:
 サービス名1:
  項目名1:値1
  項目名2:値2
  項目名3:値3
  ....

 サービス名2:
  項目名1:値1
  項目名2:値2
  項目名3:値3
  ....
```
としていくことでネットワーク内に作成するサービスが定義される。

なお、services:とサービス名、サービス名と項目名の間にはそれぞれ半角スペースが必要。

```yml:１行目
# docker-compose.ymlのフォーマットのバージョン指定
version: '3.3' # 現時点では3.3が安定版とのこと
```
```yml:２行目
services:
 # この部分に書かれたものがサービスの内容になる
```

```yml:３行目
# サービス名の定義
# 分かればなんでも良い
httpd:
```

```yml
# もとにするイメージの指定
  image: httpd:2.4.43
```
```yml
# ポート転送の設定
  ports:
   - "80:80"
```
このファイルを実行した状態でホストPCから`localhost/`にアクセスすると`It Works`と表示される(80番ポートにアクセスすると`It Works`と表示されるというのは、apacheのデフォルト設定）。

なお、この際に作成されるネットワーク名は

```shell
docker-compose.ymlのディレクトリ名_サービス名_数字
```
になる。

おまけ〜imageの代わりにDockerfileを指定する
-
上記の例ではdocker-compose.ymlの中でベースとなるdockerイメージを指定したが、イメージの代わりにDockerfileを指定することも可能。

以下のようにファイルを書き換える（コメントアウトしている部分が削除箇所）。

```yml
version: '3.3'

services:
 httpd:
  # image: httpd:2.4.43
  # 以下の2行を追加
  build:
   context: "Dockerファイルのディレクトリへの相対パス" # 同じディレクトリなら.でOK
  ports:
   - "80:80"
```
Dockerfile内でベースイメージを指定しているはずなので、そこを経由してベースイメージの情報が取得される。


おまけその２〜複数のサービスの連携
-

同一ネットワーク内で複数のサービスを起動させる場合には以下のように記述する。

```yml
version: '3'
 
services:
   mysql:
     image: mysql:8.0.20
     platform: linux/x86_64
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: wordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress
 
   wordpress:
     depends_on:
       - mysql
     image: wordpress:php7.4-apache
     platform: linux/x86_64
     ports:
       - "80:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: mysql:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
```

以下、個別解説です。

```yml:プラットフォームの指定
platform: linux/x86_64
```

dockerイメージはプラットフォームに合わせて複数用意されていることが多く、基本的にはホストOSに合わせたものがダウンロードされる。

しかしdockerイメージの中にはM1Mac対応版(=arm64版)が存在しないものも多い。

そのような場合には以下のようなエラーが出るので、platformとして`linux/x86_64`版を指定する。

```shell
no matching manifest for linux/arm64/v8 in the manifest list entries
```

`x86_64`というのはIntelMac用のバージョンだが、Docker上であれば問題なく動作する。

```yml:restartオプション
restart: always
# ホストOSやデーモンの起動時にサーバーが自動で起動される
```

```yml:環境変数
environment:
  変数名: 値
```

```yml:依存関係の規定
depends_on: 
  - mysql
```
mysqlの後にwordpressサービスの作成が開始されるように指定している。

```yml
WORDPRESS_DB_HOST: mysql:3306
```
wordpressのDBホストとして、mysqlサービスの3306番ポートを指定している。

おまけその３〜volumesの作成
-
上記の例ではDBのデータがコンテナ内に保存されるようになっているが、この方法ではコンテナを削除した際にデータがすべて消えてしまう。

しかし、docker-compose.ymlの中に`volumes`という項目を作成し、そのパスとしてホストOSのディレクトリを指定することでDBの内容をホストOSに保存することができるようになる。

```yml
version: '3'
 
services:
   mysql:
     image: mysql:8.0.20
     platform: linux/x86_64
     # 以下の2行を追加
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: wordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress
 
   wordpress:
     depends_on:
       - mysql
     image: wordpress:php7.4-apache
     platform: linux/x86_64
     ports:
       - "80:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: mysql:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
# 以下の2行を追加
volumes:
    db_data:
```

まず

```yml
volumes:
  db_data:
```
でdb_dataという名前のvolumesを作成し

```yml
volumes:
  - db_data:/var/lib/mysql
```
でdb_dataというvolumesのパスを指定している。