Docker上の設定ファイルをホストに移す

[続き](http://qiita.com/flny/items/c0fd01db5fb3de6f8098)

# コンテナ内の設定ファイルをホストに移す

[前回]() Docker上でunboundを動かしたときに 設定ファイルunbound.confを編集しました。当たり前ですが 編集後にイメージをcommitせず コンテナを削除してしまうと、編集内容が消えてしまいます。今回は unbound.confをコンテナからホストに移し、コンテナを削除しても設定が残るようにしてみます。

## コンテナ内の設定ファイルをホストにコピーする
docker cp コマンドを使います。コピー先は ~/docker/unbound/ にしました。

```
$ docker cp unbound:/etc/unbound/unbound.conf ~/docker/unbound/
$ cat ~/docker/unbound/unbound.conf
# Unbound configuration file for Debian.
#
# See the unbound.conf(5) man page.
(略)
```
あっさりコピーされました。

## ホストの設定ファイルをコンテナから参照する

少し調べた限りでは、コンテナから動的にホストのファイルを参照するには
1. docker run コマンドの -v オプションでディレクトリを共有する
のが良さそうです。というかコレしか見つけられませんでした。

ホストのファイルを直接参照するのではなく、ホストからコンテナへ編集の都度コピーするのであれば
2. docker cp コマンドでコピーする。[^1]
3. Dockerfile の ADD 命令でコピーする。
という方法がありそうです。

3パターンそれぞれ、ホストのunbound.conf を編集したあと それを反映させるまでの動きを想定してみます。
1. docker attach して service unbound restart (2アクション)
2. docker cp して docker attach して service unbound restart (3アクション)
3. docker stop して docker rm して docker build して docker run (4アクション)

アクション数では1が有利ですが、3はunbound以外のサービスでも同様の動きでよさそうなのが魅力です。この際、unbound を題材に3の方法を試してみます。

## Dockerfileを記述する

unbound.confと同じ場所にDockerfileを作成します。
```
$ nano ~/docker/unbound/Dockerfile
```

```docker:Dockerfile
FROM ubuntu:14.04
MAINTAINER flny flny@example.com

RUN apt-get update && apt-get install -y \
      unbound

ADD unbound.conf /unbound.conf
ADD start.sh /start.sh

RUN chmod +x /start.sh

EXPOSE 53
EXPOSE 53/udp

CMD /start.sh
```

同じ場所に、start.shを作成します。この中でunboundのデーモンを起動します。

```
$ nano ~/docker/unbound/start.sh
```

```sh:start.sh
#!/bin/bash

/usr/sbin/unbound -c /unbound.conf
/bin/bash
```

最後の/bin/bashがないと、デーモンが起動した直後にコンテナが終了してしまうので要注意です。


## Dockerfileを元にイメージを作成(ビルド)する

前準備として、前回作成した既存のコンテナとイメージを削除します。(同名のコンテナを作るのに邪魔になるため)

```
~$ docker stop unbound && docker rm unbound && docker rmi unbound
unbound
unbound
Untagged: unbound:latest
Deleted: db71d76a5fa81674e8788b15dca834984d0b0ccbf7ec02bdc1f20acc54d14b45
(略)
```

次に、docker build コマンドでDockerfileを指定し、イメージを作成します。
-t でイメージ名を指定します。次のパラメータ ~/docker/unbound/ はDockerfileの場所を表しています。

```
$ docker build -t unbound ~/docker/unbound/
Sending build context to Docker daemon 4.608 kB
Step 1 : FROM ubuntu:14.04
 ---> e9ae3c220b23
Step 2 : MAINTAINER flny flny@example.com
 ---> Using cache
 ---> 2913305db252
Step 3 : RUN apt-get update && apt-get install -y       unbound
 ---> Running in fb34c2b86352
Ign http://archive.ubuntu.com trusty InRelease
Get:1 http://archive.ubuntu.com trusty-updates InRelease [64.4 kB]
Get:2 http://archive.ubuntu.com trusty-security InRelease [64.4 kB]
Hit http://archive.ubuntu.com trusty Release.gpg
Get:3 http://archive.ubuntu.com trusty-updates/main Sources [311 kB]
(略)
Step 8 : EXPOSE 53/udp
 ---> Running in 6d1d511b1663
 ---> 43e0d29ce32d
Removing intermediate container 6d1d511b1663
Step 9 : CMD /start.sh
 ---> Running in 64eddac14613
 ---> 932f374aa395
Removing intermediate container 64eddac14613
Successfully built 932f374aa395
```
Dockerfileに書いた内容が次々実行され、イメージが作成されます。

## イメージを元にコンテナを作成する
イメージが出来たあとはDockerfileがないときと同じです。docker run でコンテナを作成します。

```
~$ docker run -i -t -d --name="unbound" -p 53:53 -p 53:53/udp unbound
44979f5a352d556e8f464c15d922d8795a11f3a7ca5c18754d968f78b9c12c6d
$ docker ps -l
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                    NAMES
44979f5a352d        unbound             "/bin/sh -c /start.sh"   45 seconds ago      Up 43 seconds       0.0.0.0:53->53/tcp, 0.0.0.0:53->53/udp   unbound
~$ netstat -nap | grep 53
(No info could be read for "-p": geteuid()=1000 but you should be root.)
tcp6       0      0 :::53                   :::*                    LISTEN      -
udp6       0      0 :::53                   :::*                                -
(略)
```

[続く]()

[^1]: ホストからコンテナへのコピーは、[docker 1.8からできるようになった](https://github.com/docker/docker/pull/13171)とのこと