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应用程序部署到服务器时,我们都可以通过一些简单的命令来实现。
要学习本教程,您必须具备以下条件:
(可选)为了提高安全性,您可以通过SSH禁用root登录。
警告:禁用root登录后,请确保您可以作为部署用户SSH连接到服务器,并在关闭您打开的root SSH会话以进行这些更改之前为该用户使用sudo。
本教程中的所有命令都应以deploy
用户身份运行。如果命令需要root访问权限,则前面会有sudo
。
一旦服务器安全,我们就可以开始安装包了。更新包索引文件:
deploy@droplet:~$ sudo apt-get update
然后,安装Nginx:
deploy@droplet:~$ sudo apt-get install curl git-core nginx -y
安装您将在Rails应用程序中使用的数据库。由于有许多数据库可供选择,我们不会在本教程中介绍它们。
我们不会直接安装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
此命令使用curl
从https://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
一旦设置了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密钥进行授权。首先与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应用程序中为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配置文件中,以使您的部署没有顾虑,例如自动地:
使用以下内容替换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应用程序的默认环境您可以根据需要更改所有选项。现在,需要配置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 Size
和Request Timeout
值。
如果您使用自己的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》
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。