docker

いまさらDockerに入門したので分かりやすくまとめます

はじめに

今更ながらDockerに入門したのでまとめます。
全てのコマンドの細かいオプションとかまではやりません。
Dockerコマンド体系はv1.13以降の新系です。
ここではクラスタ管理(KubernetesやSwarm)については対象外です。別記事でそのうちまとめます。
image.png

勉強背景

この記事から強い危機感を覚えました。
Dockerは世の中では当たり前の技術。せめて、少し触ってみて基本的な知識くらいは身につけなければ。。。。

TL;DR(5行)

  • Dockerは既存のLinuxカーネル機能から成り立っている
  • イメージを共有していろんな人がいろんなところで簡単にイメージからコンテナを起動できる
  • Dockerコマンドでコンテナを1つ1つ管理する
  • Dockerコマンドめちゃ叩くのはだるいからDockerfileで楽しちゃおう
  • 1つ1つコンテナを管理するのはだるいからdocker-composeで同一ホストOS上の複数コンテナをまとめて管理しちゃおう

仮想化概要

そもそもの仮想化から。

ホスト型仮想化

ホストOS上で動作する仮想化ソフトウェアを利用してVMを管理する方式。
オーバーヘッドが大きい。
代表例はVirtualBox、VMWare。
image.png

ハイパーバイザ型仮想化

ハードウェア上のハイパーバイザを利用してVMを管理する方式。
ホストOSなしでハードウェアを直接制御する。
オーバーヘッド大きい。
代表例はKVM、Heper-V、Xen。
image.png

コンテナ型仮想化

ホストOS上でコンテナと呼ばれるVMと似たようなふるまいをする仮想的な区画を用意して管理する方式。
コンテナはホストOSのカーネルを利用する。
通常、1コンテナ1プロセスで使用するためWebサーバコンテナとかDBサーバコンテナとかログ管理コンテナとか複数のコンテナを立てる構成となる。
image.png

他の仮想化と比べたコンテナ型仮想化(Docker)のメリット

  • 処理が速い
    • VM毎にCPUやメモリやストレージなどを割り当てるような処理が必要がなくオーバヘッドが少ないから
    • ゲストOSが無いため消費するリソースが少ないから
    • ゲストOSが無いためアプリケーションまでのパケット転送処理(コンテキストスイッチなど)が少ないから
  • 起動が速い
    • ゲストOSを立ち上げるわけではないから
  • 可搬性が高い
    • Dockerエンジンさえあれば基本どこでも動く。他の仮想化はもうちょっと苦労する。
  • アプリケーションを動かすための環境構築やセットアップ作業負担が軽減
    • Dockerfileやdocker-compose.ymlによるインフラのコード化
  • イメージが軽い
    • Dockerイメージはレイヤで管理しているから
  • 公式Dockerイメージが用意されている場合(JenkinsやWordPressなど)はデプロイがめちゃ楽
  • Dockerイメージを簡単に共有できる仕組み(レジストリ)

コンテナ型仮想化(Docker)のデメリット

  • ホストOSのカーネルと異なるOSは動かせない
  • 学習コスト(この記事で解決しよう!!!)

Docker概要

Dockerとは

Dockerはオープンソースのコンテナ管理ソフトウェアである。

コンポーネント

DockerではDocker Engineを中心に複数のコンポーネント単位で機能が開発されている。
必要に応じて複数のコンポーネントを組み合わせて使用する。

Docker Engine

Dockerイメージ作成やコンテナ起動などを行うDockerのコアコンポーネント。
Linuxカーネルの機能を使ったメインの処理を行い、Dockerデーモンとして動作する。
本記事説明対象内。

Docker Compose

複数コンテナを一元管理するコンポーネント。
本記事説明対象内。

Docker Registry

Dockerイメージを公開・共有するコンポーネント。
本記事説明対象内。

Docker Machine

非Linux環境用にDockerの実行環境をコマンドで自動生成するコンポーネント。
本記事説明対象外。

Docker Swarm

コンテナをクラスタ化して管理するコンポーネント。
正直、Kubernetesの台頭により存在感を失いつつある。
本記事説明対象外。

Docker Kitematic

DockerのGUIツールコンポーネント。
CUI叩ければいいでしょ。
本記事説明対象外。

Docker内部の仕組み

namespace

DockerはLinuxカーネルのnamespaceの機能を使ってコンテナ毎の区画化を実現している。
namespace毎に下記を管理している。

  • PID:プロセスに関して
  • Network:IPアドレス、ポート番号、ルーティング、フィルタリングなどのネットワークに関して
  • UID/GID:ユーザIDとグループIDに関して
  • MOUNT:マウントに関して
  • UTS:ホスト名やドメイン名に関して
  • IPC:メッセージキューなどのプロセス間通信に関して

cgroup(control group)

DockerはLinuxカーネルのcgroupの機能を使ってコンテナが利用する物理マシンリソース(CPUやメモリなど)の割り当ての管理を実現している。
プロセスをグループ化して、グループごとにリソース使用量制限をかけている。

ネットワーク

リンク機能

コンテナにはそれぞれ仮想NIC(eth0)が割り当てられ、172.17.0.0/16のセグメントのIPがDHCPで割り当てられる。
コンテナの仮想NICはホストOS上の1つのブリッジ(docker0)に接続されているためコンテナ同士で通信することが可能。(リンク機能)
ただし、複数物理サーバが存在するマルチホスト環境において、異なる物理サーバへのリンク機能を使った通信は不可。

image.png

インターフェース

コンテナ内で確認したインターフェース情報は以下。
コンテナ側から見るとまるで物理NIC(eth0)のように見える。

# ip a
(省略)
34: eth0@if35: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

しかし、ホストOS側から見ると実体はvethであることが以下から分かる。
vethは、L2の仮想NICであり、コンテナのNIC(eth0)とホストOSのブリッジ(docker0)間でトンネリングをしている。

# ip a
(省略)
35: vethd48920c@if34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    link/ether 9e:bd:4d:63:ed:38 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::9cbd:4dff:fe63:ed38/64 scope link
       valid_lft forever preferred_lft forever

また、ホストOS上で以下の通り、docker0ブリッジを確認できる。

# ip a
(省略)
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:bd:f7:d8:19 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

外部通信

DockerはLinuxカーネルのiptables機能を利用して、ホストOSの外部通信を行う。
docker0とホストOSの物理NIC間でNAPTが行われている。

Docker Hub

Docker Hubは公式レジストリサーバです。
公式のDockerイメージ(officialと記載されているもの)の他に一般のユーザの独自イメージも公開されている。
デフォルトではpullやpushはこのリポジトリに対して実行される。
プライベートレジストリを構築してそれを利用することも可能。
GitHub連携やパブリッククラウド連携機能が用意されている。
同一イメージがpushされた場合はDocker Hub内では1つしか管理しない。(全て個別に管理していたらDocker Hubの容量がとんでもないことになる)

