Profile picture

[Docker] 파이썬 컨테이너 출력 버퍼링 활성화하기

JaehyoJJAng2024년 02월 05일

▶︎ 개요

파이썬을 이용한 서비스를 컨테이너화하여 배포했을 때,

애플리케이션에서 발생한 로그가 컨테이너 로그에 기록되지 않는 문제가 있었다.

예를 들어 아래와 같이 파이썬을 실행했을 때

python3 main.py

DevBot#0737 is ready!
🟢 AI image Starting ...
🟢 BossAlert starting ...
🟢 AI text Starting ...
🟢 지식인 알림 Starting ...
🟢 CheckGameUpdate starting ...

위와 같이 로그가 출력된다면


위 애플리케이션을 도커라이징하여 컨테이너로 배포하고 로그를 확인해보면

docker-compose logs discordapp

아무 로그도 뜨지 않는다.

이 문제를 해결하기 위해서 아래와 같은 몇 가지의 방법을 사용해볼 수 있다.


▶︎ 1. 파이썬의 출력 버퍼링 비활성화

파이썬의 표준 출력 스트림의 버퍼링을 비활성화. 이를 위해 DockerfilePYTHONBUFFERED 환경변수를 아래와 같이 설정.

FROM python:3.9

ENV PYTHONUNBUFFERED=1
...

▶︎ 2. 표준 출력 및 표준 에러를 명시적으로 플러시

파이썬 코드에서 printloggin을 사용할 때 명시적으로 플러시

import sys

print("Hello, world!", flush=True)

# 또는 logging 사용 시
import logging
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logger = logging.getLogger(__name__)
logger.info("Hello, world!")

▶︎ 3. 도커 컴포즈 사용 시

도커 컴포즈 파일을 사용하는 경우 ttystdin_open 옵션을 설정

version: '3'

services:
  discord-bot:
    build: .
    environment:
      - PYTHONUNBUFFERED=1
    tty: true
    stdin_open: true
  • tty: true
    • tty 옵션은 도커 컨테이너에 가상 터미널을 할당함.
    • 이를 통해 도커는 컨테이너가 실제 터미널에서 실행되는 것처럼 동작하게 함.
    • 가상 터미널을 할당하면 애플리케이션이 터미널에서 실행되는 것처럼 표준 입출력 스트림을 처리하게 되어, 로그가 실시간으로 출력되게 됨.
  • stdin_open: true
    • stdin_open 옵션은 컨테이너의 표준 입력(stdin)을 열어둠.
    • 이를 통해 컨테이너가 실행되는 동안 표준 입력을 받을 수 있게 되며, 이는 인터랙티브 모드나 디버깅 세션에서 유용.
    • 그러나, 본인이 운영 중인 디스코드 봇 같은 애플리케이션에서는 일반적으로 표준 입력을 사용하지 않지만, 이 옵션을 설정하면 컨테이너가 입력을 받기 위해 항상 열려 있게 됨.

▶︎ 마무리

3번 방법을 사용해 컨테이너 로그 미출력 문제가 해결되었음.
image


Loading script...