前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用Capistrano,Nginx和Puma在Ubuntu 14.04上部署Rails应用程序

使用Capistrano,Nginx和Puma在Ubuntu 14.04上部署Rails应用程序

原创
作者头像
尘埃
修改2018-08-09 16:55:22
4.9K0
修改2018-08-09 16:55:22
举报

介绍

Rails是一个用Ruby编写的开源Web应用程序框架。Nginx是一种高性能HTTP服务器,反向代理和负载均衡器,以其并发性,稳定性,可伸缩性和低内存消耗而著称。与Nginx一样,Puma是另一个极其快速且并发的Web服务器,内存占用非常小,但是为Ruby Web应用程序构建。

Capistrano是一个远程服务器自动化工具,主要关注Ruby Web应用程序。它通过在SSH上编写任意工作流脚本,可以将Web应用程序可靠地部署到任意数量的远程计算机,并自动执行预编译和重新启动Rails服务器等常见任务。

在本教程中,我们将在Ubuntu上安装Ruby和Nginx,并在我们的Web应用程序中配置Puma和Capistrano。Nginx将用于捕获客户端请求并将其传递给正运行Rails的Puma Web服务器。我们将使用Capistrano自动执行常见的部署任务,因此每次我们必须将新版本的Rails应用程序部署到服务器时,我们都可以通过一些简单的命令来实现。

准备

要学习本教程,您必须具备以下条件:

  • Ubuntu 14.04 x64
  • 具有sudo权限以deploy命名的非root用户
  • Rails应用程序托管在可以部署的远程git存储库中

(可选)为了提高安全性,您可以通过SSH禁用root登录。

警告:禁用root登录后,请确保您可以作为部署用户SSH连接到服务器,并在关闭您打开的root SSH会话以进行这些更改之前为该用户使用sudo。

本教程中的所有命令都应以deploy用户身份运行。如果命令需要root访问权限,则前面会有sudo

第一步 - 安装Nginx

一旦服务器安全,我们就可以开始安装包了。更新包索引文件:

代码语言:txt
复制
deploy@droplet:~$ sudo apt-get update

然后,安装Nginx:

代码语言:txt
复制
deploy@droplet:~$ sudo apt-get install curl git-core nginx -y

第二步 - 安装数据库

安装您将在Rails应用程序中使用的数据库。由于有许多数据库可供选择,我们不会在本教程中介绍它们。

第三步 - 安装RVM和Ruby

我们不会直接安装Ruby。相反,我们将使用Ruby版本管理器。有很多可供选择(rbenv,chruby等),但我们将在本教程中使用RVM。RVM允许您在同一系统上轻松安装和管理多个rubies,并根据您的应用使用正确的一个。当您必须升级Rails应用程序以使用更新的ruby时,这会让生活变得更加轻松。

在安装RVM之前,您需要导入RVM GPG密钥:

代码语言:txt
复制
deploy@droplet:~$  gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3

然后安装RVM来管理我们的Rubies:

代码语言:txt
复制
deploy@droplet:~$  curl -sSL https://get.rvm.io | bash -s stable

此命令使用curlhttps://get.rvm.io中下载RVM安装脚本。-sSL选项由三个标志组成:

  • -s 告诉curl以“silent mode”下载文件
  • -S 告诉curl如果失败则显示错误消息
  • -L 告诉curl在检索安装脚本时遵循所有HTTP重定向

下载后,脚本将传到bash-s选项将stable作为参数传递给RVM安装脚本,以下载和安装RVM的稳定版本。

注意:如果第二个命令失败并显示消息“GPG签名验证失败”,则表示GPG密钥已更改,只需从错误输出中复制命令并运行它以下载签名。然后运行用于RVM安装的curl命令。

我们需要加载RVM脚本(作为一个函数),以便我们可以开始使用它。然后,我们需要运行requirements命令来自动安装所需的依赖项和文件,以便RVM和Ruby正常运行:

