웹사이트 검색

Ubuntu 14.04에서 Unicorn 및 Nginx로 Rails 앱을 배포하는 방법


소개

Ruby on Rails 애플리케이션을 배포할 준비가 되면 고려해야 할 유효한 설정이 많이 있습니다. 이 튜토리얼은 Ubuntu 14.04에서 Unicorn 및 Nginx를 사용하여 PostgreSQL을 데이터베이스로 사용하여 Ruby on Rails 애플리케이션의 프로덕션 환경을 배포하는 데 도움이 됩니다.

Unicorn은 Puma와 같이 Rails 애플리케이션이 요청을 동시에 처리할 수 있도록 하는 애플리케이션 서버입니다. Unicorn은 사용자가 직접 액세스하도록 설계되지 않았기 때문에 Nginx를 사용자와 Rails 애플리케이션 간의 요청 및 응답을 버퍼링하는 리버스 프록시로 사용합니다.

전제 조건

이 자습서에서는 응용 프로그램을 배포할 사용자에게 다음 소프트웨어가 설치된 Ubuntu 14.04 서버가 있다고 가정합니다.

  • Ruby on Rails, rbenv 사용
  • 레일을 사용한 PostgreSQL

해당 설정이 아직 없는 경우 위에 링크된 자습서를 따르십시오. 사용자 이름이 배포라고 가정합니다.

또한 이 자습서에서는 개발 또는 테스트 환경을 설정하는 방법을 다루지 않습니다. 이에 대한 도움이 필요하면 PostgreSQL with Rails 자습서의 예제를 따르십시오.

레일스 애플리케이션 만들기

이상적으로는 배포하려는 Rails 애플리케이션이 이미 있습니다. 이 경우 이 섹션을 건너뛰고 따라하면서 적절하게 대체할 수 있습니다. 그렇지 않은 경우 첫 번째 단계는 PostgreSQL을 데이터베이스로 사용하는 새 Rails 애플리케이션을 만드는 것입니다.

이 명령은 PostgreSQL을 데이터베이스로 사용할 "appname\이라는 새 Rails 애플리케이션을 생성합니다. 강조 표시된 "appname\을 다른 이름으로 자유롭게 대체할 수 있습니다.

  1. rails new appname -d postgresql

그런 다음 애플리케이션 디렉토리로 변경합니다.

  1. cd appname

잠시 시간을 내어 Rails 애플리케이션의 프로덕션 환경에서 사용할 PostgreSQL 사용자를 생성해 보겠습니다.

프로덕션 데이터베이스 사용자 생성

간단하게 하기 위해 프로덕션 데이터베이스 사용자의 이름을 애플리케이션 이름과 동일하게 지정하겠습니다. 예를 들어 애플리케이션 이름이 "appname\인 경우 다음과 같이 PostgreSQL 사용자를 생성해야 합니다.

  1. sudo -u postgres createuser -s appname

데이터베이스 사용자의 비밀번호를 설정하고 싶으므로 다음과 같이 PostgreSQL 콘솔에 들어갑니다.

  1. sudo -u postgres psql

그런 다음 예제에서 데이터베이스 사용자 "appname\의 암호를 다음과 같이 설정합니다.

  1. \password appname

원하는 비밀번호를 입력하고 확인하십시오.

다음 명령을 사용하여 PostgreSQL 콘솔을 종료합니다.

  1. \q

이제 적절한 데이터베이스 연결 정보로 애플리케이션을 구성할 준비가 되었습니다.

데이터베이스 연결 구성

애플리케이션의 루트 디렉터리(cd ~/appname)에 있는지 확인합니다.

원하는 텍스트 편집기에서 애플리케이션의 데이터베이스 구성 파일을 엽니다. 우리는 vi를 사용할 것입니다:

  1. vi config/database.yml

default 섹션에서 "pool: 5\라는 줄을 찾아 그 아래에 다음 줄을 추가합니다(아직 없는 경우).

  host: localhost

