Docker事始めメモ

Dockerを軽くいじってみたので備忘的なメモ。

# 基本コマンド
## イメージのダウンロード
```bash
$ docker pull {イメージ名}:{タグ名}
```

## イメージからコンテナを作成して実行
```bash
$ docker run [オプション] [--name {コンテナ名}] {イメージ名}[:{タグ名}] [コンテナで実行するコマンド] [引数]
```

**基本的なオプション**

| オプション | 説明 |
|:-----------|:------------|
| -d | バックグラウンドで実行 |
| -i | 標準入力を開く。/bin/bashなどでコンテナを操作する際に指定 |
| -t | tty(端末デバイス)を開く。/bin/bashなどでコンテナを操作する際に指定  |
| -p {host}:{container} | Dockerサーバのホストとポートマッピングを構成  |

* コンテナ名はユニークでないといけない（同じコンテナ名で実行してもエラーになる）

## 実行中のイメージの一覧を表示する
```bash
$ docker images [-a]
```
* -aオプションを付けると停止中のイメージも表示

## バックグラウンドで実行中のコンテナを停止する
```bash
$ docker stop {コンテナ名}|{コンテナID}
```

## コンテナを再実行する
```bash
$ docker start [-i] {コンテナ名}|{コンテナID}
```
* -iは`docker run`と同じ

## 独自のイメージを作成する
```bash
$ docker commit {コンテナ名}|{コンテナID} {ユーザ名}/{イメージ名}
```
ユーザ名とイメージ名は任意。

## コンテナを削除する
```bash
$ docker rm {コンテナ名}|{コンテナID}
```

## イメージを削除する
```bash
$ docker rmi {イメージ名}|{イメージID}
```

## Dockerfileからイメージを生成する
```bash
$ docker build [-t {イメージ名}[: {タグ名}]] {Dockerfileがあるディレクトリ}
```
* -t を使うとイメージ名とタグ名を指定できる

## Docker Hubにログインする
```bash
$ docker login
Username: {登録ユーザ名}
Password: {登録パスワード}
Email: {登録メールアドレス}
Login Succeeded
```

## Docker Hubにイメージをアップロードする
```bash
$ docker push {イメージ名}
```
*※ イメージ名は`{ログインユーザ名}/`から始まる名称でなければならない。*

# Dockerfile
* File名は`Dockerfile`じゃないといけない
* 1行1命令で上から順に処理される
* 1行は命令と引数で成り立つ
* #で始まる行はコメント
* 命令は大文字で記述するのが一般的

**主な命令**

| 命令 | 説明 |備考 |
|:-----------|:------------|:------------|
| FROM	| 元となるDockerイメージの指定 |
| MAINTAINER | 作成者の情報 |
| RUN | コマンドの実行 |
| ADD | ファイル／ディレクトリの追加 |
| CMD | コンテナーの実行コマンド 1 | `docker run`で上書き可能
| ENTRYPOINT | コンテナーの実行コマンド 2 | `docker run`で上書き不可 |
| WORKDIR | 作業ディレクトリの指定 |
| ENV | 環境変数の指定 |
| USER | 実行ユーザーの指定 |
| EXPOSE | ポートのエクスポート |
| VOLUME | ボリュームのマウント |

# Tips
## Dockerコマンドをsudoなしで実行する
デフォルトではdockerコマンドはsudoが必要だが、dockerグループにユーザを追加すればそのユーザでdockerコマンドが実行できるようになる。

```bash
$ sudo gpasswd -a <User> docker
```

