【Udemy】「超 Docker 完全入門」の学習メモ

Docker Docker

この記事は、Udemy のコース「米シリコンバレーDevOps監修!超Docker完全入門【優しい図解説とハンズオンLab付き】」で学習した内容を記録したものだ。

このコースでは Linux の基礎的なコマンドや docker の基礎を丁寧に説明してくれ、初心者でも短期間で docker の基礎を身に付けることができる楽しいコースになっている。

米シリコンバレーDevOps監修!超Docker完全入門【優しい図解説とハンズオンLab付き】

  1. Docker のインストール
  2. Linux の基本
    1. Linux のカーネル(kernel)とは
    2. Linux のシェル(shell)とは
    3. フォアグランドプロセスとバックグランドプロセス
      1. フォアグランドプロセス(Foreground process)
      2. バックグランドプロセス(Background process)
    4. シェルの STDIN、STDOUT、STDERR とは
    5. TTY
  3. シェルの基本コマンド
    1. ディレクトリ用操作コマンド
      1. ディレクトリ情報の表示(ls)
      2. ディレクトリの移動(cd)
      3. 現在のディレクトリを表示(pwd)
      4. ディレクトリの作成(mkdir)
    2. ファイル操作用コマンド
      1. ファイルの作成(touch)
      2. ファイルにテキストを付け足す(echo >>)
      3. ファイルの内容を表示する(cat)
      4. ファイルを削除(rm)
    3. プロセス操作用コマンド
      1. プロセスの表示(ps)
      2. プロセスをバックグランドで起動(&)
      3. プロセスをフォアグランドに戻す(fg)
    4. コマンド補助用コマンド
      1. コマンドのヘルプ(–help)(help の前にハイフン2つ)
      2. コマンドの保存先を表示(which)
      3. コマンドのマニュアルを表示(man)
    5. サーチ用コマンド
      1. ファイル・ディレクトリを探す(find)
      2. ファイルの中の文字列を検索する(grep)
    6. コマンドの入出力を切り替える
      1. コマンドの標準出力を切り替える(リダイレクト >, >>)
      2. コマンドの標準出力を別のコマンドの標準入力に渡す(パイプ | )
      3. 標準入力に対してコマンドを実行する(xargs)
    7. その他のコマンド
      1. 現在のユーザー名を表示(whoami)
      2. コマンドの出力結果を文字列の中に展開する($(…))
      3. コマンドを一定間隔で繰り返し実行する
      4. コマンドを連続して実行する
  4. Docker のコマンド
    1. イメージの操作
      1. イメージを取得する(docker pull)
      2. イメージの一覧を表示する(docker images)
      3. イメージの履歴を表示する(docker history)
      4. イメージを削除する(docker rmi)
    2. コンテナの操作
      1. イメージからコンテナを起動(docker run)
      2. 起動中のコンテナの一覧を表示(docker ps)
      3. 停止中のコンテナも含めて全ての一覧を表示(docker ps –all)
      4. コンテナを停止する(docker stop)
      5. 停止中のコンテナを削除(docker rm)
      6. コンテナをバックグランドで起動(docker run –detach)
      7. コンテナのログを表示(docker logs)
      8. 起動中のコンテナの中にシェルで入る(docker exec -it)
      9. ホストのデータをコンテナにコピー(マウント)(docker run –volume)
      10. コンテナの環境変数を設定(docker run –env)
      11. コンテナのメタデータ(様々な情報)を見る(docker inspect)
      12. コンテナにつなげるホストのポートを変える(docker run -p)
      13. コンテナが停止したら自動でコンテナを削除させる(docker run –rm)
      14. 起動中のコンテナからイメージを作成する(docker commit)
      15. Dockerfile からイメージを作成する(docker build)
    3. コンテナとイメージの削除
      1. 停止中のコンテナと無名のイメージを削除
      2. 起動中のコンテナも含むすべてのコンテナを削除
      3. 全てのイメージを削除する(起動中のコンテナも削除される)
  5. Docker の作業の流れ
    1. イメージにパッケージを加えて新しいイメージを作成する
      1. Dockerfile でレシピを作成する
      2. Dockerfile からイメージを作成する(docker build)
      3. 作成したイメージからコンテナを起動
  6. Dockerfile
    1. Dockerfile とは
    2. Dockerfile の書き方
  7. Docker-Compose
    1. Docker-Compose とは
    2. YAML とは
    3. Docker run を Docker-Compose の YAML ファイルに記述する
    4. Docker-compose コマンド
      1. YAML に定義されたコンテナサービスを起動する(up)
      2. YAML に定義されたコンテナサービスを停止し、削除する(down)
      3. 複数のコンテナのログをまとめて表示する(logs)
    5. Docker-Compose でコンテナのレプリカ(複製)を複数起動する
      1. YAML を変更する(複数のレプリカで重複を避ける)
      2. レプリカ数を指定してコンテナサービスを起動する(up –scale)
    6. Docker-Compose で起動されたコンテナ同士で通信する

