Capistrano-unicorn-nginx-osx 젬을 이용하여 맥(OSX) 서버에 배포하기

Capistrano를 이용하여 Mac OSX 서버에 레일스 프로젝트 배포하기

필자는 최근 맥 서버(OSX El Capitan)로 레일스 프로젝트를 배포하는 작업을 1주일간에 걸쳐 진행했었다. 구글 검색시에도 이와 관련된 자료가 많지 않아서, 맥의 서비스 관리 툴인 launchd에 대한 공부와 함께 수차례의 시행착오 끝에 성공적으로 배포작업을 완료할 수 있었다.

이 글을 읽는 독자가 혹 필자와 같이 맥 서버로 레일스 프로젝트를 배포해야할 상황에 닥칠 때 이 글이 도움이 될 수 있기를 바란다.

Xcode Command Line Tools 설치

가장 먼저 Xcode Command Line Tools를 설치해야 한다.
아래의 명령을 실행할 때, 설치되어 있지 않을 경우 아래와 같은 에러가 발생한다.

$ xcode-select -p
xcode-select: error: unable to get active developer directory, use `xcode-select --switch` to set one (or see `man xcode-select`)

--install 옵션을 이용하면 설치할 수 있다.

$ xcode-select --install

rbenv 설치

$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ . ~/.bash_profile

# 제대로 설치되었는지 확인하기
$ type rbenv
rbenv is a function

ruby-build 설치

rbenv을 이용하여 루비를 설치하기 위해서는 ruby-build라는 플러그인을 설치해야 한다.

$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

이제 설치 가능한 루버 버전 목록을 보기 위해서는 아래와 같은 명령을 실행한다.

$ rbenv install -l

노트 : 원하는 버전이 없는 경우는 cd ~/.rbenv/plugins/ruby-build && git pull 명령을 실행하여 ruby-build를 업데이트 한다.

ruby 설치

$ rbenv install 2.2.3
$ rbenv global 2.2.3
$ rbenv rehash

Homebrew 설치

OSX용 패키지 매니저인 homebrew를 설치한다.

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

노트 : 아래와 같은 경고문이 보이지만 비밀번호를 입력하고 계속 진행한다.

WARNING: Improper use of the sudo command could lead to data loss
or the deletion of important system files. Please double-check your
typing when using sudo. Type “man sudo” for more information.
To proceed, enter your password, or type Ctrl-C to abort.

Nginx 설치

homebrew를 이용하여 nginx를 설치한다.

$ brew install nginx

설치 후 안내문은 아래와 같다.

Docroot is: /usr/local/var/www

The default port has been set in /usr/local/etc/nginx/nginx.conf to 8080 so that
nginx can run without sudo.

nginx will load all files in /usr/local/etc/nginx/servers/.

