私の Docker TIPS 


# Docker TIPS あれこれ

Docker を使っているとアレどーすんだっけ？って探しまわることが多いのでここにまとめておこうと思います。
随時更新予定です。
先日のまとめの分も再度記載しておきます。
基本、ホストは ubuntu-server 12.04、コンテナ側は普段使いしている13.10前提で記述しています。

## docker のイメージ格納先を変更したい

apt で docker をインストールしている人がほとんどだと思います。
デフォルトでは `/var/lib/docker` になります。

```
/etc/default/docker
```

ここに設定があるのでそこで変更できます。
DNSの設定もここでできます。

格納先は `-g` オプションで設定できます。

```ini
# Docker Upstart and SysVinit configuration file

# Customize location of Docker binary (especially for development testing).
#DOCKER="/usr/local/bin/docker"

# Use DOCKER_OPTS to modify the daemon startup options.
DOCKER_OPTS="-dns 8.8.8.8 -dns 8.8.4.4 -g /opt/docker"

# If you need Docker to use an HTTP proxy, it can also be specified here.
#export http_proxy="http://127.0.0.1:3128/"

# This is also a handy place to tweak where Docker's temporary files go.
#export TMPDIR="/mnt/bigdrive/docker-tmp"

```

## コンテナを一気に削除したい

Dockerfile を書いているとゴミコンテナが大量にできてしまいます。
以下で使用していないコンテナを一度に削除してしまいましょう。

```
$ sudo docker rm $(sudo docker ps -a -q)
```

起動中のコンテナは削除されません。
強制的に削除する場合には`-f`オプションを使って下さい。

## イメージを一気に削除したい

同様にイメージも一気に削除できます。
本当にまっさらになってしまうので注意しましょう。
依存関係によってはうまく消えないので依存しているコンテナを削除してから実行しましょう。

```
$ sudo docker rmi $(sudo docker images -q)
```

依存関係などは`docker images` の `--tree`オプションを使うとわかりやすくてよいでしょう。

```
$ sudo docker images --tree
```

## aufs のリミット

Docker での aufs layer の制限は 0.7 移行、42から127に引き上げられていますが、それでも足りない場合には
export -> import することでまとめることができます。
土台になるbaseイメージなどでごっそり必要な設定、インストールを済ませ、export -> importすることで
layer 数を稼ぐことができます。
export する際にはコンテナIDが必要になるので注意して下さい。

まずコンテナIDを取得してから作業しましょう。

```
$ container_id=$(sudo docker run -d <REPOS:TAG> /bin/bash -c "")
$ sudo docker export $container_id > tmp.tar
$ cat tmp.tar | sudo docker import - <REPOS:TAG>
```

import 時に TAG を貼り直してしまっているのですが、心配な方は指定せずに最新のコンテナに TAG を振りなおしましょう。

## private-repository でイメージを共有、バックアップする

private-repository を立てることでイメージの共有を行うことができます。
S3 へのアップロードはそのうち試しますが、今回は push したイメージをファイルシステムに落とし込む方法
です。
private-repository は registry という名前で提供されています。
そのため即試すことができます。

```
$ sudo docker run -d -p 5000:5000 -v /opt/registry:/tmp/registry:rw registry
```

Docker のイメージで提供されているのでそのままだと registry が落ちると push した内容も吹き飛んでしま
います。
そのため、ホストの/opt/registry をマウントして push したイメージを永続化しています。
（デフォルトで/tmp/registryへ保存されるので）
registry は github にあるので興味のある方は見てみるといいです。
構成は `gunicorn + gevent + flask` です。
そのうち詳しく書くかも知れません。

# Dockerfile

## apt-get が遅いんだけど

apt の参照先が本家なので国内からだと遅めです。
ミラーを設定しましょう。
たまにミラーの設定のことをちらっと書いてる人がいますが、フルで書いておいた方がよいと思います。

```dockerfile
RUN echo "deb http://jp.archive.ubuntu.com/ubuntu/ saucy main restricted\n\
deb-src http://jp.archive.ubuntu.com/ubuntu/ saucy main restricted\n\
deb http://jp.archive.ubuntu.com/ubuntu/ saucy-updates main restricted\n\
deb-src http://jp.archive.ubuntu.com/ubuntu/ saucy-updates main restricted\n\
deb http://jp.archive.ubuntu.com/ubuntu/ saucy universe\n\
deb-src http://jp.archive.ubuntu.com/ubuntu/ saucy universe\n\
deb http://jp.archive.ubuntu.com/ubuntu/ saucy-updates universe\n\
deb-src http://jp.archive.ubuntu.com/ubuntu/ saucy-updates universe\n\
deb http://jp.archive.ubuntu.com/ubuntu/ saucy multiverse\n\
deb-src http://jp.archive.ubuntu.com/ubuntu/ saucy multiverse\n\
deb http://jp.archive.ubuntu.com/ubuntu/ saucy-updates multiverse\n\
deb-src http://jp.archive.ubuntu.com/ubuntu/ saucy-updates multiverse\n\
deb http://jp.archive.ubuntu.com/ubuntu/ saucy-backports main restricted universe multiverse\n\
deb-src http://jp.archive.ubuntu.com/ubuntu/ saucy-backports main restricted universe multiverse\n\
deb http://security.ubuntu.com/ubuntu saucy-security main restricted\n\
deb-src http://security.ubuntu.com/ubuntu saucy-security main restricted\n\
deb http://security.ubuntu.com/ubuntu saucy-security universe\n\
deb-src http://security.ubuntu.com/ubuntu saucy-security universe\n\
deb http://security.ubuntu.com/ubuntu saucy-security multiverse\n\
deb-src http://security.ubuntu.com/ubuntu saucy-security multiverse\n"> /etc/apt/sources.list
```

## apt でインストール中、ダイアログの選択で落ちる

apt でインストールするものの中にはユーザーと対話をしてくるものがいます。
（選択したものを設定に反映したり、パスワードを入れたりするもの）
Docker だと選択肢に答えようがないので以下をセットしてから`apt-get install`しましょう。

```
ENV DEBIAN_FRONTEND noninteractive
```

またその後使う場合、対話に戻しておきたいことがあるかも知れません。
その場合には一連の操作終了後、以下をセットしておきましょう。

```
ENV DEBIAN_FRONTEND dialog
```

## upstart への登録、upstart 関連で落ちる

有名な workaround なのであまり書かれてないのかも知れません。
インストールするものの中にはデーモン（サービス）で動作するものもあります。
ubuntu の性質上デーモンは upstart にひっかけて OS 起動時に起動するような設定を行います。
ですが、Docker では /sbin/init が書き換わっており upstart がうまく動きません。
インストール時の設定の時点で失敗、落ちてしまう事が有ります。
（upstartを動かす方法もありますが…）
その場合の対処法として以下のように設定してから `apt-get install` しましょう。

```dockerfile
RUN dpkg-divert --local --rename --add /sbin/initctl && rm -f /sbin/initctl && ln -s /bin/true /sbin/initctl
```

## fuse のインストール

apt でいろいろ入れてると fuse 関連が上手く入らず落ちてしまう事があります。
一応以下で回避できますがきっともっといい方法があるでしょう。

```dockerfile
RUN chmod go+w,u+s /tmp
RUN apt-get install libfuse2
RUN mkdir /tmp/fuse && \
    cd /tmp/fuse && \
    apt-get download fuse && \
    dpkg-deb -x fuse_* . && \
    dpkg-deb -e fuse_* && \
    rm fuse_*.deb && \
    echo -en '#!/bin/bash\nexit 0\n' > DEBIAN/postinst && \
    dpkg-deb -b . /fuse.deb && \
    dpkg -i /fuse.deb && \
    cd / && \
    rm -rf /tmp/fuse /fuse.deb
```

## 容量を少しでも減らす

`apt-get install` 時に `--no-install-recommends` をつけましょう。
一連のインストールが終わったら` apt-get clean` を実行しましょう。

## git clone 時の known_hosts

dotfiles や ソースなど git clone してくる際に落ちてるしまうことがあります。
known_hosts がまっさらなので確認してくるのですがそこで止まってしまいます。
ssh/config などで確認が入らないようにしておきましょう。

```
Host github.com
  StrictHostKeyChecking no

Host bitbucket.org
  StrictHostKeyChecking no
```

# ソフトウェアのインストール、個別設定

## supervisor で複数のデーモンを立ち上げる

公式にもあるので書きませんが、sshd があるとコンテナ内のファイルを救い出す事ができたりするので設定しておくといいでしょう。
もちろん、起動時に`-v`でマウントしておくともっと楽かも知れません。

## Docker 0.9 での tty

現在は解消されているようです。
https://github.com/dotcloud/docker/issues/4605

SSH server を立ち上げてログイン後、pty がねえよとか言われる奴です。
ログインするとプロンプトが出てこず壊したくなる
workaround でも書かれてますが run する際に`-t`オプションをつけましょう。

```
$ sudo docker run -t -p 40000:22 xxxxxx /usr/sbin/sshd -D
```

## saucy の sshd の設定

ssh でログイン後、即切断される場合の対処法です。
13.10 では pam を見るのでこの設定を書き換えておく必要があります。

```dockerfile
RUN sed -i 's/.*session.*required.*pam_loginuid.so.*/session optional pam_loginuid.so/g' /etc/pam.d/sshd
```

## nvm による node のインストール

RUN コマンドは `/bin/sh -c` として実行されるので source を叩く場合の例。
virtualenv なども同様にすればできるはず。

```dockerfile
RUN git clone git://github.com/creationix/nvm.git /home/ma2/.nvm
RUN /bin/bash -c 'source ~/.nvm/nvm.sh && nvm install 0.10.26 && nvm alias default v0.10.26 && npm install -g grunt grunt-cli bower gulp'
```

## Oracle JDK のインストール

奇特な方が Java 8 使いたいとかいうことがあるのでその人向け。
定番の`webupd8team/java`を使います。
途中でライセンスに同意しないといけないタイプなので注意です。

```dockerfile
RUN echo oracle-java7-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections

RUN apt-get install -y software-properties-common 
RUN add-apt-repository ppa:webupd8team/java -y \
  && apt-get update \
  && apt-get install -y oracle-java7-installer oracle-java6-installer oracle-java8-installer oracle-java8-set-default
```

また jdk8 ですがすこぶる落ちてくるのが遅かったり、落ちてこなかったりするのでその場合は再度トライして
下さい。
キャッシュが効いているのですぐやり直しできるはずです。

# 心霊・怪奇現象

## Permission Denied の話

### レア度 ☆☆☆
ユーザーを変更して作業する Dockerfile を書いていると build 時に稀に起きます。
明らかに問題がない場合でもおきます。
霊の仕業でしょうか？

- 再度 build し直す
- --no-cache で build し直す

で __Dokerfile未編集__ でうまく行ったりします。
それでもダメな場合は本当に Dockerfile が間違っている可能性があるので見なおしてみましょう。


## 消せないコンテナの話

### レア度 ☆☆☆☆

ファイルが消せなくなります。
Stale NFS file handle ってやつですね。
適当にファイルを消すと発生します。
霊の仕業でしょうか？

https://github.com/dotcloud/docker/issues/643
まだ直ってない様子、原因がイマイチ不明な感じがします。
勇気を持ってOSを再起動しましょう。それしか解決方法はありません。