Docker チートシート
[履歴] [最終更新] (2015/06/18 06:46:46)
1
作品
325
技術情報
最近の投稿
ここは
趣味の電子工作を楽しむ人のための作品販売プラットフォーム

ハードウェア技術を作品にして販売してみませんか?
新着作品

概要

こちらのページ で Vagrant と合わせて記載した Docker に関するコマンド逆引き集です。公式ページの「User Guide」情報をもとにしています。

関連情報

Dockerfile のポイント集はこちらです。

Docker 用語について

コンテナ

後述のイメージという型をもとに作られる実体です。例えるならば、オブジェクト指向プログラミングにおけるクラスが Docker イメージで、インスタンスが Docker コンテナです。あるイメージをもとにして複数のコンテナが作成され得ります。コンテナには containerId が自動で付与されます。containerId は英数字の羅列であり人間にとって分かり良いものではありません。そこで利便性のためにコンテナ名も付与できます。明示的に付与しない場合は適当な名前が自動で付与されます。containerId はもちろん一意ですが、コンテナ名も一意である必要があります。

  • containerId の例 "bc533791f3f5"
  • コンテナ名の例 "nostalgic_morse"

イメージ

前述のコンテナという実体を作成するための型です。繰り返しになりますが、例えるならばオブジェクト指向プログラミングにおけるクラスが Docker イメージで、インスタンスが Docker コンテナです。イメージには imageId が自動で付与されます。imageId は英数字の羅列であり人間にとって分かり良いものではありません。そこで利便性のために、ある imageId のイメージには任意の個数のタグが付与できます。タグ名はコンテナ名と異なり自動で付与されることはありません。イメージは後述のレポジトリに格納されます。imageId はレポジトリ間全体で一意です。タグ名は若干制約が緩く、あるレポジトリ内で一意であれば設定可能です。

  • imageId の例 "fc77f57ad303"
  • タグ名の例 "latest", "13.10", "dev", "v2"
  • レポジトリ名の例 "ubuntu", "training/webapp"

レポジトリ

あるレポジトリには複数のバージョンのイメージ (v10, v11,...) が格納され得ります。以上のことから言える事実として「レポジトリ名:タグ名」とすればイメージが一意に定まります。もちろん「imageId」だけでも一意に定まります。あるレポジトリ内の最新のイメージには latest タグが自動で付与されます。「レポジトリ名」とだけしたときは「レポジトリ名:latest」として処理されます。レポジトリ名には「ubuntu」といった base image や root image とよばれるものと、「training/webapp」といった user image の二種類があります。

逆引きコマンド集

イメージからコンテナを作成してシェルを起動して入る

オプション -i (--interactive) および -t (--tty) を付与して起動するのがポイントです。

$ sudo docker run -it レポジトリ名:タグ名 /bin/bash   ←例 centos:centos6

シェル内で exit したらコンテナを自動で削除するためには --rm オプションも追加しておきます。

$ sudo docker run --rm -it レポジトリ名:タグ名 /bin/bash

コンテナ一覧を表示

起動中のコンテナ一覧を表示します。

$ sudo docker ps

停止中のものも含めてすべてのコンテナ一覧を表示するためにはオプション -a (--all) を付与します。

$ sudo docker ps -a

停止中のものを含むすべてのコンテナの中で最後に作成したものを表示するためにはオプション -l (--latest) を付与します。

$ sudo docker ps -l

containerId だけを表示するためにはオプション -q (--quiet) を付与します。

$ sudo docker ps -q

長いコマンドなどを省略せずにすべて表示するためにはオプション --no-trunc を付与します。

$ sudo docker ps --no-trunc

イメージ一覧の表示

ホストに格納されているイメージの一覧は以下のコマンドで確認できます。

$ sudo docker images

history によってイメージが作成される過程における RUN, ADD, CMD などの発行履歴を表示できます。

$ sudo docker history レポジトリ名:タグ名

コンテナの停止および起動

コンテナを停止するには以下のようにします。

$ sudo docker stop コンテナ名

最後に作成されたコンテナを stop したのであれば、以下のコマンド latest オプションで何も表示されないことをもって停止されたと確認できます。

