Capistrano 를 이용한 서버 배포 및 ssl 설정

1. 배포

서버 설정을 마쳤으니 이제 실제 서버 배포 방법을 알아보자..

간혹가다 서버 배포설정을 안하고 ftp를 이용해 파일을 올린다던가 하는식으로 운영을 하는 경우가 있으나 상당히 위험하고 불편하다. 개인적으로 서버 배포 시스템은 필수로 구축해야 한다고 생각한다.

rails 배포 툴 중에 가장 잘 알려진 것이 capistrano 라는 gem 이다. 설정이 쉽고 다양한 플러그인을 지원한다. (예를 들면 옵션에 따라 배포시 db:migrate 를 자동으로 해주거나 데몬을 실행해주거나 하는등등) 현재 최신버전은  capistrano 3 이다.

capistrano + nginx + unicorn 조합인 경우 capistrano-unicorn-nginx 라는 플러그인이 있으니 그걸 함께 사용해보도록 하자.

2. 설정

  • 로컬 프로젝트 GemFile 에 capistrano 와 capistrano-unicorn-nginx 추가 후 bundle 명령어로 gem 설치해보자
group :development do
 gem 'capistrano', '~> 3.2.1'
 gem 'capistrano-unicorn-nginx', '~> 3.2.0'
end

$bundle

이제 config/deploy/production.rb 에 적절히 설정값을 넣어준다.

server 'xxx.xxx.xxx.xxx(ip주소)', user: 'deployer', roles: %w{web app db} 
set :nginx_server_name, 'fleamarkets.co.kr' #아직 도메인이 없는 경우 생략 가능

여기서 role 을 설정할때 db를 반드시 넣어줘야 서버 배포시 db migration 이 정상적으로 동작한다.

로컬 app config/database.yml db 설정은 빼먹지 말자.

production:
 adapter: postgresql
 database: fleamarket_production
 encoding: unicode
 host: localhost
 pool: 5
 username: fleamarket
 password: xxxxxxxxx
 timeout: 5000

Capfile 도 적절히 세팅해준다. db migration, asset pipeline 이 배포시 잘 동작하도록 설정해야한다. 나같은 경우 rbenv 로 루비 버전 관리를 하기 때문에 rbenv 플러그인도 포함시켜주었다.

# Load DSL and Setup Up Stages
require 'capistrano/setup'

# Includes default deployment tasks
require 'capistrano/deploy'

# Include plugin
require 'capistrano/unicorn_nginx'
require 'capistrano/bundler'
require 'capistrano/rbenv'
require 'capistrano/rails'

# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

만약 https 를 지원하고 싶으면 추가 적인 설정을 해줘야한다. https 를 지원하는 부분은 다음 포스팅에서 기본적인 부분만 다루도록할 예정이다.

자, 이제 거의 배포를 위한 준비가 완료된 상태이다.

capistrano-unicorn-nginx gem 의 경우 디폴트 배포 위치가 /var/www/app_name/ 안에 배포가 됨으로 미리 서버에 해당 디렉토리를 만들고 적절한 권한을 부여해야한다.

sudo mkdir /var/www/fleamarket
sudo chown deployer:admin /var/www/fleamarket/

bundle exec cap production setup

여기까지하면 잘되야하지만 실제로 해보니

sudo stdout: Nothing written
sudo stderr: sudo: no tty present and no askpass program specified

와 같은 에러를 뿜으며 종료되었다.

구글링을 해보니 sudo 명령어를 사용할때 deployer 유저인 경우 서버 password를 묻지 않도록 해야한다는 글이 있다.

특정 유저에게 sudo 권한을 주는건 간단하다.

sudo visudo

%admin ALL=(ALL) ALL 아래에
deployer ALL=(ALL:ALL) NOPASSWD:ALL 를 추가해주고 저장 해준다. editor 가 익숙하지 않다면 직접 vim을 이용해 sudoers 파일을 수정해줘도 된다.

수정시에 위치가 중요한데 어드민 설정 아래에 넣지 않으면 어드민이 NOPASSWD를 오버라이드해서 설정이 적용되지 않는다.

마지막으로 실서버 환경에 배포하려면 config/secret.yml 에 secret_key 를 세팅해줘야한다.

