今回は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
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
DockerHubのpython3.8の赤枠箇所にOSの確認ができます
dockerイメージについて
dockerイメージはDockerfileをもとに作成されたテンプレートファイルです
dockerイメージはあくまでイメージなので、これだけでは何もできません
Dockerfileに書かれていた情報は持っていますが、具現化してはいないので
dockerイメージでプログラムを実行したりできません
dockerコンテナについて
dockerコンテナはdockerイメージから実行されます
コンテナにはDockerfileに書いていたディレクトリや
python、app.pyファイルなどが生成されています
コンテナ側のOS(例:Windows)と
ローカルPC(例:Mac)のOSが違う場合は
ローカルPCのOS(Mac)があたかも
コンテナ側のOS(Windows)があるかのように動作してくれます
コンテナ内のプログラムファイルを実行する方法は
以下の3つあります(画像は①、②のみ記載)
- ローカルからコマンドによりコンテナ側のプログラムを実行
- コンテナに入って(docker exec)コンテナ内でプログラムを実行
- ポートフォアディングでローカルのポートからコンテナ側のポートに情報を転送してプログラムを実行する
なんとなーくのイメージができていれば問題ありません
実際に自分で手を動かしていくうちに概念は理解できるようになります
Dockerの基本操作の解説
docker用語の意味がなんとなくわかったところで実際に
dockerの基本操作を解説していきます
今回解説する主な内容はこんな感じです
- Dockerfileとコンテナ用のプログラムファイル(app.py)の作成
- dockerイメージの作成
- dockerコンテナの作成
- コンテナでプログラムを実行
- コンテナ抜ける・停止・再稼働
- ローカルで修正した内容をコンテナに反映
- 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)を作成します
最初は1.0で修正するたびに1.1, 1.2・・・って感じで増やしていくよ
イメージを作成する際にカレントディレクトリ以下のファイルはすべて読み込まれるため
不要なファイルがある場合は削除・移動しておきましょう
コピーされることはありません(ただ一度読み込まれるだけで処理時間だけ長くなります)
このほかにも『docker 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イメージ、コンテナ作成までが完了しました
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』コマンドでコンテナを再稼働させることができます
一番最初にコンテナを稼働させるときは『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』ではコンテナのメモリ上限やCPUの上限を変更できます
この他にも変更できる内容はありますので、
もっと知りたい方は公式ドキュメントを参考にしてみてください
更新する流れはこんな感じ・・・
- コンテナ停止(docker stop)
- コンテナ削除(docker rm)
- イメージの再作成(docker build)
- コンテナの再作成(docker run)
- 修正前のイメージの削除
②⑤以外は先ほど解説したものと同じコマンドを使用するので
さらーっと書いておきます
コンテナの停止
$ docker stop sample-python-server
(実行結果)
sample-python-server
コンテナの削除
$ docker rm ed8ac4e6b29e
(使い方)
docker rm [コンテナid]
(実行結果)
ed8ac4e6b29e ←削除されたコンテナidが表示されます
イメージの再作成
$ docker build -t sample-python:1.0 .
(実行結果)
略(インストールしてますよーってのがいろいろ表示される)
イメージを作成するときにイメージ名とtags(version)が同じイメージがある場合
既存イメージの名前(REPOSITORY)とTAGが〈none〉になってしまします
〈none〉のイメージは残しておくとゴチャゴチャしてしまうため削除しておきましょう
イメージを削除
$ docker rmi 1d59efb6bf98
(使い方)
docker rmi [コンテナイメージid]
(実行結果)
Deleted: sha256:1d59efb6bf984b799f75eca64ba462be0ca8b0c64e1e373064bc31e0f2f50269
コンテナの再作成
$ 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でローカルファイルの変更内容を
反映する場合は・・・
- コンテナ稼働中でも変更内容を反映することができる
- コンテナの削除・再作成も必要なし
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はプログラミングを独学で始めるための徹底ガイドを目指しています