代码语言:txt
复制
deploy@droplet:~$ source ~/.rvm/scripts/rvm
deploy@droplet:~$ rvm requirements

我们现在可以安装我们选择的Ruby。我们将安装最新的Ruby 2.2.1(在撰写本文时)作为我们的默认Ruby:

代码语言:txt
复制
deploy@droplet:~$ rvm install 2.2.1
deploy@droplet:~$ rvm use 2.2.1 --default

第四步 - 安装Rails和Bundler

一旦设置了Ruby,我们就可以开始安装Rubygems了。我们首先安装Rails gem,它将允许你的Rails应用程序运行,然后我们将安装bundler,它可以读取你的应用程序的Gemfile并自动安装所有必需的gem。

要安装Rails和Bundler:

代码语言:txt
复制
deploy@droplet:~$ gem install rails -V --no-ri --no-rdoc
deploy@droplet:~$ gem install bundler -V --no-ri --no-rdoc

使用了三个标志:

  • -V (详细输出):打印有关Gem安装的详细信息
  • --no-ri - (Skips Ri文档):不安装Ri Docs,节省空间并快速安装
  • --no-rdoc - (跳过RDocs):不安装RDocs,节省空间并加快安装速度

注意:您还可以使用以下-v标志根据您的要求安装特定版本的Rails :

代码语言:txt
复制
deploy@droplet:~$ gem install rails -v '4.2.0' -V --no-ri --no-rdoc

第五步 - 设置SSH密钥

由于我们要设置流畅的部署,因此我们将使用SSH密钥进行授权。首先与GitHub,Bitbucket或任何其他Gits Remote握手,在Gits Remote中托管Rails应用程序的代码库:

代码语言:txt
复制
deploy@droplet:~$ ssh -T git@github.com
deploy@droplet:~$ ssh -T git@bitbucket.org

如果收到Permission denied (publickey)消息,请不要担心。现在,为您的服务器生成SSH密钥(公钥/私钥对):

代码语言:txt
复制
deploy@droplet:~$ ssh-keygen -t rsa

将新创建的公钥(~/.ssh/id_rsa.pub)添加到存储库的部署密钥:

如果所有步骤都已正确完成,您现在应该能够在不输入密码的情况下您的clonegit存储库(通过SSH协议,而不是HTTP):

代码语言:txt
复制
deploy@droplet:~$ git clone git@example.com:username/appname.git

clone命令将创建一个与您的应用程序同名的目录。例如,将创建一个名为testapp_rails的目录。

我们只是克隆以检查我们的部署密钥是否正常工作,每次推送新更改时我们都不需要克隆或拉取我们的存储库。我们将让Capistrano为我们处理所有这些。您现在可以删除此克隆目录。

在本地计算机上打开终端。如果您没有本地计算机的SSH密钥,也可以为其创建一个。在您的本地终端会话中:

代码语言:txt
复制
$ ssh-keygen -t rsa

将本地SSH密钥添加到服务器的授权密钥文件中(请记住将端口号替换为您的自定义端口号):

代码语言:txt
复制
$ cat ~/.ssh/id_rsa.pub | ssh -p your_port_num deploy@your_server_ip 'cat >> ~/.ssh/authorized_keys'

第六步 - 在Rails应用程序中添加部署配置

在本地计算机上,在Rails应用程序中为Nginx和Capistrano创建配置文件。首先将这些行添加到Gemfile Rails应用程序中:

Gemfile

代码语言:txt
复制
group :development do
    gem 'capistrano',         require: false
    gem 'capistrano-rvm',     require: false
    gem 'capistrano-rails',   require: false
    gem 'capistrano-bundler', require: false
    gem 'capistrano3-puma',   require: false
end

gem 'puma'

使用bundler安装您在Gemfile中指定的gem。 输入以下命令来捆绑您的Rails应用程序:

代码语言:txt
复制
$ bundle

捆绑后,运行以下命令配置Capistrano:

代码语言:txt
复制
$ cap install

这将创建:

  • Capfile 在您的Rails应用程序的根目录中
  • deploy.rb文件在config目录中
  • deploy目录在config目录中

