docker-composeの設定

## はじめに
なんとなくでdocker-composeを使っていて設定内容まで理解できておらずつまづいたため、備忘録として記事にしました。

skyofficeというバーチャルオフィスのossを構築した内容です。
skyofficeはserverとclientの2つをDockerで動かすためdocker-composeを使用します。

## Docker　Composeについて

単体のDocker起動であればDockerファイルで設定が可能で、複数のDockerを起動する際にdocker composeを使用するとまとめて管理および実行ができます。

docker composeからDockerファイルを実行することも可能です。

(以前はdocker-composeと記載していましたが、docker composeに変更されているようです)

## 環境構築
環境により異なるため公式ドキュメントを参照ください。
公式の案内はLinuxでもDocker Desktopをインストールする方法のため、個人開発や事業規模が小さい場合以外は有料プランになります。

https://docs.docker.com/engine/install/

Linuxの場合はDocker Desktopを使用しなければ無料の認識ですので、個別にインストールします。

**Ubuntuの場合**
```shell
$ sudo apt install docker
$ sudo apt install docker-compose
```

## docker-composeの設定ファイル

compose.ymlというファイル名で、ファイル名はどのプロジェクトでも固定です。
（前はdocker-compose.ymlやdocker-compose.yamlでして、今でも動作します）

yaml形式で記載します。
以下はskyofficeのdocker-composeファイルの例です。

```yml:compose.yml
services:
  server:
    image: node:２０
    container_name: skyoffice-server
    working_dir: /usr/app/SkyOffice
    tty: true
    ports:
      - "2567:2567"
    volumes:
      - "./:/usr/app/SkyOffice"
    command:
      bash -c "yarn && yarn start"
  client:
    image: node:２０
    container_name: skyoffice-client
    working_dir: /usr/app/SkyOffice/client
    tty: true
    ports:
      - "80:5173"
    volumes:
      - "./:/usr/app/SkyOffice"
    command:
      bash -c "yarn && yarn dev --host"

```
### 第一階層
servicesは固定

公式ドキュメントを見ると他にもvolumes, config, network等を設定できて、services内から参照が可能なようです。

https://docs.docker.com/compose/compose-application-model/

### 第二階層
動作したいDockerを定義していきます。
今回はserverとclientの2つのDockerを定義。

ここでのserverやclientはサービスの識別子になります。
`docker ps`等で確認しましたがこの識別子は起動後確認できるパラメータではないようです。

### 第三階層
各Dockerの設定の定義。
今回使用したパラメータについて記載します。

**image**
Dockerのベースイメージを設定します。
nodeだったりredisだったり動作させる環境を設定します。

**container_name**
コンテナ名
`$ docker container ps`実行時に表示されるNAMES。

**tty**
仮想端末を配置するコマンド。
trueに設定する。
詳しくはこちらの[記事](https://zenn.dev/hohner/articles/43a0da20181d34)を参照ください。

**ports**
docker内のポートとdockerを動かす環境のポートの変換を設定。
今回の場合、clientを動かすとデフォルトは5173ポートで動作するが、サーバーではポート80で動いているように見せかけたいので`80:5173`と設定する。

```compose.yml
ports:
    - "{dockerを動かす環境に変換するポート番号}:{docker内で動作するポート番号}"
```

**volumes**
ローカルのどのディレクトリをDockerのどのディレクトリに配置するかの設定。
```compose.yml
volumes:
    - "{コピーするローカルのディレクトリ}:{Dockerのコピー先ディレクトリ}"
```

ローカルディレクトリはコピー対象のため現在のディレクトリの場合は`./`と設定し、コピー先に`/usr/app/SkyOffice`と設定するとSkyOfficeディレクトリの中にローカルのcompose.ymlが配置されているディレクトリが保管される。


**working_dir**
作業するディレクトリ
volumesで設定したディレクトリと同じディレクトリの場合は同じコピー先のディレクトリと同じ設定で大丈夫です。
しかし、volumesで設定するのはコピーしたいディレクトリのため必ずしも作業するディレクトリと同一ではありません。

今回はclientがSkyOfficeフォルダ内に存在して、clientからSkyOffice内のtypesフォルダにアクセスをするため、コピーはSkyOfficeディレクトリで作業するディレクトリはSkyOffice/clientディレクトリとなります。

```:SkyOfficeディレクトリ構成
SkyOffice # コピーするディレクトリ(volumes)
├ client  # ../types/message.tsファイルを参照
|         # 作業するディレクトリ(working_dir)
| ...
└ types
```

第二階層のserverとclientの2つ設定していますが、それぞれ全く別の環境のためserverの方にSkyOfficeディレクトリが存在するからといってclientでvolumesにclientディレクトリを指定するとclientの環境にはtypesフォルダができないためエラーとなります。
最初これに気づかず時間を要してしまいました。

**command**
実行するコマンドを設定
working_dirで設定したディレクトリ上で実行するコマンド。

他にもパラメータはありますが、機会があれば別の記事で書きたいと思います。

## 参考

https://docs.docker.com/compose

https://zenn.dev/hohner/articles/43a0da20181d34