【イラスト付き】Dockerの使い方を完全初心者向けに徹底解説

今回はDockerの基本的な使い方を初心者でも理解できるように

丁寧に解説します

この記事を読むとわかること・・

  • Dockerfileの書き方
  • dockerイメージ・コンテナの作成・削除方法
  • コンテナの更新方法
  • docker-compose.ymlの基本的な使い方
おへんじ
簡単な例を使ってわかりやすく説明するね

dockerってそもそもなに?って方やインストール方法が知りたい方は

以下の記事で解説していますので参考にしてみてください

dockerを使ったselenium・streamlit環境の構築方法は

こちらを参考にしてみてください


Docker使用環境

解説をする前に私が使用している環境を書いておきます

  • MacBook Pro : (13-inch, 2020, Four Thunderbolt 3 ports)
  • プロセッサ:2 GHz クアッドコアIntel Core i5
  • メモリ:16GB
  • docker version:20.10.17
おへんじ
Dockerのバージョンはターミナル上で『docker version』か『docker -v』で確認できるよ

Dockerfile・dockerイメージ・dockerコンテナについて

dockerにはいろいろな用語や概念があって意味わからん!!

って方もいると思うので、よく出るワードについて説明しておきます

難しい横文字を使って説明しても理解できないと思うのでイラストを使って

ふんわりとしたイメージを説明しておきます

イメージ優先なので正式にいうと間違っていることもあるかもしれません
  • Dockerfile : ただのテキストファイル(dockerイメージを作成するときの命令文を書く)
  • dockerイメージ : Dockerfileに書いてある命令文をもとに作られたテンプレートファイル(dockerイメージだけでは何もできない)
  • dockerコンテナ :dockerイメージをもとに作られたローカル環境とは隔離された仮想化された実行環境

これだけの説明では理解できないと思うのでもう少し丁寧に解説します

Dockerfileについて

Dockerfileはdockerイメージを作るときの
命令文が書かれたテキストファイルのことです

サンプルのDockerfileはこんな感じです

サンプルはpython3.8をベースイメージとして

必要なパッケージをインストール、ディレクトリを作成、

app.pyファイルをコンテナ内にコピーなどの簡単な設定を書いています

# python3.8をベースイメージとする
FROM python:3.8

# コンテナ内にappディレクトリを作成
WORKDIR /app

# pythonパッケージをインストールするための準備
RUN apt update
RUN apt install -y
RUN apt install -y python3-pip
RUN pip install --upgrade pip

# app.pyで使用するパッケージをインストール
RUN pip install pandas
RUN pip install numpy

# ローカルのapp.pyファイルをコンテナ内容appディレクトリにコピーする
COPY app.py /app
【豆知識】ベースイメージをpython3.8にするとコンテナ内でlinuxOSが動いています

DockerHubのpython3.8の赤枠箇所にOSの確認ができます

↑Docker Hub python3.8説明画面

dockerイメージについて

dockerイメージはDockerfileをもとに作成されたテンプレートファイルです

dockerイメージはあくまでイメージなので、これだけでは何もできません

Dockerfileに書かれていた情報は持っていますが、具現化してはいないので

dockerイメージでプログラムを実行したりできません

おへんじ
いろんな人がdockerイメージが公開できるdockerhubと呼ばれるサービスもあるよ

dockerコンテナについて

dockerコンテナはdockerイメージから実行されます

コンテナにはDockerfileに書いていたディレクトリ

python、app.pyファイルなどが生成されています

コンテナ側のOS(例:Windows)と

ローカルPC(例:Mac)のOSが違う場合は

ローカルPCのOS(Mac)があたかも

コンテナ側のOS(Windows)があるかのように動作してくれます

コンテナ内のプログラムファイルを実行する方法は

以下の3つあります(画像は①、②のみ記載)

  1. ローカルからコマンドによりコンテナ側のプログラムを実行
  2. コンテナに入って(docker exec)コンテナ内でプログラムを実行
  3. ポートフォアディングでローカルのポートからコンテナ側のポートに情報を転送してプログラムを実行する
