コード20行だけで初めるDocker

「Dockerって知ってないとやばいの？」くらいのサーバとかインフラとかが苦手な人が対象です。「まず、とりあえず、触る」を目的にするので、めちゃくちゃ端折ります。僕も専門ではないので間違っていたらご指摘くださいませ。
ちなみにWebの話をベースに書きますが、Dockerはもっと色んな事ができる夢が広がるものです。

## Dockerとは
![horizontal-logo-monochromatic-white.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546514/26f91381-306a-470f-c9ea-7f9f93e4e809.png)
> Dockerは、コンテナと呼ばれるOSレベルの仮想化環境を提供するオープンソースソフトウェアである。
https://ja.m.wikipedia.org/wiki/Docker

Oh…Wikipediaの分かりにくいページって本当に難しいですね。いったん忘れましょう。

## 改めて、Dockerとは

僕の使い方ベースで説明してみます。

**例）Web開発する時に「本番と同じ環境をローカルに欲しい！」**

**→Dockerなら都合に合わせて好きな環境をつくれる**

本番環境はインフラの人が作ってくれるけど、ローカルでも同じ動作をしないと不便です。もしMacにNode.jsやPHPなど必要なものがインストールされていても案件ごとに必要なバージョンが違ったりします。
僕はDockerを使って「今回はPHP7とNginxだよ」とか「この案件はまだApache使ってるよ」などの情報から案件ごとに別々のローカル環境を作っています。

ちなみに、「NodeとかPHPとか使わんし」って現場や案件でも必要になることはあって、「サーバにあげたら動かなくなった」系の経験がある方はちゃんとローカル環境を作れていなかったって事が多いと思います。

### 「環境って？」

例えばWebは、ユーザーがブラウザに入力したURLを「ウェブサーバ」が読み解いて、「PHP」などを使って、「データベース」からデータを集めて、HTMLの形に整えて、ブラウザに送り返す、的なことをやっています。
今はもっとシンプルだったり本当はもっとややこしかったりしますが、一例として。

この「ウェブサーバ」とか「データベース」ってのは、まぁアプリ（みたいなもの）です。今回はこれらをひとまとめにしたものを環境とします。かつてはインフラ担当の人が黒い画面を通してどこか遠くに置いてあるマシンにアクセスして、これらを一つずつインストールして”環境”を構築していました。

古き良きLAMP的イメージ図
![lamp__illust.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546514/b98f909a-54a8-9362-d098-35be0af6567f.jpeg)

### どうやって？

Dockerでは、インストールという形をとらず、そのアプリをぱっと使えるようにしてくれます。基本的にはひとつずつが独立しています。例えば上の図のWebサーバの部分だけという意味です。同時に同じものをたくさん起動する的なことも出来ます。上の図のように組み合わせることも出来ます。

## 使ってましょう！

まず一旦、今までにチュートリアルで読んだコンテナとかイメージとかDockerfileとかは忘れましょう。
今回はサーバー兼コンテンツ表示してくれるNode.jsを立ち上げてみます。

手順としては、以下の5ステップでいきましょう。

- Dockerのインストール
- フォルダーを作る
- docker-compose.ymlをコピペ
- Hello worldサンプルファイルを用意
- コマンド１行

### Dockerのインストール

Macならアプリがあります。楽ですね。
https://hub.docker.com/editions/community/docker-ce-desktop-mac

アカウント作成が必要になっています。
（バージョンが上がるごとに画面がものすごく変わるので細かい説明は端折ります。）

Windowsの方はおググりくださいませ。

準備が整うのを待つ間に次のステップに進んでおきましょう。

### フォルダーを作る

どこでもどういう名前でも大丈夫ですので作業用フォルダを作ります。
僕はいつもhtdocsというフォルダの中で作業しているので、 `~/htdocs/test-node-hello` というフォルダを作ってみました。

### docker-compose.ymlを用意する

設定を書いておくファイルです。yml（やむる）形式というらしいです。
今作ったフォルダの中にファイルを作って、

