Docker とは、指定したパッケージなどを持つ環境(=コンテナ)で、指定したコマンドの実行結果を再現するソフトウェアです。

コンテナ2「指定した環境 = nginx をインストールした環境」・「実行するコマンド = nginx (Web サーバー) を起動するコマンド」
初めて Docker を学ぶ時は、以下の3つがわからなかったので、本記事に書き残します。
- Docker の利点や使う理由
- Docker の操作方法
- Dockerfile, docker-compose
Docker の利点・使う理由
Docker を利用する利点は主に次の3つです。
パッケージの競合を回避
例えば、次の依存関係がある場合、どちらかのパッケージがインストールできません。
Docker では、ソフトウェア X のバージョン 1.0 と 2.0 の2つの環境(=コンテナ)を用意することで、パッケージの競合を回避可能です。

複数のホストを用意するのが容易
例えば、ロードバランサーやクラスターの検証をする場合、複数のサーバーが必要です。
この時、1つのサーバーに複数のコンテナを作成することで、1つのサーバーで検証できます。

以下の記事では、「ロードバランサー」+「Web サーバー3台」の合計4つのコンテナを1つのサーバーで稼働させる方法を紹介しています。
環境の移行が容易
Docker では、以下の2つを Dockerfile と呼ばれるファイル形式で保存できます。
- 「パッケージを指定した環境(=コンテナ)」
- 「実行するコマンド」
そのため、Dockerfile ファイルを渡すだけで、他のコンピュータに環境を移行できます。
(※「A さんの PC では動くが、 B さんの PC では動かない」という状況を回避できます。)
Docker をインストール
Docker を利用するために、まずはインストールをします。
- Docker をインストール
- sudo amazon-linux-extras install docker -y
InstallLearn how to choose the best method for you to install Docker Engine. This client-server application is available on Lin... - sudo systemctl start docker
- docker --version
Docker version 19.03.13-ce, build 4484c46
- sudo usermod -a -G docker `whoami`exit
Docker の使い方
Docker を初めて使う時、ググるキーワードがわからなかったり、1つ1つ調べるのが大変です。
そのため、本記事では上から順にコマンドを入力することで Docker の操作を理解できる文章構成としました。
Docker イメージの取得 pull
Docker コンテナは、Docker イメージと呼ばれるものから作成します。
リポジトリから Docker イメージを取得する方法は以下のとおりです。
docker pull <コンテナリポジトリ>:<コンテナタグ>
例えば、リポジトリから CentOS8 の Docker イメージを取得する場合は以下のコマンドとなります。
Docker イメージの一覧 images
Docker イメージの一覧を表示します。
REPOSITORY TAG IMAGE ID CREATED SIZE centos centos8 300e315adb2f 4 weeks ago 209MB
コンテナでコマンドを実行 run
docker run <コンテナリポジトリ>:<コンテナタグ> <実行するコマンド>
bin dev etc home lib (中略) var
ls コマンドが実行できたことがわかります。
コンテナの一覧 ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ff53e74d2aec centos:centos8 "ls" 3 minutes ago Exited (0) 3 minutes ago upbeat_bardeen
ls コマンドの実行が完了し、終了(Exited)したコンテナを確認できます。
コンテナを削除 rm
終了している Docker コンテナを削除します。
コンテナ終了時に自動削除 --rm
終了したコンテナを毎回削除するのは手間なので、コンテナ起動時 (docker run) のオプションで、コンテナ終了時に自動削除するように設定します。
bin dev etc home lib (中略) var
停止したコンテナが削除されていることが確認できます。
コンテナの中に入る -it bash
bash コマンドの標準入力と標準出力をホスト側に変更することで、ホストから Docker コンテナに入ったかのように操作できます。
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
バックグラウンドで実行 -d
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 03e96e9e13a8 centos:centos8 "bash" 55 seconds ago Up 54 seconds nifty_kilby
コンテナの実行中のプロセスを表示 container top
UID PID PPID C STIME TTY TIME CMD root 5564 5521 0 12:18 pts/0 00:00:00 bash
実行中のコンテナで新しくコマンドを実行 exec
実行中のコンテナに対して、bash コマンドを実行してみます。
コンテナを終了する stop
コンテナに名前をつける --name
そろそろ毎回 CONTAINER ID を調べるのがめんどくさくなってきた頃でしょうか。
そんな時はコンテナに名前をつけましょう。
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES 0f1d8d7f52b9 centos:centos8 "bash" 3 seconds ago Up 2 seconds centos
NAMES が centos になっていることがわかります。
コンテナのポートをホスト側に公開 -p
「ホスト側の 8080 ポート」と「コンテナの 80 ポート」を紐付けます。
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title>
無事、ホスト側の 8080 ポートを利用して、nginx コンテナの 80 ポートにアクセスできました。
Docker イメージを削除 rmi
REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 12766a6745ee 5 days ago 142MB centos centos8 5d0da3dc9764 6 months ago 231MB
REPOSITORY TAG IMAGE ID CREATED SIZE centos centos8 5d0da3dc9764 6 months ago 231MB
コンテナにデータ・ボリュームを追加 -v
データ・ボリュームは主に以下の用途で利用します。
- コンテナ自身を削除しても、データ・ボリュームは残り続けます。(永続化)
- データ・ボリュームはコンテナ間で共有・再利用できます。
- データ・ボリュームとしてホストのボリュームをコンテナにマウントできます。
データ・ボリュームのマウントには以下の3つが存在します。