おへんじ
あとで具体例を使って説明するから今はちゃんと理解できてなくても大丈夫だよ

なんとなーくのイメージができていれば問題ありません

実際に自分で手を動かしていくうちに概念は理解できるようになります

Dockerの基本操作の解説

docker用語の意味がなんとなくわかったところで実際に

dockerの基本操作を解説していきます

今回解説する主な内容はこんな感じです

  1. Dockerfileとコンテナ用のプログラムファイル(app.py)の作成
  2. dockerイメージの作成
  3. dockerコンテナの作成
  4. コンテナでプログラムを実行
  5. コンテナ抜ける・停止・再稼働
  6. ローカルで修正した内容をコンテナに反映
  7. docker-compose.ymlを使ったイメージ、コンテナの作成

この流れで解説していきます

説明をわかりやすくするために例を使って説明をします

今回はdockerでpython環境を構築することを目標とします

なお、今回は流れの理解を優先するため

最低限のコマンドやオプションしか使用しません

詳しいオプションなどが知りたい方は公式ドキュメントの方を参考にしてみてください

1.Dockerfileとコンテナ用のファイル作成

ディレクトリ構成は以下のとおり

root
 ├── app.py
 └── Dockerfile

Dockerfileはこんな感じ

# python3.8をベースイメージとする
FROM python:3.8

# コンテナ内にappディレクトリを作成
WORKDIR /app

# pythonパッケージをインストールするための準備
RUN apt update
RUN apt install -y
RUN apt install -y python3-pip
RUN pip install --upgrade pip

# app.pyで使用するパッケージをインストール
RUN pip install pandas
RUN pip install numpy

# ローカルのapp.pyファイルをコンテナ内容appディレクトリにコピーする
COPY app.py /app

コンテナ用のpythonファイルはこんな感じ

# coding:utf-8

# 必要なライブラリのimport
import pandas as pd
import numpy as np


def main():
    # 適当にdfを生成
    df = pd.DataFrame(np.arange(12).reshape(3, 4))

    # 作成したdfを表示
    print(df)


if __name__ == '__main__':
    main()

今回はわかりやすさ重視のためシンプルな構成にしています

2.dockerイメージの作成

上記のファイルをもとにdockerイメージを作成していきます

まず、ターミナルを起動してrootディレクトリ(Dockerfileが直下にあるディレクトリ)まで移動します

$ pwd  # 現在のディレクトリの確認
(実行結果)
/Users/username/root  # rootディレクトリにいることを確認

dockerイメージの作成

$ docker build -t sample-python:1.0 .

(使い方)
docker build -t [イメージ名]:tags(version) .

(オプションの説明)
-t: dockerイメージ名とtagが指定できます
   イメージ名→『sample-python』, tags→『1.0』
コマンド最後の『.』はDockerfileが存在するディレクトリを表しています
『.』で指定するディレクトリにDockerfileが存在しない場合はエラーになります

これにより『sample-python』という名前のdockerイメージ(version:1.0)を作成します

おへんじ
tags(version)はイメージのバージョンのことで
最初は1.0で修正するたびに1.1, 1.2・・・って感じで増やしていくよ

イメージを作成する際にカレントディレクトリ以下のファイルはすべて読み込まれるため

不要なファイルがある場合は削除・移動しておきましょう