$ sudo docker ps -l

コンテナの起動には start を利用します。

$ sudo docker start コンテナ名

コンテナの再起動も可能です。

$ sudo docker restart コンテナ名

何らかの原因で stop できないコンテナに対しては kill を実行できます。

$ sudo docker kill コンテナ名

コンテナ名を指定する

オプション --name を使用します。

$ sudo docker run -d -P --name コンテナ名  レポジトリ名:タグ名  コマンド

ある containerId のコンテナ名は docker ps や以下のコマンドで確認します。

$ sudo docker inspect -f "{{ .Name }}" containerId

後からコンテナ名を変更することもできます。

$ sudo docker rename 旧コンテナ名  新コンテナ名

バックグラウンドで起動中のコンテナ COMMAND をフォアグラウンドに変更

オプション -d (--detach) で起動したコンテナの COMMAND はバックグラウンドで実行されます。

$ sudo docker run -d -it centos:centos6 /bin/bash

docker start で起動したコンテナの COMMAND もバックグラウンドで実行されます。

host$ sudo docker run -it centos:centos6 /bin/bash
container$ exit
host$ sudo docker start containerId

バックグラウンドで実行中のコンテナ COMMAND をフォアグラウンドに変更するためには attach を利用します。コンテナを作成した際に指定した COMMAND である /bin/bash がフォアグラウンドに戻ります。

$ sudo docker attach containerId

この方法はコンテナを作成した際に指定した COMMAND を変更するものではないことに注意してください。

$ sudo docker run -d centos:centos6 top -b
$ sudo docker attach containerId

例えば上記方法で attach したとしても依然として top -b が実行された状態です。/bin/bash に変更することはできません。

起動中のコンテナに COMMAND を追加で発行する

コンテナ COMMAND に関する理解を深める

イメージには COMMAND が一つだけ指定できます。例えば Dockerfile の CMD に指定されたコマンドは、その Dockerfile でビルドされたイメージの COMMAND になります。

Dockerfile

FROM centos:centos6
CMD top -b

イメージに COMMAND が設定されている場合、その COMMAND はイメージで作成されるコンテナの COMMAND になります。

$ sudo docker build -t username/top .
$ sudo docker run -d username/top

コンテナの COMMAND は ps によって確認できます。

$ sudo docker ps -l
CONTAINER ID  IMAGE                 COMMAND               CREATED ...
f1237583f707  username/top:latest  "/bin/sh -c 'top -b'   6 seconds ago ...

ただし、イメージに設定された COMMAND は必ずしもコンテナの COMMAND にはなりません。run または create によってコンテナを作成する時に引数として指定したもので上書くことができるためです。

$ sudo docker run -d username/top ping www.yahoo.co.jp
$ sudo docker ps -l
CONTAINER ID  IMAGE                 COMMAND               CREATED ...
d8be9e3e36c3  username/top:latest  "ping www.yahoo.co.j  3 seconds ago ...

逆に、イメージに COMMAND が設定されていない場合は run または create によってコンテナを作成する時に引数として COMMAND を指定しなければエラーになります。

$ sudo docker run -d centos:centos6
FATA[0000] Error response from daemon: No command specified

追加 COMMAND を発行

exec を使用することで、起動中のコンテナに追加の COMMAND を発行できます。

バックグラウンドでコマンドを発行

$ sudo docker exec -d コンテナ名 touch hello.txt

フォアグラウンドでコマンドを発行

$ sudo docker exec コンテナ名 touch hello.txt

/bin/bash コマンドを発行

$ sudo docker exec -it コンテナ名 /bin/bash   ←★SSH ではなく直接ログイン★

特に最後の例は重要です。コンテナ内に sshd を立てるようなことは避けてください。コンテナには必要最小限のリソースのみを含めるべきだからです。

コンテナの状態を知る

コンテナがどの程度ホストのリソースを消費しているかを調査するためには stats を利用します。

$ sudo docker stats コンテナ名, コンテナ名,...

コンテナ内のプロセス一覧を表示するためには top を利用します。

$ sudo docker top コンテナ名

