Why Docker?

  1. 이런 저런 프로젝트를 진행할 때, 맥에서 신나게 개발한 내용을 aws ec2를 이용해 배포하려고 할 때, 맥에서 작성한 스크립트들이 ec2 linux machne에서 작동하지 않거나 데이터 베이스나 기타 프레임워크들의 기본 환경 설정이 달라 애를 먹은 적이 많다. 기술 스택과 그 환경을 구축하는데 생각보다 많은 시간이 든다는 것을 감안하면 개발할 때 한번, 배포할 때 한번 두 번이나 그런 시간을 투자하는 것은 매우 낭비다. 여러 개발자가 여러 환경에서 개발한다고 생각하면 더더더 큰 낭비로 이어진다.
  2. 자동 보정 카메라 어플리케이션을 개발하며, Openface라는 오픈소스 프로젝트를 이용해 API 서버를 구축했다. Openface는 너무나도 큰 프로젝트 였고 여기에 걸린 dependency가 어마어마 했다. 해당 프로젝트 위키에 설명 되어 있는 대로 모든 의존 라이브러리를 설치해보았지만 계속해서 중간에 오류가 발생했다. 10시간 넘게 쏟고도 내 맥북 머신에 해당 프로젝트를 설치하지 못했다.

위 두가지 사례는 내가 도커(Docker)를 사용한 이후로 말끔하게 사라진 문제들이다.  도커를 사용하면 PM이 conf 파일만을 작성해 공유하면 다른 개발자들은 도커를 통해 쉽게 똑같은 환경을 구축할 수 있다. 프로젝트 진행에 따라 새로운 프레임워크를 추가할 때도, conf 파일에 몇 줄의 코드를 추가함으로써, 여러 개발자들이 자신의 개발환경(OS)에 맞게 프레임워크 설치 과정을 겪을 필요가 없다. VM을 활용하여 비슷한 효과를 기대할 수 있지만, 도커는 VM을 구동하기 위한 Overhead들을 모두 제거할 수 있으며, 여러개의 컨테이너를 하나로 묶어 서비스하기도 편리하다.

도커를 사용하면서부터 팀원 간의 개발 환경 구축과 프로젝트 배포가 너무나도 쉬어졌고, 세 개 이상의 프레임 워크가 들어가고 다른 프레임워크를 사용해야 하는 확장성이 있다고 생각되는 프로젝트에는 무조건 도커(Docker)를 적용한다.

다음은 (내가 직접 겪지는 못했어도) Docker를 사용 했을 때의 주요 장점들을 정리해 놓았다.

  1. Return on investment & cost savings 
  2. Standardization & productivity
  3. CI efficiency
  4. Compatibility & maintainability
  5. Simplicity & faster configurations
  6. Rapid Deployment
  7. Continuous Deployment & Testing
  8. Multi-Cloud Platforms
  9. Isolation
  10. Security

    자세한 설명과 출처는 여기

먼저  Docker & Docker-compose를 설치한다. 자신이 개발한 프로젝트를 Linux machine에서 동작하는 어플리케이션으로 컨테이너화 시키기 위해서 Dockerfile를 작성한다.FROM debian:jessie 을 통해서 리눅스 컨테이너 이미지를 가져온다.

//Dockerfile

FROM debian:jessie
MAINTAINER kimsup10 <kss5662@gmail.com>
LABEL description="UCI I-SURF > Summer 2017 > Keyramid > SDCL"

RUN apt-get update && apt-get install -y \
curl \
git \
python3 \
python3-pip \
redis-server \
python-psycopg2 \
libpq-dev \
postgresql \
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

WORKDIR /root/keyramid

ADD ./requirements.txt /root/keyramid/requirements.txt
RUN pip3 install --upgrade pip
RUN pip3 install -r requirements.txt -U

ADD . /root/keyramid
RUN cd ~/keyramid

RUN adduser --disabled-password --gecos '' keyramid