Docker環境構築

今回の前提

  • Ubuntu16.04
  • インターネット通信可能

Dockerインストール

最新版のDocker(Community Edition)をインストールする例。

$ sudo apt-get remove docker docker-engine
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt-get install docker-ce
$ sudo docker -v
Docker version 18.06.0-ce, build 0ffa825

(必要あれば)プロキシ設定

$ sudo mkdir -p /etc/systemd/system/docker.service.d
$ sudo vi /etc/systemd/system/docker.service.d/http_proxy.conf
[Service]
Environment="HTTP_PROXY=http://<your_proxy_ip>:<your_proxy_port>/"
$ sudo vi /etc/systemd/system/docker.service.d/https_proxy.conf
[Service]
Environment="HTTPS_PROXY=http://<your_proxy_ip>:<your_proxy_port>/"
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

ちなみに↑のプロキシ設定はstackoverflowで私が貢献しました。(どうでもいい)

Docker主要コマンド

新旧コマンド対応表やDockerコマンドの全体間をつかむにはこちらの記事が分かりやすかったです。

コマンド一覧

イメージ管理用(image)

  • pull:Dockerイメージをレジストリから取得
  • ls:Dockerイメージの一覧を表示
  • inspect:Dockerイメージの詳細を表示
  • tag:Dockerイメージにタグをつける
  • push:Dockerイメージをレジストリへアップロード
  • rm:Dockerイメージの削除
  • save:Dockerイメージをtarファイルに保存
  • load:saveで固めたtarからDockerイメージを作成
  • import:exportで固めたtarファイルからDockerイメージを作成

コンテナ管理用(container)

  • ls:コンテナの一覧を表示
  • run:Dockerイメージからコンテナを生成
  • stats:コンテナのリソース使用状況を表示
  • logs:コンテナ内の実行ログ確認
  • create:Dockerイメージからコンテナの生成
  • start:コンテナの起動
  • stop:コンテナの停止
  • restart:コンテナの再起動
  • pause:コンテナの一時停止
  • unpause:一時停止中コンテナの起動
  • rm:停止中コンテナの削除
  • attach:稼働中コンテナに接続
  • exec:稼働中コンテナに接続
  • top:稼働中コンテナ内のプロセス一覧表示
  • port:コンテナの公開ポート番号表示
  • rename:コンテナの名前変更
  • cp:コンテナとホストOS間でファイルとディレクトリのコピー
  • diff:Dockerイメージが生成されてからの変更情報を表示
  • commit:変更があったコンテナからイメージを作成
  • export:コンテナをtarファイルに保存

その他

  • version:Dockerのバージョンを表示
  • info:Dockerの実行環境情報を表示
  • search:Docekrイメージの検索
  • login:Docker Hubへログイン
  • logout:Docker Hubからログアウト

コマンド実行例

イメージ管理用(image)

pull

Dockerイメージのダウンロードをする。
タグ(:以降)を省略すると最新版を取得する。
下記はcentosのイメージでタグが7のものをダウンロードする例。

# docker image pull centos:7
7: Pulling from library/centos
7dc0dca2b151: Pull complete
Digest: sha256:b67d21dfe609ddacf404589e04631d90a342921e81c40aeaf3391f6717fa5322
Status: Downloaded newer image for centos:7

ls

Dockerイメージの一覧表示をする。

# docker image ls
centos                7                   49f7960eb7e4        7 weeks ago         200MB

inspect

Dockerイメージの詳細確認をする。
イメージID、作成日、バージョン、作成者などの情報がJSON形式で取得可。

