Ubuntu20.04のDocker上でFlaskを動作させる勉強をしていて、やっと何とか動作させることができたので、今後の参考のためにメモを残します。
#flaskのpythonスクリプトの作成
まずはflaskのpythonスクリプトを作成します。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return '''\
<html>
<body>
Hello
</body>
</html>
'''
if __name__ == '__main__':
app.run(host='0.0.0.0',port=8080)
#元となるイメージファイルの検索とダウンロード
Dockerの公式イメージの中で、pythonが入っているイメージを検索します。
docker search -f is-official=true python
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
python Python is an interpreted, interactive, objec… 6263 [OK]
django Django is a free web application framework, … 1081 [OK]
pypy PyPy is a fast, compliant alternative implem… 279 [OK]
hylang Hy is a Lisp dialect that translates express… 33 [OK]
4つほど出てきましたが、今回は1番上にあるNAMEがpython
のイメージを使うことにします。下のコマンドでpython
イメージをローカルにダウンロードします。
docker image pull python
ダウンロードしたイメージの環境をbash
で確認します。
docker container run --rm -it python bash
環境の確認が終わればイメージを削除します。
docker image rm python
#Dockerfileの作成
下のDockerfileを作成します。ファイル名がDockerfile
です。
From python:latest
COPY ./hello.py /hello.py
RUN pip install flask
CMD ["python","/hello.py"]
From
には元となるDockerイメージを記載します。(上で決めたpython
が書かれています。)バージョンも指定できますが今回は最新版latest
にしています。
COPY
はホストにある./hello.py
を、作成中のDockerイメージ内に/hello.py
としてコピーを行います。
RUN
はコマンドを実行します。作成中のDocker内でpip install flask
が実行されます。
CMD
はビルドしてコンテナが実行された後、実行されるコマンドが書かれています。
#イメージの作成
先に作成したhello.py
とDockerfile
を同じフォルダに入れ、そのフォルダ内で下のコマンドを実行します。
.
├── Dockerfile
└── hello.py
docker image build ./ -t test
-t
オプションは作成するイメージの名前を決めるオプションで、今回はtest
という名前にしてあります。
ビルドの途中ではWARNING: Running pip as root will break packages and permissions.
が出ますが、「rootでのインストール禁止」との警告らしいので(多分?)問題はありません。作成したイメージを確認するには、下のコマンドを使います。
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
test latest 48395245e149 About a minute ago 896MB
python latest 9b0d330dfd02 About an hour ago 886MB
今回作成したイメージtest
と、元イメージであるpython
があるのがわかると思います。
#コンテナを起動と停止
作成したイメージtest
からコンテナtest1
を作成し起動します。
docker container run --rm -p 8080:8080 --name=test1 test
オプション-p
でホストのTCP8080をコンテナのTCP8080にポートフォワードしています。
なお、Ubuntuの再起動後も自動的にコンテナを起動をさせたい場合には、下のコマンドにします。
docker container run --restart=always -p 8080:8080 --name=test1 test
コンテナの状態を確認します。
docker container ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
911093fb7b8f test "python /hello.py" 28 seconds ago Up 28 seconds 0.0.0.0:8080->8080/tcp test1
コンテナtest1
を停止します。
docker container stop test1
#コンテナとイメージの削除
もうコンテナを使用しない場合は、コンテナを削除します。なお、コンテナの実行時に-rm
オプションを付けていれば停止時に自動的に削除されます。
docker container rm test1
イメージも使用しないのであれば、test
とpython
のイメージも削除します。
docker image rm test python
#追伸:イメージを再構築しても変更されたファイルが消えないようにする
上記の設定はコンテナ内のボリュームに全てのファイルを持たせるものです。もし元のイメージpython:latest
が更新され、イメージtest
を再構築した場合には(コンテナにデータを保存する設定になっていたとすれば)全データが初期化されます。それを防ぐためにコンテナ内の指定したフォルダにホストのフォルダをマウントするバインドと呼ばれる手法を記載します。なお、このバインドはDockerらしくないので、開発中だけの手法だと考えたほうがよいかもしれません。
バインドの設定にするには、まずファイル構成とDocketfile
を下のように変更します。
/home/test/Documents
├── Dockerfile
└── web
└── hello.py
From python:latest
RUN pip install flask
CMD ["python","/web/hello.py"]
下のコマンドを実行します。source
はフルパスで記載する必要があります。
docker container run --rm -p 8080:8080 --name=test1 --mount type=bind,source=/home/test/Documents/web,target=/web test
これで、コンテナのフォルダ/web
にホストのフォルダ/home/test/Documents/web
がマウントされました。コンテナ側で保存したいファイルがあれば、そのファイルを/web
に書き込むことによりホストの/home/test/Documents/web
に保存されるので、イメージの再構築を行っても消えることはなくなりました。