우리 서비스는 생성형 AI를 활용하여 사용자가 입력한 각 이미지에 표정과 대사를 입힌 영상을 만든 후, 영상들을 하나의 영상으로 만들어주는 서비스입니다.
그 중, 영상을 생성해주는 역할을 맡은 AI 서버를 배포할 때 생긴 문제점을 해결하는 과정을 담았습니다.
로컬의 개발환경을 그대로 서버로 가져가기 위해서 Dockerfile 을 작성했습니다.
Dockerfile
FROM python:3.10
ENV PYTHONUNBUFFERED 1
WORKDIR /app
COPY . ./
VOLUME ./image:./image
RUN pip install --upgrade pip
RUN apt-get update
RUN apt-get -y install ffmpeg
RUN pip install -r ./requirements.txt
CMD ["python3", "app.py"]
앱 작동에 필요한 python 패키지와 영상 처리에 필요한 ffmpg를 다운로드 하는 과정을 담아서 Dockerfile을 작성했습니다. 이후 만들어진 Docker 이미지의 용량을 보니 14 GB로 상당히 큰 이미지가 완성되었습니다.
14 GB 정도로 큰 이미지는 업로드할 때도 오래 걸리기 때문에, AWS EC2의 비용이 크게 발생할 수 밖에 없고 build 할 때 더 많은 시간을 소요하기 때문에 이미지의 크기를 줄여야만 하는 상황이 발생했습니다.
RUN apt-get update && apt-get -y install ffmpeg
RUN pip --no-cache-dir install -r ./requirements.txt
--no cache-dir
명령어를 통해서 필요없는 캐시 데이터를 저장하지 않게했다.위 두가지 해결방안을 적용해서 Docker 이미지를 빌드했지만, 이미지의 크기에는 큰 영향을 미치지 않고 여전히 14 GB에 가까운 크기의 이미지가 빌드되었습니다…
인터넷을 통해서 Docker 이미지를 줄이는 방법을 많이 찾아보았고, 그중 가장 보편적인 방법은 Docker image를 빌드할 때 Multi-stage 를 적용하는 것이였습니다.
Multi-stage란 여러 개의 BaseImage를 사용하여 Docker build를 수행하는 역할이다.
BaseImage란 Docker build에 사용하는 기본 이미지로써, Dockerfile에서 FROM에 설정된 이미지에 해당된다.
FROM 키워드를 기준으로 작업공간이 분리되는데, 이 분리된 작업 공간을 stage라고 한다. 즉 2개 이상의 stage로 나뉜 것을 Multi-stage라고 한다.
FROM python:3.10 AS builder
ENV PYTHONUNBUFFERED 1
ARG CACHEBUST=1
WORKDIR /app
COPY requirements.* ./
RUN apt-get update && apt-get -y install ffmpeg
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r ./requirements.txt
COPY . ./
FROM python:3.10-slim AS deployer
COPY --from=builder /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages
COPY --from=builder /app /app
RUN apt-get update && apt-get -y install ffmpeg
WORKDIR /app
CMD ["python3", "app.py"]
파이썬의 패키지를 설치하는 stage와 ffmpeg 응용프로그램을 설치하는 2개의 stage로 나눠서 작성했습니다.
각 stage는 FROM
을 기준으로 나뉘며 AS
를 통해서 별칭을 지정할 수 있습니다.
각 스테이지에 있는 데이터는 COPY
의 --from
옵션을 통해서 스테이지간 파일을 교환할 수 있다.
COPY --from=builder /app /app
는 builder
의 /app 디렉토리를 deployer
의 /app 디렉토리로 복사하는 역할을 합니다.즉 builder부분에서 파이썬의 패키지를 다운로드 한 후, 다운로드된 파일들을 deployer 스테이지에 복사하여서 이미지를 생성하였습니다!
14GB 에서 8GB 까지 데이터를 대폭 줄이게 되었다!
덕분에 EC2 서버의 볼륨을 크게 늘리지 않고, 해당 이미지를 사용하여 컨테이너를 돌릴 수 있게 되었다.
로컬에서는 실행되지만 서버에서는 실행되지 않는 문제가 발생했다.
requirment.txt
에 CPU에 종속적인 라이브러리가 존재한다고 추측
boto3~=1.34.60
requests~=2.31.0
gfpgan~=1.3.8
keras~=2.13.1
Flask~=3.0.0
numpy==1.24.3
opencv-python==4.8.0.74
onnx==1.15.0
insightface==0.7.3
psutil==5.9.5
tk==0.1.0
customtkinter==5.2.0
tkinterdnd2==0.3.0
onnxruntime==1.15.0
tensorflow==2.13.0
opennsfw2==0.10.2
protobuf==4.23.4
tqdm==4.65.0
python-dotenv~=1.0.1
gfpgan~=1.3.8
종속성에 basicar 가 존재하는 것을 확인