# やってみた系
## MacでDockerを使えるようにする
### 環境
* OS X 10.9.5
* [Homebrew](http://brew.sh/index_ja.html)/[cask](http://caskroom.io/)インストール済み

### 手順
1 - [VirtualBox](https://www.virtualbox.org/)をインストール
VirtualBoxはDockerサーバ/コンテナを動作させる仮想環境として使う。

```bash
$ brew cask install virtualbox
```

2 - dockerとboot2dockerをインストール
boot2dockerはBoot2docker仮想マシンを管理するコマンドラインツール。

```bash
$ brew install docker boot2docker
```

3 - 仮想マシンを起動

```bash
$ boot2docker init ## 仮想マシンイメージをダウンロード
...(省略)
$ boot2docker up ## 仮想マシンを起動
...(省略)
$ boot2docker status ## ステータス確認
running
```

4 - 環境変数の設定
Dockerクライアント(Mac)からDockerサーバ(仮想マシン)にアクセスできるようにする為に`boot2docker up`実行時に表示される環境変数を`export`する必要がある。

```:こういうの
DOCKER_HOST=tcp://xxx.xxx.xxx.xxx:xxxx
DOCKER_CERT_PATH=/Users/username/.boot2docker/certs/boot2docker-vm
DOCKER_TLS_VERIFY=1
```

`.bashrc`あたりに直接書いてもいいが、仮想環境を落としたり上げたりするとIPアドレスが変わる可能性があるのでここではコマンドで設定する。

```bash
$ $(boot2docker shellinit)
```
`docker version`コマンドでサーバ側の情報が表示されれば設定完了。

5 - あとは普通に使える
※ コンテナが実行されるのは仮想マシン上なので`Nginx`などをバックグラウンドで動かした場合などは`DOCKER_HOST`に向けないといけない。

## CentOSにnginxをインストールした独自イメージを作成する
1 - CentOS7のイメージをPull

```bash
$ docker pull centos:7
```

2 - Pullしたイメージからコンテナを実行

```bash
$ docker run -it --name cent1 centos /bin/bash
```
自動的にCentOSにログインした状態でのttyが開く。

3 - nginxのインストール（CentOS内部での操作）
nginxのyumレポジトリを追加する。

```/etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
```

nginxをyumでインストール

```bash
cent1$ yum install -y nginx
```
CentOSでやることはコレで終わりなので`exit`で抜ける。
※ 抜けるとコンテナは停止状態になる

4 - 現状のイメージ（nginxインストール済みCentOSイメージ）を作成する

```bash
$ docker commit cent1 myname/nginx
```

5 - myname/nginxコンテナをバックグラウンドで実行する

```bash
$ docker run -d -p 80:80 --name nginx1 myname/nginx /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
```

6 - curlで確認

```bash
$ curl localhost:80
```
HTMLが返ってくるのでちゃんとnginxが起動している。

7 - コンテナとイメージを削除する
今回作ったイメージとコンテナを削除してお掃除。

```bash
$ docker stop nginx1 ## 5で起動したコンテナを停止
$ docker rm nginx1 ## コンテナを削除
$ docker rmi myname/nginx ## 4で作成したイメージを削除
```

## nginxインストール済みCentOS7のイメージをDockerfileから作成する
「CentOSにnginxをインストールした独自イメージを作成する」でやったことをDockerfileから一括でやらせてみる。

1 - Dockerfileを作成
適当なディレクトリでDockerfileを作成する。

```~/docker/nginx-sample/Dockerfile
FROM centos
MAINTAINER myname <myname@hoge.com>
ADD nginx.repo /etc/yum.repos.d/
RUN yum install -y nginx
ENTRYPOINT /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
```

2 - nginx.repoを同じディレクトリに作成
Dockerfileの`ADD`で使う`nginx.repo`を用意しておく。
中身は「CentOSにnginxをインストールした独自イメージを作成する」の3と同じ。

3 - buildコマンドでイメージを作成

```bash
$ docker build -t myname/nginx:1.0 docker/nginx-sample
```

4 - コンテナをバックグラウンドで動かす
「CentOSにnginxをインストールした独自イメージを作成する」の5と同様にバックグラウンドで動作させてみる。

```bash
$ docker run -d --name nginx2 -p 80:80 myname/nginx:1.0
```

`curl localhost:80`でHTMLが返ってくるのでOK。

## Automated Buildを使ってGithub連携してPushのタイミングで自動でイメージをビルドする
Automated Buildという機能とGithubを連携させてイメージを任意のタイミングで自動ビルドすることができる。

0 - 前提条件

* [Docker Hub](https://hub.docker.com)にユーザ登録済み
* [Github](https://github.com)にユーザ登録済み

1 - GithubにDockerfileを置いたリポジトリを作成
ここでは「nginxインストール済みCentOS7のイメージをDockerfileから作成する」で作成したDockerfile（とnginx.repo）をそのまま置いただけのリポジトリを作成した。(*作成方法は割愛*)

2 - DockerHubとGitHubを連携
2-1. DockerHubの画面右上のプルダウンから「Settings」をポチ
2-2. 画面上部のリンクのうち「Linked Accounts & Services」をポチ
2-3. 「Public and Private (Recommended)」の「Select」ボタンをポチ
2-4. この後、GitHubの認証と認可画面があるので良しなにポチ

3 - Automated Buildの作成
3-1. DockerHubの画面右上のプルダウンから「Create Automated Build」をポチ
3-2. Githubのリポジトリが一覧表示されるので、Dockerfileを置いたリポジトリを選択
3-3. 全て必須項目になっているので適当に入力して「Create」ボタンをポチ

4 - DockerHubからビルドしてみる
画面右の「Trriger a Build」ボタンをポチ。
これだけでビルドが始まる。（ちょっと時間かかった・・・）

「Build Details」からビルド履歴が見れる。
各ビルドのリンクからログなどのビルド詳細情報も見れる。失敗した場合はここを参照すると良さ気。

5 - おまけ
「Build Settings」でビルド対象を追加できる。
Githubの「Branch」か「Tag」をターゲットにできて、それぞれDockerのタグ名を決められる。
例えば、masterブランチを「latest」タグに、1.0ブランチを「1.0」タグに指定してビルドすると、２つビルドされ、タグも２つできていることが確認できた。

6 - WebhookでGithubと連携して自動ビルドする
6-1. DockerHubの「Build Settings」リンクをポチ
6-2. 画面の中ほどの「Build Triggers」という項目にある「Activate」ボタンをポチ
6-3. 表示される「Trigger URL」をコピー
6-4. GitHubの対象リポジトリの「Settings」リンクをポチ
6-5. 「Webhooks & services」リンクをポチ
6-6. 「Webhooks」の「Add Webhook」ボタンをポチ
6-7. 「Payload URL」に先ほどコピーしたURLを貼り、「Content type」は「application/json」を選択、「Which events would you like to trigger this webhook?」は「Just the push event.」を選択、「Active」にチェックを入れて、「Add Webhook」ボタンをポチ

これでGithubにPushされたタイミングでDockerイメージが自動でビルドされるようになる。

# 参考
* [Docker](https://www.docker.com/)
* [Docker Hub](https://hub.docker.com/)