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_USER
및 APPNAME_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
setuid
및 setgid
를 지정하는 두 줄을 찾아 "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
다음과 같이 stop
및 restart
를 사용하여 애플리케이션을 제어할 수도 있습니다.
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를 기반으로 하지만 여전히 배포 자동화에 도움이 됩니다.