概要
どうやら python の print はデフォルトだとバッファリングしているようで、そのままだと docker logs の標準出力に出ないようです
簡単な対象方法を紹介します
環境
- macOS 10.15.7
- Python 3.8.5
- docker 19.03.13
アプリ作成
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
print('hello')
return 'Hello'
ターミナル上で確認
FLASK_APP=app.py pipenv run flask run
curl localhost:5000
=> hello が表示される
Dockerfile
FROM python:3.8-buster
ADD . /app
WORKDIR /app
RUN pip install pipenv
RUN pipenv install
ENV FLASK_APP app.py
EXPOSE 5000
CMD ["pipenv", "run", "flask", "run", "--host", "0.0.0.0"]
docker 上で確認
docker build -t test_app .
docker run -p 5000:5000 --name test_app test_app
docker logs test_app
=> 表示されない
対処方法1: flush=True
print 時に flush=True
を指定します
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
print('hello', flush=True)
return 'Hello'
対象方法2: PYTHONUNBUFFERED を指定する
すべての print に flush=True を入れるのは大変なので PYTHONUNBUFFERED で制御します
docker run -e PYTHONUNBUFFERED=1 --name test_app -p 5000:5000 test_app
もしくは Dockerfile を書き換えても OK です
FROM python:3.8-buster
ADD . /app
WORKDIR /app
RUN pip install pipenv
RUN pipenv install
ENV FLASK_APP app.py
ENV PYTHONUNBUFFERED 1
EXPOSE 5000
CMD ["pipenv", "run", "flask", "run", "--host", "0.0.0.0"]
app.logger の場合は
特に何もせずに docker logs に出力されました
素直に app.logger を使い回すのが docker との相性は良さそうです
import logging
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
app.logger.setLevel(logging.INFO)
app.logger.info('hello')
return 'Hello'
最後に
flask で print を使った際にバッファリングさせない方法を紹介しました
python の print はデフォルトだとバッファリングするので flask には関係なく今回の現象は発生すると思います
flask を使っている場合は素直に app.logger を使うことをおすすめします
0 件のコメント:
コメントを投稿