- 「volume」= 名前付きボリューム
- 「bind mount」 = ホスト側のパス
- 「tmpfs mount」 = メモリ (-v ではなく、--tmpfs を利用)
「名前付きボリューム」をデータ・ボリュームとしてマウント
名前付きボリュームは、オプション v の値をアルファベット文字「a-z0-9, "_", "." , "-"」で開始します。
名前を指定する場合は、Docker は、その名前を持つボリュームを作成します。https://docs.docker.jp/engine/reference/run.html#run-volume
名前は英数字で始まる必要があり、以降はa-z0-9、_(アンダースコア)、.(ピリオド)、-(ハイフン)が使えます
以下に、名前付きボリューム「volume」をデータ・ボリュームとしてマウントする例を示します。
test.txt
test1 コンテナの /hoge が永続化されていたり、test2 コンテナで共有・再利用しています。
なお、名前付きボリュームは、Docker が管理するストレージエリアに保存されます。
(ホスト側の /var/lib/docker/volumes/)
test.txt
「ホスト側のパス」をデータ・ボリュームとしてバインドマウント
ホスト側のパスは、オプション v の値を「/」で開始します。
ホスト側ディレクトリに絶対パスを指定すると、 Docker は指定したパスをバインド・マウントします。絶対パスは
https://docs.docker.jp/engine/reference/run.html#run-volume/(フォアワード・スラッシュ)で始める必要があります。
以下に、ホスト側のパス「/tmp」をデータ・ボリュームとしてマウントする例を示します。
host_side
ホスト側のボリューム /tmp/test.txt を、コンテナ側にデータ・ボリューム /hoge/test.txt としてバインドマウントできていることが確認できます。
ボリューム一覧を確認 volume ls
ホスト側で Docker が管理するストレージエリア /var/lib/docker/volumes/ に保存されたボリューム一覧を表示します。
DRIVER VOLUME NAME local volume
先ほど作成した volume という名前のボリュームが確認できます。
一括削除 system prune
以下のオブジェクトを一括削除します。
- 終了したコンテナ
- タグ無しイメージ (オプション -a で使われてないイメージも削除)
- 未使用ボリューム (オプション --volumes が必要)
- 未使用ネットワーク
Are you sure you want to continue? [y/N] y # y を押すと一括削除されます。
DRIVER VOLUME NAME
先ほど確認したボリュームは全て削除されていることが確認できます。
コンテナ、イメージ、ボリューム、ネットワークを別々に一括削除する場合は以下のとおりです。
終了したコンテナの一括削除
タグ無しイメージの一括削除
未使用ボリュームの一括削除
未使用ネットワークの一括削除
Dockerfile: Dockerイメージを作成
Dockerfile は ベースとなる Docker イメージから、新しい Docker イメージを作成する命令を記載したファイルです。
1回だけ環境構築する場合は docker exec *** でも良いですが、同じ環境を何度も構築する場合は Dockerfile に命令を書いてしまいましょう。2回目以降は Dockerfile を使いまわして環境構築できます。
Dockerfile で利用可能な命令一覧
Dockerfile で利用可能な命令の一覧は以下のとおりです。
| 命令 | 説明 |
|---|---|
| FROM | ベースイメージを設定 |
| RUN | ベースイメージで実行するコマンドを指定(新しいDocker イメージの作成) |
| CMD | コンテナの実行時のデフォルトで実行するコマンドを設定 |
| LABEL | イメージにラベル(メタデータ)を追加 |
| EXPOSE | コンテナ実行時にリッスンするポートを指定 |
| ENV | 環境変数を設定 |
| ADD | ローカルホストからイメージへファイルを追加 |
| COPY | ローカルホストからイメージへファイルをコピー |
| ENTRYPOINT | コンテナを実行モジュールとして実行するように設定 |
| VOLUME | マウントポイントを生成 |
| USER | RUN, CMD, ENTRYPOINT を実行するユーザーを指定 |
| WORKDIR | ワークディレクトリを指定 |
| ARG | ビルド時の引数を指定 |
| ONBUILD | イメージに対してトリガーを追加 |
| STOPSIGNAL | コンテナが終了する時に送信するシステムコールシグナルを追加 |
| HEALTHCHECK | コンテナのヘルスチェック方法を指定 |
| SHELL | デフォルトのシェルを指定 |
ADD と COPY の違い
基本的に COPY を使っておきましょう。COPY でやりたいことが出来ない場合は ADD の利用を検討します。
Although
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#add-or-copyADDandCOPYare functionally similar, generally speaking,COPYis preferred. That’s because it’s more transparent thanADD.COPYonly supports the basic copying of local files into the container, whileADDhas some features (like local-only tar extraction and remote URL support) that are not immediately obvious. Consequently, the best use forADDis local tar file auto-extraction into the image, as inADD rootfs.tar.xz /.
CMD と ENTRYPOINT の違い
| CMD | ENTRYPOINT | |
|---|---|---|
| 目的 | コンテナ実行時のデフォルトのコマンドを指定 | コンテナ実行時のコマンドを固定 |
| docker run <コマンド> | コマンドの上書き可能 | コマンドの上書き不可能 |
例: Dockerfile で nginx の Docker イメージを作成
Dockerfile を理解するために、CentOS8 の Docker イメージから以下のような nginx の Docker イメージを作成してみます。