secret_key는 rake secret 명령어를 사용하면 자동으로 생성된다. 해당 값을 copy paste 로 붙여넣어준다. (실제 서버를 운영할때는 서버 환경 변수로 넣어주는 것이 보안상 좋다!)

production:
 secret_key_base: xxxxxxx
 secret_token: xxxxxxx

3. 배포

자 이제 드디어 최종 배포를 해본다.

bundle exec cap production deploy

이 과정에서 한번에 잘 되는경우도 있지만 다양한 에러가 나올 수 있다.

내 경우엔 rails asset precompile 과정중에 서버 메모리가 부족해서 process 가 kill 되는 문제가 있었다. 관련해서는 잘 정리된 thread를 참고하면된다.

http://stackoverflow.com/questions/22272339/rake-assetsprecompile-gets-killed-when-there-is-a-console-session-open-in-produ

성공적으로 deploy 됐다면 브라우져에 내 rails app이 잘 나오는지 확인해본다! Good!!

Ruby on Rails 서버 세팅하기

  1. 배경

클라이언트 개발자의 경우 서버 혹은 웹개발에 대한 갈증을 가진 경우가 종종 있다. 나도 안드로이드 경력은 오래됐으나 서버를 배울 기회는 거의 없었고 항상 서버개발에 대한 갈증이 있었던 것 같다. 이번에 친한 지인들과 플리마켓이라는 서비스를 준비하면서 서버 개발을 해보고 싶어 뭣도 모르는 상태에서 급 서버 개발을 맡게 되었다.

서버 개발을 위해서는 현재 나의 상황에 맡게 어떤 OS를 사용할지 어떤 Web framework를 쓸지 배포는 뭘로할지 DB는 어떤걸 쓸지를 잘 선택해야한다. 내가 중요한게 생각했던건 2가지 첫째, “쉬워야한다” 둘째, “레퍼런스가 많아야한다” 어차피 한글로된 정보는 거의 없고 정말 막히는 부분에서는 결국 구글(스택오버플로우)의 도움을 받아야한다. 이 기준으로 정한 기준이다.

  • OS – Ubuntu 12.04
  • Web framework – Ruby on Rails
  • DB – Postgresql

Ubuntu 의 경우 16.04 까지 나와있으나 안정적인 개발을 위해 레퍼런스가 많은 12버전을 선택했다. RoR은 그나마 쉽고 API와 어드민을 개발하기에는 상당히 적합하고 또 국내 사이트에는 별로 없으나 해외 사이트를 기준으로 보면 장고나 플라스크등에 비해 레퍼런스가 많아서 어지간한 문제는 구글님께서 해결해주시는 장점이 있다.

호스팅 서버는 해외 서비스인 Vultr 을 선택했다. 해외 서비스의 경우 서버 스팩이 상당히 좋고 서비스를 관리하는데도 국내 서비스에 비해 많은 장점이 있다. 서버를 선택하면서 가장 많이 참고를 하게된 블로그 포스팅이다. 정리가 잘 되어있고 계속해서 최신정보를 업데이트 해주시는 감사한 분이다. 🙂

2. 서버 설정

가상서버를 발급받는건 Vultr 사이트에 가입하고 5분이면 된다. 너무 직관적이고 쉬워서 생략한다. 발급받은 ip와 비밀번호로 루트 계정으로 터미널을 이용해 로그인해보자.

1. 패키지 정보 최신으로 업데이트

설치해야할 것이 많으므로 패키지를 최신으로 업데이트 하자.

root@fleamarket:~# apt-get update
2. curl, git 등 서버 세팅에 기본적으로 필요한 패키지 설치

python-software-properties 는 ubuntu 12.04에 기본으로 되어있는 리포지토리의 일부 패키지가 너무 오래된 경우가 있다. 그래서 리포지토리를 쉽게 설치하기 위해 꼭 필요하다.

root@fleamarket:~# apt-get -y install curl git-core python-software-properties
3. nginx 설치 최신 버전 설치를 위해 리포지토리 추가
root@fleamarket:~# add-apt-repository ppa:nginx/stable
root@fleamarket:~# apt-get update
root@fleamarket:~# apt-get -y install nginx
root@fleamarket:~# nginx -v
(nginx version: nginx/1.8.0)
root@fleamarket:~# service nginx start

