如何使用Capistrano自动化Ruby On Rails应用程序部署

介绍


如果你还没有厌倦重复相同的单调任务来更新你的应用服务器以将你的项目上线,那么你可能最终会感到厌烦。在开发项目时所感受到的快乐往往会在进行系统管理的乏味部分时受到影响(例如上传你的代码库、修改配置、反复执行命令等)。

但是不要担心!任务自动化工具Capistrano来帮忙了。

在这篇DigitalOcean文章中,我们将创建一个稳固可靠的服务器设置,运行最新版本的CentOS来托管Ruby on Rails应用程序,使用Nginx和Passenger。我们将继续学习如何使用基于Ruby的自动化工具Capistrano来自动化部署和更新过程。

注意:本文基于我们过去的 Capistrano 文章中的知识:使用 Capistrano 自动化部署:入门指南。为了对这个工具有一个良好的了解,强烈建议您在继续阅读本文之前阅读它。同样,如果您想了解如何为基于 Rails 的应用程序部署准备一个新的 droplet 并使用 Passenger(和 Nginx),请查看如何使用 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. 部署到生产服务器

准备部署服务器


注意: 为了更好地理解下面的部分,可以将其视为一份详尽的摘要,查看有关此主题的完整文章:如何使用Passenger和Nginx部署Rails应用

更新和准备操作系统


运行以下命令来更新基于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内存小于1GB,则需要执行以下简单过程来准备一个SWAP磁盘空间,以用作临时数据保存器(RAM替代品)。由于DigitalOcean服务器配备了快速SSD硬盘,因此在执行服务器应用程序安装任务时,这并不构成问题。

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

Phusion Passenger


Red Hat 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

在下一步中,选择 项目 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 继续。

现在,Nginx 源代码将会被下载、编译并安装,同时支持 Passenger。

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

创建 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管理脚本
#    通过按照本节开头链接的主要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定义的位置:

..

## 命令部分可能添加了其他选项。
##
## 允许root在任何地方运行任何命令
root    ALL=(ALL)	ALL

..

root ALL=(ALL) ALL之后添加以下内容:

deployer ALL=(ALL) ALL

现在/etc/sudoers文件的这一部分应该是这样的:

..

## 命令部分可能添加了其他选项。
##
## 允许root在任何地方运行任何命令
root     ALL=(ALL)	ALL
deployer ALL=(ALL) ALL

..

按下CTRL+X并确认Y以保存并退出。

为基于Git的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 的 IP]:3000

# 为了终止服务器进程,
# 按下 CTRL+C

创建 Git 仓库


注意:要了解更多关于使用 Git 的信息,请查看 DigitalOcean 社区页面上的如何有效使用 Git教程。

注意:为了遵循本节内容,您需要一个 Github 帐户。或者,您可以设置一个 droplet 来托管您自己的 Git 仓库,按照 DigitalOcean 文章上的指南。如果选择这样做,请确保在部署文件中使用相关的 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/[用户名]/[应用程序名称].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 '重新启动应用程序'

  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