To have launchd start nginx at login:
mkdir -p ~/Library/LaunchAgents
ln -sfv /usr/local/opt/nginx/*.plist ~/Library/LaunchAgents
Then to load nginx now:
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.nginx.plist
Or, if you don't want/need launchctl, you can just run:
nginx
$ mkdir -p ~/Library/LaunchAgents
$ ln -sfv /usr/local/opt/nginx/*.plist ~/Library/LaunchAgents

Nginx 시작하기

$ nginx

노트 : 설치 후 안내문를 보면 기본 포트가 8080임을 알 수 있다. 따라서 브라우저에서 서버로 연결하기 위해서는 url 주소에 8080 포트를 추가해야 한다. 80 포트로 변경하기 위해서는 /usr/local/etc/nginx/nginx.conf 파일의 36번 코드라인의 8080을 80으로 변경한다. 80 포트로 변경한 후 nginx를 다시 실행한다. 이 때는 sudo로 실행한다.

$ sudo nginx

nginx 작동 명령을 요약하면 아래와 같다.

$ sudo nginx # 시작
$ sudo nginx -s stop # 중단
$ sudo nginx -s quit
$ sudo nginx -s reopen
$ sudo nginx -s reload # 재시작

MySQL 설치

참고 : Install MySQL on Mac OSX using Homebrew

$ brew install mysql

설치 후 안내문은 아래와 같다.

A "/etc/my.cnf" from another install may interfere with a Homebrew-built
server starting up correctly.

To connect:
mysql -uroot

To have launchd start mysql at login:
ln -sfv /usr/local/opt/mysql/*.plist ~/Library/LaunchAgents
Then to load mysql now:
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
Or, if you don't want/need launchctl, you can just run:

$ mysql.server start
$ ln -sfv /usr/local/opt/mysql/*.plist ~/Library/LaunchAgents
$ mysql.server start
$ mysql_secure_installation

노트 : Enter current password for root (enter for none): 와 같은 프롬프트가 보이면 그냥 엔터키를 치고, 이어서 나타나는 Set root password? [Y/n] 프롬프트에서는 Y 값을 입력하여 루트 비밀번호를 설정한다. Remove anonymous users? [Y/n] 프롬프트가 보이면 Y 값을 입력한다. Disallow root login remotely? [Y/n] 프롬프트에서도 Y 값을 입력한다. Remove test database and access to it? [Y/n] 프롬프트에서도 Y 값을 입력한다. Reload privilege tables now? [Y/n] 프롬프트에서도 Y 값을 입력하고 작업을 종료 한다.

참고 : 서버에서 sudo mysql.server start 명령실행시, ERROR! The server quit without updating PID file와 같은 에러가 발생하면 서버에서 sudo chmod -R 777 /usr/local/var/mysql/ 명령을 실행하면 해결된다. 이것은 웹서버로 배포시 mysql.socket 접속 에러를 유발한다. http://stackoverflow.com/questions/9624774/after-mysql-install-via-brew-i-get-the-error-the-server-quit-without-updating

ImageMagick 설치

$ brew install imagemagick

Node.js 설치

$ brew install node

배포용 사용자 계정 생성하기

1. deployer 배포 계정의 추가

레일스 프로젝트를 서버로 배포하기 위해 deployer라는 시스템 사용자 계정을 생성한다.

http://www.techradar.com/how-to/computing/apple/terminal-101-creating-new-users-1305687

노트 : 계정 삭제 How to Delete a Local User Using Command Line on Mac OS X

# 사용자계정 생성
$ LastUserID=$(dscl . -list /Users UniqueID | awk '{print $2}' | sort -n | tail -1)
$ NextUserID=$((LastUserID + 1))
$ sudo dscl . create /Users/deployer
$ sudo dscl . create /Users/deployer RealName "Rails Deployer"
$ sudo dscl . passwd /Users/deployer
$ sudo dscl . create /Users/deployer hint "Password Hint"
$ sudo dscl . create /Users/deployer UniqueID $NextUserID

# 그룹 생성
$ LastGroupID=$(dscl . readall /Groups | grep PrimaryGroupID | awk '{ print $2 }' | sort -n | tail -1)
$ NextGroupID=$(($LastGroupID + 1 ))
$ sudo dscl . create /Groups/deployer
$ sudo dscl . create /Groups/deployer RealName "Rails Deployer Group"
$ sudo dscl . create /Groups/deployer passwd "*"
$ sudo dscl . create /Groups/deployer gid $NextGroupID

# 사용자를 그룹에 등록하고 사용자 환경 셋팅
$ sudo dscl . create /Users/deployer PrimaryGroupID $NextGroupID
$ sudo dscl . create /Users/deployer UserShell $(which bash)
$ sudo dscl . create /Users/deployer NFSHomeDirectory /Users/deployer
$ sudo cp -R /System/Library/User\ Template/English.lproj /Users/deployer
$ sudo chown -R deployer:deployer /Users/deployer

로그인 화면으로부터 deployer 사용자 계정 숨기기

$ sudo defaults write /Library/Preferences/com.apple.loginwindow HiddenUsersList -array-add deployer

로그인 화면으로부터 deployer 사용자 계정 보이게 하기

$ sudo defaults delete /Library/Preferences/com.apple.loginwindow HiddenUsersList

노트 : 로컬 터미널에서 ssh로 원격 서버로 접속하기 위해서는 서버의 시스템환경설정의 공유 메뉴에서 원격로그인 항목을 선택한 후 Rails Deployer 또는 Rails Deployer Group을 추가해 주어야 한다.

ssh를 이용하여 비밀번호 없이 원격서버로 접속하기 위해서 로컬 터미널의 공개키를 원격 서버로 복사해 준다.

$ ssh-copy-id -i ~/.ssh/id_rsa.pub deployer@REMOTE_SERVER_IP

이후부터는 ssh deployer@REMOTE_SERVER_IP로 접속시 비밀번호를 입력하지 않아도 된다.

원격 서버에 deployer 계정으로 접속한 후 sudo 명령을 사용할 때 비밀번호를 입력하지 않도록 하기 위해서는 아래와 같이 명령을 실행하여 /etc/sudoers 파일을 열고,

$ sudo visudo

66번 라인에 아래와 같이 추가해 준다.

deployer ALL=(ALL) NOPASSWD= ALL

2. DB 사용자 계정의 추가

레일스 프로젝트에서 사용할 MySQL 데이터베이스에 접속하기 위한 DB 사용자 계정을 생성한다.

$ mysql --user=root -p mysql
mysql> CREATE USER 'deployer'@'localhost' IDENTIFIED BY 'some_pass';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'deployer'@'localhost';
mysql> \q # 종료

방금 생성한 계정으로 MySQL 서버로 접속해 본다.

$ mysql -u deployer -p

Unicorn 서비스 등록하기

맥 서버로 배포할 때 가장 어려웠던 것은 unicorn 서비스를 실행하는 것이었다.
우선, 맥에서 서비스(데몬)를 실행하기 위해서는 launchd이라는 오픈소스 통합 서비스 관리 프레임워크에 대한 이해가 필요하다.

참고 : Useful Mac OS X shell commands and their Linux equivalents

Mac OSX에 Unicorn 서비스 등록하기

이를 위해서 아래의 열거한 링크를 참고했고, launchd에 대해 공부한 내용을 정리해 놓았다.

launchd란?

위키피디아의 관련 내용을 참고하면 도움이 된다.

정의 : launchd은 오픈소스 통합 서비스 관리 프레임워크로써 데몬, 애플리케이션, 프로세스, 스크립트를 시작, 중단, 관리해 준다. 애플의 Dave Zarzycki가 만들었고 맥 OSX 타이거에서 처음으로 도입되어 아파치 라이센스하에 보호 받고 있다.

launchd 시스템은 두개의 프로그램으로 구성되어 있다.

1. launchd

시스템과 사용자 레벨에서 각종 데몬을 관리해 준다.
launchd은 두 가지 주요 기능을 가지고 있다.

  • 시스템 부팅
  • 각종 서비스의 로드와 관리

2. /Library/LaunchDaemons와 ~/Library/LaunchAgents

LaunchDaemons 폴더에는 루트 권한으로 백그라운드 프로세스를 실행하는 서비스 항목들이 위치한다.
LaunchAgents 폴더에는 사용자 권한으로 실행되는 에이전트 애플리케이션 작업들이 위치한다.

3. launchctl

launchd과 통신하는 커맨드라인 애플리케이션이다. launchd의 작업을 정의하는 property list 파일(.plist)을 읽어 들여 데몬을 로드하거나 언로드하여 특정 서비스 작업을 시작하거나 중단하게 된다.

launchd이 동작하는 상태에서 서비스의 제어는 launchctl 애플리케이션이 수행한다.
launchctl은 커맨드라인에서 표준입력 또는 인터액티브 상태로 직접 명령을 읽어 들이게 된다. 루트권한으로 실행할 때 시스템 전체에 변화를 줄 수 있다. /etc/launchd.conf 파일에 저장된 launchctl 명령은 영구적으로 실행될 수 있다. lauchctlIPC 방식으로 launchd과 통신하게 된다.

Property List(Plist)

plistlaunchd이 프로그램 설정을 위해 사용하는 파일이다. launchd이 특정 폴더를 스캔하거나 launchctl이 특정 작업을 실행할 때 프로그램이 실행되는 방법을 기술해 놓은 plist 파일을 읽게 된다. plist 파일에서 자주 사용하는 키는 아래와 같다.

Key Type Description
Label String The name of the job. By convention, the job label is the same as the plist file name, without the .plist extension. Required.
Program String A path to an executable. Useful for simple launches. At least one of Program orProgramArguments is required.
ProgramArguments Array of strings An array of strings representing a UNIX command. The first string is generally a path to an executable, while latter strings contain options or parameters. At least one ofProgram or ProgramArguments is required.
UserName String
(defaults to root or current user)
The job will be run as the given user, who may (or may not) be the user who submitted it to launchd.
OnDemand(Deprecated since 10.5) Boolean
(defaults to YES)
Deprecated as of 10.5 with the more powerful KeepAlive option. A boolean flag that defines if a job runs continuously or not.
RunAtLoad Boolean
(defaults to NO)
A boolean flag that defines if a task is launched immediately when the job is loaded into launchd.
StartOnMount Boolean
(defaults to NO)
A boolean flag that defines if a task is launched when a new filesystem is mounted.
QueueDirectories Array of strings Watch a directory for new files. The directory must be empty to begin with, and must be returned to an empty state before QueueDirectories will launch its task again.
WatchPaths Array of strings Watch a filesystem path for changes. Can be a file or folder.
StartInterval Integer Schedules job to run on a repeating schedule. Indicates number of seconds to wait between runs.
StartCalendarInterval Dictionary of integers
or
Array of dictionaries of integers
Job scheduling. The syntax is similar to cron.
RootDirectory String The job will be chrooted into this directory before execution.
WorkingDirectory String The job will be chdired into this directory before execution.
StandardInPath,
StandardOutPath,
StandardErrorPath
String Keys to determine files for input and output for the launched process.
LowPriorityIO Boolean Tells the kernel that this task is of a low priority when doing filesystem I/O.
AbandonProcessGroup Boolean
(defaults to NO)
A boolean flag that defines whether subprocesses launched from a task launched by launchd will be killed when the task ends. Useful where a short-lived task starts a long-lived subtask, but may result in zombie processes.

참고 : http://launchd.info

데몬이란?

사용자 입력이 필요없이 백그라운드에서 실행되는 프로그램을 말한다.

데몬과 에이전트

launchd은 데몬과 에이전트로 구분된다. 주된 차이점은, 에이전트가 로그인한 사용자의 권한으로 실행되는 반면, 데몬은 루트 사용자나 User 키로 지정한 사용자의 권한으로 실행된다는 것이다.

작업 정의

데몬 또는 에이전트의 실행동작은 프로퍼티 리스트(property list)라는 특수한 형태의 XML 파일에 정의되어 있다. 특정 작업이 저장되는 위치에 따라 데몬이 되기도 하고 에이전트가 되기도 한다.
특히, 운영시스템의 동작에 중요한 역할을 하는 작업 정의는 /System/Library 디렉토리에 저장되어 있다. 결코 이 디렉토리에 대해서 개인적인 데몬이나 에이전트를 정의해서는 안된다. 모든 사용자들에게 관련이 있는 작업에 대한 정의는 /Library 디렉토리에 저장하도록 한다. 특정 사용자에 대한 작업 정의는 해당 사용자의 ~/Library 디렉토리에 저장하도록 한다.

정의된 작업의 자동 로딩

시스템이 부팅될 때 루트 launchd 프로세스는 데몬 디렉토리인 /System/Library/LaunchDaemons/Library/LaunchDaemons에 정의된 작업을 검색하여 각 작업에 정의된 Disabled 키와 override database의 내용에 따라 해당 작업을 로드할지 결정하게 된다. 특정 사용자가 로그인하게 될 경우는 새로운 launchd 프로세스가 시작되어 에이전트 디렉토리인/System/Library/LaunchAgents, /Library/LaunchAgents, ~/Library/LaunchAgents에 정의된 작업을 검색하여 각 작업에 정의된 Disabled 키와 override database의 내용에 따라 해당 작업을 로드할지 결정하게 된다.

작업 로딩과 시작

특정 작업을 로딩한다고 해서 반드시 해당 작업이 시작되는 것은 아니다. 해당 작업의 시작여부는 작업 정의에 따라 결정된다. 즉, RunAtLoad 또는 KeepAlive가 명시되어 있는 경우에만 작업이 로딩될 때 조건에 무관하게 해당 작업이 시작된다.

lunchy 젬의 소개

레일스 배포시 필요한 애플리케이션 서버 unicorn 서비스를 맥 서버에서 편리하게 사용하도록 도와주는 젬이다.
capistrano를 이용하여 배포할 때 capistrano-unicorn-nignx 젬을 이용하면 unicornnginx 설정 파일을 편리하게 서버로 배포할 수 있는데, 필자는 이 젬에 lunchy 젬을 추가하고 몇가지 unicorn 서비스 관련 부분을 수정하여 capistrano-unicorn-nginx-osx 이라는 젬을 제작하여 rubygems.org로 배포해 놓았다.

Unicorn Plist 작성

맥 서버에서 unicorn 서비스를 launchd의 에이전트로 사용하기 위해서 plist 파일을 작성해야 한다.
파일명을 unicorn.plist.erb로 정하고 내용 중에 ‘erb’ 코드를 이용하여 배포시 사용하는 변수를 지정할 수 있도록 했다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>EnvironmentVariables</key>
  <dict>
      <key>PATH</key>
      <string>/Users/<%= fetch(:deploy_user)%>/.rbenv/shims:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
  </dict>
  <key>Label</key>
  <string>apps.<%= fetch(:application)%>.unicorn</string>
  <key>KeepAlive</key>
  <true/>
  <key>ProgramArguments</key>
  <array>
        <string>/Users/<%= fetch(:deploy_user)%>/.rbenv/shims/unicorn</string>
        <string>-c</string>
        <string>/Users/<%= fetch(:deploy_user)%>/apps/<%= fetch(:application) %>/shared/config/unicorn.rb</string>
        <string>-E</string>
        <string>production</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

여기서 사용한 :deploy_user 변수는 레일스 프로젝트의 config/deploy.rb 파일에서 지정해 놓으면 된다.(여기서는 배포 계정을 deployer로 지정했음)

# Deploy Account
set :deploy_user, 'deployer'

소스코드를 보면 알 수 있듯이 루비 버전관리자로 rbenv을 사용하였고, unicorn 젬이 설치될 때 사용하게 되는 unicorn 실행파일명 앞에 shims 경로를 추가해 주었다.

이 파일은 capistrno-unicorn-nginx-osx 젬 소스에 포함되어 있다.

또한 배포시에 이 파일을 업로드하는 코드를 아래와 같이 작성하였다.

desc 'Setup Unicorn initializer'
task :setup_initializer do
  on roles :app do
    execute :mkdir, '-pv', File.dirname(fetch(:unicorn_config))
    upload! template('unicorn.rb.erb'), fetch(:unicorn_config)
    sudo_upload! template('unicorn.plist.erb'), fetch(:unicorn_plist)
  end
end

6번 코드라인에 unicorn.plist.erb 파일을 template 메소드로 렌더링한 후 ~/Library/LaunchAgents/unicorn.plist 경로로 업로드한다.

이 소스는 capistrno-unicorn-nginx-osx 젬 파일로 업데이트되어 있다. 동일 파일 내에 :unicorn_config와 :unicorn_plist 변수가 정의되어 있다.

set :unicorn_config, -> { unicorn_default_config_file }
set :unicorn_plist, -> { unicorn_default_launchd_plist }

레일스 프로젝트의 배포 준비

이제는 배포할 프로젝트를 capistrano 젬을 이용하여 배포해 보자.

우선 Gemfile 파일을 열고 관련 젬을 추가하고 bundle install한다.

# Use Unicorn as the app server
gem 'unicorn'

# Use Capistrano for deployment
gem 'capistrano-rails', group: :development
gem 'capistrano-rbenv' # required
gem 'capistrano-rbenv-install'
gem 'capistrano-unicorn-nginx-osx', '~> 3.4.0.1' <====
gem 'capistrano-upload-config'
gem 'capistrano-safe-deploy-to'
gem 'capistrano-ssh-doctor'
gem 'capistrano-rails-console'
gem 'capistrano-rails-collection'
gem 'capistrano-rails-tail-log'
gem 'capistrano-faster-assets'
gem 'capistrano3-delayed-job', '~> 1.0'
gem 'daemons'

1. 배포용 작업 파일 생성하기

$ 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
  create Capfile
  Capified

2. Capfile의 수정

프로젝트 루트에 있는 Capfile을 열고 아래와 같이 변경한다.

# Load DSL and set up stages
require 'capistrano/setup'

# Include default deployment tasks
require 'capistrano/deploy'
# require 'capistrano/rails' or
require 'capistrano/bundler' # Rails needs Bundler, right?
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'

require 'capistrano/rbenv'
require 'capistrano/rbenv_install'
require 'capistrano/unicorn_nginx_osx'
require 'capistrano/faster_assets'
require 'capistrano/upload-config'
require 'capistrano/safe_deploy_to'
require 'capistrano/ssh_doctor'
require 'capistrano/rails/console'
require 'capistrano/rails/collection'
require 'capistrano/rails_tail_log'
# require 'capistrano/delayed-job'

# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

3. deploy.rb 파일의 수정

config/deploy.rb 파일을 열고 아래와 같이 수정한다.

# config valid only for current version of Capistrano
lock '3.4.0'

set :application, '[application-name]'
set :repo_url, "git@github.com:[user-name]/#{fetch(:application)}.git"

# Deploy Account
set :deploy_user, 'deployer'

set :deploy_to, "/home/[deployer-account]/apps/#{fetch(:application)}"

set :rbenv_type, :user # or :system, depends on your rbenv setup
set :rbenv_ruby, '2.2.2'
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 values

# Default value for :linked_files is []
set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')
set :config_files, fetch(:linked_files)
set :pty, true
set :keep_releases, 5
set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}

before 'deploy:check:linked_files', 'config:push'

# after 'deploy:published', 'restart' do
  # invoke 'delayed_job:restart'
# end

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

4. config/deploy/production.rb 파일 수정

server '[server-ip]', user: '[deploy-username]', roles: %w{web app db}

set :nginx_server_name, '[domain-name]'
set :unicorn_workers, 3

5. database.yml과 secrets.yml 파일의 별도 관리

이 두 파일의 내용은 보안상 노출되지 않도록 하는 것이 좋다. 따라서 git 저장소에 추가하지 않도록 한다. 대신에 이미 Gemfile 에 추가하여 설치한 capistrano-upload-config 젬에서 제공하는 rake 작업을 이용하여 배포시 로컬 머신의 이 두 파일을 서버로 직접 복사하도록 한다. 위의 26번 코드라인은 배포시에 이 두 파일을 서버로 직접 업로드하도록 해 준다.

아래와 같이 config/database.ymlconfig/secrets.yml 이 두 파일을 .gitignore 파일에 등록하여 git 소스관리에 포함하지 않도록 한다.

.
.
.
config/secrets.yml
config/database.yml

이제 cap production config:init 명령을 실행하여 config/database.production.ymlconfig/secrets.production.yml 파일을 생성하고 database.ymlsecrets.yml 파일로부터 내용을 복사한 후 적절하게 수정하여 사용한다. 이 때 주의할 것은 이 두 개의 파일은 git 소스관리에 포함할 것이 때문에 민감한 정보가 외부로 노출될 수 있다는 것이다. 따라서 데이터베이스 접속을 위한 database.ymlusernamepassword, 그리고 secrets.ymlproduction key 값은 시스템 환경변수에서 가져오도록 해야 한다. 이를 위해서 원격 서버로 접속한 후 sudo vi ~/.bash_profile 명령을 실행하여 3개의 환경변수를 지정한다.

DEPLOY_USERNAME=[deploy-username]
DEPLOY_PASSWORD=[deploy_password]
SECRET_KEY_BASE=[secret_key_base]

참고 : SECRET_KEY_BASE 키에 할당한 값은 로컬 터미널에서 rake secret 명령을 실행하여 얻을 수 있다.

위에서 생성한 두 개의 파일에 추가할 내용은 아래와 같다.

secrets.production.yml

production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

database.production.yml

production:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: [database-name]
  pool: 5
  username: <%= ENV['DEPLOY_USERNAME'] %>
  password: <%= ENV['DEPLOY_PASSWORD'] %>
  host: localhost

로컬 머신에서 환경변수 사용하기

로컬 머신에서도 환경변수를 편리하게 사용할 수 있다. 아래와 같이 Gemfile에 젬을 추가하고 bundle install 한다.

gem 'dotenv-rails', :groups => [:development, :test]

그리고 레일스 프로젝트 루트 디렉토리에 .env 파일을 생성하고 .gitignore 파일에 추가해서 git 에서 tracking하지 못하도록 한다. 방금 생성한 .env 파일을 열고 아래와 같이 작성한다. 잊어서는 안 될 사항은 .env 파일 역시 git 소스관리에 포함되지 않도록 해야 한다. 따라서 .gitignore 파일에 추가해 주도록 한다.

export DEPLOY_USERNAME='[user-name]'
export DEPLOY_PASSWORD='[user-password]'
export SECRET_KEY_BASE='[secret_key_base']

배포 실행

$ cap production setup
$ cap production deploy

실제 배포과정은 두 번의 명령을 실행하여 완성된다.

글쓴이: 최효성

외과전문의,웹프로그래밍,컴퓨터 일러스트레이션 / Surgeon, Medical Illustration, Web Programmer

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중