Docker-compose環境で開発をするために

# はじめに
　環境作成とは案外面倒くさいもので何かしらエラーが出れば環境を丸ごと作り直すなんてこともあります。そんな環境作成を簡略化し、尚且つ便利にするのがDocker-composeですが、そんなDocker-composeを使用してプログラム開発を進めたいと考えるとまた面倒があります。
　この記事では、自分自身で探したDocker-composeでの開発方法を紹介します。
　なお、この記事で書いてある内容よりもはるかに効率のいい方法があるかもしれません。というかあると思います。知っている方がいれば教えていただければ幸いです。

# docker-composeで環境作成

　Docker-composeではdocker-compose.ymlというファイルを作成して、コンテナの設定をします。docker-compose.ymlとDockerfileを編集すると、ファイルをマウントして、コンテナ外の編集が容易なファイルを用意することが出来ます。それを編集してプログラムを書きこみます。
　例として自分が作成したGitHubリポジトリにあるdocker-compose用のディレクトリをクローンしてみましょう。

```
git clone https://github.com/DogKingFun/puglic.git
```

## ディレクトリ構成

```
.
├── docker-compose.yml
├── mongo
│   ├── init.js # DB初期化用スクリプト
│   └── mongo-data # データ保存用ディレクトリ（バインドマウント）
├── nginx
│   ├── Dockerfile
│   └── conf
│       └── proxy.conf
└── server # express-generator の　pug テンプレート
```

　ここでコンテナ内にコピーするのはserver内の全プログラムコードとnginxの設定ファイル、それからmongoのmongo-dataです。

## docker-compose.yml

　docker-compose.ymlは次の通り。

```docker-compose.yml
version: '3'

services:
   nginx:
     build: ./nginx
     container_name: nginx
     depends_on:
       - server
     ports:
       - 80:80

   server:
     build: ./server
     container_name: server
     depends_on:
       - mongo

   mongo:
     image: mongo
     container_name: mongo
     environment:
       MONGO_INITDB_DATABASE: admin
     volumes:
       - ./mongo/init.js:/docker-entrypoint-initdb.d/init.js:ro
       - ./mongo/mongo-data:/data/db
     # Start mongo with authentication enabled
     command: [mongod, --auth]
```

　ここでマウントに直接関係している項をピックアップするならbuildでしょう。buildでは各コンテナのDockerfileの位置を表します。

## serverのDockerfile

　serverディレクトリのDockerfile、つまりnode.jsのDockerfileは次の通り。

```:server/Dockerfile
FROM node

# アプリケーションディレクトリを作成する
WORKDIR /usr/src/server

# キャッシュを利用するために、package.jsonとpackage-lock.jsonのみをコピーし、
# 依存関係を先にインストール
COPY package*.json ./
RUN npm install

# アプリケーションコードをコンテナにコピー
COPY . .

EXPOSE 3000
CMD [ "node", "bin/www" ]
```

　Dockerfile内に書いてあるコメントの通りですが、アプリケーションコードをコンテナに内にコピーするためにCOPY . . をします。

## nginxのDockerfile

　nginxのディレクトリのDockerfileは次の通り。

```:nginx/Dockerfile
FROM nginx

# デフォルトの設定を削除
RUN rm /etc/nginx/conf.d/default.conf

# 作成した設定ファイルをコピー
COPY conf/proxy.conf /etc/nginx/conf.d
```

　nginxのconfファイル内で編集したproxy.confファイルをコピーしています。

## まとめ
　コンテナ外にあるデータをコンテナ内にコピーすることで、プログラムを編集したりすることができ、自分はこの方法でwebアプリの開発を行っています。

# 起動

```
docker-compose up
```


　このようにdocker-composeを起動することで各コンテナが作られ、コピー対象のデータがコンテナ内にコピーされるわけなのですが、コンテナを閉じてから再起動してみればキャッシュが残っているのか何なのか、前回起動したコンテナが再起動し、プログラムを編集したとしても反映されません。
 そのためプログラムを反映させるにはコンテナを再構築させなければいけません。

```
docker-compose up --build
```

　こうすることで、コンテナは再構築されます。

## 蛇足

　因みに今回の議題とは外れるところなのですが、docker-compose upではログが出力され、バックグラウンドで起動されるわけではないのですが、

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

 とすることでコンテナがバックグラウンドで起動します。

# ゴミ掃除

　docker-compose up --build　と何回もやっていると、次のように空(?)のイメージが大量に残るようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2647158/54534ea7-09a6-0d91-1fcd-8d25e62ee088.png)

　それをちゃんと削除してあげましょう。

## 全イメージの削除

```
docker images -aq | xargs docker rmi -f
```

　こうすると起動しているコンテナのイメージ以外は消えてくれるようです。

## 全コンテナの削除

　ついでに全コンテナの削除方法。何かしら良く分からないエラーを吐きまくったら全部削除すればいいと思うよ。

```
docker ps -aq | xargs docker rm -f
```

# 最後に

　初めにもいいましたが、これが最高率のdocker-composeを使用した開発方法かと言われれば、そうではない気がします。
　自分にとってはこの開発方法が一番！
　とか
　そもそもdocker-composeの使い方を間違えている！
　などなどありましたらTwitterでもGitHubでもこの記事内でもいいので教えてくださると幸いです。
　**以上！**