파일 맨 아래로 스크롤하면 production 섹션이 다음과 같이 설정되어 있음을 알 수 있습니다.

  username: appname
  password: <%= ENV['APPNAME_DATABASE_PASSWORD'] %>

프로덕션 사용자 이름이 이전에 생성한 데이터베이스 사용자와 일치하지 않는 경우 지금 설정하십시오.

데이터베이스 암호는 APPNAME_DATABASE_PASSWORD 환경 변수에서 읽을 수 있도록 구성되어 있습니다. Git과 같은 분산 버전 제어 시스템을 사용하는 경우 쉽게 노출될 수 있으므로 프로덕션 암호와 비밀을 애플리케이션 코드베이스 외부에 보관하는 것이 가장 좋습니다. 다음에 환경 변수를 사용하여 데이터베이스 인증을 설정하는 방법을 살펴보겠습니다.

rbenv-vars 플러그인 설치

프로덕션 Rails 애플리케이션을 배포하기 전에 환경 변수를 사용하여 프로덕션 비밀 키와 데이터베이스 비밀번호를 설정해야 합니다. 런타임 시 애플리케이션에 비밀번호와 비밀을 로드하는 데 사용할 수 있는 환경 변수를 관리하는 쉬운 방법은 rbenv-vars 플러그인을 사용하는 것입니다.

rbenv-vars 플러그인을 설치하려면 .rbenv/plugins 디렉토리로 변경하고 GitHub에서 복제하기만 하면 됩니다. 예를 들어 rbenv가 홈 디렉토리에 설치된 경우 다음 명령을 실행합니다.

  1. cd ~/.rbenv/plugins
  2. git clone https://github.com/sstephenson/rbenv-vars.git

환경 변수 설정

이제 rbenv-vars 플러그인이 설치되었으므로 필요한 환경 변수를 설정하겠습니다.

먼저 서명된 쿠키의 무결성을 확인하는 데 사용할 비밀 키를 생성합니다.

  1. cd ~/appname
  2. rake secret

생성된 비밀 키를 복사한 다음 원하는 편집기로 .rbenv-vars 파일을 엽니다. 우리는 vi를 사용할 것입니다:

  1. vi .rbenv-vars

여기에서 설정한 모든 환경 변수는 Rails 애플리케이션에서 읽을 수 있습니다.

먼저 SECRET_KEY_BASE 변수를 다음과 같이 설정합니다(강조 표시된 텍스트를 방금 생성하고 복사한 암호로 바꿉니다).

SECRET_KEY_BASE=your_generated_secret

다음으로 APPNAME_DATABASE_PASSWORD 변수를 다음과 같이 설정합니다(강조표시된 "APPNAME\을 애플리케이션 이름으로, "prod_db_pass\를 프로덕션 데이터베이스 사용자 암호로 바꿉니다).

APPNAME_DATABASE_PASSWORD=prod_db_pass

저장 및 종료.

다음 명령을 실행하여 rbenv-vars 플러그인으로 애플리케이션에 설정된 환경 변수를 볼 수 있습니다.

  1. rbenv vars

비밀 또는 데이터베이스 암호를 변경하는 경우 .rbenv-vars 파일을 업데이트하십시오. 이 파일을 비공개로 유지하고 공개 코드 리포지토리를 포함하지 않도록 주의하세요.

프로덕션 데이터베이스 생성

이제 애플리케이션이 PostgreSQL 데이터베이스와 통신하도록 구성되었으므로 프로덕션 데이터베이스를 생성해 보겠습니다.

  1. RAILS_ENV=production rake db:create

컨트롤러 생성

예제를 따라가는 경우 스캐폴드 컨트롤러를 생성하여 애플리케이션에서 볼 수 있는 항목을 갖게 됩니다.

  1. rails generate scaffold Task title:string note:text

이제 이 명령을 실행하여 프로덕션 데이터베이스를 업데이트합니다.

  1. RAILS_ENV=production rake db:migrate

자산 사전 컴파일

