서버로 배포하기
우선 서버 셋팅이 완료된 상태로 가정하고 Capistrano 3를 이용하여 배포하는 과정을 진행해 보기로 한다.
서버 셋팅
배포할 서버에는 아래와 같은 프로그램을 미리 설치해 둔다. 여기서는 테스트 목적으로 배포할 것이기 때문에, 가상서버를 준비하기로 한다. 가상머신용 툴로는 VMware Fusion
v8.5.4를 사용하였다. 무료로 사용할 수 있는 툴로는 오라클사의 VM VirtualBox
가 있으며 여기를 방문하면 패키지를 다운로드 받아 설치할 수 있다.
또한, 우분투 16.04 서버 셋팅하기를 참고하면 VirtualBox
로 가상 서버를 생성하여 서버 환경을 구축할 수 있다. 레일스 프로젝트를 배포하기 전에 서버로 접속해서 아래의 두 라이브러리를 인스톨한다. 서버 배포시 bundle install
명령 실행시 오류를 해결하기 위한 조치다.
# sudo apt-get install -y libreadline-dev libpq-dev
가상머신의 시스템에는 아래의 프로그램이 설치된다.
- git : 소스관리
- Nginx : 웹서버
- ImageMagick : 이미지 작업을 위한 툴
- MySQL/PostgreSQL : 데이터베이스 서버
- Nodejs : 서버사이드 자바스크립트
주의
MySQL DB 서버
를 사용할 경우 원격서버의 /etc/mysql/conf.d/
디렉토리에 deployer.cnf
파일을 새로 추가하고 아래와 같이 문자 인코딩을 uft8
로 추가해 주어야 한글 인코딩 문제를 해결할 수 있다.
[email protected] $ sudo vi /etc/mysql/conf.d/deployer.cnf
[mysqld]
character-set-server = utf8
그리고 배포 전용 계정('deployer'
)도 추가해 둔다.
노트
아직 서버에 배포용 계정을 생성하지 않았다면 서버로 접속한 후 아래와 같이 계정을 생성한다.
[email protected] $ sudo adduser deployer
[email protected] $ sudo addgroup admin
[email protected] $ sudo usermod -a -G admin deployer
서버로 접속해서 nginx.conf
파일의 user
속성을 변경한다.
[email protected] $ sudo vi /etc/nginx/nginx.conf
user deployer;
배포시에 sudo
실행시 deployer
계정에 대한 비밀번호를 묻게 되는데 이를 방지 하기 위해서, 서버로 접속한 후에 아래와 같이 명령을 실행하고,
[email protected] $ sudo visudo
맨 아래 줄에 아래와 같이 추가해 준다.
deployer ALL=(ALL) NOPASSWD: ALL
또한, 매번 ssh
로 서버에 접속할 때마다 비밀번호를 입력하는 절차를 생략하기 위해서, 아래와 같이 ssh
키를 서버로 복사한다.
$ ssh-copy-id -i ~/.ssh/id_rsa [email protected]
[email protected]'s password:
노트
해당 디렉토리에 id_rsa
파일이 없다면 SSH Key 생성하기를 참고하여 생성한다.
이후부터는 ssh
로 연결시에 비밀번호 입력없이 바로 접속이 된다.
노트
여기서 사용한 ubuntu.vm
은 가상머신으로 설치한 우분투 서버의 가상 도메인이다. 도메인 대신 서버의 ip를 지정해도 된다. 맥 사용자들은 Horst
라는 툴을 사용하면 /etc/hosts
파일을 GUI로 편하게 관리할 수 있다.
제대로 설정이 되었다면 아래의 명령을 실행했을 때 비밀번호 입력없이 결과를 확인할 수 있다.
$ ssh [email protected] 'hostname; uptime'
ubuntu
10:26:54 up 3:49, 1 user, load average: 0.02, 0.02, 0.05
주의
복수개의 서버를 설치 중이라면 모든 서버에서 위의 작업을 해 주어야 한다.
Gemfile의 추가
프로젝트의 Gemfile
을 열고 파일 하단에 코멘트 처리되어 있는 두개의 젬을 활성화하고, Capistrano
관련 젬을 추가한 후 데이터베이스 젬을 환경에 맞게 추가한다.
# 추가할 젬
# Use Capistrano for deployment
gem 'capistrano-rbenv', '~> 2.0'
gem 'capistrano-rbenv-install', '~> 1.2.0'
gem 'capistrano-rails', group: :development
gem 'capistrano3-puma' , group: :development
gem 'capistrano-figaro-yml', '~> 1.0.2'
gem 'capistrano-upload-config'
gem 'capistrano3-nginx', '~> 2.0'
gem 'capistrano-rails-collection'
프로젝트에 적용하기 위해서 번들 인스톨한다.
```bash
$ bin/bundle install
Capistrano의 초기화
그리고 프로젝트에 사용하기 위해서 Capistrano
를 초기화한다.
$ cap install
mkdir -p config/deploy
create config/deploy.rb
create config/deploy/staging.rb
create config/deploy/production.rb
mkdir -p lib/capistrano/tasks
Capified
Capistrano의 배포 환경설정
위에서 생성된 config/deploy.rb
파일을 열고 아래와 같이 변경한다.
# config valid only for current version of Capistrano
lock '3.6.1'
set :application, 'rcafe2'
set :repo_url, '[email protected]:rorlab/rcafe2.git'
set :migration_role, :app
set :rbenv_type, :user # or :system, depends on your rbenv setup
set :rbenv_ruby, File.read('.ruby-version').strip
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
set :rbenv_map_bins, %w{rake gem bundle ruby rails}
set :rbenv_roles, :all # default value
# Default branch is :master
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp
# Default deploy_to directory is /var/www/my_app_name
set :deploy_to, '/home/deployer/apps/rcafe2'
# Default value for :scm is :git
# set :scm, :git
# Default value for :format is :airbrussh.
# set :format, :airbrussh
# You can configure the Airbrussh format using :format_options.
# These are the defaults.
# set :format_options, command_output: true, log_file: 'log/capistrano.log', color: :auto, truncate: :auto
# Default value for :pty is false
set :pty, true
# Default value for :linked_files is []
set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')
# Default value for linked_dirs is []
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'public/system')
# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
# Default value for keep_releases is 5
# set :keep_releases, 5
before 'deploy:check:linked_files', 'config:push'
before 'deploy:starting', 'figaro_yml:setup'
after 'figaro_yml:setup', 'puma:nginx_config'
namespace :deploy do
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
# Here we can do anything such as:
# within release_path do
# execute :rake, 'cache:clear'
# end
end
end
end
Staging 서버 환경
다음 config/deploy/staging.rb
파일을 열고 아래와 같이 변경한다.
server 'ubuntu16.dev', user: 'deployer', roles: %w{app db web}
set :nginx_server_name, 'staging.ubuntu16.dev'
Capfile 업데이트
# Load DSL and set up stages
require 'capistrano/setup'
# Include default deployment tasks
require 'capistrano/deploy'
# Include tasks from other gems included in your Gemfile
require 'capistrano/rbenv'
require 'capistrano/rbenv_install'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano/puma'
require 'capistrano/figaro_yml'
require 'capistrano/upload-config'
require 'capistrano/puma/nginx' # if you want to upload a nginx site template
require 'capistrano/nginx'
require 'capistrano/rails/collection'
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
Figaro 설치
$ figaro install
create config/application.yml
append .gitignore
config/application.yml
staging:
RCAFE2_DATABASE_USERNAME: deployer
RCAFE2_DATABASE_PASSWORD: deployer1234
RCAFE2_SECRET_KEY_BASE: 9cf54a6500186dfd9ee00f66162b7f0ce120d36df0c4927e789b5ce782a8b1fb95d0c793f9e1cb2256be36a1658caee06d78608eb9bc2ec838bbb6a2c21e2abb
production:
RCAFE2_DATABASE_USERNAME: deployer
RCAFE2_DATABASE_PASSWORD: deployer1234
RCAFE2_SECRET_KEY_BASE: f62932f3c1
Staging 서버 설정 파일의 생성과 업로드
$ cap staging config:init
00:00 config:init
Created: config/database.staging.yml as empty file
Created: config/secrets.staging.yml as empty file
default: &default
adapter: postgresql
encoding: unicode
# For details on connection pooling, see rails configuration guide
# http://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
staging:
<<: *default
database: rcafe2_staging
username: <%= ENV['RCAFE2_DATABASE_USERNAME'] %>
password: <%= ENV['RCAFE2_DATABASE_PASSWORD'] %>
staging:
secret_key_base: <%= ENV["RCAFE2_SECRET_KEY_BASE"] %>
Staging 환경 파일 생성
config/environments/staging.rb
파일을 생성하고 config/environments/production.rb
파일 내용을 복사해서 붙여넣기 한 후 아래의 코드를 추가한다.
config.secret_key_base = '<%=ENV["RCAFE2_SECRET_KEY_BASE"] %>'
Staging 서버 점검하기
$ cap staging doctor
$ cap staging deploy:check
배포 실행
$ cap staging setup
$ cap staging deploy
git:check
퍼미션 오류가 날 때는 github
저장소의 Settings
페이지에서 Deploy keys
를 등록해 준다. deployer 계정으로 서버에 접속해서 ssh-keygen
명령을 실행한다. 그리고 cat ~/.ssh/id_rsa.pub
명령을 실행한 후 출력되는 내용을 복사해서 키 값으로 사용하면 된다.
Note 로컬 프로젝트 디렉토리에서 아래와 같이 명령을 실행하면
secret
키를 생성할 수 있다$ bin/rake secret
이 때 생성된 키를 위의
RCAFE2_SECRET_KEY_BASE
값으로 할당하면 된다.
데이터베이스의 생성
(1) PostgreSQL 서버를 사용할 경우
서버에 접속하여 아래와 같이 DB 유저를 생성하고 권한을 부여한 후 데이터베이스를 생성한다.
[email protected] $ sudo -i -u postgres
[email protected] $ createuser --interactive # `deployer` 유저생성
[email protected] $ sudo -i -u deployer
[email protected] $ createdb rcafe2_staging
(2) MySQL 서버를 사용할 경우
서버에 접속하여 아래와 같이 데이터베이스를 생성하고 권한을 부여한다.
[email protected] $ mysql -u root -p
mysql> create database rcafe_production;
mysql> grant usage on *.* to [email protected] identified by 'password';
mysql> grant all privileges on rcafe_production.* to [email protected];
마지막으로 한가지 추가할 것은 서버에서 rake db:seed
가 실행되도록 하여 기본 게시판을 생성하도록 한다.
$ cap staging rails:rake:db:seed
에러 없이 배포가 완료되면 브라우저에서 확인한다.
소스코드의 관리
- 이후 소스변경이 필요한 경우 커밋 후
git push
한 다음,cap staging deploy
명령을 실행하면 된다. - 잘 못 배포된 경우에는
cap staging deploy:rollback
명령으로 취소할 수 있다.
지금까지 설명한 배포과정이 다소 길고 복잡한 감이 있다. 또한 각자의 환경에 따라 예상치 못했던 여러가지 에러가 발생할 것으로 생각한다. 각자 따라해 보고 문제가 발생하면 아래에 코멘트를 달아 함께 공유하고 고민해 보자.
References: