最速Docker研究会(DockerのTipsを20個上げていくぜ編)
最近Dockerにどっぷりなんですが、Dockerについて色々地雷Tipsがあるのでそれをベストプラクティス風にまとめてみました。
Dockerコマンドが動いたけど、これからプロジェクトのDockerfileを書くようにしてみたいんだけど。。。みたいな人にオススメ。
インストール編
1. MacでDockerのインストールで詰まった
なんかよくわからないエラーが出てインストール出来ないんだけど><
versionを確認して最新の環境にしましょう。とくにxCodeとVirtualBoxとvagrantのバージョンは最新のものでないとダメです。
$ brew -v Homebrew 0.9.5 $ VirtualBox --help Oracle VM VirtualBox Manager 4.3.6 (C) 2005-2013 Oracle Corporation All rights reserved. $ vagrant -v Vagrant 1.4.3 $ docker version Client version: 0.7.6 Go version (client): go1.2 Git commit (client): bc3b2ec Server version: 0.7.6 Git commit (server): bc3b2ec Go version (server): go1.2
Dockerで環境構築編
2. docker -t -i + docker commitはなるべく使わない
使うとしたら、バグっぽい動作しているDockerfileのentrypointを削除してdocker -t -i
3. docker build時には必ずタグを付ける。
タグ名は
$ docker build -t mainyaa/redis .
4. fswatchで監視してビルドする(Mac only)
Dockerfileを編集してbuildしてのサイクルは自動化しましょう
$ brew install fswatch $ fswatch . "docker build -t <yourname>/<tag> ."
5. dvmを使う
vagrant上で動かすのはなるべく軽いゲストOSを選ぶ(boot2dockerかcoreosがオススメ)。
vagrant sshなしでMac上からvagrantのdockerコマンドを叩けるdvmを入れる。dvmはvagrantの薄いラッパー&管理ツール。dvmはboot2dockerをゲストOSに使う。CoreOSより軽い。
Dockerはとにかくディスクを圧迫するので、常に軽くすることを意識する。
本体のVagrantfileは~/.dvm/にある。clangビルドしてるとメモリ足りないよーとかで、Dockerのメモリを増やしたいときなどは~/.dvm/dvm.confで設定できる
インストール:
$ brew install dvm
dvmの起動とenv設定:
$ dvm up $ eval "$(dvm env)" $ echo << 'EOF' >> ~/.bashrc if [ -f dvm ]; then eval "$(dvm env)" fi EOF source ~/.bashrc
6. GCEやAWS上のdockerを叩くときにsudoが聞かれてうざいとき。
$ sudo gpasswd -a <username> docker $ sudo service docker restart $ exit
シェルを初期化するために一旦ログアウトしてください。
Dockerfile編
さて、ここからが本編です!
個人的にはここが一番重要だと思ってます。ハマりどころがたくさんあるので、ここを参考に
7. Dockerfileのapt-get updateやyum updateの前にはミラーサーバーを書く
run echo "deb http://us.archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
8. 一つ前のコンテナIDを取得するalias
$ cat << 'EOF' >> ~/.bashrc alias dl='docker ps -l -q' EOF
使い方(ログを見たり):
$ docker logs`dl`
9. ディスクがいっぱいになってきたんだけど
/var/lib/dokcerを別のディスクに割り当てるといいかもしれません。
10. Dockerfileの各所で要らないものを削除する
Dockerはファイルサイズとの戦いです。少しでも削りましょう。
run apt-get update && apt-get upgrade -y # こうではなく run apt-get update && apt-get upgrade -y && apt-get clean && rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/* #こう書きましょう run apt-get install -y openssh-server # こうではなく run apt-get install -y openssh-server --no-install-recommends # --no-install-recommendsオプションを付ける
11. ローカルの1週間以上前のコンテナを削除
ローカルのコンテナはどんどん消しても問題ありません。
Dockerfileさえあればいつでも元に戻せます
$ docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm
12. ローカルの1週間以上前のコンテナを削除はよく使うのでaliasも設定しておこう
$ cat << 'EOF' >> ~/.bashrc alias dkwrm="docker ps -a | grep "weeks ago" | awk '{print $1}' | xargs docker rm" EOF
13. docker run時に WARNING: IPv4 forwarding is disabled. って出るんだけど
IPv4 forwardingの設定をしましょう
$ sysctl -w net.ipv4.ip_forward=1 $ echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
14. apt-get updateで変なエラーが出るんだけど!(debian/ubuntu)
perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAGE = (unset), LC_ALL = (unset), LC_CTYPE = "UTF-8", LANG = "en_US" are supported and installed on your system. perl: warning: Falling back to the standard locale ("C"). locale: Cannot set LC_CTYPE to default locale: No such file or directory locale: Cannot set LC_MESSAGES to default locale: No such file or directory locale: Cannot set LC_ALL to default locale: No such file or directory
対策:Dockerfileに以下の行を足しましょう。
run locale-gen en_US.UTF-8 run update-locale LANG=en_US.UTF-8 env LC_ALL C env LC_ALL en_US.UTF-8
補足:これはMacのiTermがlocaleのenvを自動送信しているのが原因です。
Preferences > Profiles > Terminalの “Set locale environment variables on startup” のチェックを外せばうまくいくらしいですが、試してないです。
これのおかげで特に設定しなくてもツールやmanが日本語になっていたりします。
15. apt-getするとpromptのところで止まってしまう
Dockerfileに、
env DEBIAN_FRONTEND noninteractive
を設定しましょう。
まとめ
さて、以上の地雷を回避したDockerfileはこんなかんじになると思います
(後述するDockerfileをTDDするためにはopenssh-serverも必要かもしれません。
from ubuntu:12.04 maintainer KazuyukiMori <mainya@gmail.com> # set locale run locale-gen en_US.UTF-8 run update-locale LANG=en_US.UTF-8 env DEBIAN_FRONTEND noninteractive env LC_ALL C env LC_ALL en_US.UTF-8 run echo "deb http://us.archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list run apt-get update run apt-get install -y redis-server --no-install-recommends run apt-get upgrade -y && apt-get clean && rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/* expose 6379 entrypoint ["/usr/bin/redis-server"]
15. Advanced Tips: DockerfileをCIで回す
serverspec
configspec ならDockerfileまではけていいですが出来たてなので、とりあえず、開発が活発そうなserverspecで。configspecはserverspecの冪等性を捨てただけのものです。
僕もまだちゃんとした環境を作れてないので、以下のブログを参考にしてください。
serverspecとdocker-apiでDockerfileをTDD
これの何が嬉しいかというと、Dockerは差分ビルドなので、ビルドがあっという間に終わり、書いてて楽しいということです。
Dockerfileの中身はただのshellscriptなので、スクラッチから環境構築をいつでもやり直せるという安心感があります。
普段あなたが叩いているビルドコマンドやデプロイコマンドをDockerfileに書くだけです。Chef/puppetが使いたい人は別に使っても良いのです。
AWSが嫌になったらGoogle Compute EngineでもDegial OcealでもRackspaceでも、どこでもほぼ確実にプロダクション環境が用意できる
なお、Dockerのproduction環境で動かすのは推奨されていません。気をつけてね☆
あれ?数えてみたら15個しかなかった。まあいいか。
参考にしたリンク
via: The Docker Guidebook
via: Dockerfile Best Practice
via: serverspecとdocker-apiでDockerfileをTDD
via: 以前開催したGCE + Dockerハンズオンの発表資料