Container라는 개념이 나오고, 벌써 몇년이 지났습니다. 제가 있는 회사에서도 Docker에 빠르게 적응해왔고, 어느덧 개발팀의 개발환경이 다양한 도커 기반의 환경으로 변화하게 되었습니다. 개발에 있어 진보적이지만, 운영에 있어서는 보수적인 저는 아직 프로덕션에 도커 기반의 환경을 구성하는 것에는 회의적입니다. 다만, 스테이징 및 개발팀의 로컬 개발 환경을 포함한 관리에 있어서는 도커가 그 어떠한 환경보다 편리하다는 데에 동의합니다.

팀의 로컬 및 스테이징 개발 환경을 도커로 전환하면서 동시에 CI/CD를 적용하기 위한 작업을 진행하였는데, 그 과정에서 django와 mariadb를 어떻게 연결하고 매칭 하는지에 대해 글을 써보겠습니다. 더 나아가, 도커로 전환한 개발 환경을 어떻게 CI/CD 처리하는 지에 대해서도 향후 글을 이어나가 볼 계획입니다.

도커와의 친숙도

기존 우리 개발팀은 test용 Database를 프런트엔드 개발자가 더욱 용이하게 사용 가능하도록 도커화 하였습니다. 실제 데이터와 가장 가깝게 구성한 무거운 이미지와 가상으로 생성한 데이터만 들어있는 가벼운 이미지 2종류로, 브런치별로 마이그레이션이 반영된 이미지를 운영하였습니다.

  • masterdb:
    – 이미지 리스트:
       – 98 (98번 브런치의 소스에 맞추어 마이그레이션 되어있는 디비)– 99– 100
  • testdb:
    – 이미지 리스트:
       – 98 (98번 브런치의 소스에 맞추어 마이그레이션 및 테스트 데이터가 들어있는 DB)

기존에 도커를 위와 같이 활용하면서, Django 특유의 마이그레이션 파일에 대한 충돌과, 브런치&DB간의 전환에 따른 불편함 등을 많이 해소하게 되었습니다. 특히 프런트엔드 개발자가 별도의 마이그레이션 과정 없이 간편하게 서버와의 테스트를 수행할 수 있는 점도 효과적이었습니다.

이러한 경험속에서 도커를 활용한 개발 환경 운영이 더욱 쉬워질 수 있을 것으로 보았고, 도커를 활용한 CI/CD 연계가 이루어 지면, 백엔드와 프런트엔드 개발에 있어 빠른 업무 전환이 가능할 것으로 보았습니다.

소스와 DB 모두 도커화하기

운영 환경을 제외한 개발 환경 전체를 도커화 하면서 기존의 개발팀이 관리하던 근본적인 부분을 흔들지는 않았습니다. 크게 아래와 같은 목적을 중심으로 도커화를 결정하였습니다.

  • 스테이징 서버 운영 비용 감소 (기존의 정책은 개발자 1명당 스테이징 1개였습니다.)
  • 개발자의 unit test 대기 시간 제거 (로컬에서 unit test를 돌리는 과정)
  • CI/CD 연동 간편화
  • 기획&디자인의 실시간 개발 상황 체크
  • 쉽고 빠른 스테이징 배포
  • 브런치 전환의 편리성 강화

도커화를 위해서 아래와 같은 순서로 업무를 진행합니다.

  1. 소스코드의 배포용 베이스 이미지 선정
  2. DB의 베이스 이미지 선정
  3. 소스코드 배포용 이미지의 Dockerfile 작성
  4. 효율적인 배포를 위한 docker-compose.yml 파일 작성
소스코드 배포용 베이스 이미지 선정

현재 운영중인 소스는 python 2.7 대 소스로 구성되어 있고, ubuntu 에서 작동하고 있습니다. 이를 바탕으로 적당한 이미지를 https://hub.docker.com/ 에서 쉽게 찾을수 있었습니다. 특히 python은 official 이미지가 모두 갖춰져 있고 ubuntu 버전에 따라 다른 이미지를 만들어 제공하고 있습니다. https://hub.docker.com/_/python/

정상적으로 실행되는지 파악하기 위해 아래 명령어를 통해 이미지를 실행해봅니다.

docker run -ti python:2.7-jessie

$ docker run -ti python:2.7-jessie
Unable to find image 'python:2.7-jessie' locally
2.7-jessie: Pulling from library/python
3d77ce4481b1: Extracting  54.26MB/54.26MB
7d2f32934963: Download complete
0c5cf711b890: Download complete
9593dc852d6b: Downloading  26.26MB/131.1MB
3e91bf320c1d: Download complete
eb8a8e8aa76e: Downloading  3.386MB/15.08MB
0a01197b99bb: Waiting
81ee5add9a9e: Waiting

위와 같은 화면이 나온 후 완료되었을 때 아래 화면이 출력되면 이미지가 정상 작동하는 상황입니다.

Digest: sha256:93123b88622bd79f91d3d91df06d2e6a7ee13e44e97e16fdb1c145596f3d75f9
Status: Downloaded newer image for python:2.7-jessie
Python 2.7.15 (default, Jun  6 2018, 19:40:49)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
DB용 이미지 선정

DB용 이미지는 python 보다 간편하게 설정할 수 있습니다. 기본적으로 mariadb 에서 제공하는 official 이미지가 있기 때문에 사용중인 버전에 맞는 이미지를 바로 사용하면 됩니다.

https://hub.docker.com/_/mariadb/

Dockerfile 쉽게 작성하기

Dockerfile은 도커 이미지를 생성하기 위한 명령어들의 집합입니다. 변수 선언이나 docker 운용에 필요한 다양한 값들이 함께 제공되기도 합니다. Dockerfile을 처음 작성하면 여러가지 어려움을 겪게 되는데 이를 해소하기 위해서는 Dockerfile을 생성하기 전에 이미지 안에 직접 접속하여 명령어들을 입력해보는 방식으로 해소가 가능합니다.

먼저 Dockerfile을 작성할 폴더에서 Dockerfile을 만들고 최상단에 아래 값을 입력하여 줍니다.

from python:2.7-jessie
WORKDIR /root/app
ADD . /root/app

파일을 저장한 후 Dockerfile 이 있는 경로의 터미널에서 아래 명령어를 입력합니다.

docker build -t test .

$ docker build -t test .
Sending build context to Docker daemon  2.048kB
Step 1/4 : from python:2.7-jessie
 ---> 4c6bc950b1a3
Step 2/4 : WORKDIR /root/app
Removing intermediate container cfded6341fbc
 ---> bb42e03333e8
Step 3/4 : ADD . /root/app
 ---> 8d430ceadc09
Step 4/4 : CMD ["pip", "freeze"]
 ---> Running in c0b63668315a
Removing intermediate container c0b63668315a
 ---> e7bc22470dde
Successfully built e7bc22470dde
Successfully tagged test:latest

위 명령어는 현재 경로 (.) 에서 도커파일을 읽어 source 라는 도커 이미지를 생성하라는 명령어입니다. 이를 통해 도커 이미지를 생성하고 나면, docker run -dit test 로 도커 이미지를 실행하여 줍니다.

실행한 후 아래 명령어를 통해 정상 작동 여부와 container id 값을 확인합니다.

docker ps -a

docker가 정상 실행되어 있고 status에 이상이 없다면, 배포 프로세스를 위한 스크립트를 만들 차례입니다. 이부분은 다음 글에서 좀더 상세히 뜯어보도록 하겠습니다.