[Team_ForV] Docker Setting

Update:     Updated:

카테고리:

태그:

문제상황 발생!

image
음성파일 합성을 위해선 TTS 라는 라이브러리와 g2pk라는 라이브러리가 필요하다.

g2pk는 영어가 입력되었을 시 보이는 것처럼 한국어 발음에 맞춰서 변환해주고,
-> 최종적으로 변환된 문장을 TTS라이브러리를 통해 음성으로 만들어준다.

그래, 여기까지는 그렇다 치는데 이 라이브러리들을 사용하는데에 2가지 문제가 있었다.

  1. 위 라이브러리들은 3.6 ~ 3.7 사이의 파이썬 버전을 요구했다. 하지만 API Server가 이미 먼저 만들어진 상태였고, API Server는 최신 버전의 파이썬을 사용중이었기 때문에 버전이 맞지 않았다.
  2. 결정적으로 g2pk 라이브러리를 사용하기 위해 설치되는 서브 모듈 중 ‘mecab’이라는 라이브러리가 당최 가상환경에서 설치되지를 않았다(아마 M1 환경에서 제대로 설치가 되지 않는 것 같다). 구글링해보니 이미 악명 높은 라이브러리인 것 같더라..

Docker를 이용하여 문제를 해결해보자!!

image

Docker는 ‘컨테이너 기반의 오픈소스 가상화 플랫폼’이다.

여기에서 말하는 ‘컨테이너’는 다양한 프로그램, 실행환경을 컨테이너로 추상화하고 동일한 인터페이스를 제공하여 프로그램의 배포 및 관리를 단순하게 해준다.
백엔드 프로그램, 데이터베이스 서버, 메시지 큐등 어떤 프로그램도 컨테이너로 추상화할 수 있고 AWS, Azure, Google cloud등 어디에서든 실행할 수 있다.

Docker의 컨테이너 개념을 이용해서 필요한 각각의 실행환경들을 컨테이너로 분리하여 Docker 위에서 돌아가도록 구성하게 되었다.
이렇게 구성할 경우, model server와 api server의 실행환경이 다르더라도 하나의 서버에 여러개의 컨테이너를 실행하면서 서로 영향을 미치지 않고 독립적으로 실행되어 마치 가벼운 Virtual Machine을 사용하는 느낌을 줄 수 있다.

docker-compose.yml & DockerFile

- docker-compose.yml

frontend(react), api server(django), model server(flask), mysql, rabbitMQ, celery
이렇게 총 6개의 컨테이너를 구성했다.

# docker-compose.yml
version: "3"

services:
  frontend:
    build:
      context: ./frontend
    command: [ "npm", "start" ] 
    restart: always
    ports:
      - 3000:3000
    networks:
      - tts
    volumes:
      - ./frontend/:/frontend
      - ./frontend/node_modules/:/frontend/node_modules
    environment:
      - CI=true
      - CHOKIDAR_USEPOLLING=true
      - REACT_APP_BACKEND_URL=http://localhost:5000
    tty: true
  
  apiserver:
    build:
      context: ./backend/apiserver
      args:
        DJANGO_ALLOWED_HOSTS: "*"
        DJANGO_SECRET_KEY: "*"
        DJANGO_CORS_ORIGIN_WHITELIST: "*"
    command: sh -c "/wait && python ./apiserver/manage.py makemigrations && python ./apiserver/manage.py makemigrations mainApp && python ./apiserver/manage.py migrate && python ./apiserver/db_init.py && python ./apiserver/model_init.py && python ./apiserver/manage.py runserver 0.0.0.0:8000"
    restart: on-failure
    ports:
      - 8000:8000
    volumes:
      - ./backend:/backend
    networks:
      - tts
    depends_on:
      - ttsmysql

  ttsmysql:
    image: mysql
    command: --lower_case_table_names=1
    container_name: ttsmysql
    ports:
      - "3306:3306"
    environment:
      - MYSQL_DATABASE=tts
      - MYSQL_USER = root
      - MYSQL_ROOT_PASSWORD=1234
      - TZ=Asia/Seoul
    networks:
      - tts

  modelserver:
    platform: linux/amd64
    build: ./backend/modelserver
    ports:
      - 5000:5000
    restart: unless-stopped
    networks:
      - tts
    environment:
      - FLASK_APP=app
      - FLASK_ENV=development
    command: flask run --host=0.0.0.0
    volumes:
      - ./backend:/backend

  rabbit:
      hostname: tts_host
      image: rabbitmq:3-management
      command: rabbitmq-server
      restart: unless-stopped
      environment:
        - RABBITMQ_DEFAULT_USER=tts
        - RABBITMQ_DEFAULT_PASS=tts123
        - RABBITMQ_DEFAULT_VHOST=tts_host
      ports:
        - 5672:5672  
        - 15672:15672
      volumes:
      - ./backend:/var/lib/rabbitmq
      networks:
        - tts
      depends_on:
        - modelserver

  celery:
    platform: linux/amd64
    build: ./backend/modelserver
    restart: unless-stopped
    depends_on:
      - "apiserver"
      - "rabbit"
      - "modelserver"
    networks:
      - tts
    command: ["celery","-A", "celery_app", "worker", "--loglevel=info"]
    volumes:
      - ./backend:/backend