logs を利用するとコンテナ COMMAND がターミナルに出力する内容を表示することができます。

$ sudo docker logs コンテナ名

Unix におけるテクニックの一つ tail -f のように監視出力するためには以下のようにします。

$ sudo docker logs -f コンテナ名

コンテナの状態を知るための汎用コマンド docker ps でも取得できますが、特にポートマッピングの情報だけを取得したい場合は以下のようにします。

$ sudo docker port コンテナ名  コンテナ内のポート番号

コンテナ内の各種情報を json で出力するためには inspect を利用します。オプション -f で情報のフィルタリングが可能です。

$ sudo docker inspect コンテナ名
$ sudo docker inspect -f '{{ .NetworkSettings.IPAddress }}' コンテナ名

ホストの状態を知る

コンテナ数やイメージ数、それらを格納しているホストのディレクトリ情報などを表示します。

$ sudo docker info

ホストの Docker デーモンにレポートされるコンテナおよびイメージのイベントを監視するためには以下のコマンドを実行します。

$ sudo docker events

過去のある時刻からさかのぼって表示するためには --since を利用します。引数は UNIX 時間です。

$ sudo docker events --since=0

コンテナの削除

事故防止のため running 状態のコンテナは削除できません。事前に stop しておく必要があります。

$ sudo docker stop コンテナ名
$ sudo docker rm コンテナ名

オプション -f (--force) を付与すれば running 状態であっても削除できます。

$ sudo docker rm -f コンテナ名

ホストからイメージを削除

$ sudo docker rmi レポジトリ名:タグ名

イメージのダウンロード

イメージは必要なときになければ自動でダウンロードされます。しかしながら事前にダウンロードするためには以下のようにします。まず以下のコマンドで検索します。

$ sudo docker search 検索ワード

以下のコマンドで実際にダウンロードします。用語集に記載したようにレポジトリには様々なバージョンのイメージが格納されています。タグ名を省略すると latest タグの付与されたイメージが取得されます。

$ sudo docker pull レポジトリ名:タグ名

タグをイメージに付与

$ sudo docker tag imageId レポジトリ名:新タグ名

新しいイメージを作成

コンテナに施された各種変更をコミットして新しいイメージを作成するためには commit を使用します。これは実験的にいろいろなことを試す用途で使用します。

host$ sudo docker run -it レポジトリ名:タグ名 /bin/bash
container$ コンテナ内でいろいろなコマンドを実行 && exit
host$ sudo docker commit -m "メッセージ" -a "AUTHOR" containerId  レポジトリ名:タグ名

本番環境で動作させるコンテナのイメージを用意する目的としては commit ではなく Dockerfile からビルドして作成したイメージを利用します。カレントディレクトリ '.' 内に Dockerfile が存在する場合は以下のコマンドでビルドします。

$ sudo docker build -t レポジトリ名:タグ名 .

作成したイメージは Docker Hub にアップロードします。

$ sudo docker push レポジトリ名:タグ名

ファイルシステムの変更状態を表示

diff はファイルシステムの変更状態を確認するコマンドです。commit の際に意図しない変更が含まれていないか確認できます。

$ sudo docker diff コンテナ名
  • A: Add
  • C: Change
  • D: Deleted

コンテナをポートマッピングされた状態で作成する

コンテナ内サービスが LISTEN しているポート番号すべてについて、ホストの任意のインタフェースから転送するためには以下のように -P オプションを使用します。これは loopback interface (いわゆる localhost 127.0.0.1 が割り当てられているインタフェース) を含みます。

$ sudo docker run -d -P レポジトリ名:タグ名  コマンド

マッピングするポート番号を明示的に指定するためには -p オプションを使用します。複数のポートをマッピングするためにはオプション -p を複数回指定します。

$ sudo docker run -d -p ホストのポート番号:コンテナ内サービスがLISTENするポート番号  レポジトリ名:タグ名  コマンド

ホストの特定のインタフェースにだけポートを bind することもできます。例えば上述の loopback interface にだけ bind するためには以下のようにします。

