如何使用 Capistrano 自動部署 Ruby On Rails 應用程式

介紹


如果您尚未厭倦重複執行相同乏味任務以更新應用伺服器以使項目上線,您可能最終會感到厭倦。在開發項目時感到的喜悅往往會在系統管理的無聊部分時受到影響(例如上傳代碼庫、修改配置、反覆執行命令等)

但請勿害怕!任務自動化工具Capistrano在此處可派上用場。

在這篇DigitalOcean文章中,我們將創建一個堅固的伺服器設置,運行最新版本的CentOS來托管使用Nginx和Passenger的Ruby on Rails應用程序。我們將繼續學習如何使用基於Ruby的自動化工具Capistrano自動化部署和更新過程。

注意:本文基於我們先前的 Capistrano 文章中的知識:使用 Capistrano 自動化部署:入門指南。為了充分了解這個工具,強烈建議您在繼續閱讀本文之前先閱讀它。同樣地,如果您想要了解有關使用 Passenger(和 Nginx)為 Rails 應用程序部署準備一個新的 droplet,請查看如何使用 Passenger 和 Nginx 部署 Rails 應用程序文章。

注意:Capistrano 依賴於 Git 進行部署。要了解更多,請閱讀 DigitalOcean 社區文章,點擊這裡

術語表


1. 準備部署服務器


  1. 更新和準備操作系統
  2. 設置 Ruby 環境和 Rails
  3. 下載並安裝應用程序及 HTTP 服務器
  4. 創建 Nginx 管理腳本
  5. 配置 Nginx 進行應用部署
  6. 下載並安裝 Capistrano
  7. 為部署創建系統用戶

2. 為基於 Git 的 Capistrano 部署準備 Rails 應用程序


  1. 創建基本的 Ruby-On-Rails 應用程序
  2. 創建 Git 存儲庫

3. 使用 Capistrano 自動化部署


  1. 在項目目錄中安裝 Capistrano
  2. 在項目目錄中使用 config/deploy.rb
  3. 在項目目錄中使用 config/deploy/production.rb
  4. 部署到生產服務器

準備部署服務器


注意:為了更好地理解以下部分,可以視為一個詳細摘要,請查閱有關主題的完整文章:如何使用Nginx部署Rails應用程序使用Passenger

更新和準備操作系統


執行以下命令以更新基於CentOS的droplet的默認工具:

yum -y update

通過執行以下命令安裝包含開發工具的捆綁包:

yum groupinstall -y 'development tools'

本教程所需的一些套件(例如libyaml-devel、nginx等)在官方CentOS存儲庫中找到。

運行以下命令以添加EPEL存儲庫:

sudo su -c 'rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm'

yum -y update

最後,為了安裝一些額外的庫和工具,執行以下命令:

yum install -y curl-devel nano sqlite-devel libyaml-devel

設置Ruby環境和Rails


注意:本部分是我們專門文章如何在CentOS 6.5上安裝Ruby 2.1.0的摘要。

運行以下兩個命令來安裝 RVM 並為 Ruby 創建系統環境:

curl -L get.rvm.io | bash -s stable

source /etc/profile.d/rvm.sh
rvm reload
rvm install 2.1.0

由於 Rails 需要 JavaScript 解析器,我們還需要設置 Node.js。

運行以下命令使用 yum 下載並安裝 nodejs:

yum install -y nodejs

使用 RubyGems 的 gem 執行以下命令來下載並安裝 rails

gem install bundler rails

下載並安裝應用程序及 HTTP 服務器


注意:如果您的 VPS 內存少於 1 GB,您需要執行以下簡單的步驟來準備一個 SWAP 磁盤空間,用作臨時數據持有者(RAM 替代品)。由於 DigitalOcean 服務器配備了快速的 SSD 硬盤,這在執行服務器應用程序安裝任務時並不是真正的問題。

# 創建 1024 MB 的 SWAP 空間
sudo dd if=/dev/zero of=/swap bs=1M count=1024
sudo mkswap /swap
sudo swapon /swap

Phusion Passenger


紅帽 Linux 的默認包管理器 RPM(RPM Package Manager)使用包含在 .rpm 文件中的應用程序。不幸的是,在 Passenger 的情況下,它們相當過時。因此,我們將再次使用 RubyGem 來下載並安裝最新可用版本的 Passenger – 版本 4