# docker image inspect 49f7960eb7e4
[
    {
        "Id": "sha256:49f7960eb7e4cb46f1a02c1f8174c6fac07ebf1eb6d8deffbcb5c695f1c9edd5",
        "RepoTags": [
            "centos:7"
        ],
        "RepoDigests": [
            "centos@sha256:b67d21dfe609ddacf404589e04631d90a342921e81c40aeaf3391f6717fa5322"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2018-06-04T22:19:34.475342266Z",
        "Container": "ef04c6fb40e53318c38014531a0bb5647e2d659dbe8a5e375374d4bbac57a02d",
        "ContainerConfig": {
            "Hostname": "ef04c6fb40e5",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"/bin/bash\"]"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:40ef8420eda09fa48ca36df234cb2b68387b5e13abb352e6390da642afe0351d",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.schema-version": "= 1.0     org.label-schema.name=CentOS Base Image     org.label-schema.vendor=CentOS     org.label-schema.license=GPLv2     org.label-schema.build-date=20180531"
            }
        },
        "DockerVersion": "17.06.2-ce",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:40ef8420eda09fa48ca36df234cb2b68387b5e13abb352e6390da642afe0351d",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.schema-version": "= 1.0     org.label-schema.name=CentOS Base Image     org.label-schema.vendor=CentOS     org.label-schema.license=GPLv2     org.label-schema.build-date=20180531"
            }
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 199678471,
        "VirtualSize": 199678471,
        "GraphDriver": {
            "Data": {
                "MergedDir": "/var/lib/docker/overlay2/10b389d643af1b23fb8cb748dd6d730dd9721e6cd7365f453dca69915881378e/merged",
                "UpperDir": "/var/lib/docker/overlay2/10b389d643af1b23fb8cb748dd6d730dd9721e6cd7365f453dca69915881378e/diff",
                "WorkDir": "/var/lib/docker/overlay2/10b389d643af1b23fb8cb748dd6d730dd9721e6cd7365f453dca69915881378e/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:bcc97fbfc9e1a709f0eb78c1da59caeb65f43dc32cd5deeb12b8c1784e5b8237"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

tag

Dockerイメージにタグをつけて別名保存する。
下記はcentosのイメージにcentos_hogeというタグを付ける例。IMAGE IDは元と同一。

# docker image tag centos goldkou/centos_hoge:1.0

# docker image ls
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
goldkou/centos_hoge   1.0                 49f7960eb7e4        7 weeks ago         200MB ★
centos                7                   49f7960eb7e4        7 weeks ago         200MB

push

レジストリ(デフォルトではDocker Hub)へDockerイメージをアップロードする。
Docker Hubへpushするにはloginが必要。

# docker image ls
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
goldkou/centos_hoge   1.0                 49f7960eb7e4        7 weeks ago         200MB
centos                7                   49f7960eb7e4        7 weeks ago         200MB

# docker image push goldkou/centos_hoge:1.0
The push refers to repository [docker.io/goldkou/centos_hoge]
bcc97fbfc9e1: Mounted from library/centos
1.0: digest: sha256:eed5b251b615d1e70b10bcec578d64e8aa839d2785c2ffd5424e472818c42755 size: 529

rm

ローカルのDockerイメージ削除をする。

# docker image ls
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
goldkou/centos_hoge   1.0                 49f7960eb7e4        7 weeks ago         200MB
centos                7                   49f7960eb7e4        7 weeks ago         200MB

# docker image rm goldkou/centos_hoge:1.0
Untagged: goldkou/centos_hoge:1.0

# docker image ls
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
centos              7                   49f7960eb7e4        7 weeks ago         200MB

save

Dockerイメージをtarファイルに保存する。

# docker image ls
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
node                  latest              52fe93b8eea7        3 days ago          674MB

# docker image save -o node.tar 52fe93b8eea7

# ls |grep node.tar
node.tar

load

saveで固めたtarからDockerイメージを作成する。

# docker image load -i node.tar
Loaded image ID: sha256:52fe93b8eea726594f3b8efefedc2e3a1db02828ab57632b217b953f00192950

import

exportで固めたtarファイルからDockerイメージを作成する。

# docker image import tmp.tar
sha256:39243504993c62780816c916461a4383e8751b8f90367888b6c8d4ce51727f15

# docker image ls
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
<none>                <none>              39243504993c        3 seconds ago       668MB

コンテナ管理用(container)

ls

コンテナの一覧表示をする。
-aオプションで起動中と停止中も含めて全て表示する。
STATUSはUP/Up(Paused)/Exitedのいずれか。

# docker container ls -a
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS                           PORTS                  NAMES

run

Dockerイメージからコンテナの生成と起動を行う。

通常起動(オプションなし)

以下はcentosのイメージからコンテナの生成と起動をする例。

# docker container run centos
# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS                NAMES
5586349638c8        centos              "/bin/bash"         6 seconds ago       Exited (0) 5 seconds ago                         tender_panini
起動して潜り込む

以下はcentosのイメージからコンテナの生成と起動をして、そのままコンテナに潜り込む例。
/bin/bashでコンテナ内でbash起動する。
-itオプションでコンソールに結果を出力する。
--nameオプションで任意のコンテナ名を指定する。
Ctrl+C(あるいはexitコマンド)で抜けるとコンテナが停止してしまう(STATUSがExitedになる)ため、Exitedにしたくない場合は、Ctrl+Q+Pでプロセスだけ停止して抜ける。

# docker container run -it --name "test1" centos /bin/bash
[root@1b758d38b739 /]# (Ctrl+Q+Pで抜ける)
# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS                NAMES
1b758d38b739        centos              "/bin/bash"         14 seconds ago      Up 22 seconds                        test1
バックグラウンド実行

以下はcentosのイメージからバックグラウンドでコンテナの生成と起動をして、自分自身にpingを実行し続ける例。
-dオプションでバックグラウンドで実行する。
-itオプションを有効にしていないためコンソールでは出力結果を確認できない。

# docker container run -d centos /bin/ping localhost
5c617037cee01f183b0a67489334cacb90fd1015be2352119980810c81944fc4
ネットワーク設定

以下はホストOSの8080番にアクセスするとコンテナの80番で動いているhttpサービスにアクセスするポート転送とAA:AA:AA:AA:AA:AAというMACアドレスを指定してコンテナを生成して実行する例。
-pオプションでポート転送設定する。
--mac-addressでMACアドレス指定する。
他にもDNSサーバIPアドレス、ホスト名、IPアドレスなどの指定が可能。

# docker container run -it -p 8080:80 --mac-address="AA:AA:AA:AA:AA:AA" httpd /bin/bash
root@d983b5e75160:/usr/local/apache2# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
54: eth0@if55: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether aa:aa:aa:aa:aa:aa brd ff:ff:ff:ff:ff:ff ★MACアドレスが指定したものになっているs
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
環境変数の設定

-eオプションで環境変数を設定する。

# docker container run -it -e hoge=hoge centos /bin/bash
[root@897dd18ebe7e /]# set |grep hoge
hoge=hogehoge

また、環境変数ファイルを別途用意してそれを読み込むことも可能。
--env-fileオプションでファイル指定する。

# cat env_list
hoge=hogehoge
fuga=fugafuga

# docker container run -it --env-file=env_list centos /bin/bash
[root@97c69057c511 /]# set
hoge=hogehoge
fuga=fugafuga
ボリューム割り当て

-vオプションで<ホストOSディレクトリ>:<コンテナ側ディレクトリ>形式でコンテナにボリュームを割り当てる。

#ホストOSのマウント元情報確認
# pwd
/root/sample
# ls
sample.txt

#マウントポイント指定してコンテナ起動
# docker container run -it -v /root/sample/:/opt ubuntu
root@77851efa9a86:/# cd /opt/
root@77851efa9a86:/opt# ls
sample.txt ★マウントによりホストOS上のsample.txtが見えていることを確認

stats

稼働中コンテナの状態を確認する。
topコマンドのようにCPU使用率やメモリ使用率などを確認ができる。

# docker container stats test1
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
5734bad7afbb        test1               0.00%               380KiB / 15.55GiB   0.00%               2.11kB / 0B         0B / 0B             1

logs

作成済みコンテナ内での実行ログを確認する。

# docker container logs -t 5c617037cee0
2018-07-23T08:32:58.463727463Z PING localhost (127.0.0.1) 56(84) bytes of data.
2018-07-23T08:32:58.463781213Z 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.048 ms
2018-07-23T08:32:59.462708207Z 64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.034 ms
2018-07-23T08:33:00.461835156Z 64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.044 ms
(省略)

create

Dockerイメージからコンテナの作成をする。
createだけではSTATUSはCreatedのままで起動(UP)はしない。
--nameオプションでnameを指定しない場合は適当な名前が振られる。

# docker image ls
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
centos              latest              49f7960eb7e4        7 weeks ago         200MB

# docker container create centos
e86597be9bbf20e5c5345a103cb1e6302f8a034d803b9cd2d92a27e6a65a259f

# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
e86597be9bbf        centos              "/bin/bash"         11 seconds ago      Created                                  stoic_noyce

start

コンテナの起動をする。
STATUSがUPになる。

# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS                NAMES
af3e7da4f96a        ubuntu              "/bin/bash"         15 minutes ago      Exited (0) 1 second ago                          angry_tereshkova

# docker container start af3e7da4f96a
af3e7da4f96a

# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS                NAMES
af3e7da4f96a        ubuntu              "/bin/bash"         15 minutes ago      Up 1 second                                      angry_tereshkova

stop

コンテナの停止をする。
STATUSがExitedになる。

# docker container stop af3e7da4f96a
af3e7da4f96a

# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS                NAMES
af3e7da4f96a        ubuntu              "/bin/bash"         20 minutes ago      Exited (0) 1 second ago                          angry_tereshkova

restart

コンテナの再起動をする。
STATUSがUPになる。

# docker container restart af3e7da4f96a
af3e7da4f96a

# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS                NAMES
af3e7da4f96a        ubuntu              "/bin/bash"         20 minutes ago      Up 2 seconds                                     angry_tereshkova

pause

コンテナの一時停止をする。
STATUSがUp(Paused)になる。

# docker container pause af3e7da4f96a
af3e7da4f96a

# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS                NAMES
af3e7da4f96a        ubuntu              "/bin/bash"         23 minutes ago      Up 14 seconds (Paused)                           angry_tereshkova

unpause

STATUSがPausedになっているものを再開する。
STATUSがUPになる。

# docker container unpause af3e7da4f96a
af3e7da4f96a

# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS                NAMES
af3e7da4f96a        ubuntu              "/bin/bash"         37 minutes ago      Up 13 minutes                                    angry_tereshkova

rm

停止中コンテナの削除をする。

# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                   PORTS                NAMES
af3e7da4f96a        ubuntu              "/bin/bash"         40 minutes ago      Up 17 minutes                                 angry_tereshkova

# docker container stop af3e7da4f96a
af3e7da4f96a

# docker container rm af3e7da4f96a
af3e7da4f96a

# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                   PORTS                NAMES

attach

稼働中コンテナへ接続する。
attachの場合はコンテナ内でシェルが動作していなければ接続することができない。
Ctrl+C(あるいはexitコマンド)で抜けるとコンテナが停止してしまう(STATUSがExitedになる)ため、Exitedにしたくない場合は、Ctrl+Q+Pで抜ける。

#接続
# docker container attach 34da816d9447

#コンテナ内でプロセス一覧確認。/bin/bashプロセスはもともと動いていた1つだけ。
[root@34da816d9447 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 05:32 pts/0    00:00:00 /bin/bash
root        16     1  0 05:37 pts/0    00:00:00 ps -ef

#exitで抜ける
[root@34da816d9447 /# exit
exit

#STATUSがExitedになった
# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS                NAMES
34da816d9447        49f7960eb7e4        "/bin/bash"         5 minutes ago       Exited (0) 5 seconds ago                        test1

exec

稼働中コンテナへ接続する。
接続する際に稼働コンテナでPID=1のプロセスを実行するため、コンテナ内でシェルが動作している必要がない。
Ctrl+C(あるいはexitコマンド)で抜けた後もSTATUSはUpのままで、接続時に起動したプロセスが停止するだけ。
-itオプションはコンソール出力のお決まりのオプション。

#コンテナ接続
# docker container exec -it 34da816d9447 /bin/bash

#コンテナ内でプロセス一覧確認。今回はもともとあがっていた/bin/bashプロセス(PID=16)と接続する際に起動した/bin/bashプロセス(PID=1)の2つ。
[root@34da816d9447 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 06:02 pts/0    00:00:00 /bin/bash ★接続時に起動したプロセス
root        16     0  0 06:02 pts/1    00:00:00 /bin/bash
root        31    16  0 06:02 pts/1    00:00:00 ps -ef

#exitで抜ける
[root@34da816d9447 /]# exit
exit

#STATUSがUpのままであることを確認。
# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                   PORTS                NAMES
34da816d9447        49f7960eb7e4        "/bin/bash"         30 minutes ago      Up 20 seconds                                 test1

top

稼働コンテナ内のプロセス一覧を表示する。

# docker container top 34da816d9447
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                20384               20365               0                   15:02               pts/0               00:00:00            /bin/bash

port

コンテナの公開ポート番号表示をする。

# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
46574bb37e1e        node                "/bin/bash"         27 minutes ago      Up 13 minutes       0.0.0.0:80->80/tcp   nodejs001

# docker container port nodejs001
80/tcp -> 0.0.0.0:80

rename

コンテナの名前変更を行う。

# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
46574bb37e1e        node                "/bin/bash"         30 minutes ago      Up 15 minutes       0.0.0.0:80->80/tcp   nodejs001

# docker container rename nodejs001 nodejs001_hoge

# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
46574bb37e1e        node                "/bin/bash"         30 minutes ago      Up 16 minutes       0.0.0.0:80->80/tcp   nodejs001_hoge ★名前が変更されている

cp

コンテナとホストOS間でファイルとディレクトリのコピーをする。

#コンテナ46574bb37e1e上の/etc/passwdファイルをホストの/tmpディレクトリに移動
# docker container cp 46574bb37e1e:/etc/passwd /tmp

#ファイルの確認
# ll /tmp |grep passwd
-rw-r--r--  1 root root  1236  7月 17 14:35 passwd

diff

Dockerイメージが生成されてからの差分を表示する。

  • A:ファイル追加(ADD)
  • C:ファイル更新(CHANGE)
  • D:ファイル削除(DELETE)
# docker container diff 46574bb37e1e
C /etc
C /etc/subgid
C /etc/subuid-
C /etc/passwd-
C /etc/shadow
C /etc/shadow-
C /etc/group
C /etc/passwd
C /etc/gshadow
C /etc/gshadow-
C /etc/group-
C /etc/subuid
C /etc/subgid-
C /root
A /root/.bash_history
C /var
C /var/log
C /var/log/faillog
C /var/log/lastlog

commit

コンテナからイメージを作成する。

# docker container commit 28bd5bc4292e ubuntu_img
sha256:ab6ea87d1613643bf1be1c7826e6a8aa0712675c232ea294d2b5bb48f54739b1

# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu_img          latest              ab6ea87d1613        7 seconds ago       82.4MB

export

コンテナからtarファイルを作成する。

# docker container export 46574bb37e1e > tmp.tar

その他

version

Dockerのバージョンを表示する。

# docker version
Client:
 Version:           18.06.0-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        0ffa825
 Built:             Wed Jul 18 19:11:02 2018
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.06.0-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       0ffa825
  Built:            Wed Jul 18 19:09:05 2018
  OS/Arch:          linux/amd64
  Experimental:     false

info

Dockerの実行環境情報を表示する。

# docker info
Containers: 1
 Running: 1
 Paused: 0
 Stopped: 0
Images: 4
Server Version: 18.06.0-ce
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: d64c661f1d51c48782c9cec8fda7604785f93587
runc version: 69663f0bd4b60df09991c08812a60108003fa340
init version: fec3683
Security Options:
 apparmor
 seccomp
  Profile: default
Kernel Version: 4.4.0-21-generic
Operating System: Ubuntu 16.04 LTS
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 15.55GiB
Name: XXXXX
ID: GTKQ:OBBP:FIX2:4VBK:HQJU:F2GF:IQOZ:5ICS:OFCT:KPI2:MN5R:R7RF
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
HTTP Proxy: http://XXXXX
HTTPS Proxy: http://XXXXX
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false

WARNING: No swap limit support

search

Docker Hubに公開されているイメージの検索する。
WEB-UIで表示されるものとほぼ同じ情報を取得する。

# docker search centos
NAME                               DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
centos                             The official build of CentOS.                   4419                [OK]
ansible/centos7-ansible            Ansible on Centos7                              114                                     [OK]
(省略)

login

Docker Hubへログイン。
Docker Hubへpushするためにはログインしておく必要がある。

# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: goldkou
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

logout

Docker Hubからログアウト。

# docker logout
Removing login credentials for https://index.docker.io/v1/

便利ワンライナー

ホストOSからコンテナのIP確認

# docker image inspect --format '{{ .NetworkSettings.IPAddress }}' <コンテナIDまたはコンテナ名>

Dockerfile

Dockerfile概要

Dockerfileはコンテナの構成情報を定義したファイルである。
Dockerfileを用意すれば何回もDockerコマンドを叩く必要なく、1コマンドでDockerイメージを生成できるため、構築の手間を省力化したりミスをなくしたりDockerfileそのものを手順書の一部として扱える。逆にDockerfileが無いとコンテナ操作に関する手順書やパラメータシートなどを別途管理する必要が出てきてしまう。
新イメージを作るのにベースイメージからいったんコンテナを起動して、命令実行している。
image.png

build

buildコマンド

buildコマンドでDockerfileからDockerイメージを作成する。
-tオプションで出来上がる任意のDockerイメージ名を指定する。
-fオプションでDockerfileのパスを指定する。

# docker image build -t <イメージ名> -f <Dockerfile>

Automated Build

GitHubまたはBitbucketで公開されているDockerfileからDockerイメージをビルドしてDocker Hubに登録する機能。
GitHub(Bitbucket)のアカウントとDocker Hubのアカウント間の連携設定が必要。
ファイル名が"Dockerfile"である必要がある。
例えば、こちらの記事のようにWebhookを利用してGitHubでタグが付いたらその時点でBuildしてDocker Hubにイメージを登録しておくとかできる。

image.png

レイヤー

build実行時は内部では命令毎にイメージを作成する動きをしているが、実際には効率的にイメージを管理するためにそれぞれイメージの全体でなくイメージ間の差分(tar)であるレイヤーの積み重ねを管理している。
このレイヤー数にはストレージドライバ起因で上限があるため、できるだけ命令は以下のように1つにまとめた方がよい。

NG例
RUN yum -y install httpd
RUN yum -y install git
OK例
RUN yum -y install \
            httpd\
            git

命令

命令一覧

  • FROM:ベースイメージの指定
  • MAINTAINER:作成者情報を設定
  • RUN:ベースイメージから起動したコンテナ内で実行するコマンドを設定
  • ENV:環境変数を設定
  • WORKDIR:場所(ディレクトリ)を移動
  • USER:ユーザ変更設定
  • LABEL:メタ情報(バージョンやコメントなど)設定
  • EXPOSE:公開ポート番号設定
  • ADD:ファイルやディレクトリを取得(リモート可)
  • COPY:ファイルやディレクトリを取得(ローカルのみ)
  • VOLUME:ボリューム設定
  • ONBUILD:次のbuild時に実行されるコマンドを設定
  • CMD:作成したイメージが起動されたら実行するコマンドを設定
  • ENTRYPOINT:作成したイメージが起動されたら実行するコマンドを設定

命令詳細

FROM

ベースイメージの指定をする命令。

FROM centos

MAINTAINER

Dockerfileの作成者情報を設定する命令。
ただし、MAINTAINERは1.13から非推奨であり、代わりにLABEL命令を使います。

MAINTAINER goldkou

RUN

Dockerイメージを作成する際にコンテナ内でコマンドを実行する命令。
実行形式はExec形式とShell形式の2種類がある。
Exec形式はシェルを介さずに実行する。公式的にはこちらが推奨とされている。
Shell形式は/bin/sh -cのシェルを介して実行する。

Exec形式例
RUN ["yum -y install httpd"]
Shell形式例
RUN yum -y install httpd

ENV

コンテナ内の環境変数を設定する命令。
runコマンドのenvオプションと同様のことができるが、envオプションの内容が優先となる。

ENV hoge=hogehoge\
    fuga=fugafuga

WORKDIR

場所(ディレクトリ)を移動する命令。
次以降の命令は移動した先の場所が起点となる。

WORKDIR /tmp
RUN ["pwd"]

USER

ユーザ変更する命令。
次以降の命令者は変更した後のユーザになる。

USER admin
RUN ["whoami"]

LABEL

イメージにメタ情報(バージョンやコメントなど)を設定する命令。
inspectコマンドで内容を確認できる。

LABEL title="sampleImage"\
      version="1.0"\
      description="This is a sample."
# docker image inspect 1a5099f89ade |grep title
                "title": "sampleImage",

# docker image inspect 1a5099f89ade |grep version
                "org.label-schema.schema-version": "= 1.0     org.label-schema.name=CentOS Base Image     org.label-schema.vendor=CentOS     org.label-schema.license=GPLv2     org.label-schema.build-date=20180531",
                "version": "1.0"

# docker image inspect 1a5099f89ade |grep description
                "description": "This is a sample.",

EXPOSE

コンテナの公開ポート番号を設定する命令。
外部からアクセスする場合にはrunコマンドの-pオプションによるポート転送が必要。

EXPOSE 80

ADD

ファイルやディレクトリを取得する命令。
ホストOS上のローカルファイルでもリモートファイルでも可。
リモートファイルの場合はパーミッションが600になる点に注意。

ADD https://github.com/docker/cli/blob/master/README.md /tmp

COPY

ファイルやディレクトリを取得する命令。
ホストOS上のローカルファイルのみ可。ローカルファイルのコピーを行う場合はCOPYを使うことが推奨されている。

COPY tmp.txt /tmp

VOLUME

ボリュームを割りあてる命令。
コンテナ内のマウントポイントを指定する。
ホストOSなどからボリュームがマウントされる。具体的にどこにマウントされるかなどの詳細はこちらの記事が勉強になりました。
コンテナ内のファイルはコンテナを削除すると消えてしまうので、重要なデータはコンテナでなく外部ボリュームで管理すべし。

VOLUME /myvol

ONBUILD

次のbuildで実行するコマンドをイメージに仕込む命令。
自身のDockerfileから生成したDockerイメージをベースイメージとして別のDockerfileでビルドされるときに実行されるコマンドを設定する。
(正直なところ、ONBUIDならではの効果的な使い道がまだ分からない。ADDやCMDとかでそれできるよねって感じ。ベースイメージを軽くできるとか?)
以下は、ADD命令を利用してホストOS上のtmp.tarファイルをコンテナの/var/www/html配下に格納する例。

ONBUILD ADD tmp.tar /var/www/html/

CMDとENTRYPOINT

CMD

Dockerfileで作成したDockeイメージから稼働したコンテナ内で指定コマンドを実行する命令。
runコマンドの引数に指定したコマンドでCMDの内容をオーバーライドできる。
1つのDockerfileにCMDは1つのみ。
Exec形式はシェルを介さずに実行する。公式的には推奨とされている。
Shell形式は/bin/sh -cのシェルを介して実行する。

Exec形式例
CMD ["ping","127.0.0.1","-c","5"]
Shell形式例
CMD ping 127.0.0.1 -c 5
ENTRYPOINT

Dockerfileで作成したDockeイメージから稼働したコンテナ内で指定コマンドを実行する命令。
runコマンドの引数に指定したコマンドでCMDの内容をオーバーライドできるが、--entrypointオプションが必要。
1つのDockerfileにENTRYPOINTは1つのみ。
Exec形式はシェルを介さずに実行する。公式的には推奨とされている。
Shell形式は/bin/sh -cのシェルを介して実行する。公式的には非推奨とされている。

Exec形式例
ENTRYPOINT ["ping","127.0.0.1","-c","5"]
Shell形式例
ENTRYPOINT ping 127.0.0.1 -c 5
CMDとENTRYPOINTの併用

CMDとENTRYPOINTを1つのDockerfileに併用する場合は、CMDの値がENTRYPOINTの末尾に追加される。(CMDがENTRYPOINTのオプションとして扱われる)
以下は、localhostにpingする命令の例。

ENTRYPOINT ["ping"]
CMD ["127.0.0.1", "-c", "50"]
CMDとENTRYPOINTの違い

CMDとENTRYPOINTの主な違いはrunコマンド実行時の上書きの仕方だけ。
詳細はこちらの記事

コメントアウト

Dockerfileは#でコメントアウトします。

# This is a comment out of the dockerfile.

Dockerfile動かしてみる

とりあえずそれぞれの意味はそんなに無いけど、いろいろな命令をDockerfileに書いてみる。

Dockerfile
FROM centos

MAINTAINER goldkou

LABEL title="sampleImage"\
      version="1.0"\
      description="This is a sample."

RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol

ENV hoge=hogehoge

EXPOSE 80

WORKDIR /tmp
RUN ["pwd"]

ADD https://github.com/docker/cli/blob/master/README.md /tmp

COPY sample.txt /tmp

上記Dockerfileからビルド実行。

# docker image build -f Dockerfile .
Sending build context to Docker daemon   2.56kB
Step 1/12 : FROM centos
 ---> 49f7960eb7e4
Step 2/12 : MAINTAINER goldkou
 ---> Running in b9faffa441a8
Removing intermediate container b9faffa441a8
 ---> b5697add76f7
Step 3/12 : LABEL title="sampleImage"      version="1.0"      description="This is a sample."
 ---> Running in e9fe12c0088a
Removing intermediate container e9fe12c0088a
 ---> b78833368ef8
Step 4/12 : RUN mkdir /myvol
 ---> Running in a6dbd3e448f0
Removing intermediate container a6dbd3e448f0
 ---> fe87721af021
Step 5/12 : RUN echo "hello world" > /myvol/greeting
 ---> Running in 2634122c6694
Removing intermediate container 2634122c6694
 ---> f973b12fa4a6
Step 6/12 : VOLUME /myvol
 ---> Running in ae03fe76efb3
Removing intermediate container ae03fe76efb3
 ---> 69cbebb5e50d
Step 7/12 : ENV hoge=hogehoge
 ---> Running in 25d01e7b2374
Removing intermediate container 25d01e7b2374
 ---> b490efb7db45
Step 8/12 : EXPOSE 80
 ---> Running in 224cfe63507f
Removing intermediate container 224cfe63507f
 ---> 9e34c56c1d60
Step 9/12 : WORKDIR /tmp
 ---> Running in 66ae8c28c3c0
Removing intermediate container 66ae8c28c3c0
 ---> 74d787ad9a85
Step 10/12 : RUN ["pwd"]
 ---> Running in 0e804a695f55
/tmp
Removing intermediate container 0e804a695f55
 ---> 409b71d637f0
Step 11/12 : ADD https://github.com/docker/cli/blob/master/README.md /tmp
Downloading  51.02kB
 ---> 5b6890980869
Step 12/12 : COPY sample.txt /tmp
 ---> b4dc0b57f8a8
Successfully built b4dc0b57f8a8

なんとなくできたぽいけど、上記のStepが本当にできたかをいくつか調べる。

#イメージ一覧確認
# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              b4dc0b57f8a8        23 seconds ago      200MB

#コンテナ起動
# docker container run -it -p 8080:80 b4dc0b57f8a8

#/tmpに移動していることを確認(上記Step9)
[root@6ea955b74e97 tmp# pwd
/tmp

#OSがCentOS最新版であることを確認(上記Step1)
# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)

#マウントされていることを確認(上記Step4~6)
# cat /myvol/greeting
hello world

#環境変数確認(上記Step7)
[root@6ea955b74e97 tmp]# printenv |grep hoge
hoge=hogehoge

#/tmpにファイルが格納されていることを確認(上記Step11~12)
[root@6ea955b74e97 tmp]# ls /tmp
README.md  ks-script-3QMvMi  sample.txt  yum.log

#exitでコンテナを抜ける

#ポート番号確認(上記Step8)
# docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                         PORTS                  NAMES
6ea955b74e97        b4dc0b57f8a8        "/bin/bash"         24 minutes ago      Up 24 minutes                  0.0.0.0:8080->80/tcp   dazzling_beaver

#メタ情報確認(上記Step3)
# docker image inspect 6ea955b74e97 |grep title
                "title": "sampleImage",
# docker image inspect 6ea955b74e97 |grep version
                "org.label-schema.schema-version": "= 1.0     org.label-schema.name=CentOS Base Image     org.label-schema.vendor=CentOS     org.label-schema.license=GPLv2     org.label-schema.build-date=20180531",
                "version": "1.0"
# docker image inspect 6ea955b74e97 |grep description
                "description": "This is a sample.",

compose

同一ホストOS上の複数コンテナを一括管理するコンポーネント。
"docker-compose.yml"ファイルに複数コンテナの構成情報を定義し、docker-composeコマンドで起動や停止などの管理をする。
通常、複数のサーバ群(コンテナ群)で1つのサービスを構成するため、それらをまとめるcomposeの需要がある。

docker-composeインストール

#docker-composeインストール
# curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   617    0   617    0     0    427      0 --:--:--  0:00:01 --:--:--   427
100 11.2M  100 11.2M    0     0   562k      0  0:00:20  0:00:20 --:--:-- 1536k

#権限変更
# chmod +x /usr/local/bin/docker-compose

#インストール確認(バージョン確認)
# docker-compose --version
docker-compose version 1.22.0, build f46880fe

docker-compose.yml

サービス一覧

  • image:ベースイメージの指定
  • build:Dockerfileの指定
  • command:コンテナ内で実行するコマンドの設定
  • links:コンテナ間リンク設定
  • ports:ホストOS外部への公開ポート設定
  • expose:コンテナ間のみでの公開ポート設定
  • volumes:ボリュームマウントの設定
  • volumes_from:別コンテナをボリュームとしてマウントするための設定
  • environment:環境変数設定
  • env_file:環境変数をファイル読み込みで設定
  • container_name:コンテナの名前設定

サービス詳細

image

ベースイメージの指定をする。
Dockerイメージを直接指定する方法。
docker-compose.ymlにはimageかbuildのどちらかの記載が必須。(コンテナ起動にはイメージ必須だから)

docker-compose.yml
sampleserver:
  image: ubuntu

build

Dockerfileの指定をする。
Dockerfile内のFROM命令でイメージ指定できるため、間接的にイメージを指定できる。
docker-compose.ymlにはimageかbuildのどちらかの記載が必須。(コンテナ起動にはイメージ必須だから)

ディレクトリ構成
# ls
Dockerfile  docker-compose.yml
Dockerfile
FROM ubuntu
docker-compose.yml
sampleserver:
  build .

command

コンテナ内で実行するコマンドの指定をする。

command: /bin/bash

links

コンテナ間リンク設定をする。
コンテナ内の/etc/hostsに名前設定がされる。

links:
  - dbserver

ports

コンテナの外部への公開ポート設定をする。
以下はホストOSへの5000番ポートアクセスをコンテナの5000ポートに転送する設定例。

ports:
  - "5000:5000"

expose

コンテナ間のみでの公開ポート設定をする。

expose:
  - "5000"

volumes

コンテナにボリュームをマウントする。
<ホストOSのディレクトリパス>:<コンテナのディレクトリパス>の形式で指定する。(コンテナ側は省略可)

volumes:
  - /tmp:/tmp

volumes_from

別のコンテナからボリュームをマウントする。
下はstorageという名前のコンテナからマウントする例。

volumes_from:
 - storage

environment

コンテナ内の環境変数設定をする。

environment:
  - hoge=hogehoge

env_file

コンテナ内の環境変数をファイル読み込みで設定する。

envfile
hoge=hogehoge
fuga=fugafuga
env_file: envfile

container_name

コンテナの名前設定をする。

container_name: sample-container1

docker-composeコマンド

docker-compose.ymlファイルと同一ディレクトリで実行するか-fオプションでファイルパスを指定して実行する。

docker-composeコマンド一覧

  • ps:コンテナの一覧表示
  • up:コンテナの生成と起動
  • scale:生成するコンテナ数の指定
  • logs:コンテナログの確認
  • run:コンテナの実行
  • start:コンテナの起動
  • stop:コンテナの停止
  • restart:コンテナの再起動
  • rm:コンテナの削除

docker-composeコマンド詳細

ps

コンテナの一覧表示をする。

# docker-compose ps
        Name             Command    State    Ports
--------------------------------------------------

up

docker-compose.ymlからコンテナの生成と起動を行う。

# cat docker-compose.yml
ubuntuServer:
   image: ubuntu

centosServer:
   image: centos

# docker-compose up
Pulling ubuntuServer (ubuntu:)...
latest: Pulling from library/ubuntu
c64513b74145: Pull complete
01b8b12bad90: Pull complete
c5d85cf7a05f: Pull complete
b6b268720157: Pull complete
e12192999ff1: Pull complete
Digest: sha256:3f119dc0737f57f704ebecac8a6d8477b0f6ca1ca0332c7ee1395ed2c6a82be7
Status: Downloaded newer image for ubuntu:latest
Creating sample_ubuntuServer_1 ... done
Creating sample_centosServer_1 ... done
Attaching to sample_ubuntuServer_1, sample_centosServer_1
sample_ubuntuServer_1 exited with code 0
sample_centosServer_1 exited with code 0

# docker-compose ps
        Name             Command    State    Ports
--------------------------------------------------
sample_centosServer_1   /bin/bash   Exit 0
sample_ubuntuServer_1   /bin/bash   Exit 0

scale

docker-compose.ymlファイルから生成するコンテナの数を指定する。

# cat docker-compose.yml
ubuntuServer:
   image: ubuntu

centosServer:
   image: centos

# docker-compose scale ubuntuServer=2 centosServer=3
WARNING: The scale command is deprecated. Use the up command with the --scale flag instead.
Creating sample_ubuntuServer_1 ... done
Creating sample_ubuntuServer_2 ... done
Creating sample_centosServer_1 ... done
Creating sample_centosServer_2 ... done
Creating sample_centosServer_3 ... done

# docker-compose ps
        Name             Command    State    Ports
--------------------------------------------------
sample_centosServer_1   /bin/bash   Exit 0
sample_centosServer_2   /bin/bash   Exit 0
sample_centosServer_3   /bin/bash   Exit 0
sample_ubuntuServer_1   /bin/bash   Exit 0
sample_ubuntuServer_2   /bin/bash   Exit 0

run

起動済みコンテナで新たにコマンドを実行する。
以下は/bin/bashを実行する例。

# docker-compose run ubuntuServer /bin/bash
root@552410439d29:/#

start

複数コンテナの一括起動をする。
何も指定しなければ一括となる。

# docker-compose start
Starting ubuntuServer ... done
Starting centosServer ... done

stop

複数コンテナの一括停止をする。
何も指定しなければ一括となる。

# docker-compose stop

restart

複数コンテナの一括再起動をする。
何も指定しなければ一括となる。

# docker-compose restart
Restarting sample_ubuntuServer_1 ... done
Restarting sample_centosServer_1 ... done

rm

複数コンテナの一括削除をする。
何も指定しなければ一括となる。

# docker-compose rm
Going to remove sample_ubuntuServer_1, sample_centosServer_1
Are you sure? [yN] y
Removing sample_ubuntuServer_1 ... done
Removing sample_centosServer_1 ... done

docker-composeを動かしてみる

公式Dockerイメージとして用意されているWordPressを使って、webコンテナとDBコンテナとstorageコンテナの3コンテナを構築してみる。

まずは、データ保存用コンテナstorageを作成するためのDockerfileを定義する。
busyboxとは標準的なLinuxコマンドを実行できるDocker Hub上に公開されているDockerイメージです。

Dockerfile
FROM busybox
MAINTAINER goldkou
VOLUME /var/lib/mysql

上記Dockerfileをもとにstorageという名前でbuild実行して、コンテナ起動します。

# docker image build -t storage .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM busybox
latest: Pulling from library/busybox
8c5a7da1afbc: Pull complete
Digest: sha256:cb63aa0641a885f54de20f61d152187419e8f6b159ed11a251a09d115fdff9bd
Status: Downloaded newer image for busybox:latest
 ---> e1ddd7948a1c
Step 2/3 : MAINTAINER goldkou
 ---> Running in 440983f98554
Removing intermediate container 440983f98554
 ---> def7c880ba89
Step 3/3 : VOLUME /var/lib/mysql
 ---> Running in 27cf3184bbfb
Removing intermediate container 27cf3184bbfb
 ---> 45008d31fff7
Successfully built 45008d31fff7
Successfully tagged storage:latest

# docker container run -it --name storage storage
/ # (Ctrl+PとCtrl+Qで抜ける)

つづいて、WEBコンテナとDBコンテナの2コンテナを起動するdocker-compose.ymlを定義します。
DBコンテナはストレージとしてさきほど作成したstorageコンテナを使用します。

docker-compose.yml
webserver:
  image: wordpress

  ports:
    - "80:80"

  links:
    - "dbserver:mysql"

dbserver:
  image: mysql

  volumes_from:
    - storage

  environment:
    MYSQL_ROOT_PASSWORD: password

バックグラウンドでdocker-composeをupします。

# docker-compose up -d
Pulling dbserver (mysql:)...
latest: Pulling from library/mysql
be8881be8156: Pull complete
c3995dabd1d7: Pull complete
9931fdda3586: Pull complete
bb1b6b6eff6a: Pull complete
a65f125fa718: Pull complete
2d9f8dd09be2: Pull complete
37b912cb2afe: Pull complete
54242fcd8eaa: Pull complete
e93b1a3a7883: Pull complete
d2fe83c975e6: Pull complete
1dbae693ec58: Pull complete
8946842549c8: Pull complete
Digest: sha256:359aae7806f177d819f6611ee379ae4efbfcd0bc381d2141ad0bc23a38ccf049
Status: Downloaded newer image for mysql:latest
Pulling webserver (wordpress:)...
latest: Pulling from library/wordpress
be8881be8156: Already exists
69a25f7e4930: Pull complete
65632e89c5f4: Pull complete
cd75fa32da8f: Pull complete
15bc7736db11: Pull complete
b2c40cef4807: Pull complete
f3507e55e5eb: Pull complete
e6006cdfa16b: Pull complete
a3ed406e3c88: Pull complete
745f1366071d: Pull complete
bdfcada64ad8: Pull complete
86f2b695cc77: Pull complete
5f634a03970a: Pull complete
a329a7ebde19: Pull complete
fb3d2649f534: Pull complete
8fa928654124: Pull complete
a925e4a45888: Pull complete
b5e827c13dc3: Pull complete
980d732311db: Pull complete
45de3b0df525: Pull complete
Digest: sha256:0f18ed4fa287da8129a643125434f3f65f40f3032971aa974fd10e0b03f3a1d3
Status: Downloaded newer image for wordpress:latest
Creating wordpress_dbserver_1 ... done
Creating wordpress_webserver_1 ... done

ホストOSの80番ポートにブラウザでアクセスしてWordPressの画面が表示されれば成功です。

(注意点)
docker-compose upで起動したwordpressのwebserverがSQLコネクションエラーでExitedになってしまいました。docker container stop webserverで復旧しました。

最後に、お片付けします。

# docker-compose stop
Stopping wordpress_webserver_1 ... done
Stopping wordpress_dbserver_1  ... done


# docker-compose rm
Going to remove wordpress_webserver_1, wordpress_dbserver_1
Are you sure? [yN] y
Removing wordpress_webserver_1 ... done
Removing wordpress_dbserver_1  ... done


# docker-compose ps
Name   Command   State   Ports
------------------------------

プライベートレジストリ

リモートのDocker Hubでなく、プライベートレジストリ(ローカル)を自分で構築して利用することができる。
プライベートレジストリ用にDocker Hub上で"registry"という名前でDockerイメージが用意されている。
プライベートレジストリのバックエンドとして例えばAWSのS3などを使えば高信頼性のプライベートレジストリを簡単に作ることができる。
また、有料だがAWSやAzureでプライベートレジストリサービスの提供も行われている。

#registryイメージ探索
# docker search registry
NAME                                    DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
registry                                The Docker Registry 2.0 implementation for s…   2093                [OK]
(省略)

#バージョン2のレジストリイメージ取得
# docker image pull registry:2.0
2.0: Pulling from library/registry
4d2e9ae40c41: Pull complete
a3ed95caeb02: Pull complete
7c8152785df5: Pull complete
8b04aafd7cd8: Pull complete
c97c75d2d42e: Pull complete
4b3ef98bba76: Pull complete
edee0288d356: Pull complete
ea2a9399d365: Pull complete
ddf532273b60: Pull complete
e9e91aa1843e: Pull complete
6144b0ffbb4c: Pull complete
Digest: sha256:3cac1869696e4ff3435bbc30391749ac373f7471736dbb48dfa9bfde08c4efd2
Status: Downloaded newer image for registry:2.0

#プライベートレジストリコンテナ起動
# docker container run -d -p 5000:5000 registry:2.0
9b89aef7d9abf796e59a65e8ba7ae42d4c66cfa90f876f1572ae9aea04a6c7e9

#push対象イメージにタグを付与
# docker image tag 49f7960eb7e4 localhost:5000/sample_centos

#イメージ一覧確認
# docker image ls
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
localhost:5000/sample_centos   latest              49f7960eb7e4        7 weeks ago         200MB
registry                       2.0                 3bccd459597f        3 years ago         549MB

#プライベートレジストリにイメージをアップロード
# docker image push localhost:5000/sample_centos
The push refers to repository [localhost:5000/sample_centos]
bcc97fbfc9e1: Pushed
latest: digest: sha256:a0ede55508fc10f4755360ef12ed66de9355a909028c70126acdf6ab787350d3 size: 3181

#ローカルのイメージ削除
# docker image rm 49f7960eb7e4
Untagged: centos:7
Untagged: centos@sha256:b67d21dfe609ddacf404589e04631d90a342921e81c40aeaf3391f6717fa5322
Deleted: sha256:49f7960eb7e4cb46f1a02c1f8174c6fac07ebf1eb6d8deffbcb5c695f1c9edd5
Deleted: sha256:bcc97fbfc9e1a709f0eb78c1da59caeb65f43dc32cd5deeb12b8c1784e5b8237
# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
registry            2.0                 3bccd459597f        3 years ago         549MB

#プライベートレジストリからイメージダウンロード
# docker image pull localhost:5000/sample_centos
Using default tag: latest
latest: Pulling from sample_centos
7dc0dca2b151: Pull complete
Digest: sha256:a0ede55508fc10f4755360ef12ed66de9355a909028c70126acdf6ab787350d3
Status: Downloaded newer image for localhost:5000/sample_centos:latest
# docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
localhost:5000/sample_centos   latest              49f7960eb7e4        7 weeks ago         200MB ★増えている
registry                       2.0                 3bccd459597f        3 years ago         549MB