【初心者向け】Dockerで手軽にNode.js開発環境構築 (1)

最近は Docker と Node.js 周りの変化が目まぐるしい
最新とは言わないまでも、とりあえず流れに遅れないレベルでの開発環境構築を目指してみる

# 開発環境
MackBook Air (macOS High Sierra)
Docker CE for Mac 17.12.0

# Docker for Mac のインストール

以下の公式サイトから「Get Docker CE for Mac (Stable)」でダウンロード
Kubernetes 使いたい場合は Edge 版じゃなきゃダメらしい

https://store.docker.com/editions/community/docker-ce-desktop-mac

メニューバーにアイコンが表示されてこんな感じになればOK

![png](https://qiita-image-store.s3.amazonaws.com/0/199914/75fab1c9-d073-1fba-4746-e3760fa7a0ca.png)

Docker Hub にサインインするには Docker Hub アカウントが必要なので後回し
自作イメージを公開する際には必要だが、どうせなら Automation Build とか使いたいしやっぱり後回し

一応ターミナルでも確認（Version は異なるはず）

```bash
$ docker -v
Docker version 17.12.0-ce, build c97c6d6
$ docker-compose -v
docker-compose version 1.18.0, build 8dd22a9
```

# Docker とは

初心者向けといいつつこの辺の解説は割愛します

## Docker で hello-world

とりあえず「イメージ」と「コンテナ」の概念を何となく押さえれば何とかなる
かなり雑な例えだが、オブジェクト指向言語における「クラス」と「インスタンス」のような関係

hello-world イメージからコンテナを生成して実行する

```
$ docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
ca4f61b1923c: Pull complete 
Digest: sha256:083de497cff944f969d8499ab94f07134c50bcf5e6b9559b27182d3fa80ce3f7
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://cloud.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/
```

色々書いてあるが
"hello-world イメージはローカルに存在しないよ"
"Docker Hub から latest タグのイメージを pull しておいたよ"
くらいを押さえておく

次にコンテナ一覧を確認する

```
$ docker ps -a
CONTAINER ID  IMAGE        COMMAND   CREATED             STATUS                          PORTS  　NAMES
450b7bcdb08b  hello-world  "/hello"  About a minute ago  Exited (0) About a minute ago          　hopeful_mirzakhani
```


| 見出し          | 説明    |
|----------------|------------------|
| `CONTAINER ID` | コンテナID        |
| `IMAGE`        | 元となったイメージ |
| `COMMAND`      | コンテナ起動時のプロセスで実行するコマンド |
| `CREATED`      | いつ生成したか |
| `STATUS`       | Up, Exited, Restarting など |
| `PORTS`        | コンテナが開放しているポート |
| `NAMES`        | コンテナ名 |

### STATUS が Exited になっている

コンテナを起動 → `COMMAND` のプロセスを実行 → `/hello` が hello-world のメッセージを出力
→ プロセスを終了 → コンテナも終了

となっていることが原因
これでは困るので
実際に使うコンテナのコマンドには `/bin/sh` など、プロセスが終了しないものを設定する

### NAME に謎の名前が…

起動時に名前を設定しないと自動で設定される

### コンテナとイメージの削除

一通り理解したら削除しておく

```
$ docker rm hopeful_mizakhani (NAMES か CONTAINER ID を指定)
$ docker ps -a
CONTAINER ID    IMAGE           COMMAND         CREATED         STATUS          PORTS           NAMES
```

イメージ一覧を確認して削除

```
$ docker images
REPOSITORY     TAG       IMAGE ID         CREATED           SIZE
hello-world    latest    f2a91732366c     3 months ago      1.85kB

$ docker rmi hello-world
$ docker images
REPOSITORY     TAG       IMAGE ID         CREATED           SIZE
```

# Docker Compose とは

複数コンテナを同時に起動するためのコンポーネント
Docker for Mac にもともと入っている

なかなかクリティカルなデメリットがあるのが気がかりだが
Kubernetes の学習コストもかなり高いし、今回は Docker Compose を使うことにする

### メリット
・コンテナ起動時の設定をyamlファイルに書いておけば毎回冗長な docker run コマンドを実行する必要がなくなる
・現時点では Kubernetes より簡単に複数コンテナを連携できる

### デメリット
・Compose file の書き方を学習する必要がある
・この先使わなくなるかもしれない
（実はコンテナを本番運用するなら Kubernetes 一択という事情があり、開発環境も Kubernetes にする流れになってきている）

次は Node.js の設定を行う

次回[【初心者向け】Dockerで手軽にNode.js開発環境構築 (2)](https://qiita.com/yuji001/items/4f54496fd2f577c56b1d)