用以下内容替换Capfile的内容:

Capfile

代码语言:txt
复制
# Load DSL and Setup Up Stages
require 'capistrano/setup'
require 'capistrano/deploy'

require 'capistrano/rails'
require 'capistrano/bundler'
require 'capistrano/rvm'
require 'capistrano/puma'

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

Capfile会将一些预定义的任务加载到您的Capistrano配置文件中,以使您的部署没有顾虑,例如自动地:

  • 选择正确的Ruby
  • 预编译
  • 将您的Git存储库克隆到正确的位置
  • Gemfile更改后安装新的依赖项

使用以下内容替换config/deploy.rb的内容

config/ deploy.rb

代码语言:txt
复制
# Change these
server 'your_server_ip', port: your_port_num, roles: [:web, :app, :db], primary: true

set :repo_url,        'git@example.com:username/appname.git'
set :application,     'appname'
set :user,            'deploy'
set :puma_threads,    [4, 16]
set :puma_workers,    0

# Don't change these unless you know what you're doing
set :pty,             true
set :use_sudo,        false
set :stage,           :production
set :deploy_via,      :remote_cache
set :deploy_to,       "/home/#{fetch(:user)}/apps/#{fetch(:application)}"
set :puma_bind,       "unix://#{shared_path}/tmp/sockets/#{fetch(:application)}-puma.sock"
set :puma_state,      "#{shared_path}/tmp/pids/puma.state"
set :puma_pid,        "#{shared_path}/tmp/pids/puma.pid"
set :puma_access_log, "#{release_path}/log/puma.error.log"
set :puma_error_log,  "#{release_path}/log/puma.access.log"
set :ssh_options,     { forward_agent: true, user: fetch(:user), keys: %w(~/.ssh/id_rsa.pub) }
set :puma_preload_app, true
set :puma_worker_timeout, nil
set :puma_init_active_record, true  # Change to false when not using ActiveRecord

## Defaults:
# set :scm,           :git
# set :branch,        :master
# set :format,        :pretty
# set :log_level,     :debug
# set :keep_releases, 5

## Linked Files & Directories (Default None):
# set :linked_files, %w{config/database.yml}
# set :linked_dirs,  %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}

namespace :puma do
  desc 'Create Directories for Puma Pids and Socket'
  task :make_dirs do
    on roles(:app) do
      execute "mkdir #{shared_path}/tmp/sockets -p"
      execute "mkdir #{shared_path}/tmp/pids -p"
    end
  end

  before :start, :make_dirs
end

namespace :deploy do
  desc "Make sure local git is in sync with remote."
  task :check_revision do
    on roles(:app) do
      unless `git rev-parse HEAD` == `git rev-parse origin/master`
        puts "WARNING: HEAD is not the same as origin/master"
        puts "Run `git push` to sync changes."
        exit
      end
    end
  end

  desc 'Initial Deploy'
  task :initial do
    on roles(:app) do
      before 'deploy:restart', 'puma:start'
      invoke 'deploy'
    end
  end

  desc 'Restart application'
  task :restart do
    on roles(:app), in: :sequence, wait: 5 do
      invoke 'puma:restart'
    end
  end

  before :starting,     :check_revision
  after  :finishing,    :compile_assets
  after  :finishing,    :cleanup
  after  :finishing,    :restart
end

# ps aux | grep puma    # Get puma pid
# kill -s SIGUSR2 pid   # Restart puma
# kill -s SIGTERM pid   # Stop puma

deploy.rb文件包含一些初始情况下的默认设置,可帮助您管理应用程序版本并在进行部署时自动执行某些任务:

  • 使用production作为Rails应用程序的默认环境
  • 自动管理应用的多个版本
  • 使用优化的SSH选项
  • 检查您的git遥控器是否是最新的
  • 管理您应用的日志
  • 在管理Puma工作人员时将应用程序预加载到内存中
  • 完成部署后启动(或重新启动)Puma服务器
  • 在发行版中的特定位置打开Puma服务器的套接字