Dockerfileにコピーをするって記載してないファイルは読み込みはされますが
コピーされることはありません(ただ一度読み込まれるだけで処理時間だけ長くなります

このほかにも『docker build』コマンドには

たくさんのオプションがあるので、他のオプションも

知りたい方は公式ドキュメントを参考にしてください

【豆知識】2回目以降のbuildは1回目からの差分を読み込むためbuildにかかる時間が短いです

buildが完了するとdockerイメージが作成されていますので

『docker images』コマンドで確認しておきます

$ docker images
(実行結果)
REPOSITORY     TAG  IMAGE ID      CREATED       SIZE
sample-python  1.0  1d59efb6bf98  44 hours ago  1.14GB

先ほど作成したsample-pythonのdockerイメージが作成されていたらOKです

3.docker コンテナの作成

先ほど作成したdockerイメージからコンテナを作成します

$ docker run -it --name sample-python-server -d sample-python:1.0

(使い方)
docker run -it --name [コンテナ名] -d [イメージ名]:tag

(オプションの説明)
--name [コンテナ名]     :コンテナに名前をつける(任意)コンテナ名→『sample-python-server』
-d(-d=True)           :デタッチドモードで起動する・・・コンテナ内に入らずコンテナが実行される
              (-dをつけないとコンテナ実行と同時にコンテナ内に入りpython3.8が起動する)
[イメージ名]:tag        :ベースにするdockerイメージとtag(version)を指定する
              (先ほど作成した『sample-python:1.0』を指定)
-it                :コンテナを起動状態にしておくためのオプション
              (-itをつけないとコンテナが起動状態で維持できない)
-p(例では使用なし)     :ポートフォアリング ローカルの特定のポートへの通信をコンテナ側の特定のポートへ転送する

これにより『sapmle-python-server』という名前のコンテナが作成されます

このほかにもたくさんのオプションがあるので、他のオプションも

知りたい方は公式ドキュメントを参考にしてください

runが完了するとコンテナが作成されていますので

『docker ps』コマンドで確認しておきます

$ docker ps  # 稼働しているコンテナを表示
(実行結果)
CONTAINER ID  IMAGE              COMMAND    CREATED         STATUS        PORTS  NAMES
ed8ac4e6b29e  sample-python:1.0  "python3"  15 minutes ago  Up 14 minutes     sample-python-server

『sample-python-server』のコンテナが稼働していたらOKです

おへんじ
停止しているコンテナも確認したい場合は『docker ps -a』コマンドで確認できるよ

ここまでの操作でdockerイメージ、コンテナ作成までが完了しました

4.コンテナでプログラムを実行

先ほど作成した『sample-python-server』コンテナ内に入ってみます

$ docker exec -it sample-python-server bash

(使い方)
docker exec -it [コンテナ名] [コマンド名(今回はシェルを指定)]

(オプションの説明)
-it [コンテナ名] [コマンド名] : コンテナの中で実行する[コマンド名]を記載する
※今回の場合は、コンテナの中でbashを使用したかったのでbashとしています

(実行結果)
root@ed8ac4e6b29e:/app#  ←これはコンテナの/appディレクトリにいることを示しています

これでコンテナ内に入ることができました

コンテナ内の状態を確認してみます

root@ed8ac4e6b29e:/app pwd
(実行結果)
/app

root@ed8ac4e6b29e:/app ls
(実行結果)
app.py

『docker exec』でbashを指定したので『ls』や『pwd』などのコマンドが使用できます

Dockerfileに書いていた/appディレクトリやapp.pyファイルがコンテナ内に確認できます

コンテナ内のapp.pyを実行してみましょう

root@ed8ac4e6b29e:/app python3 app.py

(実行結果)
0  1   2   3
0  0  1   2   3
1  4  5   6   7
2  8  9  10  11

app.pyで作成したデータフレームが表示されているので

app.pyが実行できています

5.コンテナ抜ける・停止・再稼働

コンテナを出るときはMacの場合

『Contorol』+『q』+『p』を同時に押すことで抜けることができます

コンテナを抜けると『root@ed8ac4e6b29e:/app#』が
『path %』の表記に戻ります

コンテナから抜けた後にコンテナを停止しておきます

$ docker stop sample-python-server  # コンテナの停止

(使い方) 
docker stop [コンテナ名]

(実行結果)
sample-python-server ←停止したコンテナ名が表示されます

実行すると停止したコンテナ名が表示されます

『docker ps』で確認してみると

$ docker ps

(実行結果)
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

稼働しているコンテナがないことがわかります

再度コンテナを稼働させたいときは

$ docker start sample-python-server

(使い方)
docker start [コンテナ名]

(実行結果)
sample-python-server ←稼働したコンテナ名が表示されます

『docker start』コマンドでコンテナを再稼働させることができます

再稼働させるときは、runコマンドやオプションは不要です

一番最初にコンテナを稼働させるときは『docker run』コマンドを

使いましたが、『docker run』コマンドは最初にdockerイメージから

コンテナを作成するときだけに使用します

『docker start』コマンドにオプションをつける必要はありません

『docker run』コマンドのときにつけたオプションは、再稼働時も適用されます

6.ローカルで修正した内容をコンテナに反映

これで一連のdockerの使い方の説明はしましたが

app.pyファイルに修正したい箇所があった場合の

変更内容の反映方法について説明しておきます

まずはローカルでapp.pyに以下の文を追記します

# coding:utf-8

# 必要なライブラリのimport
import pandas as pd
import numpy as np


def main():
    # 適当にdfを生成
    df = pd.DataFrame(np.arange(12).reshape(3, 4))

    # 作成したdfを表示
    print(df)

  # -------------追記部分------------
   print("追加箇所:コンテナでこれが表示されたら反映完了")



if __name__ == '__main__':
    main()

これをコンテナに反映させていきます

方法はざっくり言うと

  • コンテナ作り直す

です笑

結局それが一番シンプルな方法になります

コンテナを更新する方法として『docker update』コマンドがありますがコンテナ内のファイル内容の更新はできません

『docker update』ではコンテナのメモリ上限やCPUの上限を変更できます

この他にも変更できる内容はありますので、

もっと知りたい方は公式ドキュメントを参考にしてみてください

更新する流れはこんな感じ・・・

  1. コンテナ停止(docker stop)
  2. コンテナ削除(docker rm)
  3. イメージの再作成(docker build)
  4. コンテナの再作成(docker run)
  5. 修正前のイメージの削除

②⑤以外は先ほど解説したものと同じコマンドを使用するので

さらーっと書いておきます

コンテナの停止

$ docker stop sample-python-server
(実行結果)
sample-python-server

コンテナの削除

$ docker rm ed8ac4e6b29e
(使い方)
docker rm [コンテナid]
(実行結果)
ed8ac4e6b29e ←削除されたコンテナidが表示されます
おへんじ
コンテナidは『docker ps』を実行したときに表示されるよ

イメージの再作成

$ docker build -t sample-python:1.0 .
(実行結果)
略(インストールしてますよーってのがいろいろ表示される)
【豆知識】
イメージを作成するときにイメージ名とtags(version)が同じイメージがある場合
既存イメージの名前(REPOSITORY)とTAGが〈none〉になってしまします

〈none〉のイメージは残しておくとゴチャゴチャしてしまうため削除しておきましょう

イメージを削除

$ docker rmi 1d59efb6bf98
(使い方)
docker rmi [コンテナイメージid]
(実行結果)
Deleted: sha256:1d59efb6bf984b799f75eca64ba462be0ca8b0c64e1e373064bc31e0f2f50269
おへんじ
イメージidは『docker images』で確認できるよ

コンテナの再作成

$ docker run -it --name sample-python-server -d sample-python:1.0
(実行結果)
9eecea4c7689dd913d94c988a4586d63999fdea8ac8402aebdb0a7f8bfdce506

コンテナ内に入る

$ docker exec -it sample-python-server bash
(実行結果)
root@9eecea4c7689:/app#

コンテナ内のプログラムの実行

root@9eecea4c7689:/app python app.py
(実行結果)
   0  1   2   3
0  0  1   2   3
1  4  5   6   7
2  8  9  10  11
追加箇所:コンテナでこれが表示されたら反映完了

これにてローカルの修正内容をコンテナに反映することができました

docker-compose.ymlについて

最後にdocker-compose.ymlの使い方を解説します

docker-compose.ymlとは

一言でいうと・・・

コンテナ内のアプリケーションを動かすための設定を書くファイルのこと

docker-compose.ymlでも

dockerイメージ・dokcerコンテナを作成することはできます

docker-compose.ymlを使用することのメリットは・・・

  • 毎回オプションなどの設定やパッケージインストールの必要がなくなる
  • 複数のコンテナを任意の順番で起動することができる
  • コンテナが稼働していてもローカルファイルの変更内容を反映できる

要は1回docker-compose.ymlを書いておけば面倒な設定が省略できちゃう

って感じです

docker-compose.ymlの使い方

docker-compose.ymlを使った

dockerイメージ・dockerコンテナの作成方法を

解説していきます

先ほどと同じコンテナを作成します

docker-compose.ymlはこんな感じ・・

version: '3'
services:
  sample-python:                 # 下の行のimage:がない場合は『カレントディレクトリ+ここに書いた"sample-python"』がイメージ名になる
    container_name: sample-python-server  # コンテナ名を指定
    build:                                # build時の設定
      context: .                          # Dockerが参照するディレクトリの位置(基本はトップディレクトリの.にしておくことが多い)
      dockerfile: ./Dockerfile            # Dockerfileのパス
    image: sample-python:1.0              # dockerイメージ名とtags(version)
    tty: true                             # コンテナを起動状態にしておく設定(dockerコマンドでいう-itオプション)

dockerイメージの作成

$ docker-compose build
(実行結果)
略(いろいろインストールしてるよーって表示される)

dockerイメージの確認

$ docker images
(実行結果)
REPOSITORY     TAG  IMAGE ID      CREATED     SIZE
sample-python  1.0  19a85566f35e  2 hours ago 1.14GB

sample-pythonという名前のdockerイメージが作成されています

dockerコンテナの起動

$ docker-compose up -d
(実行結果)
[+] Running 1/1
 ⠿ Container sample-python-server  Started  # sample-python-serverコンテナ稼働したよーって表示される

dockerコンテナの確認

$ docker ps
(実行結果)
CONTAINER ID   IMAGE               COMMAND     CREATED         STATUS         PORTS     NAMES
b2efbd681ac9   sample-python:1.0   "python3"   2 minutes ago   Up 2 minutes             sample-python-server

コンテナが稼働していることが確認できます

dockerコンテナの中に入る

コンテナの中に入るコマンドはdocker-compose.ymlを使用している場合は2つあります

【1つ目】

$ docker exec -it sample-python-server bash

(実行結果)
root@b2efbd681ac9:/app#

先ほどと同じ方法です

【2つ目】

$ docker-compose exec sample-python bash

(使い方)
docker-compose exec [イメージ名] bash

(実行結果)
root@b2efbd681ac9:/app#

どちらのコマンド使用しても同様にコンテナに入ることができます

コンテナ内のプログラムの実行

root@b2efbd681ac9:/app python app.py
(実行結果)
   0  1   2   3
0  0  1   2   3
1  4  5   6   7
2  8  9  10  11

コンテナを抜ける

先ほどと同じで『Contorol』+『q』+『p』を同時に押すことで抜けることができます

コンテナの停止・削除

$ docker-compose down

コンテナの停止のみ

$ docker-compose stop

コンテナの削除のみ

$ docker rm [コンテナ名]

これでイメージ・コンテナの作成

をすることができました

docker-compose.ymlを使った方がイメージ・コンテナの作成は

シンプルで簡単なのが理解できたと思います

ローカルでの修正内容の反映

最後にdocker-compose.ymlを使った場合の

ローカルファイルの変更内容をコンテナに反映する方法を紹介しておきます

docker-compose.ymlでローカルファイルの変更内容を

反映する場合は・・・

  • コンテナ稼働中でも変更内容を反映することができる
  • コンテナの削除・再作成も必要なし
イメージを更新したときに更新前のイメージは〈none〉となるため、都度削除は必要です

dockerコンテナの確認

$ docker ps
(実行結果)
CONTAINER ID   IMAGE               COMMAND     CREATED         STATUS         PORTS     NAMES
b2efbd681ac9   sample-python:1.0   "python3"   2 minutes ago   Up 2 minutes             sample-python-server

稼働していることを確認

ローカルでapp.pyに追加文を記載します

# coding:utf-8

# 必要なライブラリのimport
import pandas as pd
import numpy as np


def main():
    # 適当にdfを生成
    df = pd.DataFrame(np.arange(12).reshape(3, 4))

    # 作成したdfを表示
    print(df)

  # -------------追記部分------------
   print("追加箇所:コンテナでこれが表示されたら反映完了")



if __name__ == '__main__':
    main()

コンテナに変更内容を反映

$ docker-compose up -d --build
(実行結果)
略(いろいろインストールしてるよーって表示あり)

(オプションの説明)
--build :コンテナ起動するときにbuildも一緒に実行できる
-d      :バックグランドのままコンテナが起動する

このコマンドで『up』+『build』を同時に行えます

docker-compose.ymlファイルのみを更新した場合は

『–build』オプションは不要です

コンテナの確認をしてみると・・

$ docker ps
(実行結果)
CONTAINER ID   IMAGE               COMMAND     CREATED         STATUS         PORTS     NAMES
800ee4000cba   sample-python:1.0   "python3"   7 minutes ago   Up 7 minutes             sample-python-server

コンテナidが更新されていることがわかります

これは一見コンテナが更新されているように感じますが

内部的な処理としては、別のイメージがbuildされて

upによりコンテナが実行されています

実行するコマンドは減りましたが内部的な処理は変わっていません

〈none〉イメージは削除

$ docker rmi  19a85566f35e
(実行結果)
Deleted: sha256:19a85566f35e5c90122b7863f007e8e0014c07f127869f48f1663e78599a63a2

コンテナでapp.pyを実行

# コンテナ内に入る
$ docker-compose exec sample-python bash
(実行結果)
root@800ee4000cba:/app#

# コンテナ内でapp.pyを実行
root@800ee4000cba:/app python3 app.py
(実行結果)
   0  1   2   3
0  0  1   2   3
1  4  5   6   7
2  8  9  10  11
追加箇所:コンテナでこれが表示されたら反映完了

コンテナ内のapp.pyに変更が反映されているのがわかります

いかがでしたでしょうか

dockerのイメージ・コンテナの理解や使い方が

なんとなーくでも理解できたかと思います

この記事を読んだだけでは、dockerの概念的な部分は

理解できないと思いますが実際に自分で手を動かしていく

うちに、少しずつ理解できます

下のページでdockerを使った

selenium・streamlit環境の構築方法を

解説していますので参考にしてみてください

まとめ

Dockerfile・dockerイメージ・dockerコンテナとは

Dockerfile・・・

  • テキストファイル(dockerイメージを作成するときの命令文を書く)

dockerイメージ・・・

  • Dockerfileに書いてある命令文をもとに作られたテンプレートファイル

dockerコンテナ・・・

  • dockerイメージをもとに作られた
    ローカル環境とは隔離された仮想化された実行環境

docker-compose.ymlとは

  • コンテナ内のアプリケーションを動かすための設定を書くファイルのこと

docker-compose.ymlを使うメリットは

  • 1回オプションなどの設定やパッケージインストールの必要がなくなる
  • 複数のコンテナを任意の順番で起動することができる
  • コンテナが稼働していてもローカルファイルの変更内容を反映できる

ohenziblogはプログラミングを独学で始めるための徹底ガイドを目指しています

最新情報をチェックしよう!