awesome-composeでローカル開発環境をお手軽にセットアップする

## この記事は
「awesome-compose」をつかってローカル環境に開発環境を作る方法です。

## 自己紹介
Java（Spring Boot）のWebアプリ開発を主にやってます。

## きっかけ
### ローカル環境がこわれた
ローカルでSpring Bootの開発でごちゃごちゃやっていたらGradleが壊れてしまいました。

``gradle install``実行時に、こんなエラー（↓）がでました。

```bash
FAILURE: Build failed with an exception.

* What went wrong:
Task 'install' not found in root project 'frontend'.
# 以下略
```
ググってもAndroid系の記事ばかり出てきてなんかよくわからなかったです。

もっと調べろよ！と言われればそれまでですが、いい機会なのでDockerできれいな環境を作りたくなりました。

ときには別の道に逃げましょう。

### docker-composeちゃんと書くの大変
ネットでググりつつ自分の環境に合わせて書くわけですが、Dockerの基礎力が弱いので、つまづいたときになかなか先に進めません。リファレンス見ても直感的に理解するまでの道は遠いです。

真似ながら学んでいきたい性質（たち）なので、質の良いサンプルがあると助かります。

## awesome-composeとは
Docker公式のdocker-composeのサンプル集です。以下にあります。

https://github.com/docker/awesome-compose

README.mdには以下のように書いています。
（以下一部引用。Google翻訳）
> These samples provide a starting point for how to integrate different services using a Compose file and to manage their deployment with Docker Compose.
> これらのサンプルは、Composeファイルを使用してさまざまなサービスを統合し、DockerComposeを使用してそれらのデプロイメントを管理する方法の開始点を提供します。

サンプルとしてまずは動かしてみて、自分の環境にあうようにカスタマイズしていくイメージでしょうか。

>The following samples are intended for use in local development environments such as project setups, tinkering with software stacks, etc. These samples must not be deployed in production environments.
>次のサンプルは、プロジェクトセットアップ、ソフトウェアスタックの調整など、ローカル開発環境での使用を目的としています。これらのサンプルは、実稼働環境にデプロイしないでください。

使い所としてはローカル開発環境であることが明記されてます。じっさいのところ、本番環境ではクラウドのマネージドサービスを使うなど選択肢がいろいろあるかと思います。

## awesome-composeの特徴
- ご覧いただくとわかるように、さまざまなコンテナの組み合わせがサンプルとして用意されてます。探せば自分がほしいものが見つかるのではないでしょうか。
- docker-compose.ymlだけでなく、アプリのサンプルもついてきます。アプリも含めてDocker環境をいちからつくるのは結構骨が折れるので、そこはありがたいですね。

## 動かしてみる
### 1. Docker環境のインストール
詳細は割愛します。Mac版は以下にあります。

- Docker Desktop for Mac
  - https://hub.docker.com/editions/community/docker-ce-desktop-mac/

### 2. awesome-composeの入手
先に紹介したGitHubのサイトからクローンします。

```bash
git clone https://github.com/docker/awesome-compose.git
```

### 3. コンテナの起動
SpringとPostgreSQLのコンテナを起動する「spring-postgres」を使ってみます。

プロジェクトルートから``spring-postgres``ディレクトリを移動し、

```bash
cd spring-postgres
```

``docker-compose``コマンドで起動します。

```bash
docker-compose up -d
```

### 4. 動作確認
ブラウザで``localhost:8080``にアクセスします。
![helloworld.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33137/e782d53c-0e2d-ba67-2ec1-8b49f0fdb9f0.png)
初期ページが表示されれば起動成功です。
詳細は省きますが、「Hello from Docker」の「Docker」は、PostgreSQLコンテナ起動時にINSERTされたレコードをSpringから参照、画面表示したものです。
## 解説（docker-compose.yaml）
とりあえず動けばいいや、でよければこれ以上読まなくても大丈夫です。
以降は、docker-compose.yamlの雑な解説をするので、興味があればお読みください。
### backendサービス（Spring）の設定
```yaml
version: "3.7"
services:
 backend:
 build: backend # (1)
 ports:
 - 8080:8080
 environment:
 - POSTGRES_DB=example # (2)
 networks:
 - spring-postgres
```
- (1) backendサービスのイメージ作成は、``build``に指定したディレクトリ名``backend``にある``Dockerfile``でおこないます。
- (2) ``environment``はコンテナ内で使用する環境変数を設定します。``POSTGTES_DB=example``は、SpringからPostgreSQLへ接続するときの接続文字列で使用するDB名です。``backend/src/main/resources/application.properties``内で参照しています。
### dbサービス（PostgreSQL）の設定
```yaml
 db:
 image: postgres
 restart: always
 secrets:
 - db-password # (3)
 volumes:
 - db-data:/var/lib/postgresql/data # (4)
 networks:
 - spring-postgres
 environment:
 - POSTGRES_DB=example
 - POSTGRES_PASSWORD_FILE=/run/secrets/db-password # (5)
volumes:
 db-data: # (6)
secrets:
 db-password:
 file: db/password.txt # (7)
networks:
 spring-postgres:
```
- (3) 機密情報（パスワード）を指定します。
- (4) コンテナ内のPostgreSQLのデータディレクトリをホストマシンのディレクトリにマウントします。
- (5) 機密情報（パスワード）が記載されたファイルのパスを環境変数に設定します。
- (6) (4)にたいしてマウントするホスト側のディレクトリを指定します。ここでは記載がないので、永続化はされないようですね。
- (7) コンテナ内のPostgreSQLで使用するパスワードファイルのパスを設定します。デフォルトでは、ここで指定したファイルはコンテナの``/run/secrets``ディレクトリにマウントされるらしい。

## 最後に
とりあえず動かすだけはできました。
次はカスタマイズして自分なりの環境を作りたいです。

## 参考
- [Compose ファイル・リファレンス](https://docs.docker.jp/compose/compose-file.html)
- [Docker Compose入門 (1) ～アプリケーションをコンテナで簡単に扱うためのツール～](https://knowledge.sakura.ad.jp/21387/)
- [Docker Compose入門 (2) ～ウェブサーバの開発環境を作るための準備～](https://knowledge.sakura.ad.jp/23632/)
- [Docker Compose入門 (3) ～ネットワークの理解を深める～](https://knowledge.sakura.ad.jp/23899/)
- [Docker Compose入門 (4) ～ネットワークの活用とボリューム～](https://knowledge.sakura.ad.jp/26522/)
- [Dockerfileを改善するためのBest Practice 2019年版](https://www.slideshare.net/zembutsu/dockerfile-bestpractices-19-and-advice)
- [docker images を全削除する](https://qiita.com/fist0/items/2fb1c7f894b5bdff79f4)
- [《滅びの呪文》Docker Composeで作ったコンテナ、イメージ、ボリューム、ネットワークを一括完全消去する便利コマンド](https://qiita.com/suin/items/19d65e191b96a0079417)