Django와 Konlpy를 함께 쓰는 환경을 Docker로 구현하기

snoop2head·2020년 4월 3일
1

docker

목록 보기
1/1
post-thumbnail

Konlpy가 필요한 이유

현재 나는 유저가 검색하는 phrase를 기반으로 운동을 추천해주는 서비스를 구현하고 있다. 여기서 tokenizer로 KoNLPy를 쓴 이유는, 유저가 검색하는 phrase에서 단어들을 잘 뽑아냈기 때문이다.

Tokenizer의 역할을 예를 들어서, 내 웹사이트에서는 유저가 "복근에 좋은 운동"이라고 검색하면 검색어 키워드들로서 ["복근", "좋다", "운동]을 뽑아낸다. Twitter(Okt) 형태소 분석기나 MeCab 형태소 분석기가 내 웹사이트에서 사용자들의 검색어를 제일 잘 분해했다.

근데 왜 KoNLPy는 어렵지?

pip install konlpy

하하하. pip으로 설치하는 것은 그저 시작일 뿐이다. KoNLPy는 기본 설정이 어렵다. 대표적인 삽질 세 가지는,

1) KoNLPy는 자바와 파이썬 둘 다 요구한다. 따라서 자바를 설치하고 JDK, JRE를 설치해야 한다. 설치하는 것도 어려운데, 경로 설정은 더더욱 어렵다.

2) Mecab 모듈이 제일 가볍고, 형태소 분해를 잘 한다. 그런데 MeCab은 KoNLPy를 설치한 이후 별도로 설치를 해야 한다.

3) KoNLPy 기능 중 몇몇은 Windows 지원을 하지 않는다.

Django + KoNLPy on AWS

내 Django 프로젝트에 KoNLPy를 쓰려면, Java를 설치해야 한다.

그런데 Java 설정이 참 어렵다. 이건 마치 물건 하나를 생산하기 위해서는 공장부터 지어야 한다는 불편함이다.

이 때문에 배포가 어려웠다. 배포는 AWS 서버실에 어딘가에 있는 컴퓨터에다가 내 웹사이트를 다운로드하고 설정하는 과정이다. 내 local computer에다가 Java를 설정하는 것은 그나마 나은데, 남의 컴퓨터에다가는 어떻게 설치해야 하는지 막막했다.

Docker을 써야 해!

따라서 Docker을 이용하기로 했다. 내가 바라본 Docker의 장점은 단 한 가지였다.

어느 기계에서도 같은 개발 환경을 구현해서 프로그램을 돌릴 수 있다.

당시에는 Docker의 장점을 저거 하나 밖에 몰랐다. Docker을 사용한 경험이 없었기 때문이다. 글을 작성하는 오늘도 Docker을 배우기 시작한지 일주일이 안 됐다 ㅋㅋㅋㅋㅋ

그러나 개발자에게는 얼마나 빨리 배우고, 얼마나 빨리 써먹는지가 중요하다. 때문에 학습 경력을 시간으로 따지는 건 의미가 없다고 생각한다.

Dockerizing KoNLPy & Django

Docker은 한층 한층 탑을 쌓는 것이다.

우리의 최종 목표는 다음과 같은 탑을 쌓는 것이다. 위의 사진과 같은 개발환경을 코드로 하나하나씩 쌓아 올려보자.

# basing on ubuntu OS
FROM ubuntu:latest
LABEL maintainer="Ahn Young Jin <snoop2head@gmail.com>"
  • 다행히 theluwin님께서 이미 MeCab을 포함한 KoNLPy를 Docker에 올려놓은 개발 환경을 구축하셨다. Docker Hub에 올려놓으신 코드를 참고해서 만들었다.
  • FROM은 Docker Hub에서 코드를 가져오는 것이다.
  • 살짝 엄밀하지 못하지만, FROM으로 Docker Hub에서 코드를 가져오는 것은 다음과 같다.
    • Python 유저라면 pip install + import를 한 번에 섞은 것으로 이해하면 된다.
    • Go 유저라면 Github에서 바로 import하는 것으로 이해하면 된다.
  • FROM으로 우리는 ubuntu를 Docker Container의 OS로 지정했다.
# apt init
ENV LANG=C.UTF-8
ENV TZ=Asia/Seoul
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
    apt-get install -y --no-install-recommends tzdata g++ git curl
# installing java jdk and java jre
RUN apt-get install -y default-jdk default-jre

# installing python3 and pip3
RUN apt-get install -y python3-pip python3-dev