Docker のインストール

Windows の場合

  • Install Docker Desktop on Windows の「Download from Docker Hub」をクリック。
  • Docker Desktop for Windows ページの「Get Docker」ボタンでインストーラ-をダウンロードする。

Mac の場合

  • Install Docker Desktop on Mac の「Download from Docker Hub」をクリック。
  • Docker Desktop for Mac ページの「Get Docker」ボタンでインストーラ-をダウンロードする。

Linux の基本

Linux のカーネル(kernel)とは

カーネルは、CPU やメモリ、入出力装置(マウス、キーボードなど)、ネットワークなどのハードウェア資源を管理して抽象化し、アプリケーション側がハードウェアの違いを意識せずに利用できる手段を提供する。また、実行中のプログラムの状態を管理する。

Linux のシェル(shell)とは

シェルは、ユーザーが OS と対話するためのインターフェースを提供するプログラムのこと。ユーザーがコマンドを入力すると、シェルはそのコマンドを理解してカーネルのプログラムを実行する。

ユーザー
↑ ↑ ↑ ↑
↓ ↓ ↓ ↓
シェル
↑ ↑ ↑ ↑
↓ ↓ ↓ ↓
カーネル
↑ ↑ ↑ ↑
↓ ↓ ↓ ↓
ハードウェア(CPU やメモリ、マウス、キーボードなど)

また、シェルには sh, tcsh, bash, zsh, … など、いくつかの種類がある。

フォアグランドプロセスとバックグランドプロセス

フォアグランドプロセス(Foreground process)

フォアグランドプロセスとは、実行する処理(プロセス)の完了を待ち、完了するまで次のプロセスが実行できないものをいう。
フォアグランドプロセスを実行したシェルは、完了するまでコマンドの入力を受け付けない。

バックグランドプロセス(Background process)

バックグランドプロセスとは、実行する処理(プロセス)の完了を待たずに次のプロセスが実行できる。
バックグランドプロセスを実行したシェルは、完了を待たないので、すぐに次のコマンドの入力を受け付ける。

シェルの STDIN、STDOUT、STDERR とは

シェルからフォアグランドでプロセスを実行させると、インプット(入力したコマンド)とアウトプット(プロセスの結果の表示)をターミナルで見ることができる。

シェルに対してコマンドを入力するとき、標準として(暗黙的に)使用される入力元のことを STDIN と呼ぶ。

また、シェルが返すプロセスの結果を、標準として(暗黙的に)吐き出す出力先のこと STDOUT と呼ぶ。プロセスがエラーのときの標準出力先は STDERR と呼ばれる。

TTY

シェルの STDIN と STDOUT をターミナルに繋げること、つまりシェルに対してコマンドの入力やその実行結果の出力をできるようにすることを、TTY(Tele Typewiter) をターミナルにアタッチする、と表現する。

docker の中にシェルで入るときには

$ docker exec --interactive --tty

というコマンドを使用する。

シェルの基本コマンド

ディレクトリ用操作コマンド

ディレクトリ情報の表示(ls)

ls は list の略。

$ ls

#隠しファイルも含めてすべてを表示
$ ls -a

ディレクトリの移動(cd)

cd は change directory の略。

cd home/

現在のディレクトリを表示(pwd)

pwd は print working directory の略。

$ pwd

ディレクトリの作成(mkdir)

mkdir は make directory の略。

$ mkdir sample_dir

ファイル操作用コマンド

ファイルの作成(touch)

$ touch test_file

ファイルにテキストを付け足す(echo >>)

$ echo "この文章がファイルに追加されます。" >> test_file