使用以下命令简单下载并安装Passenger:

gem install passenger

Nginx


注意:通常,要下载并安装Nginx,您可以添加EPEL存储库(我们已经完成了),然后通过yum获取Nginx。然而,要使Nginx与Passenger一起工作,必须使用必要的模块编译其源代码。

运行以下命令开始编译带有本机Passenger模块的Nginx:

passenger-install-nginx-module

运行命令后,按Enter键确认您选择的语言(在我们的情况下为Ruby)。您可以使用箭头键和空格键仅选择Ruby。

Use <space> to select.
If the menu doesn't display correctly, ensure that your terminal supports UTF-8.

 ‣ ⬢  Ruby
   ⬢  Python
   ⬢  Node.js
   ⬡  Meteor

在下一步中,选择Item 1

1. Yes: download, compile and install Nginx for me. (recommended)
    The easiest way to get started. A stock Nginx 1.4.4 with Passenger
    support, but with no other additional third party modules, will be
    installed for you to a directory of your choice.

然后按Enter键继续。

现在,将下载、编译和安装带有Passenger支持的Nginx源代码。

注意:此操作可能需要一些时间 – 可能比人们期望的要长!

创建Nginx管理脚本


编译Nginx后,为了方便控制,我们需要创建一个简单的管理脚本。

运行以下命令以创建脚本:

nano /etc/rc.d/init.d/nginx

复制并粘贴以下内容:

#!/bin/sh
. /etc/rc.d/init.d/functions
. /etc/sysconfig/network
[ "$NETWORKING" = "no" ] && exit 0

nginx="/opt/nginx/sbin/nginx"
prog=$(basename $nginx)

NGINX_CONF_FILE="/opt/nginx/conf/nginx.conf"

lockfile=/var/lock/subsys/nginx

start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

restart() {
    configtest || return $?
    stop
    start
}

reload() {
    configtest || return $?
    echo -n $”Reloading $prog: ”
    killproc $nginx -HUP
    RETVAL=$?
    echo
}

force_reload() {
    restart
}

configtest() {
    $nginx -t -c $NGINX_CONF_FILE
}