# install postgres module
RUN apt-get install -y python-psycopg2
  • KoNLPy에 필요한 Java의 JDK와 JRE를 설치한다.
  • Python3와 Python3의 Package Manager인 pip3을 설치한다.
  • Django 서버가 죽었을 때 Database가 함께 날라가는 대참사를 방지해야 한다. 따라서 AWS에서 Django Project를 돌리기 위해서는 Database를 따로 떼어내야 한다.
    • Django는 Relational Database 중에서 PostgreSQL과 호환성이 제일 좋다.
    • Django ORM을 이용해서 PostgreSQL Database를 조작하기 위해서 python 모듈인 psygopg2를 설치한다.
RUN cd /usr/local/bin && \
    ln -s /usr/bin/python3 python && \
    ln -s /usr/bin/pip3 pip && \
    pip3 install --upgrade pip

# apt cleanse
RUN apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# timezone
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
  • pip을 upgrade한다.
  • apt-get으로 다운로드 받은 파일들을 정리한다.
# make workspace
RUN mkdir -p /workspace
WORKDIR /workspace

# install konlpy dependencies: jpype, konlpy, with mecab module
RUN pip install jpype1-py3 konlpy
RUN cd /workspace && \
    curl -s https://raw.githubusercontent.com/konlpy/konlpy/master/scripts/mecab.sh | bash -s
  • Docker Container에서 우리가 KoNLPy를 설치할 공간을 workspace라는 폴더로 따로 만든다.
  • konlpy를 돌리기 위해서 필요한 jpype 모듈을 다운로드 받는다.
  • mecab 모듈도 다운로드 받는다.
# getting environment variable on console
ENV PYTHONNUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1

# WSGIPath settings and DJANGO_SETTINGS_MODULE for deployment
ENV WSGIPath config/wsgi.py
ENV DJANGO_SETTINGS_MODULE config.settings
# copying local file into container's /code/ directory
COPY ./requirements.txt /code/requirements.txt

# python & Django configuration
RUN apt-get install -y python3-pip
RUN pip install --upgrade pip
RUN pip install -r /code/requirements.txt
  • 프로젝트에 있는 requirements.txt 파일을 container의 "code" 라는 폴더에 가져온다.
  • COPY라는 명령어는 말 그대로 복붙이다.
  • requirements.txt에 명시된 모듈들을 pip을 이용해서 모두 설치한다.
# copying the rest of the files into container's /code/ directory
# container's working directory is /code/
COPY . /code/
WORKDIR /code/

#Exposing port to 8000
EXPOSE 8000
  • 프로젝트의 나머지 폴더 & 파일들을 container의 "code"라는 폴더에 가져온다.
  • port 8000으로 django를 열어놓는다.
# CMD multiple commands using start.sh file
ADD start.sh /
RUN chmod +x /start.sh

CMD ["/start.sh"]
  • CMD라는 명령어는 terminal에서 bash shell나 zsh shell에서 입력하는 명령어를 시행하는 것과 같다.
    • CMD는 RUN과는 다르다.
    • RUN은 새로운 이미지를 만들고, 새로운 층을 쌓아올리는 것이다.
    • CMD는 그저 terminal에서 command line을 실행시키는 것이다.
  • 그러나 CMD 명령어를 Dockerfile에서 작성했을 때, 한 가지 명령어 밖에 실행시키지 못한다.
  • 따라서 다음과 같은 start.sh라는 shell 파일을 따로 분리했다.
#!/bin/bash
python ./manage.py migrate
python ./manage.py runserver 0.0.0.0:8000
  • Django 프로젝트를 웹으로 돌리는 manage.py migrate & runserver이다.
  • 배포할 AWS 환경에 따라서 PORT값인 8000을 5000으로, 혹은 다른 PORT 값으로 변경할 수 있다.

맺음말

  • Ubuntu를 기초 OS로 삼으며, 그 위에다가 Java와 Python까지 쌓아 올렸으니 용량이 상당하다.
  • Python 3.7 lite를 이용해서 Python 용량을 줄일 생각이다.
  • 중간에 pip install python3가 중복돼서 설치됐다. 오작동은 일으키지 않으나, 이를 깔끔하게 정리할 예정이다.
  • django project를 dockerizing하는 것을 배우시는 분들은 Docker 웹사이트의 official docs는 추천하지 않는다. 비공감 수가 공감 수 만큼이나마 많으며, 에러가 많다.
  • 대신에 Djangocon Europe 2018의 docker tutorial을 추천드린다. 필자 Github에 이를 정리해 놓았는데, 이를 velog에서도 작성할 예정이다.
  • 위의 Dockerfile들에 영어 주석을 다는 것은 개인적인 습관이다.

Docker Hub 및 Github

profile
break, compose, display

0개의 댓글