networks:
  tts:
    driver: bridge

- Dockerfile

image

Dockerfile을 이해하기 위해선 docker 이미지라는 개념을 먼저 알아야한다.

도커 이미지란, 서비스 운영에 필요한 서버 프로그램, 소스 코드, 컴파일된 실행 파일을 묶은 형태로써 기존에 있는 이미지에 추가적인 구성을 더해 또 다른 이미지를 만들 수 있다.
도커 허브와 같은 컨테이너 레지스트리에서 pull 받아서 사용하거나, dockerfile을 직접 작성해 이미지를 만들어서 push할 수 있다.

다 살펴보진 않고, 문제의 핵심부분인 model server에 쓰인 Dockerfile만 보자.

# Dockerfile
FROM python:3.6.15

# Python
RUN apt-get update && \
  apt-get install -y --no-install-recommends apt-utils && \
  apt-get -y install software-properties-common && \
  apt-get update --fix-missing && \
  apt-get -y install --fix-missing python3-pip && \
  python3 -m pip install pip --upgrade

RUN apt-get update -y && \
  apt-get install -y --no-install-recommends build-essential gcc \
  libsndfile1

# mecab start
RUN apt-get update && \
  apt-get install -y --no-install-recommends tzdata g++ git curl
RUN apt-get install python3-setuptools
RUN apt-get install -y default-jdk default-jre
# mecab end

WORKDIR /backend/modelserver

COPY requirements.txt .
COPY requirements_TTS.txt .

RUN pip install -r requirements.txt
RUN pip install -r requirements_TTS.txt

RUN pip install celery
RUN pip install google-cloud-storage

RUN pip install nltk==3.6.7
RUN pip install konlpy==0.6.0
RUN pip install mecab-ko==1.0.0
RUN pip install mecab-python==1.0.0
RUN pip install python-mecab-ko==1.0.14
RUN pip install g2pk==0.9.4

# mecab start
# RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 2
# RUN update-alternatives --config python3
RUN cd . && \
  curl -s https://raw.githubusercontent.com/konlpy/konlpy/master/scripts/mecab.sh | bash -s
# mecab end

RUN export LC_ALL=C.UTF-8
ENV LANG=C.UTF-8
ENV LANGUAGE=C.UTF-8

COPY . .
USER root

다음 글 소개

도커의 개념과 프로젝트에 사용한 도커 세팅에 대해 간단히 알아보았다.
다음 글에서는 ‘음성 학습’과 ‘음성 합성’에 필요한 AI 학습 모델과 라이브러리들에 대해 좀 더 자세히 알아보도록 하자.

Reference

1) https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html
[초보를 위한 도커 안내서 - 도커란 무엇인가?]
2) https://somjang.tistory.com/entry/Docker-ubuntu1604-%EA%B8%B0%EB%B0%98%EC%97%90%EC%84%9C-mecab-ko-%ED%99%9C%EC%9A%A9%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95
[ubuntu16.04 기반에서 mecab-ko 활용하는 방법]
3) https://github.com/litsynp/flask-g2pk [flask-g2pk]

Team_ForV 카테고리 내 다른 글 보러가기

댓글 남기기