```
test-node-hello
└── docker-compose.yml
```

以下をコピペ。

```yml:docker-compose.yml
version: '3'
services:
  app:
    image: node:13.2.0
    ports:
      - "8080:8080"
    volumes:
      - ./:/src
    working_dir: /src
    command: "node server.js"
```

Node.jsらしき記述がありますね。

### サンプルファイルを用意する

ここにserver.jsをつくりました。

```
test-node-hello
├── docker-compose.yml
└── server.js
```

```javascript:server.js
var http = require('http');

http.createServer(function (req, res)
{
	res.writeHead(200, {'Content-Type': 'text/plain'});
	res.end('Hello World\n');
}).listen(8080);

console.log('Server running at http://localhost:8080/');
```

[Node.jsの公式サンプル](https://nodejs.org/en/docs/guides/getting-started-guide/)の簡易版です。


### コマンド

これを `test-node-hello` のディレクトリで実行します。

```
docker-compose up -d
```
しばらく文字がずらずらと流れてくるかと思います、しばらく待ちます。

なにやら進行している図。
![docker-compose-up-d_ss.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546514/4c270561-09ea-0c02-ff16-f47df4ce89ba.jpeg)



これで、起動しているはずです。
起動しているかの確認は `Kitematic` というアプリを使って確認するのが楽です。Dockerのアプリをインストールしたらついてきます。

![kitematic_ss_001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546514/1e3ab10c-e1a8-9fd5-c317-d5003572fcde.jpeg)


`Containers`の一覧内の該当のもの（test-node-hello_app_1）のアイコンが「うねうね」になり、 `Server running at http://localhost:8080/` と表示されて、右側のWeb Preview部分が表示されていればバッチリです。
（こうなっていなかったらもう一回`docker-compose up -d`やってみてください。）
このWeb Previewをクリックするとブラウザが開き、`Hello World` の文字が！

![chrome_ss_001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546514/0a10235e-270f-8d9b-dbda-8a819574e5fb.jpeg)


おめでとうございます！
これで、DockerでNode.jsを立ち上げてHello Worldを表示出来ました！

お疲れさまでした！

## 退屈な説明文
今回はあえて「イメージ」「コンテナ」「サービス」などの用語をなるべく使わないようにしました。その都合で少し知識がある方には逆にわかりにくくなっているかもしれません。また、極力コマンドを叩かないようにしたので、遠回りしている部分もあります。

上記の例では、 `docker-compose` という仕組みを通して、DockerでNode.jsを使えるようにしました。
多くのNodeのHello Worldチュートリアルでは「ローカルマシンにNode.jsをインストールして、 `node -v`する」というところから始まるものが多いですが、インストールすることなくNode.jsだけを使えるように出来ました。実際にターミナルで `node -v` とやってみても `node: command not found` 的に表示されたり、先程あつかったバージョンとは違うことがわかると思います。

![node-v_ss_001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546514/a5665769-e320-bf33-1d50-0f0a04324593.jpeg)
（同じマシン上の、ローカル（左）とDocker内（右） `node -v`の結果）

こうすれば例えば、試してみたい新しいフレームワークの要求しているNodeのバージョンがローカルにインストールされているものと違ってもサクッとお試しできます。
「月イチだけPHP保守案件がある」とかもこんな感じでローカル環境を用意しておくといいかと思います。

今回はシンプルにするためにWebサーバとブラウザへの出力を一つのサービスで行えるNode.jsをサンプルにしましたが、実際に扱っている案件や勉強の内容に合わせてトライしてみると理解が進むと思います。一昔前まではLAMP環境を作ってみましょう！とかやってました。最近だとNode.jsとMongoDBを使えるようにしてみたりって感じでしょうか。

これだけではまだ利便性としては実感がわかないと思いますが、**実際にコンテナを起動して、アクセスしてブラウザに表示できた成果**を忘れないようにしてください。
是非ここからdocker-composeを改造してみたり、Kubernetesに進んでみたり、nodeのフレームワークに挑戦してみましょう！