docker初心者なので、環境構築、超簡単なContainerの起動、Dockerfileとdocker xxのコマンドライン辺りをチラシの裏しておきます。
Dockerfileは人様の完成品を元にカスタマイズするとハマる事なく捗ります。
Docker環境をEC2にsetupする
まずEC2を建ててDockerを動かして見ましょう。EC2はt2-microで十分です。
apt-get install docker.io
でinstallされますがv1.0系が入ってしまいます。fig等を使いたい場合には、v1.3以上が必要なので、docker.ioから直接持ってくるべし。
#curl -sSL https://get.docker.io/ubuntu/ | sudo sh
#apt-get update
#apt-get -y install sysv-rc-conf
#sysv-rc-conf docker on
#docker version
でdocker clientのverを確認
# docker version
Client version: 1.4.1
Client API version: 1.16
...
初めてのDocker
初めての方は、まずは簡単なnginxなどのContainerを作ってみて、色々dockerコマンドを触ってみると良いです。慣れてきたらDockerfileのベストプラクティスで最適化して下さい。
以下をDockerfileという名前で保存します。Ubuntu14.04ベースにcurlとnginxが入ったContainerを作る設定。
FROM ubuntu:14.04
RUN apt-get update && apt-get -y install nginx curl
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx"]
そうしたら、作ったDockerfileのdirectoryから、何も考えずに、以下のコマンドを流してみる。
#docker build -t test1/test:1.0 ./
#docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
test1/test 1.0 55469de80222 57 seconds ago 250.3 MB
ubuntu 14.04 5ba9dab47459 12 days ago 192.7 MB
#docker run -p 25525:80 -d test1/test:1.0
#docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
b54eb8dd4253 test1/test:1.0 "/bin/sh" 8 seconds ago Up 8 seconds 0.0.0.0:25525->80/tcp
#curl localhost:25525
curlに対して、Welcome to nginxのhtmlが表示されたら、containerのnginxが反応してくれているので成功です!
Dockerハマりポイント
以下、Docker初心者として踏んだ地雷、ハマりポイントを列挙しておきます。
ProcessがForegroundで動いていないとContainerは終了する
これ超重要!
Docker Containerでnginxとかmongoとかelasticsearchを動かしたい場合には、DockerfileにRUN service nginx start
とかじゃダメなんです!Background実行だけじゃダメ絶対!
ちなみに、上のDockerfileにあるecho "daemon off;" >> /etc/nginx/nginx.conf
という謎のオマジナイは、nginxをdaemon化(background実行)する事を防ぐ為の物です。『Docker』『フォアグラウンド』とかでググると、この問題に対するBest practiceが見つかります。
自分が見つけた範囲では、以下の様な解決のApproachがありました。流行はSupervisorなんですかね。
docker run xxx
して、docker ps
しても、起動中のContainerが見つからない場合には、これが原因の可能性があります。
docker ps -a
でContainerが終了しているか確認してください。
docker containerのshellを操作したい
Containerを動かしたは良いが、しばらくしてどうも調子が良くないので、中に入ってshell操作して動作状況を確認したい、と言うケースは多々あると思います。そんなときは、docker exec
を使ってください。docker v1.3からサポートされた便利ツールで、#docker exec –it <containerID> bash
でOKです。
ちなみに、v1.3以前は以下の様な方法がとられていましたが、v1.3以降はdocker execで捗る様になります。
-
docker logs <containerID>
でstdoutのlogを眺める - containerのlogを/var/logなどに吐き出す様にしておき、/var/logを
docker run -v
でhost側からもアクセス出来るようにする - containerにsshdを仕込んでおき、sshでcontainerにlogin/shell操作する
- nsenterというtoolをcontainerに仕込んでおき、 containerのprocessに入りshell操作する
docker containerのresource消費量を知りたい
docker v1.5から、docker stats <containerID>
でCPU, Memory, network trafficの量を吐き出してくれるようになりました。
docker stats <containerID1> <containerID2> <containerID3>
とcontainer IDを続けて列挙すると、それら全てを纏めて吐き出してくれます。docker stats $(docker ps -q)
とすると、動作中のcontainerの全てのresource消費量を吐き出してくれます。
Dockerコマンド
docker build
Dockerfileから、docker imageを作成。以下の場合、./dokcertest以下のDockerfile
を見に行く
#docker build -t test1/test:1.0 ./dockertest
#docker images
で作成したimageができているか確認
#docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZ
test1/test 1.0 407b5768bc5f 5 hours ago 467.5 MB
ubuntu 14.04 5ba9dab47459 10 days ago 192.7 MB
#docker build --no-cache -t test1/test:1.0 ./dockertest
と--no-cache
を付けると、強制的に再度docker imageを作成。
docker run (一番ベタな方法)
docker imageからContainerを起動 (#docker images
で表示されたImiage IDか、Build時に-t
で指定したrepository/tagを指定する)。-d
でbackground実行です。
#docker run -d 407b5768bc5f
#docker run -d test1/test:1.0
docker images -q | head -1
が一番新しいimage IDをくれるので、一番直近に作ったimageを起動する場合は以下でもOK
#docker run -d $(docker images -q | head -1)
docker run (Port指定)
Containerのport80を、hostの25525にmapして起動。
#docker run -p 25525:80 -d 407b5768bc5f
#docker run -p 25525:80 -d test1/test:1.0
host上で、curl localhost:25525
すると、Container上のport80に渡され、Container側のhttp serverの応答を受け取れます。(Container側で、http serverが起動する設定になっていれば)
docker run (Containerのshellに遷移)
-it
を付けると、Container起動後、Containerのshellに遷移してします。DockerfileのCMD
やENDPOINT
でforeground実行されるAppがある場合は、そのlogが表示されます。foreground実行されるAppが無い場合は、Container側のShell操作が可能です。ctl+p → ctl+q
でHost側のshell操作に戻って来れます。
#docker run -it 407b5768bc5f
#docker run -it test1/test:1.0
注意点
-
-it
する時は、-d
を付けないでください(でないとBackground起動されちゃいます)。
docker run (HostのdirectoryをContainerからもアクセスできるようにする)
-v オプションで、(host側の絶対path):(Container側の絶対path)と表記します。要絶対パス
#docker run -v /home/ubuntu:/root/test -d 407b5768bc5f
#docker run -v /home/ubuntu:/root/test -d test1/test:1.0
docker run (Containerを強制的にshell状態で起動)
#docker run -it 407b5768bc5f /bin/sh
#docker run -it test1/test:1.0 /bin/sh
docker run xxx /bin/sh
とかすると、Containerの起動時に(DockerfileのCMD
の内容を上書きして) DockerfileのCMD
の内容は行われずにContainerのshell状態になります。Containerが期待通りの動作をしない様な場合に、上記の様にdocker run -it xxx /bin/sh
でCMDの内容の実行を抑止しつつContainerのshellに入り、そこでCMDの内容をdebug logを沢山吐く設定で動かして見る、などで使います。
ちなみにDocker始めたたての頃、人様のDocker コマンドの記事を見ていて、docker runする時は、docker run -d 407b5768bc5f /bin/sh
の様に、最後に/bin/shのoptionが常時必要だと思っていました(恥ずかし)。
docker link
他のcontainerと連携させる場合に使います。長くなるので、興味のある人はこちらの記事を参照下さい。
docker ps
dockerの起動状態を確認。docker stop
等で、Containerを止めたいときにContainer IDを確認するのによく使います。
#docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
6707e5555b5a test1/test:1.0 "/bin/sh" 3 seconds ago Up 2 seconds 24224/tcp, 80/tcp
romantic_blackwell
docker ps -a
すると、過去のContainerも含めたstatusが見れるので、containerが勝手に死んでいるなどの疑いがあるときにはこれで確認。
docker stop
docker containerの停止(#docker ps
で表示されたContainer IDを指定する)
#docker stop 6707e5555b5a
全ての動作中containerの停止
#docker stop $(docker ps -q)
docker logs
docker containerのstdoutのlogを表示します。Containerの調子が悪いときにstdoutのlogを見るのに使います。
docker containerの中に入って、debug等の目的でshell commandを色々実行したい場合には、docker execを使って下さい。
#docker logs 6707e5555b5a
docker exec
docker containerに入って、containerの動作状況やlogの確認をしたい場合に使います。
docker v1.3からサポートされました(超便利!) 。
それまでは、containerにsshdを仕込んで居たり、nsenterってtoolを使ったりしてましたが、docker tool側がサポートしてくれました
#docker exec –it 6707e5555b5a bash
docker rmi
docker imageの削除
#docker rmi 407b5768bc5f
REPOSITORY が <none> になっているものを強制削除する場合
#docker rmi -f $(docker images | awk '/^<none>/ { print $3 }')
全てのDocker imageを強制削除
#docker rmi -f $(docker images -q)
docker rm
docker containerの削除
#docker rm `docker ps -a -q`