스크린샷 2015-05-30 오전 1.32.44

브라우져에 ip주소를 쳐보면 특별한 문제가 없으면 nginx 기본 페이지가 보인다! 이제 반은 끝난것 🙂

 

4. DB 설치 및 설정 (Postgresql)

DB 는 postgresql을 사용했다. 이 부분은 특별한 이유는 없고 기존에 한번 사용해본 경험이 있고 역시 레퍼런스가 많아서 선택하게됐다. 좋다고는 하는데 뭐가 좋은지는…

설치
root@fleamarket:~# apt-get install postgresql postgresql-contrib libpq-dev
콘솔 접속
root@fleamarket:~# sudo -u postgres psql
최초 설치시에는 postgres 유저의 비밀번호가 없으므로 설정해주는것이 좋다.
pastgres=# \password
Enter new password:
Enter it again:
db유저 생성 (난 항상 앱이름으로 유저 이름을 쓴다) 및 db 만들기
postgres=# create user fleamarket with password 'password';
postgres=# create database fleamarket_production owner fleamarket;
postgres=# \q (종료)

db 설정을 마쳤다.

5. postfix 와 node.js 설치

플리마켓의 경우 이메일 인증이 들어가므로 postfix 패키지를 설치해야한다. postfix 설치시에 Internet Site 를 선택후 나머진 기본 값을 선택해주면된다. 추가로 레일즈에서 자바 스크립트의 효율적으로 사용과 assets pipeline 을 위해 node.js를 설치해준다.

root@fleamarket:~# apt-get install postfix
root@fleamarket:~# add-apt-repository ppa:chris-lea/node.js (리포지토리 추가)
root@fleamarket:~# apt-get update
root@fleamarket:~# apt-get -y install nodejs
6. 루비 설치

루비 설치전에 배포를 위한 계정을 생성해주자. 보안을 위해서는 서버 배포관련된 부분은 루트계정을 사용하지 않는것이 정석이다. 루비를 설치하기전에 계정을 미리생성하는것은 루비 버전 관리자를 통해 루비를 설치하고 싶어서이다. 루비버전을 관리하는 잘나가는(?) 루비 버전관리자가 rbenv, rvm 이렇게 두가지가 있다. 난 최근 가장 많이 사용된다는 rbenv를 사용해보았다.

root@fleamarket:~# addgroup admin
root@fleamarket:~# adduser deployer --ingroup admin
root@fleamarket:~# su deployer
deployer@fleamarket:/root$ cd
deployer@fleamarket:~$ curl -L https://raw.github.com/fesplugas/rbenv-installer/master/bin/rbenv-installer | bash

여기까지 하면 rbenv 설치까지 완료된다. 완료 후 나오는 콘솔 메세지를 잘 살펴보면 환경변수를 설정하라고 설명이 되어있다.

export RBENV_ROOT="${HOME}/.rbenv"

if [ -d "${RBENV_ROOT}" ]; then
 export PATH="${RBENV_ROOT}/bin:${PATH}"
 eval "$(rbenv init -)"
fi
deployer@fleamarket:~$ vim /home/deployer/.bashrc

스크린샷 2015-05-30 오전 11.52.11

deployer@fleamarket:~$ . ~/.bashrc
deployer@fleamarket:~$ rbenv bootstrap-ubuntu-12-04
deployer@fleamarket:~$ rbenv install 2.2.2

deployer@fleamarket:~$ rbenv global 2.2.2
deployer@fleamarket:~$ ruby -v
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
deployer@fleamarket:~$ gem install bundler --no-ri --no-rdoc
deployer@fleamarket:~$ bundle -v
Bundler version 1.10.1

환경 변수를 정상적으로 추가하고 적용해준다.

bootstrap-ubuntu-12-04 는 ruby를 설치하기전에 필요한 디펜던시를 미리 설치해준다.

루비를 설치하는과정은 서버 성능에 따라 상당히 오래걸리니 커피한잔 마시고 오는것을 추천한다. 🙂

루비 설치가 완료되면 레일즈 앱 배포를 위한 서버 설정은 끝난것이다. 만세!

다음번에는 개발중인 레일즈 앱을 실제 서버에 deploy 하는 방법을 포스팅해보겠다.