【個人メモ】docker image を作っていく流れ

**社内共有用**

# dockerに関する情報共有

[Docker](https://www.docker.io/)の社内プレゼン・ハンズオンやるやるいっててやれていないのでQiitaを使って一部代用。

# docker image を自作するには

自作する方法はあるのだけれど、
今時点だとMac OS Xな環境で行う場合どうすれば楽にできるんだろうか、
って思ったので個人的にメモとしてまとめておく。

今回boot2dockerを利用するため、
以下のブログエントリを参考しました。大変ありがたかったです。 m(_ _)m。

[boot2dockerでdockerを試す](http://blog.n-z.jp/blog/2014-02-23-boot2docker.html)

# 環境構築
## boot2dockerを使おう

[boot2dockerでdockerを試す](http://blog.n-z.jp/blog/2014-02-23-boot2docker.html)
の通りインストールすればよいので割愛

homebrewでインストールをして
起動準備をして、起動を行う。

boot2dockerインストール時に合わせてdockerもインストールされる。

```bash
> brew install boot2docker
> boot2docker init
> boot2docker start
```

## docker hostの設定をする

homebrewでインストールを行い、
[DOCKER_HOST](https://github.com/dotcloud/docker/pull/3303)環境変数に
boot2dockerのゲストマシンのエンドポイントを指定

```bash
> brew install homebrew
> export DOKCER_HOST='tcp://localhost:4243'
```

これで準備完了

## dockerの動作確認

docker pull ubuntuを試す

```
> docker pull ubuntu
```

で、docker imageをpullすることが出来れば
boot2docker, dockerの設定は成功。

![568e4f8c-a3c0-6476-f35c-16abee18670e.png](https://qiita-image-store.s3.amazonaws.com/0/3985/b891f8d3-d1b6-cc14-df92-bd8c2636ee09.png)


# Dockerfileの構築
## ディレクトリ・ファイルの構成

僕は以下の形で
スクリプトや設定ファイルを収めたディレクトリ、
Dockerfileを配置している。

![スクリーンショット 2014-03-02 9.39.24.png](https://qiita-image-store.s3.amazonaws.com/0/3985/ce035aaf-8b67-8361-5313-147ff3395770.png)

各ディレクトリに何を置いて、
そしてDockerfileに何を書くのかを簡単に書いていく。

## まずはDockerfile書いてdocker imageをビルドだ

Dockerfileに以下のコマンドを書いていく。

```bash
FROM centos

MAINTAINER Keiji Matsuzaki <futoase@gmail.com>
```

MAINTAINERの部分は適宜自分の名前・メールアドレスに書き換えること。
[docker indexに表示される](https://index.docker.io/u/futoase/docker-growthforecast/)。

![スクリーンショット 2014-03-02 9.59.12.png](https://qiita-image-store.s3.amazonaws.com/0/3985/6b39981a-9fd5-d336-f385-f5242dae099f.png)


この状態で、```docker build``` を実行する。

![828fc62a-21a3-4835-ad01-fcc0f5733d7a.png](https://qiita-image-store.s3.amazonaws.com/0/3985/ab0bc109-ba02-fd0c-90d4-92f0981d702e.png)


docker公式の **centos** docker imageを利用し、
docker imageが構築される。

この場合、特に何もしないから公式のdocker imageと同じものができあがる。

## 作りたてのdocker imageを起動する

作りたてのdocker imageのIMAGE IDを取得する。

```
> docker images -q | head -1
9f3172f57d27
```

取得したdocker imageのIMAGE IDを利用し、
```docker run``` コマンドを実行する。

```bash
> docker run -i -t $(docker images -q | head -1) /bin/bash
bash-4.1#
```

-i でインタラクティブモード、
-t で仮想端末を有効にする。
そして最後に渡している/bin/bash は、
docker containerで実行するコマンドだ。

以上のオプションを渡すことにより、
入力待ち状態にすることができた。
またdocker containerを作ることもできた！

ただこのままだとdocker containerから抜けた瞬間に
docker containerが消えてしまうけれど。

# docker templateを書いていこう

簡素なdocker templateを書いて、
試しに動作させてみよう

以下の要件(真顔)を満たす感じで。

- 利用するdocker imageは **docker official imageにあるcentos** とする
- reverse proxyとして **nginx** を利用する
- 予め用意しておいたウェブアプリを動作させる
- 各サービスを起動させるスクリプトを```docker run```時に実行させるようにする
- docker containerの外からは80番ポートでアクセスできるようにする

## Dockerfile

Dockerfileを以下のように書く。

```bash:Dockerfile
FROM centos

MAINTAINER Keiji Matsuzaki <futoase@gmail.com>

# setup remi repository
RUN wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
RUN wget http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
RUN curl -O http://rpms.famillecollet.com/RPM-GPG-KEY-remi; rpm --import RPM-GPG-KEY-remi
RUN rpm -Uvh remi-release-6*.rpm epel-release-6*.rpm
RUN yum -y update && yum -y upgrade

# setup nginx yum repository
ADD ./templates/nginx.repo /etc/yum.repos.d/nginx.repo
RUN yum -y update

# setup tools
RUN yum -y groupinstall --enablerepo=epel,remi "Development Tools"

# install nginx
RUN yum -y install --enablerepo=nginx nginx

# mkdir /tmp/download
RUN mkdir -p /tmp/download

# setup ruby-install
RUN wget -O /tmp/download/ruby-install-0.4.0.tar.gz https://github.com/postmodern/ruby-install/archive/v0.4.0.tar.gz
RUN cd /tmp/download && tar -xvzf ruby-install-0.4.0.tar.gz
RUN cd /tmp/download/ruby-install-0.4.0 && make install

# cleanup
RUN rm -rf /tmp/download

# install ruby 2.1.1
RUN ruby-install ruby 2.1.1

ENV PATH /opt/rubies/ruby-2.1.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

RUN gem install bundle --no-ri --no-rdoc 

# install sinatra-hello-world
RUN adduser -m app
RUN mkdir -p /var/app && chown app:app /var/app
RUN su app -c 'git clone https://github.com/Substanz/sinatra-hello-world.git /var/app/sinatra-hello-world'
RUN su app -c 'cd /var/app/sinatra-hello-world && bundle ins --path vendor/bundle'

# add startup.sh
ADD ./scripts/startup.sh /var/app/startup.sh
RUN chown app:app /var/app/startup.sh
RUN chmod +x /var/app/startup.sh
CMD ["/var/app/startup.sh"]
```

### Dockerfileがやってること

1. remi yum リポジトリの登録
2. nginx yum リポジトリの登録
3. [ruby-install](https://github.com/postmodern/ruby-install) のインストール
4. [ruby v2.1.1](https://www.ruby-lang.org/ja/news/2014/02/24/ruby-2-1-1-is-released/)のインストール
5. [bundler](https://github.com/bundler/bundler)をインストール
6. 用意したサンプルアプリをgithubのリポジトリからcloneする
7. startup.shスクリプトをホストからdocker imageにコピー・実行権限付与
8. [CMD](http://docs.docker.io/en/latest/reference/builder/#cmd) により、detach した時に実行されるコマンドを登録(上記の場合、startup.shを利用)

### ネットワーク経由で手に入らないリソースについて

**nginx.conf**, **nginx.repo**, **startup.sh** については
ホスト側にあるtemplates, scriptsディレクトリから
必要なファイルをコピーしている。

- **nginx.repo** ファイルを利用して```yum nginx``` リポジトリを登録
- **nginx.conf** ファイルを利用して```nginx``` の設定を行う
- **startup.sh** ファイルを利用して```git clone``` を行ったアプリケーションを起動する

## templatesディレクトリ

僕は、templatesディレクトリに
マシンのミドルウェアを設定するためのファイルをおいている。

今回はnginxのyum リポジトリ設定ファイル、
リバースプロキシ設定ファイルを置いている。

## scriptsディレクトリ

scriptsディレクトリについては、
マシン起動時に実行するコマンドを書いた
スクリプトファイルをまとめるようにしている。

今回は、docker run -d (detach mode)の時に
実行するスクリプトファイルを置いた。

## docker imageを作成する。

```bash
> docker build .
```

## boot2dockerのポートフォワードを指定

[dockerのdocument](https://docs.docker.io/en/latest/installation/mac/#forwarding-vm-port-range-to-host)に[VBoxManageコマンド](http://www.virtualbox.org/manual/ch08.html)を実行せよ、と書かれている。

boot2dockerをstopさせたあと、ポートフォワードの設定を行う

```bash
> boot2docker stop
> VBoxManage modifyvm "boot2docker-vm" --natpf1 "nginx,tcp,,8080,,8080";
```

boot2docker マシンのIPアドレス設定やポートフォワードなどについては
既に本家にPRが上がっている。

[PR#93](https://github.com/boot2docker/boot2docker/pull/93/)がmergeされれば
便利になると思う...

## 動作確認

終わったら、boot2dockerを起動し、
docker containerを立ち上げ、
http://localhost:8080/ にアクセスする。

```bash
> boot2docker up
> docker run -p 8080:8080 -d $(docker images -q | head -1) 
> open http://localhost:8080/
```

Welcome to underground... が出ればOK

![スクリーンショット 2014-03-02 2.42.14.png](https://qiita-image-store.s3.amazonaws.com/0/3985/0792868b-e111-986c-7edb-179989240060.png)

docker imageの作成手順については以上 :smile: 

# 他参考

- [Docker commands](http://docs.docker.io/en/latest/reference/commandline/)
- [Dockerfile Reference](http://docs.docker.io/en/latest/reference/builder/)
- [Docker Run Reference](http://docs.docker.io/en/latest/reference/run/)