您可以根据需要更改所有选项。现在,需要配置Nginx。在您的Rails项目目录中创建config/nginx.conf,并向其添加以下内容(再次,替换为您的参数):

config/ nginx.conf

代码语言:txt
复制
upstream puma {
  server unix:///home/deploy/apps/appname/shared/tmp/sockets/appname-puma.sock;
}

server {
  listen 80 default_server deferred;
  # server_name example.com;

  root /home/deploy/apps/appname/current/public;
  access_log /home/deploy/apps/appname/current/log/nginx.access.log;
  error_log /home/deploy/apps/appname/current/log/nginx.error.log info;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  try_files $uri/index.html $uri @puma;
  location @puma {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    proxy_pass http://puma;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 10M;
  keepalive_timeout 10;
}

与前一个文件一样,它nginx.conf包含的默认值与deploy.rb文件中的配置一样立即可用。这会侦听端口80上的流量并将请求传递给您的Puma套接字,将nginx日志写入应用程序的“当前”版本,压缩所有资产并在浏览器中将其缓存到最大到期时间,在公共场合提供HTML页面文件夹作为静态文件,并设置默认的最大值Client Body SizeRequest Timeout值。

第七步 - 部署Rails应用程序

如果您使用自己的Rails应用程序,请提交您刚刚进行的更改,并将它们推送到本地计算机远程:

代码语言:txt
复制
$ git add -A
$ git commit -m "Set up Puma, Nginx & Capistrano"
$ git push origin master

注意:如果这是第一次使用此系统中的GitHub,您可能必须使用GitHub用户名和电子邮件地址发出以下命令:

代码语言:txt
复制
$ git config --global user.name 'Your Name'
$ git config --global user.email you@example.com

再次,从您的本地计算机,进行首次部署:

代码语言:txt
复制
$ cap production deploy:initial

这会将您的Rails应用程序推送到服务器上,为您的应用程序安装所有必需的gem,并启动Puma Web服务器。这可能需要5-15分钟,具体取决于您的应用使用的Gems数量。在此过程发生时,您将看到调试消息。

如果一切顺利,我们现在准备将您的Puma Web服务器连接到Nginx反向代理。

nginx.conf符号链接到sites-enabled目录:

代码语言:txt
复制
deploy@droplet:~$ sudo rm /etc/nginx/sites-enabled/default
deploy@droplet:~$ sudo ln -nfs "/home/deploy/apps/appname/current/config/nginx.conf" "/etc/nginx/sites-enabled/appname"

重启Nginx服务:

代码语言:txt
复制
deploy @droplet: ~$ sudo service nginx restart

您现在应该可以将Web浏览器指向您的服务器IP并查看您的Rails应用程序了!

正常部署

每当您对应用程序进行更改并希望将新版本部署到服务器时,提交更改,像往常一样推送到git remote,然后运行deploy命令:

代码语言:txt
复制
$  git add -A
$  git commit -m "Deploy Message"
$  git push origin master
$  cap production deploy

注意:如果您对config/nginx.conf文件进行了更改,则在部署应用程序后,您必须在服务器上重新加载或重新启动Nginx服务:

deploy@droplet:~$ sudo service nginx restart

结论

现在你将在你的服务器上运行一个Rails应用程序,Puma作为你的Web服务器,以及配置了基本设置的Nginx和Capistrano。更多服务器配置的教程请前往腾讯云+社区学习相关内容。


参考文献:《Deploying a Rails App on Ubuntu 14.04 with Capistrano, Nginx, and Puma》

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
  • 准备
  • 第一步 - 安装Nginx
  • 第二步 - 安装数据库
  • 第三步 - 安装RVM和Ruby
  • 第四步 - 安装Rails和Bundler
  • 第五步 - 设置SSH密钥
  • 第六步 - 在Rails应用程序中添加部署配置
  • 第七步 - 部署Rails应用程序
  • 正常部署
  • 结论
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档