こんにちは。
Dockerについて学習したので、アウトプットも兼ねて__初学者ならではの視点__で記事を書いてみようと思います。
筆者が初めてDockerについて記事を読んで学習した際、__「で、結局何ができるんだ?」__という疑問が残ってしまいましたが、実際にコマンドを叩いてコンテナ構築をしてみると、何が便利なのかイメージができたので実践してみることをお勧めします。
なお、仕組み等の詳細説明は割愛します。
間違った部分等ありましたらご指摘いただけると幸いです。
Dockerの特徴
コンテナは、__Dockerfile__というソースコードから構築します。(このようにコードベースでインフラ構築を定義する考え方を_Infrastructure as Code_といいます。)
これによって、__開発したアプリケーションが別環境だと動かない__といった環境差異を防ぐことができます。他にも、
- Dockerfileを(Github等で)共有することで、どこでも誰でも同じ環境が作れる。
- 環境を壊してしまった場合などに、環境の再構築が容易。
などといった特徴があります。
コンテナ構築の流れ
Dockerfileからイメージを作り、イメージからコンテナを立ち上げるという流れです。
イメージ
とは ... コンテナの構成をまとめたもので、コンテナを構築するベースのようなものです。DockerHubには、wordpress, mysql, python
などがイメージファイルとして公開されており、それらを自分で組み合わせたイメージを作成します。
Docker Hub 概要 — Docker-docs-ja 19.03 ドキュメント
なお、Dockerではコンテナ1つにアプリケーション1つが推奨されているので、例えばMySQL
+ nginx
+ flask
など、複数のアプリケーションを組み合わせているサービスををDockerで動かす場合は、利用するアプリケーション分コンテナを構築し、docker-composeやKubernatesなどの__コンテナオーケストレーションサービス__を利用する必要があります。
ローカル環境にコンテナを構築
今回は、コンテナ環境でPythonのwebフレームワークである、flaskを動かしてみようと思います。
なお、ホスト環境にPythonやFlaskをインストールする必要はありません。
ローカル環境にDockerがインストールされていることが前提です。
Get Docker | Docker Documentation
前提ファイルの準備
Dockerfileとpythonファイルのmain.pyを同じディレクトリに用意します。
./
├ main.py
└ Dockerfile
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello from Docker!'
if __name__ == '__main__':
app.debug = True
app.run(host='0.0.0.0')
pythonファイルの内容は、ルートにアクセスがあったらHello from Dockerと表示する単純なflaskプログラムです。
FROM python:latest
RUN mkdir /src && \
pip install flask
COPY main.py /src
CMD ["python", "/src/main.py"]
# "python /src/main.py"と同じ
-
FROM
... 作成するDockerイメージの__ベースイメージを指定__。DockerHubからダウンロードされる。pythonの最新バージョンを指定。 -
RUN
... __イメージのビルド時__に実行されるコマンド。src
というディレクトリを作成するコマンドと、pipを使ってflaskをインストールするコマンドを指定。 -
COPY
... ホストマシンのファイルやディレクトリをコンテナ内にコピーする。先程用意したmain.py
をコンテナ内のsrc
ディレクトリにコピーする。 -
CMD
... __コンテナ起動時__に実行されるコマンドを指定。スペース区切りで配列化した形式。python /src/main.py
でpythonファイルを実行している。
イメージのビルド
$ docker image build -t tutorial/docker-flask:latest .
-t
以降は、<account name>/<image name>:<tag>
の形式で指定します。
-
account name
... 名前衝突を避けるための__名前空間__ -
image name
... イメージ名 -
tag
... バージョン__や__ラベル
末尾にDockerfileのあるディレクトリを指定します。(今回はカレントを指定)
このように表示されればビルドが完了です。
Successfully built 03bb880c97ac
Successfully tagged tutorial/docker-flask:latest
docker image ls
コマンドで、イメージのリストが確認できます。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
tutorial/docker-flask latest 03bb880c97ac 7 minutes ago 895MB
コンテナ起動
最後に、作成したイメージからコンテナを起動します。
$ docker container run -d -p 8080:5000 tutorial/docker-flask:latest
-d
はバックグラウンドで実行するオプションです。
ここで__重要__なのが、-p 8080:5000
の部分です。
これは__ポートフォワーディング__という設定で、ホストのポートとコンテナ内のポートを接続する設定です。
flaskでは、デフォルトで5000
番ポートを使用しているため、この記述で__8080番ポートへのアクセスを、5000番ポートへ転送__しています。
アクセスしてみる
localhostの8080番ポートにアクセスすると、無事Hello from Docker!
と表示され、コンテナ内でpythonが動いていることが確認できます。
後片付け
コンテナの停止
$ docker ps -a
で起動しているコンテナを確認します。
-a
を指定することで、停止中のコンテナも表示されます。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
8b15d95aa3b2 tutorial/docker-flask:latest "python /src/main.py" 10 minutes ago Up 10 minutes 0.0.0.0:8080->5000/tcp sad_blackwell
$ docker stop <CONTAINER ID or NAMES>
でコンテナが停止します。
$ docker stop 8b15d95aa3b2
もしくは
$ docker stop sad_blackwell
$ docker ps -a
で、STATUS
がExited
となっており、停止されているのが確認できます。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8b15d95aa3b2 tutorial/docker-flask:latest "python /src/main.py" 15 minutes ago Exited (0) 3 minutes ago sad_blackwell
コンテナを再度起動する際も、同様に$ docker start <CONTAINER ID もしくは NAMES>
でコンテナを起動することができます。
コンテナ削除(任意)
停止のやり方と同様に、$ docker ps -a
でCONTAINER IDもしくはNAMESの欄を確認します。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8b15d95aa3b2 tutorial/docker-flask:latest "python /src/main.py" 23 minutes ago Up 6 minutes 0.0.0.0:8080->5000/tcp sad_blackwell
$ docker rm <CONTAINER ID or NAMES>
でコンテナの削除ができます。
$ docker rm 8b15d95aa3b2
もしくは
$ docker rm sad_blackwell
$ docker ps -a
で削除できたか確認する
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
無事消えていることが確認できました。
イメージ削除(任意)
$ docker images
で保存されているのイメージの確認をします。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tutorial/docker-flask latest 03bb880c97ac 39 minutes ago 895MB
イメージの削除は、$ docker rmi <REPOSITORY or IMAGE ID>
で行います。
$ docker rmi tutorial/docker-flask
もしくは
$ docker rmi 03bb880c97ac
$ docker images
で削除の確認
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
イメージが削除されていることが確認できました。