docker에서 단독으로 실행할 때 Python 앱이 아무것도 인쇄하지 않습니다.
내 dockerfile에서 시작되는 Python (2.7) 앱이 있습니다.
CMD ["python","main.py"]
main.py 는 시작될 때 일부 문자열을 인쇄하고 나중에 루프로 이동합니다.
print "App started"
while True:
time.sleep(1)
-it 플래그로 컨테이너를 시작하면 모든 것이 예상대로 작동합니다.
$ docker run --name=myapp -it myappimage
> App started
그리고 나중에 로그를 통해 동일한 결과를 볼 수 있습니다.
$ docker logs myapp
> App started
-d 플래그를 사용하여 동일한 컨테이너를 실행하려고하면 컨테이너가 정상적으로 시작되는 것처럼 보이지만 출력이 표시되지 않습니다.
$ docker run --name=myapp -d myappimage
> b82db1120fee5f92c80000f30f6bdc84e068bafa32738ab7adb47e641b19b4d1
$ docker logs myapp
$ (empty)
그러나 컨테이너는 여전히 실행중인 것 같습니다.
$ docker ps
Container Status ...
myapp up 4 minutes ...
첨부는 아무것도 표시하지 않습니다.
$ docker attach --sig-proxy=false myapp
(working, no output)
어떤 아이디어가 잘못 되었습니까? 백그라운드에서 실행될 때 "인쇄"가 다르게 작동합니까?
도커 버전 :
Client version: 1.5.0
Client API version: 1.17
Go version (client): go1.4.2
Git commit (client): a8a31ef
OS/Arch (client): linux/arm
Server version: 1.5.0
Server API version: 1.17
Go version (server): go1.4.2
Git commit (server): a8a31ef
마지막으로 GitHub 에서 @ahmetalpbalkan 덕분에 Docker에서 데몬 라이즈 드를 실행할 때 Python 출력을 볼 수있는 솔루션을 찾았습니다 . 추가 참조를 위해 여기에 직접 대답하십시오.
버퍼링되지 않은 출력을
CMD ["python","-u","main.py"]
대신에
CMD ["python","main.py"]
문제를 해결합니다. 당신은 통해 출력 (둘 다, stderr 및 stdout)을 볼 수 있습니다
docker logs myapp
지금!
필자의 경우 Python을 실행 -u
해도 아무런 변화가 없었습니다. 그러나 트릭 PYTHONUNBUFFERED=0
은 환경 변수 로 설정 하는 것이 었습니다 .
docker run --name=myapp -e PYTHONUNBUFFERED=0 -d myappimage
나를 위해 그것은 버그가 아닌 기능입니다. 의사 TTY가 없으면 stdout에 아무것도 없습니다. 따라서 간단한 해결책은 다음을 사용하여 실행중인 컨테이너에 의사 TTY를 할당하는 것입니다.
$ docker run -t ...
동작의 자세한 이유를 설명하는 이 기사 를 참조하십시오 .
버퍼링에는 일반적으로 세 가지 모드가 있습니다.
- If a file descriptor is unbuffered then no buffering occurs whatsoever, and function calls that read or write data occur immediately (and will block).
- If a file descriptor is fully-buffered then a fixed-size buffer is used, and read or write calls simply read or write from the buffer. The buffer isn’t flushed until it fills up.
- If a file descriptor is line-buffered then the buffering waits until it sees a newline character. So data will buffer and buffer until a \n is seen, and then all of the data that buffered is flushed at that point in time. In reality there’s typically a maximum size on the buffer (just as in the fully-buffered case), so the rule is actually more like “buffer until a newline character is seen or 4096 bytes of data are encountered, whichever occurs first”.
And GNU libc (glibc) uses the following rules for buffering:
Stream Type Behavior
stdin input line-buffered
stdout (TTY) output line-buffered
stdout (not a TTY) output fully-buffered
stderr output unbuffered
So, if use -t
, from docker document, it will allocate a pseudo-tty, then stdout
becomes line-buffered
, thus docker run --name=myapp -it myappimage
could see the one-line output.
And, if just use -d
, no tty was allocated, then, stdout
is fully-buffered
, one line App started
surely not able to flush the buffer.
Then, use -dt
to make stdout line buffered
or add -u
in python to flush the buffer
is the way to fix it.
As a quick fix, try this:
from __future__ import print_function
# some code
print("App started", file=sys.stderr)
This works for me when I encounter the same problems. But, to be honest, I don't know why does this error happen.
You can see logs on detached image if you change print
to logging
.
main.py:
import time
import logging
print "App started"
logging.warning("Log app started")
while True:
time.sleep(1)
Dockerfile:
FROM python:2.7-stretch
ADD . /app
WORKDIR /app
CMD ["python","main.py"]
Usually, we redirect it to a specific file (by mounting a volume from host and writing it to that file).
Adding a tty using -t is also fine. You need to pick it up in docker logs.
Using large log outputs, I did not have any issue with buffer storing all without putting it in dockers log.
'programing tip' 카테고리의 다른 글
jQuery를 사용하여 JavaScript 객체의 속성 반복 (0) | 2020.07.21 |
---|---|
파이썬에서 날짜 문자열 형식을 어떻게 확인합니까? (0) | 2020.07.21 |
.php 파일을 사용하여 MySQL 덤프 생성 (0) | 2020.07.21 |
일반 링크를 사용하여 양식을 제출하십시오. (0) | 2020.07.21 |
NGINX는 프록시 웹 소켓을 역전시키고 SSL을 활성화합니까 (wss : //)? (0) | 2020.07.21 |