$ sudo docker run -d -p 127.0.0.1:ホストのポート番号:コンテナ内サービスがLISTENするポート番号  レポジトリ名:タグ名  コマンド

コンテナ内サービスが UDP ポートを LISTEN している場合には /udp を付与します。

$ sudo docker run -d -p ホストのポート番号:コンテナ内サービスがLISTENするポート番号/udp  レポジトリ名:タグ名  コマンド

コンテナ間の通信路を設定する

各コンテナは内部的なネットワークに所属しており、そのネットワークにおける IP が割り当てられています。この IP は docker inspect で調査できます。

$ sudo docker inspect -f '{{ .NetworkSettings.IPAddress }}' コンテナ名

オプション --link によってコンテナ間の通信路を確保できます。

$ sudo docker run -d --name コンテナ名1  レポジトリ名:タグ名  コマンド
$ sudo docker run -d --name コンテナ名2  --link コンテナ名1:エイリアス名  レポジトリ名:タグ名  コマンド

JSON の出力情報をフィルタリングすることで確認できます。

$ sudo docker inspect -f "{{ .HostConfig.Links }}" コンテナ名2

リンクオプション --link を付与して起動したコンテナ内では特殊な環境変数が利用できるようになります。また、環境変数に加えて /etc/hosts にリンク先のコンテナの DNS 情報が追記されます。リンク先のコンテナを再起動するなどして IP が更新されると環境変数はそのままですが /etc/hosts は自動更新されます。名前解決のためには環境変数ではなく /etc/hosts を利用することが推奨されています。

コンテナ内のファイルを取得

cp によってコンテナ内のディレクトリまたはファイルをホスト側にコピーできます。

$ sudo docker cp コンテナ名:ファイルまたはディレクトリのパス情報  ホストのパス情報

ファイルシステム毎バックアップするためには export を利用します。

$ sudo docker export コンテナ名 > backup.tar
$ gzip backup.tar

後述の data volume は export の対象外となることに注意してください。復旧時に利用するためには以下のようにまずイメージを新規に作成します。

$ cat backup.tar.gz | sudo docker import - レポジトリ名:タグ名

これを利用して作成されるコンテナにはバックアップ時のファイル一式がすべて含まれています。

$ sudo docker run -it レポジトリ名:タグ名  /bin/bash

ただし、イメージとしては新規作成となるためタグ情報や docker history で確認できる履歴は失われます。イメージの共有を目的とする場合は export/import ではなく、イメージをビルドしてから後述の save/load を利用してください。

コンテナに Data Volume を割り当てる

ホストのディレクトリをマウント

これはその性質上 Dockerfile では使用できません。汎用性が損なわれるためです。

$ sudo docker run -d -P -v /host/dir:/container/mntdir  レポジトリ名:タグ名  コマンド

読み込み専用 (readonly) でマウントするためには以下のようにします。

$ sudo docker run -d -P -v /host/dir:/container/mntdir:ro  レポジトリ名:タグ名  コマンド

ホストのファイルをマウント

ファイル単体のマウントが可能です。ただしマウントされたファイルを vi や sed で書き換えようとすると busy などのエラーが出ることがあります。これは inode の変更が発生するような編集時に生じます。その場合はディレクトリごとマウントしたほうがよいと公式ドキュメントには記載されています。以下の例では bash_history をマウントしています。これは Dockerfile を作成する際に有用です。コンテナ内におけるコマンド履歴がホストで後から取得できるためです。

$ sudo docker run --rm -it -v ~/.bash_history:/.bash_history centos:centos6 /bin/bash

オプション --rm はコンテナが stop されたら自動でコンテナを削除するオプションです。オプション -d とは併用できません。

Data Volume Container の作成

Data Volume には前述のホストのディレクトリをマウントする形式のものと、ここで取り扱う Docker が提供する仮想的なボリュームの二種類があります。仮想的な DataVolume は Amazon EBS のようなものです。両方とも -v オプションで指定するためややこしいですが区別してください。ホスト側のパス情報を記載しないことで、Docker が提供する仮想的なボリュームが作成されます。複数回の指定が可能です。

$ sudo docker run -d -it -v /DataVolume名  --name コンテナ1  centos:centos6  /bin/bash

