今から始めるDocker初心者にお届けするDockerの始め方


Dockerをここ1週間程触ってみました。
今まで何回かDockerを触ったことがあるのですが、

* CUIのオプション多すぎて覚えられないしVagrantよりオプション多くてウザくね？
* コンテナーをproductionで運用するイメージが全然沸かなかったし、コンテナーが突然落ちるとか回りから少し聞いていた
* ``` vagrant up ``` とAnsibleで事足りていた

等があり、イマイチ本気で取り組んでいませんでした。
とある事情で[swagger-ui](https://hub.docker.com/r/swaggerapi/swagger-ui/)をDockerで使い

**やっぱpullするだけで環境できるのスゲー便利だな**

と思いRailsアプリケーションをDockerで作成してみました。

**が、しかしいざやり始めてググるとDockerのアップデートが頻繁で古い情報と最新の情報が混在している** のが現状で情報を探すのが大変でした。

そこで2017年11月現在でこれやっておけばDockerがすんなりはいれるんじゃないか？
という情報をまとめて書こうかと思いまとめてみました。

## 対象者

* まだDockerを触ったことがない人
* DevOpesでAnsibleとかChefとか触っているけどもDocker使っていない方
* Docker何それ美味しいの？って方

尚、当人もDocker初心者なので指摘等ありましたら編集リクエストお願い致します。mm

## なぜDockerが良いのかを知る


* [とりあえずDockerの何が良いの？1分で教えてよ！](http://bufferings.hatenablog.com/entry/2016/02/11/004342)

これが僕にはDockerを真剣に触ろうと思ったきっかけでその後Dockerでミドルウェアを幾つか(swagger-ui,redash,jenkins) ``` docker pull ``` して触ってみて先述したとおり利便性を感じて始めました。


今まで自分はprovisioningツールでサーバーは管理していたものの

* 冪等性を担保するのが大変
* 寝かして置くと動かなくなる(テストを書いていなかったのが原因かも知れませんが)
* Debugに時間がかかる

何となく漠然とprovisioningツールだけでサーバーを管理、保守するのが辛くはない?けども、時間がかかるし
もっとスマートに素早くサーバーを構築したいという漠然としたものがありました。

上記リンクを読んでみて、該当する部分があったらとりあえず初めて見るといいと思います。



## Docker for Macを使う

次に初めてみたいと思ったら

[Docker for Mac](https://www.docker.com/docker-mac)を使ってみましょう。
手軽に ``` Docker pull ``` して触れます。

リンクを押すのが面倒な方は

```
brew cask install docker
```

でOKです。

昔はVirtualboxにDocker用のVMを生成してそのVMからDockerでしたが、やはり一回VMに入るコストとVMに入ってからのDockerは億劫さがあります。

Docker for Macはそういう煩わしさから開放させてくれます。
また以前にDocker Toolbox等を使っていた人もMigrationツールで素直に移行できるかと思います。
(Docker for Macが勝手にやってくれます)

Macな人は使うと良いでしょう。

## DockerのCUIのオプションに億劫さを感じる人ならばKitematicを入れてみましょう

[Kitematic (Beta)](https://kitematic.com/)を[Docker for Mac](https://www.docker.com/docker-mac)導入後に入れてみましょう。

リンクを押すのが億劫な片は

```
brew cask install kitematic
```

でOkです。

Kitematic経由でDocker Imageからの起動、コンテナの状態確認を簡単に行えます。

例としてjenkinsを試してみる場合

![dokcer-jenkins1](https://raw.githubusercontent.com/ryurock/qiita_images/master/kitematic-jenkins.png)

できたコンテナにlocalからアクセスする場合もGUIから簡単に行えます。

![dokcer-jenkins2](https://raw.githubusercontent.com/ryurock/qiita_images/master/kitematic-jenkins2.png)




## Docker Composeから入る

大概のアプリケーションを構築する場合DataBaseに接続して....ってのがほぼです。
そこでコンテナ同士の連携を簡単にできるdocker-composeから始めましょう。

例としてRails + Postgresで構成を構築するならばコレだけです。

* [Quickstart: Compose and Rails](https://docs.docker.com/compose/rails/)



``` docker-compose.yml ``` に記載されている

```yaml
services
  db:
  .
  .
  web:
  .
  .
```

この2つはコンテナ側に割り当てられているIPアドレスを ``` /etc/hosts ``` に書き込んでくれます。
そしてそれを参照して2つのコンテナとの連携をしてくれます。

たったこれだけで Rails + Postgresの環境が手に入ります。

上記2つのコンテナを起動するのは下記のコマンドだけです。

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

またこの2つのコンテナの起動を停止するのも下記だけです

```
docker-compose stop
```

Railsアプリベースならコレを元に改良するだけでもいいでしょう。

golangを始めたいのならば公式golangのイメージもあります

* [Docker golang image (offical)](https://docs.docker.com/samples/library/golang/)


amazonlinuxのコンテナもあります

* [Docker amazonlinux image](https://docs.docker.com/samples/library/amazonlinux/)

このイメージをこんな風に足すだけでよいのです。

(例としてamazonlinux + postgrsにする場合)

```yaml
version: '3'
services:
  db:
    image: postgres
  web:
    image: amazonlinux
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
```


幸い有志?による日本語ドキュメントもあります。(少しバージョンは古いらしいですが、今でも十分使えます)

* [Docker Compose 日本語ドキュメント](http://docs.docker.jp/compose/toc.html)

Dockerfileを書いて試したい方は下記を一読してから書き始めるとよいかもしれません。

* [Dockerfile のベストプラクティス](http://docs.docker.jp/engine/articles/dockerfile_best-practice.html)


## Dockerを始めるならコマンドはコレだけでOK

DockerにはいっぱいCUIのオプションが存在しますが、とりあえず始めるならコレだけ覚えればOKです。

### コンテナの起動

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

### コンテナに入る(SSH風に入る)

```
docker-compose exec {コンテナの名前} /bin/bash
```

--loginも足すと ``` /etc/profile ``` を読み込んでくれます

```
docker-compose exec {コンテナの名前} /bin/bash --login
```

### コンテナの起動状態確認

```
docker-compose ps
```

### コンテナの停止

```
docker-compose stop
```

### イメージのbuild

```
docker-compose build
```

### 使われていないイメージの削除

```
docker image prune
```

そんなに難しくありません。

## 最後に

回りから **Ansibleが上手く動かない** と言われてついカッとなって始めてみたDockerですが、
やり始めると意外とシンプルな事に気づきました。
自分も初心者なのでこれからもっとガッツリ触っていこうかと思う所存でございます。mm