이 시점에서 애플리케이션이 작동해야 하지만 이미지, CSS 및 스크립트가 로드되도록 자산을 미리 컴파일해야 합니다. 이렇게 하려면 다음 명령을 실행합니다.

  1. RAILS_ENV=production rake assets:precompile

시험 적용

애플리케이션이 작동하는지 테스트하려면 프로덕션 환경을 실행하고 서버의 공용 IP 주소에 바인딩할 수 있습니다(서버의 공용 IP 주소로 대체).

  1. RAILS_ENV=production rails server --binding=server_public_IP

이제 웹 브라우저에서 다음 URL을 방문하십시오.

http://server_public_IP:3000/tasks

제대로 작동하면 다음 페이지가 표시됩니다.

Rails 서버로 돌아가서 Ctrl-c를 눌러 애플리케이션을 중지합니다.

유니콘 설치

이제 유니콘을 설치할 준비가 되었습니다.

이를 수행하는 쉬운 방법은 애플리케이션의 Gemfile에 추가하는 것입니다. 선호하는 편집기에서 Gemfile을 엽니다(응용 프로그램의 루트 디렉터리에 있는지 확인).

  1. vi Gemfile

파일 끝에 다음 줄과 함께 Unicorn gem을 추가합니다.

gem 'unicorn'

저장 및 종료.

Unicorn 및 미해결 종속성을 설치하려면 Bundler를 실행합니다.

  1. bundle

이제 Unicorn이 설치되었지만 구성해야 합니다.

유니콘 구성

Unicorn 구성을 config/unicorn.rb에 추가해 보겠습니다. 텍스트 편집기에서 파일을 엽니다.

  1. vi config/unicorn.rb

이 구성을 복사하여 파일에 붙여넣습니다.

# set path to application
app_dir = File.expand_path("../..", __FILE__)
shared_dir = "#{app_dir}/shared"
working_directory app_dir


# Set unicorn options
worker_processes 2
preload_app true
timeout 30

# Set up socket location
listen "#{shared_dir}/sockets/unicorn.sock", :backlog => 64

# Logging
stderr_path "#{shared_dir}/log/unicorn.stderr.log"
stdout_path "#{shared_dir}/log/unicorn.stdout.log"

# Set master PID location
pid "#{shared_dir}/pids/unicorn.pid"

저장 및 종료. 이는 응용 프로그램의 위치와 소켓, 로그 및 PID의 위치로 Unicorn을 구성합니다. 자유롭게 파일을 수정하거나 필요한 다른 옵션을 추가하십시오.

이제 구성 파일에서 참조된 디렉터리를 만듭니다.

  1. mkdir -p shared/pids shared/sockets shared/log

유니콘 초기화 스크립트 만들기

Unicorn을 쉽게 시작 및 중지하고 부팅 시 시작되도록 초기화 스크립트를 생성해 보겠습니다.

스크립트를 생성하고 다음 명령으로 편집용으로 엽니다(원하는 경우 강조 표시된 부분을 응용 프로그램 이름으로 바꿉니다).

  1. sudo vi /etc/init.d/unicorn_appname

다음 코드 블록을 복사하여 붙여넣고 USERAPP_NAME(강조 표시됨)을 적절한 값으로 대체해야 합니다.

#!/bin/sh

### BEGIN INIT INFO
# Provides:          unicorn
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the unicorn app server
# Description:       starts unicorn using start-stop-daemon
### END INIT INFO

set -e

USAGE="Usage: $0 <start|stop|restart|upgrade|rotate|force-stop>"

# app settings
USER="deploy"
APP_NAME="appname"
APP_ROOT="/home/$USER/$APP_NAME"
ENV="production"

# environment settings
PATH="/home/$USER/.rbenv/shims:/home/$USER/.rbenv/bin:$PATH"
CMD="cd $APP_ROOT && bundle exec unicorn -c config/unicorn.rb -E $ENV -D"
PID="$APP_ROOT/shared/pids/unicorn.pid"
OLD_PID="$PID.oldbin"

# make sure the app exists
cd $APP_ROOT || exit 1

