Dockerを用いて、Flaskで作ったアプリを自宅のサーバ上で動かし、常駐させようと考えたが、その際にハマったことについてまとめておく。
環境
- Ubuntu 24.04
- Docker 24.0.5
- Flask 3.0.0
問題
とりあえず、以下のようなDocker関連のファイルを作成した。
# Dockerfile
FROM python:3.10.5-alpine3.16
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "5000:5000"
volumes:
- ./app:/usr/src/app:rw
environment:
TZ: Asia/Tokyo
command: ["python3", "main.py"]
tty: true
Flask == 3.0.0
そして、以下のようなmain.py
を作成した。
from flask import Flask
app=Flask(__name__)
@app.route("/")
def hello():
return "Hello!\n"
if __name__=="__main__":
app.run()
ディレクトリは以下のような構成とした。
.
├── app
│ └── main.py
├── Dockerfile
├── docker-compose.yml
└── requirements.txt
そして、いつものようにdocker-compose build
からdocker-compose up
でコンテナを立ち上げたが、LANからアクセスできなかった。
これは、Flaskのデフォルトのホストがlocalhost
になっているためで、サーバ外部からサーバのlocalhost
にアクセスすることはできないということである。
そこで、app.run()
の引数にhost="0.0.0.0"
を追加した。これで、外部からのアクセスを許可することができるはずである。
if __name__=="__main__":
app.run(host="0.0.0.0")
しかし、これでもアクセスができなかった。本来ならhttp://[サーバのIPアドレス]:5000
(5000はFlaskのデフォルトのポート番号)でアクセスできるはずだが、これができない。ファイアウォールの問題かと思ったのだが、5000番ポートの開放をしてもアクセスはできず、別に原因があることがわかった。
解決
いろいろ調べた結果、Docker側のポート設定が必要だということがわかった。
docker-compose.yml
を以下のように修正する。
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "5000:5000"
volumes:
- ./app:/usr/src/app:rw
environment:
TZ: Asia/Tokyo
command: ["python3", "main.py"]
tty: true
これにより、5000番ポートを通じてアクセスすることができるようになった。
また、app.run()
の引数にもポート番号を指定する必要があるので、以下のように修正する。
if __name__=="__main__":
app.run(host="0.0.0.0", port=5000)
これで、LANからhttp://[サーバのIPアドレス]:5000
へアクセスできるようになった。
$ curl -i [サーバのIPアドレス]:5001
HTTP/1.1 200 OK
Server: Werkzeug/3.0.4 Python/3.10.5
Date: Mon, 99 Sep 9999 99:99:99 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 6
Connection: close
Hello!
まとめ
以上のことにより、無事自宅内のLANからアクセスできるFlaskアプリを用意することができた。
Flaskの動作にDockerを用いる際には、ポートの設定に注意することが重要だということがよく分かった。
参考
Flaskで立てたサーバーが外部からアクセスできない場合に確認すべきこと #Python - Qiita