サービスを起動せず単に Data Volume がマウントされているコンテナとして使用する場合は running 状態になっている必要がないため create コマンドを使用してもよいです。実は run コマンドは create コマンドと start コマンドの組み合わせです。

$ sudo docker create -it -v /DataVolume名  --name コンテナ1  centos:centos6  /bin/bash

確かに作成されていることが確認できます。

$ sudo docker inspect -f "{{.Volumes}}" コンテナ1
map[/DataVolume名:/mnt/sda1/var/lib/docker/vfs/dir/10d29ffa290e5bb47dd90fd43647e51f1079161f3c1acc002623a911c073dd56]

Data Volume Container をマウント

仮想的な Data Volume は他のコンテナを作成する時に --volumes-from オプションでマウントできます。

$ sudo docker run -it --volumes-from コンテナ1  --name コンテナ2  centos:centos6 /bin/bash

このようにして作成したコンテナはまた他のコンテナにマウントできます。間接的に最初の「-v /DataVolume名」がすべてのコンテナで共有された状態が実現されます。

$ sudo docker run -it --volumes-from コンテナ2  --name コンテナ3  centos:centos6 /bin/bash

Data Volume Container を削除

2015/02/28 現在 v1.5 に関して Data Volume はそれをマウントするコンテナすべてを削除しても消滅しません。削除するためには Data Volume をマウントするコンテナを一つを除いて削除したうえで、明示的に -v で削除します。

$ sudo docker rm コンテナ3
コンテナ3
$ sudo docker rm コンテナ2
コンテナ2
$ sudo docker rm -v /DataVolume名  コンテナ1
/DataVolume名
コンテナ1

仮想的な DataVolume はホストのファイルシステムのどこかに格納されてはいますが、それに直接アクセスすることは想定されていません。"Managing Data in Containers" で警告されているように参照するコンテナをすべて削除してしまうと DataVolume には実質的にアクセスできなくなります。これは "dangling" volumes とよばれます。

Docker will not warn you when removing a container without providing
the -v option to delete its volumes. If you remove containers without
using the -v option, you may end up with "dangling" volumes; volumes
that are no longer referenced by a container. Dangling volumes are
difficult to get rid of and can take up a large amount of disk
space. We're working on improving volume management and you can check
progress on this in pull request #8484

DataVolume を間違って削除して大切なデータを失うことを避けるための設計だと思われますが、ディスク容量を圧迫する原因になりますので最後の参照コンテナを rm するときには必ず -v オプションで一緒に削除するようにしてください。

削除のタイミングに関する補足

2015/02/28 現在 v1.5 に関する補足です。

コンテナ

  • 例えるならば AWS の EC2
    • stop: stop
    • rm: terminate
  • ファイルシステムは stop 後も保持される
  • Docker ホストを再起動してもコンテナのファイルシステムは保持される (物理的にはホストのファイルシステムに保存されているため)
  • コンテナを rm するとファイルシステムは削除される

仮想的な DataVolume

  • 例えるならば AWS の EBS
  • 参照するコンテナ stop 後も保持される
  • Docker ホストを再起動しても保持される (物理的にはホストのファイルシステムに保存されているため)
  • コンテナを rm しても保持される
  • 参照するコンテナを rm する時に明示的に -v で指定したときにのみ削除される

Docker Hub に依存せずにイメージを共有する

Docker Hub をはじめとする Registry を利用すれば、ある開発環境で用意した Docker イメージを別の環境と容易に共有できます。何らかの事情で Registry を利用できない場合は以下の方法で Docker イメージを tar.gz 化して共有します。

$ sudo docker save レポジトリ名:タグ名 | gzip > sample.tar.gz

別の Docker 環境に取り込むためには以下のようにします。

$ sudo docker load < sample.tar.gz

これによって Dockerfile およびそれが依存するファイル一式を共有するという事態を避けられます。Dockerfile を利用したビルドはそのビルドを実行した時点の yum レポジトリの状況などに依存したものになるため、Dockerfile を共有するのではなく Docker イメージを共有することが推奨されます。