sig () {
  test -s "$PID" && kill -$1 `cat $PID`
}

oldsig () {
  test -s $OLD_PID && kill -$1 `cat $OLD_PID`
}

case $1 in
  start)
    sig 0 && echo >&2 "Already running" && exit 0
    echo "Starting $APP_NAME"
    su - $USER -c "$CMD"
    ;;
  stop)
    echo "Stopping $APP_NAME"
    sig QUIT && exit 0
    echo >&2 "Not running"
    ;;
  force-stop)
    echo "Force stopping $APP_NAME"
    sig TERM && exit 0
    echo >&2 "Not running"
    ;;
  restart|reload|upgrade)
    sig USR2 && echo "reloaded $APP_NAME" && exit 0
    echo >&2 "Couldn't reload, starting '$CMD' instead"
    $CMD
    ;;
  rotate)
    sig USR1 && echo rotated logs OK && exit 0
    echo >&2 "Couldn't rotate logs" && exit 1
    ;;
  *)
    echo >&2 $USAGE
    exit 1
    ;;
esac

저장 및 종료. 이렇게 하면 service unicorn_appname을 사용하여 Unicorn과 Rails 애플리케이션을 시작하고 중지할 수 있습니다.

스크립트의 권한을 업데이트하고 Unicorn이 부팅 시 시작되도록 활성화합니다.

  1. sudo chmod 755 /etc/init.d/unicorn_appname
  2. sudo update-rc.d unicorn_appname defaults

지금 시작하겠습니다.

  1. sudo service unicorn_appname start

이제 Rails 애플리케이션의 프로덕션 환경이 Unicorn에서 실행되고 있으며 shared/sockets/unicorn.sock 소켓에서 수신 중입니다. 외부 사용자가 애플리케이션에 액세스할 수 있으려면 먼저 Nginx 역방향 프록시를 설정해야 합니다.

Nginx 설치 및 구성

apt-get을 사용하여 Nginx를 설치합니다.

  1. sudo apt-get install nginx

이제 텍스트 편집기로 기본 서버 블록을 엽니다.

  1. sudo vi /etc/nginx/sites-available/default

파일의 내용을 다음 코드 블록으로 바꿉니다. 강조 표시된 부분을 적절한 사용자 이름 및 애플리케이션 이름으로 바꾸십시오.

upstream app {
    # Path to Unicorn SOCK file, as defined previously
    server unix:/home/deploy/appname/shared/sockets/unicorn.sock fail_timeout=0;
}

server {
    listen 80;
    server_name localhost;

    root /home/deploy/appname/public;

    try_files $uri/index.html $uri @app;

    location @app {
        proxy_pass http://app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }

    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}

저장 및 종료. 이렇게 하면 Nginx가 리버스 프록시로 구성되므로 HTTP 요청이 Unix 소켓을 통해 Unicorn 애플리케이션 서버로 전달됩니다. 적절하다고 생각되는 대로 자유롭게 변경하십시오.

Nginx를 다시 시작하여 변경 사항을 적용합니다.

  1. sudo service nginx restart

이제 서버의 공용 IP 주소 또는 FQDN을 통해 Rails 애플리케이션의 프로덕션 환경에 액세스할 수 있습니다. 이전에 생성한 작업 컨트롤러에 액세스하려면 웹 브라우저에서 애플리케이션 서버를 방문하십시오.

http://server_public_IP/tasks

애플리케이션을 처음 테스트했을 때 보았던 것과 동일한 페이지가 표시되어야 하지만 지금은 Nginx 및 Unicorn을 통해 제공되고 있습니다.

결론

축하해요! Nginx 및 Unicorn을 사용하여 Ruby on Rails 애플리케이션의 프로덕션 환경을 배포했습니다.

프로덕션 Rails 애플리케이션 배포를 개선하려는 경우 Capistrano를 사용하여 배포를 자동화하는 방법에 대한 자습서 시리즈를 확인해야 합니다. 이 시리즈는 CentOS를 기반으로 하지만 여전히 배포 자동화에 도움이 됩니다.