서버로 배포하기

우선 서버 셋팅이 완료된 상태로 가정하고 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로 추가해 주어야 한글 인코딩 문제를 해결할 수 있다.

root@ubuntu $ sudo vi /etc/mysql/conf.d/deployer.cnf
[mysqld]
character-set-server = utf8

그리고 배포 전용 계정('deployer')도 추가해 둔다.

노트

아직 서버에 배포용 계정을 생성하지 않았다면 서버로 접속한 후 아래와 같이 계정을 생성한다.

root@ubuntu $ sudo adduser deployer
root@ubutnu $ sudo addgroup admin
root@ubuntu $ sudo usermod -a -G admin deployer

서버로 접속해서 nginx.conf 파일의 user 속성을 변경한다.

root@ubuntu $ sudo vi /etc/nginx/nginx.conf
user deployer;

배포시에 sudo 실행시 deployer 계정에 대한 비밀번호를 묻게 되는데 이를 방지 하기 위해서, 서버로 접속한 후에 아래와 같이 명령을 실행하고,

root@ubuntu $ sudo visudo

맨 아래 줄에 아래와 같이 추가해 준다.

deployer ALL=(ALL) NOPASSWD: ALL

또한, 매번 ssh로 서버에 접속할 때마다 비밀번호를 입력하는 절차를 생략하기 위해서, 아래와 같이 ssh 키를 서버로 복사한다.

$ ssh-copy-id -i ~/.ssh/id_rsa deployer@ubuntu.vm
deployer@ubuntu.vm's password:

노트

해당 디렉토리에 id_rsa 파일이 없다면 SSH Key 생성하기를 참고하여 생성한다.

이후부터는 ssh로 연결시에 비밀번호 입력없이 바로 접속이 된다.

노트

여기서 사용한 ubuntu.vm은 가상머신으로 설치한 우분투 서버의 가상 도메인이다. 도메인 대신 서버의 ip를 지정해도 된다. 맥 사용자들은 Horst라는 툴을 사용하면 /etc/hosts 파일을 GUI로 편하게 관리할 수 있다.

제대로 설정이 되었다면 아래의 명령을 실행했을 때 비밀번호 입력없이 결과를 확인할 수 있다.

$ ssh deployer@ubuntu.vm '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, 'git@github.com: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 유저를 생성하고 권한을 부여한 후 데이터베이스를 생성한다.

deployer@ubuntu $ sudo -i -u postgres
postgres@ubuntu $ createuser --interactive  # `deployer` 유저생성
postgres@ubuntu $ sudo -i -u deployer
deployer@ubuntu $ createdb rcafe2_staging
(2) MySQL 서버를 사용할 경우

서버에 접속하여 아래와 같이 데이터베이스를 생성하고 권한을 부여한다.

deployer@ubuntu $ mysql -u root -p
mysql> create database rcafe_production;
mysql> grant usage on *.* to deployer@localhost identified by 'password';
mysql> grant all privileges on rcafe_production.* to deployer@localhost;

마지막으로 한가지 추가할 것은 서버에서 rake db:seed가 실행되도록 하여 기본 게시판을 생성하도록 한다.

$ cap staging rails:rake:db:seed

에러 없이 배포가 완료되면 브라우저에서 확인한다.

소스코드의 관리

  • 이후 소스변경이 필요한 경우 커밋 후 git push한 다음, cap staging deploy 명령을 실행하면 된다.
  • 잘 못 배포된 경우에는 cap staging deploy:rollback 명령으로 취소할 수 있다.

지금까지 설명한 배포과정이 다소 길고 복잡한 감이 있다. 또한 각자의 환경에 따라 예상치 못했던 여러가지 에러가 발생할 것으로 생각한다. 각자 따라해 보고 문제가 발생하면 아래에 코멘트를 달아 함께 공유하고 고민해 보자.


Git소스 https://github.com/rorlab/rcafe2/tree/chapter_05_16


References:

  1. SSH Key 생성하기
  2. Sudo without password on Ubuntu
  3. NginX 주요 설정 (nginx.conf)

results matching ""

    No results matching ""