Dockerfile を作成
Dockerfile から Docker イメージを作成
Nginx の Docker イメージから Docker コンテナを作成し、アクセス
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>Test Page for the Nginx HTTP Server on Red Hat Enterprise Linux</title>
無事に Dockerfile から Nginx をインストールした Docker イメージを作成可能なことを確認できました。
docker-compose: 複数のコンテナを実行
docker-compose は、複数のコンテナを一気に起動するためのファイルです。
docker-compose で利用可能な命令一覧は以下のとおりです。
docker-compose: インストール
Linux 系で docker-compose をインストール
docker-compose version 2.4.1, build 6d1ac21
Linux 系以外で docker-compose をインストール
以下のドキュメントに従ってインストールしてください。
docker-compose: 使い方
先程自作した Nginx と、公式の Nginx の2つの Docker イメージを利用して、2つのコンテナを起動する docker-compose を作成します。
docker-compose.yml ファイルの作成
version: '3' services: my_nginx: build: context: . dockerfile: Dockerfile ports: - "8080:80" official_nginx: image: nginx ports: - "8081:80"
Compose ファイル (docker-compose.yml) の書き方は以下のとおりです。
docker-compose で複数コンテナを一括起動
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a2acd90e276f nginx "nginx -g 'daemon of…" 6 minutes ago Up 6 minutes 0.0.0.0:8081->80/tcp http_official_nginx_1 f7cc5a4d0c56 http_my_nginx "/bin/sh -c '/usr/sb…" 6 minutes ago Up 6 minutes 0.0.0.0:8080->80/tcp http_my_nginx_1
自作した Nginx と、公式の Nginx の2つのコンテナが起動していることが確認できます。
また、それぞれのコンテナにアクセス可能なことも確認できます。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>Test Page for the Nginx HTTP Server on Red Hat Enterprise Linux</title>
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title>
docker-compose でコンテナ群を一括終了
補足事項:名前付きボリューム
個人的にハマったのでメモ書きとして置いておきます。
名前付きボリュームを使うには、以下にあるようにトップレベルの
https://docs.docker.jp/compose/compose-file/compose-file-v3.html#volumesvolumesキーに記述する必要があります。
つまり、以下のような記載をすると次のようなエラーが発生します。
version: "3"
services:
web:
image: nginx:alpine
volumes:
- html:/usr/share/nginx/html/
ports:
- "80:80"
ERROR: Named volume "html:/usr/share/nginx/html:rw" is used in service "web" but no declaration was found in the volumes section.
正しい記載は以下です。(docker run -v の名前付きボリュームの作成方法と異なります。)
version: "3"
services:
web:
image: nginx:alpine
volumes:
- html:/usr/share/nginx/html/
ports:
- "80:80"
volumes:
html:
関連記事
コンテナ環境構築シリーズの記事は以下のとおりです。
参考記事
公式ドキュメント

Docker 日本語ドキュメント(有志による翻訳)
Docker で検索すると一番上に出てくる Qiita の記事



![AWSコンテナ設計・構築[本格]入門](https://m.media-amazon.com/images/I/518jpjD7X8L._SL160_.jpg)












![マイクロサービスパターン[実践的システムデザインのためのコード解説] impress top gearシリーズ](https://m.media-amazon.com/images/I/61Sj9ZggwML._SL160_.jpg)
