웹사이트 검색

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


소개

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

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

전제 조건

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

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

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

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

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

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

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

rails new appname -d postgresql

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

cd appname

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

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

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

sudo -u postgres createuser -s appname

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

sudo -u postgres psql

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

\password appname

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

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

\q

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

데이터베이스 연결 구성

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

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

vi config/database.yml

production 섹션을 다음과 같이 업데이트하십시오.

production:
  <<: *default
  host: localhost
  adapter: postgresql
  encoding: utf8
  database: appname_production
  pool: 5
  username: <%= ENV['APPNAME_DATABASE_USER'] %>
  password: <%= ENV['APPNAME_DATABASE_PASSWORD'] %>

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

저장 및 종료.

rbenv-vars 플러그인 설치

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

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

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

환경 변수 설정

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

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

cd ~/appname
rake secret

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

vi .rbenv-vars

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

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

SECRET_KEY_BASE=your_generated_secret

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

APPNAME_DATABASE_USER=appname

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

APPNAME_DATABASE_PASSWORD=prod_db_pass

저장 및 종료.

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

rbenv vars

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

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

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

RAILS_ENV=production rake db:create

컨트롤러 생성

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

rails generate scaffold Task title:string note:text

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

RAILS_ENV=production rake db:migrate

자산을 미리 컴파일해야 합니다.

RAILS_ENV=production rake assets:precompile

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

RAILS_ENV=production rails server --binding=server_public_IP

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

http://server_public_IP:3000/tasks

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

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

푸마 설치

이제 Puma를 설치할 준비가 되었습니다.

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

vi Gemfile

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

gem 'puma'

저장 및 종료.

Puma 및 미해결 종속성을 설치하려면 Bundler를 실행하십시오.

bundle

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

푸마 구성

Puma를 구성하기 전에 서버에 있는 CPU 코어 수를 조회해야 합니다. 다음 명령으로 쉽게 할 수 있습니다.

grep -c processor /proc/cpuinfo

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

vi config/puma.rb

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

# Change to match your CPU core count
workers 2

# Min and Max threads per worker
threads 1, 6

app_dir = File.expand_path("../..", __FILE__)
shared_dir = "#{app_dir}/shared"

# Default to production
rails_env = ENV['RAILS_ENV'] || "production"
environment rails_env

# Set up socket location
bind "unix://#{shared_dir}/sockets/puma.sock"

# Logging
stdout_redirect "#{shared_dir}/log/puma.stdout.log", "#{shared_dir}/log/puma.stderr.log", true

# Set master PID and state locations
pidfile "#{shared_dir}/pids/puma.pid"
state_path "#{shared_dir}/pids/puma.state"
activate_control_app

on_worker_boot do
  require "active_record"
  ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
  ActiveRecord::Base.establish_connection(YAML.load_file("#{app_dir}/config/database.yml")[rails_env])
end

작업자 수를 서버의 CPU 코어 수로 변경합니다.

저장 및 종료. 이것은 애플리케이션의 위치와 소켓, 로그 및 PID의 위치로 Puma를 구성합니다. 자유롭게 파일을 수정하거나 필요한 다른 옵션을 추가하십시오.

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

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

Puma Upstart 스크립트 생성

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

Puma GitHub 리포지토리에서 홈 디렉터리로 Jungle Upstart 도구를 다운로드합니다.

cd ~
wget https://raw.githubusercontent.com/puma/puma/master/tools/jungle/upstart/puma-manager.conf
wget https://raw.githubusercontent.com/puma/puma/master/tools/jungle/upstart/puma.conf

이제 제공된 puma.conf 파일을 열어 Puma 배포 사용자를 구성할 수 있습니다.

vi puma.conf

setuidsetgid를 지정하는 두 줄을 찾아 "apps\를 배포 사용자 및 그룹의 이름으로 바꿉니다. 예를 들어 배포 사용자가 호출된 경우 "deploy\ 행은 다음과 같아야 합니다.

setuid deploy
setgid deploy

저장 및 종료.

이제 스크립트를 Upstart 서비스 디렉토리에 복사하십시오.

sudo cp puma.conf puma-manager.conf /etc/init

puma-manager.conf 스크립트는 관리해야 하는 응용 프로그램에 대해 /etc/puma.conf를 참조합니다. 이제 인벤토리 파일을 만들고 편집해 보겠습니다.

sudo vi /etc/puma.conf

이 파일의 각 라인은 puma-manager가 관리할 애플리케이션의 경로여야 합니다. 지금 애플리케이션에 경로를 추가하십시오. 예를 들어:

/home/deploy/appname

저장 및 종료.

이제 응용 프로그램이 Upstart를 통해 부팅 시 시작되도록 구성되었습니다. 이는 서버가 재부팅된 후에도 애플리케이션이 시작됨을 의미합니다.

Puma 애플리케이션을 수동으로 시작

관리되는 모든 Puma 앱을 지금 시작하려면 다음 명령을 실행하십시오.

sudo start puma-manager

다음과 같이 puma Upstart 스크립트를 사용하여 단일 Puma 애플리케이션을 시작할 수도 있습니다.

sudo start puma app=/home/deploy/appname

다음과 같이 stoprestart를 사용하여 애플리케이션을 제어할 수도 있습니다.

sudo stop puma-manager
sudo restart puma-manager

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

Nginx 설치 및 구성

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

sudo apt-get install nginx

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

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

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

upstream app {
    # Path to Puma SOCK file, as defined previously
    server unix:/home/deploy/appname/shared/sockets/puma.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 소켓을 통해 Puma 애플리케이션 서버로 전달됩니다. 적절하다고 생각되는 대로 자유롭게 변경하십시오.

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

sudo service nginx restart

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

http://server_public_IP/tasks

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

결론

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

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