ファイルの内容を表示する(cat)

cat は concatenate の略。concatenate は「追加する、連結する」といった意味がある。ファイルの内容を STDOUT に追加して出力するという意味でコマンド名が cat になっている。

$ cat test_file

ファイルを削除(rm)

rm は remove の略。

$ rm test_file

プロセス操作用コマンド

プロセスの表示(ps)

ps は process status の略。

$ ps

プロセスをバックグランドで起動(&)

プロセスをバックグランドで起動するためには、コマンドの末尾に & を付けて実行させる。

$ sleep 50 &

プロセスをフォアグランドに戻す(fg)

fg は foreground の略。

$ fg

コマンド補助用コマンド

コマンドのヘルプ(–help)(help の前にハイフン2つ)

ps コマンドの使い方が知りたいなら「ps –help」を入力する。(help の前にハイフン2つ)

$ ps --help
Usage: ps [-aefls] [-u UID] [-p PID]

Report process status

 -a, --all       show processes of all users
 -e, --everyone  show processes of all users
 -f, --full      show process uids, ppids
 -h, --help      output usage information and exit
 -l, --long      show process uids, ppids, pgids, winpids
 -p, --process   show information for specified PID
 -s, --summary   show process summary
 -u, --user      list processes owned by UID
 -V, --version   output version information and exit
 -W, --windows   show windows as well as cygwin processes

With no options, ps outputs the long format by default

コマンドの保存先を表示(which)

ps コマンドの保存先を知りたいなら「which ps」とする。

$ which ps
/usr/bin/ps

コマンドのマニュアルを表示(man)

man は manual の略。ps コマンドのマニュアルが見たいときは、「man ps」とする。

サーチ用コマンド

ファイル・ディレクトリを探す(find)

find 検索パス 検索する条件 [アクション]

という形式で使用する。例えば、

  • 検索するパスが「/」ならルートから、「./」ならカレントディレクトリから検索する。
  • 検索する条件が「-type d」ならディレクトリを探し、「-type f」ならファイルを探す。
    検索する条件が「-name hoge」なら hoge という名前のファイル・ディレクトリを探す。
$ find / -type f -name mkdir.exe
/bin/mkdir.exe
/usr/bin/mkdir.exe

ファイルの中の文字列を検索する(grep)

grep [オプション...] 検索文字列 [ファイル名1] [ファイル名2] ...

という形式で使用する。

$ cat test_file
abcde
fghij
abcxyz
123456789

$ grep abc test_file
abcde
abcxyz

$ grep -n abc test_file
1:abcde
3:abcxyz

また、ディレクトリを指定して、その中の全てのファイルを検索したい場合は次のようにする。