rh_status() {
    status $prog
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit 2
esac

按下CTRL+X,然後確認按Y以保存並退出。

將此管理腳本的模式設置為可執行:

chmod +x /etc/rc.d/init.d/nginx

配置用於應用部署的Nginx


在配置我們的服務器的最後一步中,我們需要創建一個Nginx服務器塊,這大致相當於Apache的虛擬主機。

您可能還記得在安裝Passenger的Nginx期間看到的,此過程包括將一段代碼添加到Nginx的配置文件 nginx.conf 中。默認情況下,除非另有說明,否則此文件可在 /opt/nginx/conf/nginx.conf 下找到。

輸入以下命令以使用文本編輯器nano打開此配置文件進行編輯:

nano /opt/nginx/conf/nginx.conf

作為第一步,找到http {節點,並在passenger_rootpassenger_ruby指令之後添加以下內容:

# 僅供開發目的。
# 上傳實際應用程序時,請刪除此行。
# 仅供 * 測試 * 用途。
passenger_app_env development;    

滾動文件並找到server { ..。將默認位置註釋掉,即:

..

#    location / {
#            root   html;
#            index  index.html index.htm;
#        }

..

並定義您的默認應用程序根目錄:

# 設置部署應用程序的文件夾。
# 我們使用的是:/home/deployer/apps/my_app
root              /home/deployer/apps/my_app/public;
passenger_enabled on;

按下CTRL+X,並確認按Y保存並退出。

運行以下命令重新加載帶有新應用程序配置的 Nginx:

# !! 請記得創建一個 Nginx 管理腳本
#    通過按照 CentOS 上的主要 Rails 部署文章
#    連接到本節開頭。

/etc/init.d/nginx restart

要檢查 Nginx 的狀態,您可以使用:

/etc/init.d/nginx status

注意:要了解有關 Nginx 的更多信息,請參閱 如何在 VPS 上配置 Nginx Web 服務器

下載並安裝 Capistrano


一旦我們的系統準備好,通過 RubyGems 獲取 Capistrano 的最新版本非常容易。

您可以簡單地使用以下命令獲取 Capistrano 版本 3:

gem install capistrano

為部署創建系統用戶


在這一步,我們將創建一個 CentOS 系統用戶來執行部署操作。這將是 Capistrano 使用的用戶。

注意:為了保持基本的設置,我們將創建一個具有必要特權的 deployer 用戶。對於更完整的設置,請考慮使用 Capistrano 入門教程中的 groups 示例。

創建一個新的系統用戶 deployer

adduser deployer

設置 deployer 的密碼:

passwd deployer

# 輸入密碼
# 確認密碼

使用文本編輯器 nano 編輯 /etc/sudoers

nano /etc/sudoers

滾動文件並找到 root 的定義處:

..

## COMMANDS 部分可能添加其他選項。
##
## 允許 root 在任何地方運行任何命令
root    ALL=(ALL)	ALL

..

root ALL=(ALL) ALL 之後添加以下內容:

deployer ALL=(ALL) ALL

此處的 /etc/sudoers 文件現在應該如下所示:

..

## COMMANDS 部分可能添加其他選項。
##
## 允許 root 在任何地方運行任何命令
root     ALL=(ALL)	ALL
deployer ALL=(ALL) ALL

..

按下 CTRL+X 然後確認 Y 保存並退出。

為 Git-Based Capistrano 部署準備 Rails 應用程序


一旦我們的系統準備好,所有必要的應用程序都已設置並正常運作,我們就可以繼續創建一個示例的 Rails 應用程序,作為樣本使用。

在第二階段,我們將創建一個 Git 存儲庫,並將代碼庫推送到 GitHub 上的中央位置,供 Capistrano 用於部署。

注意: 在這裡,我們正在創建一個示例應用程序。對於實際的部署,您應該確保在自己的系統上執行這些操作,並確保一切都有備份 – 以防萬一! 另外,請注意,您需要從與應用程序部署所在的服務器不同的位置運行 Capistrano。

創建一個基本的 Ruby-On-Rails 應用程序


注意: 下面的步驟是為了創建一個替代的 Rails 應用程序,以嘗試 Capistrano。

已經安裝了 Ruby 和 Rails,我們只需要一個命令就可以開始。

執行以下命令以讓 Rails 創建一個名為 my_app 的新應用程序:

# 創建一個示例的 Rails 應用程序
rails new my_app

# 進入應用程序目錄
cd my_app

# 創建一個示例資源
rails generate scaffold Task title:string note:text

# 創建一個示例數據庫
RAILS_ENV=development rake db:migrate

為了測試您的應用程式是否設定正確並且一切運作正常,請進入應用程式目錄並運行一個簡單的伺服器通過rails s

# 進入應用程式目錄
cd my_app

# 運行一個簡單的伺服器
rails s

# 您現在應該能夠通過
# 訪問:http://[您的 droplet's IP]:3000

# 終止伺服器進程,
# 按 CTRL+C

創建 Git 倉庫


注意:要了解更多有關使用 Git 的資訊,請查看 DigitalOcean 社區頁面上的如何有效使用 Git教程。

注意:為了跟隨本部分,您需要一個 Github 帳戶。或者,您可以設置一個 droplet 來托管您自己的 Git 倉庫,並參照這篇DigitalOcean 文章上的相關 URL 進行部署文件。如果您選擇這樣做,請確保在部署文件中使用相關的 URL。

我們將使用Github提供的示例指令來創建源倉庫。

my_app目錄中執行以下自解釋命令來初始化一個倉庫:

# !!這些命令需要在
#您的開發機器上執行,從那裡您將
#部署到您的伺服器。
#根據
#您的操作系統的選擇,指示可能會略有不同。
#
#請確保為應用程序設置正確的路徑
#否則,Nginx可能無法找到它。

#初始化存儲庫
git init

#將所有文件添加到存儲庫
git add .

#提交更改
git commit -m "first commit"

#添加您的 Github 存儲庫鏈接 
#示例:git remote add origin [email protected]:[用戶名]/[項目名稱].git
git remote add origin [email protected]:user123/my_app.git

#創建 RSA/SSH 金鑰
#按照屏幕上的說明進行操作
ssh-keygen -t rsa

#查看金鑰的內容並將其添加到您的 Github
#通過從當前遠程會話中複製並粘貼
#訪問:https://github.com/settings/ssh
#了解有關此過程的更多信息,
#請訪問:https://help.github.com/articles/generating-ssh-keys
cat /root/.ssh/id_rsa.pub

#設置您的 Github 信息
# Username:
#用法:git config --global user.name "[您的用戶名]"
git config --global user.name "user123"

# Email:
#用法:git config --global user.email "[您的電子郵件]"
git config --global user.email "[email protected]"

#將項目的源代碼推送到您的 Github 帳戶
git push -u origin master

使用 Capistrano 自動化部署


正如您從我們的第一篇 Capistrano 文章中記得的那樣,開始使用這個庫的方法是將其安裝在專案目錄中。在本節中,我們將看到如何執行此操作,然後創建需要設置服務器的文件。

在專案目錄內安裝 Capistrano


我們文章中的另一個簡單步驟是安裝 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

在專案目錄中使用 config/deploy.rb


檔案 deploy.rb 包含與部署伺服器相關的參數和設定。在這裡,我們將告訴 Capistrano 我們想要連接和部署到哪些伺服器,以及如何執行。

注意: 當編輯檔案(或定義配置)時,您可以將它們註釋掉或添加新行。請確保不要有一些範例設定覆蓋您正在添加的設定。

執行以下命令使用 nano 文本編輯器編輯檔案:

nano config/deploy.rb

添加下面的程式碼塊,並根據您自己的設定進行修改:

# 定義應用程式的名稱
set :application, 'my_app'

# 定義 Capistrano 可以訪問源代碼庫的位置
# set :repo_url, 'https://github.com/[user name]/[application name].git'
set :scm, :git
set :repo_url, 'https://github.com/user123/my_app.git'

# 定義應用程式代碼的放置位置
set :deploy_to, "/home/deployer/apps/my_app"

set :pty, true

set :format, :pretty

# 在這裡設置部署後的指令。
# 部署完成後,Capistrano
# 將根據描述執行這些指令。
# 要了解更多關於創建任務的資訊,
# 請查看:
# http://capistranorb.com/

# namespace: deploy do

#   desc 'Restart application'
#   task :restart do
#     on roles(:app), in: :sequence, wait: 5 do
#       # 這裡是你的重新啟動機制,例如:
#       execute :touch, release_path.join('tmp/restart.txt')
#     end
#   end

#   after :publishing, :restart

#   after :restart, :clear_cache do
#     on roles(:web), in: :groups, limit: 3, wait: 10 do
#       # 在這裡我們可以做任何事情,例如:
#       # 在 release_path 內
#       #   execute :rake, 'cache:clear'
#       # end
#     end
#   end

# end

按 CTRL+X 然後確認 Y 以保存並退出。

在項目目錄中使用 config/deploy/production.rb


注意:deploy.rb 類似,您需要對 production.rb 文件進行一些修改。最好修改代碼而不是附加以下塊。

運行以下命令使用 nano 文本編輯器編輯文件:

nano config/deploy/production.rb

輸入您服務器的設置,類似如下:

# 定義角色、用戶和部署服務器的IP地址
# role :name, %{[user]@[IP adde.]}
role :app, %w{[email protected]}
role :web, %w{[email protected]}
role :db,  %w{[email protected]}

# 定義服務器
server '162.243.74.190', user: 'deployer', roles: %w{web}

# SSH 選項
# 更多選項請參見文件中的已注釋示例部分
# 。
set :ssh_options, {
    forward_agent: false,
    auth_methods: %w(password),
    password: 'user_deployers_password',
    user: 'deployer',
}

按下 CTRL+X 確認後輸入 Y 保存並退出。

部署到生產服務器


設置完成後,就是部署的時間了。

在開發機器上運行以下代碼即可部署到生產服務器。如上文件中所定義,Capistrano 將:

  • 連接到部署服務器

  • 下載應用程式原始碼

  • 執行部署動作(例如,重新啟動應用程式)

cap production deploy

要了解更多有關 Capistrano 及其功能的資訊,請考慮閱讀Capistrano 文件

<div class=“author”>提交者:<a
href=“https://twitter.com/ostezer”>O.S. Tezer</a></div>

Source:
https://www.digitalocean.com/community/tutorials/how-to-automate-ruby-on-rails-application-deployments-using-capistrano