RUN을 통해서 debian:jessie 이미지 상에서 실행시킬 명령어들을 명시할 수 있다. 개발에 필요한 의존성들을 설치하는 명령어들을 명시한다.
WORKDIR을 프로젝트 폴더로 명시하여 프로젝트와 관련된 작업이 실행될 수 있도록 한다.

이후 다음과 같은 명령어를 통해 프로젝트를 위한 Docker image를 생성하고, 이를 실행시킬 수 있다. (위 Dockerfile에서 서버를 실행시키는 명령어(Django의 경우, python manage.py runserver)가 포함되지 않았으므로 해당 예제 코드만으로는 서버가 열리지는 않는다.)

$ docker build -t projectname . $ docker run projectname

이제 데이터베이스를 비롯한 여러 프레임워크들을 사용해보도록 하자. 하나의 리눅스 컨테이너 안에 sudo apt-get install 명령어를 통해 모든 것을 설치해 쓸 수도 있지만 그렇게 편한 방법은 아니다. docker-compose를 이용하면 훨씬 쉽게 여러 프레임워크를 별도의 컨테이너로 만들고 이를 하나로 묶어 서비스할 수 있다.

//docker-compose.yml
version: '2'

services:
  # PostgreSQL database
  db:
    image: postgres:9.4
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=postgres
    ports:
      - "5432"

  # Redis
  redis:
    image: redis:2.8.19
    hostname: redis

  # Django web server
  web:
    build:
      context: .
      dockerfile: Dockerfile
    hostname: web
    command: ./scripts/init_server.sh
    volumes:
      - .:/root/keyramid  # mount current directory inside container
    ports:
      - "8000:8000"
    # set up links so that web knows about db, rabbit and redis
    links:
      - db
      - redis
    depends_on:
      - db

해당 프로젝트에서는 redis와 postgresql을 사용한다. 이런 유명한 프레임워크들의 경우 이미 docker 이미지가 docker hub에 올라가 있어 사용자들은 어떤 이미지를 사용할 것인지 docker-compose.yml에 명시해주기만 하면 된다. 어떤 서비스를 컨테이너화 시킬 것인지 명시하고, 이를 위한 이미지를 먼저 명시한다.

services:
  # PostgreSQL database
  db:
    image: postgres:9.4
...
  redis:
    image: redis:2.8.19
...

아래와 같은 environment 설정을 하면, 웹 프레임워크 상에서 데이터베이스에 접근하기 위한 설정 시 user, password 그리고 database name 등에 사용할 수 있다.

services:
  # PostgreSQL database
  db:
    ...
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=postgres
    ports:
      - "5432"

그리고 결국 이러한 데이터베이스 서비스들을 사용하는 것은 사용자가 개발한 프로젝트 이므로 이를 해당 프로젝트 서비스에 명시하면 된다. 본 예제에서는 프로젝트의 서비스 명을 web이라고 했다. 해당 서비스 이미지를 만들기 위한 dockerfile을 지정해주고, 해당 리눅스 이미지에서 Server를 직접 실행시킬 command를 명시한다. 그리고 이를 db와, redis에 링크한다는 것을 명시해주면 된다. depends_on에 다른 서비스를 명시할 경우, 명시된 서비스들 없이는 해당 서비스가 작동하지 않는다.

web:
  build:
    context: .
    dockerfile: Dockerfile
  hostname: web
  command: ./scripts/init_server.sh
  volumes:
    - .:/root/keyramid  # mount current directory inside container
  ports:
    - "8000:8000"
  # set up links so that web knows about db, rabbit and redis
  links:
    - db
    - redis
  depends_on:
    - db

이후 아래의 명령어를 이용해 docker-compose가 각각의 컨테이너에 담겨 있는 여러 프레임워크들이 하나의 서비스로 동작하게 만들어 준다.

$ docker-compose build
$ docker-compose up

 

Why Docker?”의 1개의 생각

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google photo

Google의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중

search previous next tag category expand menu location phone mail time cart zoom edit close