Docker에 관해서는 아래의 읽을거리를 참고하세요.

ROR Lab <Docker를 이용한 손쉬운 레일스 배포> 세미나: https://www.facebook.com/naverd2/posts/505653179563380

<가장 빨리 만나는 Docker> : https://pyrasis.com/book/DockerForTheReallyImpatient/Chapter01


참고로 macOS Sierra 환경에서 작업하였다. 리눅스 환경에서는 docker 명령을 실행할때 항상 sudo를 추가해야 한다. 번거롭다면 관리자 그룹에 추가시켜주자.


배포하기위한 'rails-new-docker'라는 이름의 간단한 앱을 만든다. static page로 'hello docker'를 띄워보자.

$ rails new rails-new-docker

$ cd rails-new-docker

$ vi Gemfile

...

# Use high_voltage for static page

gem 'high_voltage', '~> 3.0'

...

$ bundle install

$ mkdir app/views/pages

$ vi app/views/pages/home.html.erb

<h1>hello docker!!</h1>


remote 저장소에 소스를 올린다. docker 컨테이너에 로컬의 소스를 복사해서 넣을 수도 있겠으나, 배포의 목적으로 만드는 것이기 때문에 다른 호스트에서 컨테이너를 실행할때 소스코드를 받아오기 위해 remote 저장소에 올린다.

$ git init

$ git add .

$ git commit -m 'first commit'

$ git remote add origin [리모드 저장소 주소]

$ git push origin master


Docker 이미지를 만들기 위한 Dockerfile을 생성한다.

Dockerfile

FROM ubuntu
MAINTAINER stardust(handhee7@gmail.com)

# 아래는 자신의 앱에 관한 필요한 설정을 만들면 된다.
# Run upgrades
RUN apt-get update

# Install basic packages
RUN apt-get -qq -y install git curl build-essential openssl libssl-dev python-software-properties python g++ make
RUN apt-get -qq -y install libsqlite3-dev
RUN apt-get -qq -y install nodejs

# Install Ruby
RUN apt-get -qq -y install ruby-full
RUN gem install bundler --no-ri --no-rdoc
RUN gem install foreman compass

# Install rails-new-docker
WORKDIR /app
RUN git clone https://github.com/Stardust-kr/rails-new-docker.git /app
RUN bundle install --without development test

# Run rails-new-docker
ENV SECRET_KEY_BASE dockerkeybase
ENV RAILS_ENV production
EXPOSE 5959
CMD foreman start -f Procfile

foreman을 활용하여 웹 서버시 수행될 명령을 Procfile에 미리 기록하여 사용할 수 있다. 대신 쉘 스크립트를 활용할 수 있다.


Procfile

web: bundle exec rails server -p 5959


rails_12factor 젬을 추가하여 로그를 표준출력으로 나오게 한다. docker logs [CONTAINER NAME OR ID]를 입력했을 때 앱에 관한 로그를 볼 수 있다.


Gemfile

# Use rails_12factor for stdout logs
gem 'rails_12factor'


다시 리모트 저장소에 푸시한다. Dockerfile은 코드에 포함될 필요는 없지만 동일한 앱을 구성하려는 사용자를 위해 코드의 버전과 똑같이 관리될 수 있도록 추가해주었다.


이제 이미지를 만들자. 네임스페이스/이름:태그 형태로 생성할 수 있다.  이미지가 생성되면 해당 이미지를 이용하여 컨테이너를 실행시켜보자. 그리고 실행된 이미지를 확인한다.

$ docker build -t stardustkr/rails-new-docker:0.1 .

$ docker run --name v0.1 -d -p 5959:5959 stardustkr/rails-new-docker:0.1

$ docker ps -l

$ docker logs v0.1


브라우저를 열고 localhost:5959/pages/home에 접속해보자.

실제 사용하는 앱은 데이터베이스를 필요로 할 것이다. 하지만 앱과 데이터베이스가 동시에 존재하는 컨테이너는 만들지 않을것이다. 왜냐하면 새로운 버전의 앱이 만들어져 다시 새로운 이미지를 만들어 배포 한다 가정 했을 때 기존 컨테이너 내부의 데이터베이스는 날아가기 때문이다.


