Dockerを使ってみる
ここでは、実際に Docker コンテナと Docker Hub を使って、自作 Web アプリケーションを別の人に渡してみます。 Docker コンテナを用いた自作 Web アプリケーションを作成し、次に、Docker Hub を介してこのイメージをやりとりします。
Docker の Daemon が起動していない場合は、以下のコマンドで起動してください。Ubuntu からログインしたり再起動すると、これが必要です。また、WSL上でのUbuntuではこれは必要ありません。
sudo systemctl start docker
sudo systemctl enable docker
Flaskの環境構築とWebサーバの起動
まず、Flask という Python ベースの Web サーバアプリケーションの実行環境を Docker コンテナで作成します。
ここからは、Docker コンテナ内部で行う作業なのか、Ubuntu 上で行う作業なのかを意識してほしいと思います。
どちらで作業をしているかは、端末の左端で見分けることができます。
-
Ubuntu 上での作業の場合は↓みたいになります。
[oreshi@akipon docker_practical]$
-
コンテナ内部での作業の場合は↓みたいになります。
root@576d2ea40830:/#
1. Pythonコンテナの実行
Ubuntu 上の端末で、以下のコマンドで Python のコンテナ環境を実行します。
docker container run --name base -it -p 8080:80 python:3.7.5-slim bash
以下のようなログが流れて、最後が root@576d2ea40830:/#
という様なものになるはずです(数字は違うと思います)。これでコンテナが実行され、内部に入りました。
[oreshi@akipon docker_practical]$ docker container run --name base -it -p 8080:80 python:3.7.5-slim bash
Unable to find image 'python:3.7.5-slim' locally
3.7.5-slim: Pulling from library/python
Digest: sha256:59af1bb7fb92ff97c9a23abae23f6beda13a95dbfd8100c7a2f71d150c0dc6e5
Status: Downloaded newer image for python:3.7.5-slim
root@576d2ea40830:/#
※ 裏側で何をしているかというと、Docker Hub から Python 3.7.5 (python:3.7.5-slim
) のイメージを pull し、イメージからコンテナをbaseという名前で作成します。
その後、作成したコンテナで bash を実行し、コンテナ内部での作業を開始します。
コンテナ内部での作業は、ターミナルが root@576d2ea40830:/#
という様なものになります。
今回は、コンテナのライフサイクルを意識するために、--rm
オプションを付けていません。
2. Flaskのインストール
次に、以下のコマンドで、「1. Python コンテナの実行」で作成した base コンテナに flask をインストールします。入力部分が root@576d2ea40830:/#
のままであることを確認してください。
この作業はコンテナ内部です。
pip install flask
以下のようなログが流れるはずです。細かい部分は違うと思います。
root@576d2ea40830:/# pip install flask
Collecting flask
Downloading https://files.pythonhosted.org/packages/f2/28/2a03252dfb9ebf377f40fba6a7841b47083260bf8bd8e737b0c6952df83f/Flask-1.1.2-py2.py3-none-any.whl (94kB)
|████████████████████████████████| 102kB 8.9MB/s
Collecting Jinja2>=2.10.1
Downloading https://files.pythonhosted.org/packages/7e/c2/1eece8c95ddbc9b1aeb64f5783a9e07a286de42191b7204d67b7496ddf35/Jinja2-2.11.3-py2.py3-none-any.whl (125kB)
|████████████████████████████████| 133kB 6.0MB/s
Collecting itsdangerous>=0.24
Downloading https://files.pythonhosted.org/packages/76/ae/44b03b253d6fade317f32c24d100b3b35c2239807046a4c953c7b89fa49e/itsdangerous-1.1.0-py2.py3-none-any.whl
Collecting Werkzeug>=0.15
Downloading https://files.pythonhosted.org/packages/cc/94/5f7079a0e00bd6863ef8f1da638721e9da21e5bacee597595b318f71d62e/Werkzeug-1.0.1-py2.py3-none-any.whl (298kB)
|████████████████████████████████| 307kB 6.8MB/s
Collecting click>=5.1
Downloading https://files.pythonhosted.org/packages/d2/3d/fa76db83bf75c4f8d338c2fd15c8d33fdd7ad23a9b5e57eb6c5de26b430e/click-7.1.2-py2.py3-none-any.whl (82kB)
|████████████████████████████████| 92kB 11.4MB/s
Collecting MarkupSafe>=0.23
Downloading https://files.pythonhosted.org/packages/c2/37/2e4def8ce3739a258998215df907f5815ecd1af71e62147f5eea2d12d4e8/MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl
Installing collected packages: MarkupSafe, Jinja2, itsdangerous, Werkzeug, click, flask
Successfully installed Jinja2-2.11.3 MarkupSafe-1.1.1 Werkzeug-1.0.1 click-7.1.2 flask-1.1.2 itsdangerous-1.1.0
WARNING: You are using pip version 19.3.1; however, version 24.0 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
これで、flask がインストールされました。 Python 自体をインストールしたわけではありません。 Python 自体は、「1. Python コンテナの実行」で pull してきたイメージにすでにインストールされているからです。
3. ファイルの確認
この時点でコンテナ内部に、どのようなファイルが存在しているかを以下のコマンドで確認してみましょう。
ls /
以下のような出力が返ってくるはずです。bin から var までは、すべて完全に一致するはずです。
root@576d2ea40830:/# ls /
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
4. 別のコンソールを開く
次に、Ubuntu 上で、別のコンソールを開きます。Ubuntu の場合は、端末の左上のタブアイコンを押してください。 また、別のコンソールは、Ubuntu 上での作業であり、コンテナ内部での作業ではないことを意識してください。
5. 実行ファイルの作成
以下のコマンドを実行し、"./app.py"というファイルを作ってみましょう。このファイルは、コンテナにコピーし Flask で実行します。 これは、Ubuntu 上での作業です。
gedit ./app.py
※ gedit が入っていない場合は、sudo apt -y install gedit
でインストールしてみてください。
installコマンドを実行する前に、sudo apt update
が必要かもしれません。
続けて、以下の Python プログラムを書き込みます。"[JIBUN NO SUKINA BUNSHOU]"というところに、自分の好きな文書を入れてみましょう。 ここでは、"Hi, this is written by 210150!" としました。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return "[JIBUN NO SUKINA BUNSHOU]"
app.run(debug=True, host='0.0.0.0', port=80)
6. ファイルをコンテナへコピー
以下のコマンドで、作成したapp.py
を base コンテナへコピーします。
これは、Ubuntu 上で行う作業で、Ubuntu 上で作ったファイルを、base コンテナにコピーするものです。
具体的には、./app.py
を base
イメージの /
にコピーする、というものです。
docker container cp ./app.py base:/
7. ファイルをコンテナ上で確認
コンテナを実行した元のコンソールに戻り、以下のコマンドでファイルがコピーされたことを確認してください。 また、コンテナ内部での作業に戻ったことを意識してください。
ls /
以下のように、左端にapp.py というファイルが確認できるはずです。app.py から var までは、すべて完全に一致するはずです。
root@576d2ea40830:/# ls /
app.py bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
以下のコマンドで、app.py の中身を確認できます。 「5. ファイルの作成と入力」で作成したものと同一ですね。
root@576d2ea40830:/# cat ./app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return "Hi, this is written by 210150!"
app.run(debug=True, host='0.0.0.0', port=80)
8. Webサーバの起動
それでは、Flask を用いた簡易 Web サーバを起動してみましょう。 以下のコマンドで、コンテナ上で Flask を用いた簡易 Web サーバを起動します。
python -u ./app.py
以下のようなログが流れるはずです。細かい部分は違うと思います。
root@576d2ea40830:/# python -u ./app.py
* Serving Flask app 'app'
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:80
* Running on http://172.17.0.2:80
Press CTRL+C to quit
* Restarting with stat
* Debugger is active!
* Debugger PIN: 113-519-528
docker container run --name base -it -p 8080:80 python:3.7.5-slim bash 0.93s user 0.45s system 0% cpu 2:39:35.17 total
9. Webサーバへのアクセス
起動した簡易 Web サーバを、ホスト OS のブラウザから http://127.0.0.1:8080
もしくはhttp://localhost:8080
にアクセスし、"Hi, this is written by 210150!" というメッセージが表示されていることを確認してください。http://172.17.0.2:80
はたぶんアクセスできません。
http://127.0.0.1:8080
でアクセスできない場合は、docker container run
した時に出てくるそれっぽい数字の下の方のやつを開いてみてください。
チェックポイント:できたら見せてください
ここまで、Python イメージの Docker コンテナを利用した、Flask による簡易 Web サーバの構築が完了しました。 なお、この時点では、base コンテナは起動した状態です。
10. コンテナの終了
最後に、コンテナ上の Python を起動させた端末上でCtrl+C
(Ctrl キーと C キーの同時押し) を打って、Python プログラムを終了さます。
その後、exit
コマンドでコンテナを終了します。
また、最後に使ったコンテナを削除しておきます。
docker ps -a
WebサーバのDockerイメージの作成
ここからは、「Flask の環境構築と Web サーバの起動」で作成した base コンテナを新規の Docker イメージとしてコミットします。
1. 作成したイメージのコミット
以下のコマンドで、base コンテナから"semi1_c2img1_app
"という Docker イメージを作成します。これをコミット (commit) と言います。これを行わないと、コンテナを停止するごとに追加したファイルやデータが消えてしまいます。
docker commit base semi1_c2img1_app
以下のようなログが表示されるはずです。sha256:c82...の数字は異なると思います。
[oreshi@akipon docker_practical]$ docker commit base semi1_c2img1_app
sha256:c82ebcd027abd8c998085bf970fd16a32f9e6486103c2224c8955553b479a4a2
また、以下のコマンドで正しくイメージ化できたかを確認してください。 正しくイメージ化できていれば、ブラウザで「9. Web サーバへのアクセス」と一緒のメッセージが見えるはずです。
[oreshi@akipon docker_practical]$ docker container run --name trial1 -it -p 8080:80 semi1_c2img1_app python -u /app.py
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 353-638-136
2. コミットしたイメージの確認
以下のコマンドで、コミットしたイメージ "semi1_c2img1_app" がローカルに保存されていることを確認できます。
docker image ls
以下のようなログが表示されるはずです。
REPOSITORY TAG IMAGE ID CREATED SIZE
semi1_c2img1_app latest 74a73a02e6c6 27 seconds ago 265MB
nginx latest 62d49f9bab67 11 days ago 133MB
nginx 1.18 c2c45d506085 2 weeks ago 133MB
hello-world latest d1165f221234 7 weeks ago 13.3kB
python 3.7.5-slim 9f4008bf3f11 17 months ago 178MB
次に以下のコマンドで、コミットしたイメージを改名します。この名前は、Docker Hub へ登録した際に利用されます。 ACCOUNT_NAMEは、Docker Hubへのユーザ登録で登録したアカウント名を入れてください。
docker image tag semi1_c2img1_app ACCOUNT_NAME/semi1_c2img1_app
それぞれのオプションの詳しい意味は、以下の通りです。
docker image tag
:既存のDockerイメージに新しいタグ(別名)を付けるコマンドsemi1_c2img1_app
:タグを付けたい元のイメージ名ACCOUNT_NAME/semi1_c2img1_app
:新しく付けるタグ名(リポジトリ名を含む形式)。例:Docker Hubなどにプッシュする際のアカウント名や組織名を指定
最後に、あらためて docker image ls
コマンドでイメージを確認してみましょう。
以下のように、"ACCOUNT_NAME/semi1_c2img1_app"が追加されているはずです。
REPOSITORY TAG IMAGE ID CREATED SIZE
semi1_c2img1_app latest 74a73a02e6c6 27 seconds ago 265MB
oreshi/semi1_c2img1_app latest 74a73a02e6c6 27 seconds ago 265MB
nginx latest 62d49f9bab67 11 days ago 133MB
nginx 1.18 c2c45d506085 2 weeks ago 133MB
hello-world latest d1165f221234 7 weeks ago 13.3kB
python 3.7.5-slim 9f4008bf3f11 17 months ago 178MB
3. Docker Hubへの登録
まず、以下のコマンドで Docker Hub にログインします。
docker login
次に、コミットしたイメージを push します。
docker image push ACCOUNT_NAME/semi1_c2img1_app
それぞれのオプションの詳しい意味は、以下の通りです。
docker container run
:新しいコンテナを作成して起動する--name base
:コンテナに「base」という名前を付ける-it
:-i
(標準入力を開いたままにする)と-t
(擬似ターミナルを割り当てる)の組み合わせ。対話的なシェル操作が可能になる-p 8080:80
:ホストの8080番ポートをコンテナの80番ポートに割り当てる(ポートフォワーディング)。ホストの http://localhost:8080 でコンテナ内の80番ポートにアクセスできるpython:3.7.5-slim
:使用するDockerイメージ名(Python 3.7.5の軽量版)bash
:コンテナ起動時に実行するコマンド(bashシェルを起動)
以下のようなログが流れ、アップロードしていることがわかります。
[oreshi@akipon docker_practical]$ docker image push ACCONUT_NAME/semi1_c2img1_app
Using default tag: latest
The push refers to repository [docker.io/ACCOUNT_NAME/semi1_c2img1_app]
18ccea9d031c: Pushed
36c21e895230: Mounted from library/python
870ea4318145: Mounted from library/python
ca56b6fe98b7: Mounted from library/python
459d9d53a256: Mounted from library/python
831c5620387f: Mounted from library/python
latest: digest: sha256:59161a3778a1f0a5de00573a1a10ec79f68401e0a23ba99110a07b460f10e957 size: 1582
最後に、以下のコマンドで Docker Hub で登録されたかを確認します。時間が経たないと出てこないと思います。
docker search ACCOUNT_NAME/semi1_c2img1_app
4. イメージをメンバーに渡す
チームメンバーのイメージを Docker Hub 経由でもらってみましょう :) BETSU_NO_ACCOUNT_NAMEはチームメンバーのアカウント名です。
たとえば、以下のコマンドでイメージを取得と実行ができます。
docker container run --name moraimono -it -p 8080:80 [BETSU_NO_ACCOUNT_NAME]/semi1_c2img1_app python -u /app.py
以下のようなログが流れ、イメージが実行されます。
[oreshi@akipon docker_practical]$ docker container run --name moraimono -it -p 8080:80 BETSU_NO_ACCOUNT_NAME/semi1_c2img1_app python -u /app.py
Unable to find image 'BETSU_NO_ACCOUNT_NAME/semi1_c2img1_app:latest' locally
latest: Pulling from BETSU_NO_ACCOUNT_NAME/semi1_c2img1_app
Digest: sha256:59161a3778a1f0a5de00573a1a10ec79f68401e0a23ba99110a07b460f10e957
Status: Downloaded newer image for BETSU_NO_ACCOUNT_NAME/semi1_c2img1_app:latest
* Serving Flask app 'app' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on all addresses (0.0.0.0)
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://127.0.0.1:80
* Running on http://172.17.0.2:80 (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 138-658-489
最後に、ブラウザから http://127.0.0.1:8080
にアクセスし、先程とは違うメッセージが表示されていることを確認してください。
また、もらった相手にメッセージが正しいかを確認してもらってください。
http://127.0.0.1:8080
でアクセスできない場合は、docker container run
した時に出てくるそれっぽい数字の下の方のやつを開いてみてください。
チェックポイント:できたら見せてください
お疲れさまでした!
これで、Docker コンテナと Docker Hub を利用した、自作 Web アプリケーションのやりとりは完了です。
最後に、できたものを教員にチェックしてもらってください