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

介绍

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

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

deploy@droplet:~$ sudo apt-get update

然后,安装Nginx:

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密钥:

deploy@droplet:~$  gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3

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

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正常运行:

deploy@droplet:~$ source ~/.rvm/scripts/rvm
deploy@droplet:~$ rvm requirements

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

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:

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 :

deploy@droplet:~$ gem install rails -v '4.2.0' -V --no-ri --no-rdoc

第五步 - 设置SSH密钥

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

deploy@droplet:~$ ssh -T git@github.com
deploy@droplet:~$ ssh -T git@bitbucket.org

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

deploy@droplet:~$ ssh-keygen -t rsa

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

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

deploy@droplet:~$ git clone git@example.com:username/appname.git

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

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

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

$ ssh-keygen -t rsa

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

$ 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

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应用程序:

$ bundle

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

$ cap install

这将创建:

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

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

Capfile

# 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

# 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

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应用程序,请提交您刚刚进行的更改,并将它们推送到本地计算机远程:

$ git add -A
$ git commit -m "Set up Puma, Nginx & Capistrano"
$ git push origin master

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

$ git config --global user.name 'Your Name'
$ git config --global user.email you@example.com

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

$ cap production deploy:initial

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

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

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

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服务:

deploy @droplet: ~$ sudo service nginx restart

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

正常部署

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

$  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》

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

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

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏kl的专栏

spring boot集成redisson的最佳实践

本文假使你了解spring boot并实践过,非spring boot用户可跳过也可借此研究一下。redisson是redis的java客户端程序,国内外很多公...

1.9K7
来自专栏iOSDevLog

iOS打包framework - Swift完整项目打包Framework,嵌入OC项目使用

--------------------------------打包篇-------------------------------****

1484
来自专栏Java帮帮-微信公众号-技术文章全总结

Nginx入门详解文档

Nginx入门详解文档 1 文章内容 掌握nginx+tomcat反向代理的使用方法。 掌握nginx作为负载均衡器的使用方法。 掌握nginx实现web缓存...

5119
来自专栏java学习

MySQL安装图解

MySQL安装图解 一、MYSQL的安装 1、打开下载的mysql安装文件mysql-5.5.27-win32.zip,双击解压缩,运行“setup.exe”。...

4376
来自专栏王硕

原 Windows 64位下 PostgreSQL的编译

38811
来自专栏Vamei实验室

Linux进程基础

计算机实际上可以做的事情实质上非常简单,比如计算两个数的和,再比如在内存中寻找到某个地址等等。这些最基础的计算机动作被称为指令 (instruction)。所谓...

2165
来自专栏程序员宝库

Linux进程基础

计算机实际上可以做的事情实质上非常简单,比如计算两个数的和,再比如在内存中寻找到某个地址等等。这些最基础的计算机动作被称为指令(instruction)。所谓的...

2264
来自专栏散尽浮华

进程管理利器-supervisor部署记录

一、简单介绍 supervisor是用来管理进程的一个工具,止于为什么要用supervisor,是因为相对于linux传统的进程管理方式来说,它有很多的优势: ...

3728
来自专栏运维

Nginx1.10.2稳定版本tcp四层负载安装配置过程略解

nginx1.10.2(2016.10.18)是最新稳定版,适合线上运行,最新开发版为1.11.8(2016.12.27)

1181
来自专栏C/C++基础

DOS常用命令大全

2010-04-17 22:27:19|  分类: 电脑技术 |  标签:dos命令大全 |字号大中小 订阅

2081

扫码关注云+社区

领取腾讯云代金券