필자는 아마존 RDS를 연결할 것이다. 로컬 호스트의 DB에 연결하든, 다른 외부의 DB의 연결하든 사용자의 마음일 것이다.

앱에 db를 필요로하는 scaffold를 생성하고, docker 이미지에 mysql관련 패키지를 추가로 설치한 다음 외부 db와 연결하여 띄워보자.


$ rails g scaffold post title content

$ rake db:migrate

$ vi Gemfile

...

# Use mysql2

gem 'mysql2'

...

$ vi Dockerfile

...

# Install Mysql

ENV DEBIAN_FRONTEND noninteractive

RUN echo "mysql-client mysql-client/root_password password" | debconf-set-selections

RUN echo "mysql-client mysql-client/root_password_again password" | debconf-set-selections

RUN apt-get install -qq -y mysql-client libmysqlclient-dev

...

$ docker build -t stardustkr/rails-new-docker:0.2 .

$ docker run -i -t -e DATABASE_URL="mysql2://[Mysql 계정명]:[Mysql 계정비밀번호]@[Mysql 서버 주소]/[DB명]" stardustkr/rails-new-docker:0.2 bundle exec rake db:reset

$ docker run --name v0.2 -d -p 5959:5959 -e DATABASE_URL="mysql2://[Mysql 계정명]:[Mysql 계정비밀번호]@[Mysql 서버 주소]/[DB명]" stardustkr/rails-new-docker

$ docker ps -l


만들어진 posts 페이지로 접속해보자.

localhost:5959/posts

rails 앱은 동작하는데 에러 페이지를 띄운다면 로그를 확인해보자.

$ docker logs v0.2


이제 동일한 앱을 서버에 배포해보자. 개인 서버여도 좋고 아마존 등 클라우드 서비스여도 좋다. 여기서는 아마존 ec2에 배포할 것이다.

서버를 설정하기 전에 이미지를 먼저 배포한다. Docker hub에 배포하여 사용하겠다. Docker hub: https://hub.docker.com

github처럼 repository를 만들자. 앱과 똑같은 이름으로 만들었다. 

로컬에서 로그인 하고 push를 하자.

$ docker login --username=[Docker hub 사용자 이름]

$ docker push stardustkr/rails-new-docker:0.2

푸시 끝


ec2는 우분투 이미지로 생성하였다. ec2에 ssh연결하여 docker를 설치하자.

# sudo apt-get update

# sudo apt-get install docker.io

# sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker


이미지를 pull 하고 실행시켜주자. 이미 로컬에서 테스트하면서 db를 초기화 하였으므로 초기화 코드는 없이 진행한다.

# sudo docker pull stardustkr/rails-new-docker:0.2

# sudo docker run --name v0.2 -d -p 80:5959 -e DATABASE_URL="mysql2://[Mysql 계정명]:[Mysql 계정비밀번호]@[Mysql 서버 주소]/[DB명]" stardustkr/rails-new-docker


이제 인스턴스의 publid dns로 접속해보자.

http://[인스턴스 public dns]/hosts

아래와 같이 로컬에서 작업환 환경과 동일하게 표시됨을 알 수 있다. DB를 똑같은것을 적용하였으므로 로컬에서 생성했던 글이 동일하게 표시됨을 알 수 있다.

마지막으로 기존에 만들었던 미용실 프로젝트를 docker로 배포해 볼 것이다.

Gemfile에 rails_12factor를 추가하고 Dockerfile과 Procfile을 추가한다. 위 과정을 동일하게 수행하여 아마존 ec2 인스턴스에 올려보았다.

아래 인스턴스에서 그 결과를 확인 할 수 있다.


http://ec2-52-79-125-65.ap-northeast-2.compute.amazonaws.com


이미지는 docker pull stardustkr/charmbithair:0.1로 받을 수 있다.

github: https://github.com/Stardust-kr/charmbitHair.git

+ Recent posts