grep 検索文字列 ディレクトリ/*

サブディレクトリも含めて検索したい場合は、-r オプション(–recursive)を付けて次のようにする。

grep -r 検索文字列 ディレクトリ

コマンドの入出力を切り替える

コマンドの標準出力を切り替える(リダイレクト >, >>)

「コマンド > ファイル」とした場合、コマンドの標準出力をファイルに書き込む。ファイルが既に存在する場合は、上書きされる。

$ cat test_file
hello world!

$ echo "hello" > test_file

$ cat test_file
hello

また、「コマンド >> ファイル」とした場合、コマンドの標準出力をファイルに追記する。

$ cat test_file
hello

$ echo "hello world" >> test_file

$ cat test_file
hello
hello world

コマンドの標準出力を別のコマンドの標準入力に渡す(パイプ | )

「コマンド1 | コマンド2」とした場合、コマンド1の標準出力がコマンド2の標準入力に渡される。

$ cat test_file
hello
hello world

$ cat test_file | grep -n world
2:hello world

標準入力に対してコマンドを実行する(xargs)

xargs コマンドを実行すると、標準入力から受け取ったデータを、任意のコマンドに引数として渡すことができる。パイプで他のコマンドの出力を受け取って、次のコマンドを実行させる、といった使い方をすることが多い。

$ ls
test_file

$ cat test_file
hello
hello world

$ ls | xargs echo >> test_file

$ cat test_file
hello
hello world

test_file

その他のコマンド

現在のユーザー名を表示(whoami)

現在ログインしている自分の名前を表示するには「whoami」と入力する。

$ whoami

コマンドの出力結果を文字列の中に展開する($(…))

$() を使用すると、あるコマンドの出力結果を別のコマンドの引数の文字列に組み込むことができる。

$ echo "現在のディレクトリ:$(pwd)"

コマンドを一定間隔で繰り返し実行する

watch コマンドを使用すると、一定間隔(デフォルト2秒毎)で指定のコマンドの実行を繰り返させることができる。

$ watch コマンド

コマンドを連続して実行する

「コマンド1が成功したら、コマンド2を実行する」というようなことを行いたい場合は、&& でコマンドをつなぐ。

$ コマンド1 && コマンド2

例えば、次のコマンドは、Linux のパッケージマネージャー apt をアップデートしたら、curl コマンドをインストールするという意味になる。(-y は何か聞かれたら全て yes にするという意味のオプション)

$ apt update && apt install -y curl

Docker のコマンド

イメージの操作

イメージを取得する(docker pull)

public あるいは private の Docker Registry からイメージをダウンロードするには、つぎのコマンドを実行する。

$ docker pull イメージ名

例えば、Webサーバーの Nginx の docker イメージを取得する場合

$ docker pull nginx

この際にターミナルをもう一つ開いて、

$ watch -t "docker ps"

を実行しておくと、docker ps コマンドを2秒毎に実行してくれるので便利。

イメージの一覧を表示する(docker images)

ダウンロードした docker イメージの一覧を表示するには次のコマンドを入力する。

$ docker images

イメージの履歴を表示する(docker history)

$ docker history イメージ名

例えば、nginx の履歴を表示するなら、

$ docker history nginx

イメージを削除する(docker rmi)

$ docker rmi イメージ名

例えば、nginx のイメージを削除するなら、

$ docker rmi nginx

コンテナの操作

イメージからコンテナを起動(docker run)

$ docker run -p 80:80 --name nginx nginx

-p は –publish の略であり、「-p 80:80」により、host 側のポートを 80、コンテナ側のポートを 80 という形に、host とコンテナのポートをマッピングする。

nginx ではデフォルトでポート 80 をオープンにしているため、コンテナ側は 80 にする。host 側をポート 1000 としてマッピングするなら「-p 1000:80」とすればよい。

–naem オプションで起動するコンテナに名前を付けることができる。

起動中のコンテナの一覧を表示(docker ps)

ps は process status の略。

$ docker ps

停止中のコンテナも含めて全ての一覧を表示(docker ps –all)

$ docker ps --all

あるいは -a でもよい。

$ docker ps -a

コンテナを停止する(docker stop)

$ docker stop コンテナID
$ docker stop nginx

停止中のコンテナを削除(docker rm)

$ docker rm コンテナID

コンテナをバックグランドで起動(docker run –detach)

–detach オプション(-d でもよい)を使用することでバックグランドで起動することができる。

$ docker run --detach -p 80:80 --name nginx nginx

コンテナのログを表示(docker logs)

$ docker logs コンテナID

このコマンドを実行すると、コンテナ内のログが STDOUT に出力される。つまりターミナルに表示される。コンテナをバックグランドで起動しているときにログを見ることができる。

起動中のコンテナの中にシェルで入る(docker exec -it)

-it オプションは「–interactive」と「–tty」を兼ねたもの。バックグランドで起動しているコンテナと対話できるようになる。

$ docker exec -it コンテナ名 シェルの種類
$ docker exec -it nginx sh
$ docker exec --interactive --tty nginx bash

コンテナから出るには「exit」を入力する。

ホストのデータをコンテナにコピー(マウント)(docker run –volume)

正確にはコピーするわけではなく、マウントなので、コンテナ内で書き換えられたデータは、ホスト側に保存される。コンテナ内には保存されない。

$ docker run --volume ホスト側パス:コンテナ側パス

現在のディレクトリをコンテナ内の /home にマウントして、nginx イメージからコンテナをバックグランドで起動するには次のようにする。

$ docker run -d --volume $(pwd):/home nginx

その他の例

$ docker run --volume index.html:/home nginx

メモ:Windows ではホスト側のパスの表記上の問題により、この書き方では上手く行かなかった。

コンテナの環境変数を設定(docker run –env)

$ docker run --env キー=値

とすることで、コンテナ内に環境変数を追加することができる。

$ docker run -d --env TEST_ENV=hello_world --name nginx nginx

また、コンテナ内では「$env」を入力することで、設定された環境変数を確認することができる。

コンテナのメタデータ(様々な情報)を見る(docker inspect)

$ docker inspect コンテナID
$ docker inspect nginx

コンテナにつなげるホストのポートを変える(docker run -p)

-p は –publish の略。

docker run -p 8080:80 -d --name nginx nginx

コンテナが停止したら自動でコンテナを削除させる(docker run –rm)

docker stop でコンテナを停止させたときに、自動でそのコンテナを削除させたい場合は、次のように docker run コマンド時に –rm オプションを指定する。

docker run -d -p 80:80 --rm --name nginx nginx

起動中のコンテナからイメージを作成する(docker commit)

docker commit コンテナ名 イメージ名

例えば、起動中のコンテナ nginx から、sample_image という名前の新しいイメージを作成する場合は、次のようにする。

docker commit nginx sample_image

イメージを作成する場合の注意点

volume マウントしたデータはあくまでもホスト側で保存されていて、コンテナ内には保存されていない。そのため、volume マウントしてある起動中のコンテナからイメージを作成しても、作成されたイメージには volume マウントしたデータは反映されない。

Dockerfile からイメージを作成する(docker build)

–tag で新しく作られるイメージの名前を指定する。

$ docker build --tag イメージ名 Dockerfileがあるディレクトリパス
$ docker build --tag my_image .

コンテナとイメージの削除

停止中のコンテナと無名のイメージを削除

$ docker system prune

起動中のコンテナも含むすべてのコンテナを削除

docker rm -v -f $(docker ps -a -q)

$(docker ps -a -q) により、() 内のコマンドをバックグランドで実行して、その結果を用いて rm コマンドを実行する。

全てのイメージを削除する(起動中のコンテナも削除される)

docker rmi -f $(docker images -a -q)

Docker の作業の流れ

イメージにパッケージを加えて新しいイメージを作成する

Dockerfile でレシピを作成する

# FROM で基になるイメージを指定(latest は最新のもの)
FROM nginx:latest

# WORKDIR でコンテナが起動したときのコマンドを開始する位置を指定
WORKDIR /usr/share/nginx/html

# COPY でホストからコンテナにファイルをコピー(--volume と同じ)。
# 左側がホスト、右側がコンテナ
# ホストはカレントディレクトリに対する相対パス、コンテナは WORKDIR に対する相対パスを指定
COPY index.html index.html

# RUN で、docker イメージを作っている最中に実行するシェルコマンド
# 次のコマンドで、Linux のパッケージマネージャー apt をアップデートしたら、curl コマンドをインストール
RUN apt update && apt install -y curl

Dockerfile からイメージを作成する(docker build)

–tag で新しく作られるイメージの名前を指定する。

$ docker build --tag イメージ名 Dockerfileがあるディレクトリパス
$ docker build --tag my_image .

作成したイメージからコンテナを起動

$ docker run -d -p 8080:80 --name my_container my_image

Dockerfile

Dockerfile とは

Dockerfile は docker イメージの設計書。ダウンロードした docker イメージをそのまま使うのではなく、ライブラリなどのパッケージを追加して自分専用のイメージを作成したい場合にこのファイルを使用する。作成の元になる docker イメージを指定し、それに対して追加する内容を記述する。

Dockerfile の書き方

# FROM で基になるイメージを指定(latest は最新のもの)
FROM nginx:latest

# WORKDIR でコンテナが起動したときのコマンドを開始する位置を指定
WORKDIR /usr/share/nginx/html

# COPY でホストからコンテナにファイルをコピー(--volume と同じ)。
# 左側がホスト、右側がコンテナ
# ホストはカレントディレクトリに対する相対パス、コンテナは WORKDIR に対する相対パスを指定
COPY index.html index.html

# RUN で、docker イメージを作っている最中に実行するシェルコマンド
# 次のコマンドで、Linux のパッケージマネージャー apt をアップデートしたら、curl コマンドをインストール
RUN apt update && apt install -y curl

その他に、環境変数を設定する ENV

ENV env_key env_value

コンテナが起動したときに最初に実行するコマンドを指定する CMD

CMD ["nginx", "-g", "daemon", "off"]

などがある。

Docker-Compose

Docker-Compose とは

Nginx コンテナの他に Node コンテナも起動したい場合など、複数のコンテナを起動する場合は、それぞれ Docker run するのは煩わしい。

そのような場合は、Docker-Compose を使用すると複数のコンテナを一括で管理できる。Docker-Compose による複数コンテナの管理には、YAML 形式のファイルを使用する。

Docker-Compose は複数のコンテナを管理するためのものだが、単独の docker コンテナを管理するためにも使用することができる。コンテナの操作を YAML に記述しておけば、Git にコミットできるという利点もある。

YAML とは

YAML は、JSON と同様に、構造化されたデータを表すためのフォーマットのこと。インデント(字下げ)を使って、データの階層構造を表す。

YAML は基本的には Key-Value ペアのマップになっていて、行頭が「-(ハイフン」で始まるものだけがリスト(配列)を表す。

Docker run を Docker-Compose の YAML ファイルに記述する

$ docker run -d --name nginx\
  --env env_key=env_value \
  -p 80:80 \
  --volume $(pwd):/usr/share/nginx/html \
  nginx

という docker run コマンドは次のような YAML で記述できる。

version: 3.7
services:
  nginx:
    image: nginx:latest
    container_name: nginx
    environment:
      - env_key=env_value
    ports:
      - "80:80"
    volumes:
      - $(pwd):/usr/share/nginx/html

Docker-compose コマンド

YAML に定義されたコンテナサービスを起動する(up)

$ docker-compose --file docker-compose.yaml up

–file オプションは -f でもよい。また -d(–detach)を付けるとコンテナがバックグランドで起動する。

YAML に定義されたコンテナサービスを停止し、削除する(down)

$ docker-compose -f docker-compose.yaml down

複数のコンテナのログをまとめて表示する(logs)

–follow オプション(-f)を付けるとリアルタイムで表示する。付けないとその時点のログを出力する。

$ docker-compose -f docker-compose.yaml logs --follow

Docker-Compose でコンテナのレプリカ(複製)を複数起動する

YAML を変更する(複数のレプリカで重複を避ける)

YAML の次の点を変更する。

  • コンテナ名が重複するのを防ぐために、container_name を削除する。これにより自動で名前が付けられるようになる。
  • ポート番号が重複するのを防ぐため、ホスト側のポートをレンジ(幅を持たせて)で指定する。

変更前

version: 3.7
services:
  nginx:
    image: nginx:latest
    container_name: nginx
    environment:
      - env_key=env_value
    ports:
      - "80:80"
    volumes:
      - $(pwd):/usr/share/nginx/html:ro

変更後

version: 3.7
services:
  nginx:
    image: nginx:latest
    environment:
      - env_key=env_value
    ports:
      - "80-85:80"
    volumes:
      - $(pwd):/usr/share/nginx/html

レプリカ数を指定してコンテナサービスを起動する(up –scale)

up コマンド実行時に、–scale オプションでレプリカ数を指定する。

$ docker-compose -f docker-compose.yaml up --scale nginx=3

このようにすると、nginx コンテナが3つ起動される。

Docker-Compose で起動されたコンテナ同士で通信する

Docker-Compose で起動されたコンテナ同士はデフォルトで通信ができるようになっている。また Docker-Compose で起動されていない(つまり YAML 外の)コンテナとは通信できない。

docker-compose.yaml

version: "3.7"
services:
  nginx:
    image: nginx:latest
    container_name: docker_compose_nginx
    environment:
      - env_key=env_value
    ports:
      - "80:80"
    volumes:
      - ${PWD}:/usr/share/nginx/html:ro
  ubuntu:
    image: ubuntu
    container_name: docker_compose_ubuntu
    command: ["sleep", "1500"]
    ports:
      - "8080:8080"

docker-compose up で起動する。

$ docker-compose -f docker-compose.yaml up -d

ubuntu コンテナに入って、nginx コンテナに curl してみる。docker-compose で起動されたコンテナ同士は名前で通信できる。

$ docker exec -it docker_compose_ubuntu bash
$ apt update && apt install -y curl
$ curl docker_compose_nginx:80

これで nginx の /usr/share/nginx/html/index.html が取得できれば通信成功。

タイトルとURLをコピーしました