简介
Rails是一个用Ruby编写的开源Web应用程序框架。它遵循配置哲学上的约定,假设有最佳
的做事方式。这允许您编写更少的代码,同时完成更多的工作,而不必经历无数的配置文件。
Nginx是一个高性能的HTTP服务器、反向代理和负载均衡器,以其对并发性、稳定性、可伸缩性和低内存消耗的关注而闻名。和Nginx一样,Puma是另一个速度极快的并发Web服务器,内存占用非常小,但它是为Ruby Web应用程序构建的。
Capstrano是一个远程服务器自动化工具,主要专注于Ruby Web应用程序。它用于通过SSH编写任意工作流脚本,将Web应用可靠地部署到任意数量的远程计算机上,并自动执行常见任务,如资产预编译和重启Rails服务器。
在本教程中,我们将在DigitalOcean Ubuntu Drop上安装Ruby和Nginx,并在我们的Web应用程序中配置Puma和Capstrano。Nginx将用于捕获客户端请求,并将其传递给运行Rails的彪马Web服务器。我们将使用Capstrano自动执行常见的部署任务,所以每次我们必须将新版本的Rails应用程序部署到服务器上时,我们都可以通过几个简单的命令来完成。
前提条件
要遵循本教程,您必须具备以下条件:
- Ubuntu 14.04 x64 Drop
- 拥有sudo权限的非根用户
14.04](https://andsky.com/tech/tutorials/initial-server-setup-with-ubuntu-14-04)
([Ubuntu初始服务器设置]解释了如何设置。) - 托管在准备部署的远程Git存储库中的工作Rails应用程序
或者,为了提高安全性,您可以禁用通过SSH的root登录并更改SSH端口号,如使用Ubuntu 14.04进行初始服务器设置中所述。
<$>[警告]
警告: 关闭根登录后,请确保您可以以ploy
用户的身份SSH到您的Droplet,并在_关闭您打开的根SSH会话之前使用sudo
来进行这些更改。
<$>
本教程中的所有命令都应以ploy
用户身份运行。如果该命令需要超级用户访问权限,则前面会有sudo
。
Step 1-安装Nginx
一旦VPS安全,我们就可以开始安装包了。更新程序包索引文件:
1sudo apt-get update
然后,安装Nginx:
1sudo apt-get install curl git-core nginx -y
第二步-安装数据库
安装您将在Rails应用程序中使用的数据库。由于有很多数据库可供选择,因此我们不会在本指南中介绍它们。你可以在这里看到主要问题的说明:
也一定要看看:
- 如何在Ubuntu 14.04上将MySQL与您的Ruby on rails应用程序一起使用
- 如何在Ubuntu 14.04上将PostgreSQL与Ruby on rails应用程序一起使用
第三步-安装RVM和Ruby
我们不会直接安装Ruby。相反,我们将使用Ruby版本管理器。它们有很多可供选择(rbenv、chruby等),但在本教程中我们将使用RVM。RVM允许您轻松地在同一系统上安装和管理多个红宝石,并根据您的应用程序使用正确的红宝石。当您必须升级您的Rails应用程序以使用较新的Ruby时,这将使您的工作变得容易得多。
在安装RVM之前,您需要导入RVM GPG密钥:
1gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
然后安装RVM来管理我们的Ruby:
1curl -sSL https://get.rvm.io | bash -s stable
该命令使用curl
从https://get.rvm.io
.下载rvm安装脚本-sSL
选项由三个标志组成:
-s
告诉cURL以‘静默模式’下载文件-S
告诉cURL在失败时显示错误消息-L
告诉cURL在检索安装脚本时遵循所有HTTP重定向
下载后,脚本被_piped_ to bash
。-s
选项将stable
作为参数传递给RVM安装脚本,以下载和安装RVM的稳定版本。
<$>[备注] 注意: 如果第二条命令失败,并提示GPG签名验证失败,则表示GPG密钥已更改,只需从错误输出中复制命令并运行即可下载签名。然后为RVM安装运行curl命令。 <$>
我们需要加载RVM脚本(作为一个函数),以便可以开始使用它。然后,我们需要运行requirements s
命令来自动安装RVM和Ruby正常运行所需的依赖项和文件:
1source ~/.rvm/scripts/rvm
2rvm requirements
现在我们可以安装我们选择的Ruby了。我们将安装最新的Ruby 2.2.1
(撰写本文时)作为我们的默认Ruby:
1rvm install 2.2.1
2rvm use 2.2.1 --default
第四步-安装导轨和捆绑器
一旦设置好Ruby,我们就可以开始安装Rubygems了。我们将从安装rails gem开始,它将允许您的rails应用程序运行,然后我们将安装bundler
,它可以读取您的应用程序的Gemfile
,并自动安装所有必需的gem。
安装Rails和Bundler:
1gem install rails -V --no-ri --no-rdoc
2gem install bundler -V --no-ri --no-rdoc
使用了三个标志:
-v
(详细输出):打印有关Gem安装的详细信息--no-ri
-(跳过Ri文档):不安装Ri文档,节省空间,安装速度快--no-rdoc
-(跳过RDocs):不安装RDocs,节省空间,加快安装速度
<$>[注]
注意: 您也可以根据自己的需求安装特定版本的Rails,使用-v
标志:
1gem install rails -v '4.2.0' -V --no-ri --no-rdoc
<$>
第五步-设置SSH密钥
由于我们希望设置平稳部署,因此我们将使用SSH密钥进行授权。首先与GitHub、BitBucket或任何其他托管Rails应用程序代码库的Git Remote握手:
1ssh -T [email protected]
2ssh -T [email protected]
如果收到`许可被拒绝(公钥)‘的消息,请不要担心。现在,为您的服务器生成SSH密钥(公钥/私钥对):
1ssh-keygen -t rsa
将新创建的公钥~/.ssh/id_rsa.pub
添加到您仓库的部署密钥中:
如果所有步骤都正确完成,您现在应该能够在不输入密码的情况下‘克隆’您的Git存储库(通过SSH协议,而不是HTTP):
1git clone [email protected]:username/appname.git
如果您需要用于测试的示例应用程序,您可以使用以下专门为本教程创建的测试应用程序:GitHub上的示例Rails应用程序
git clone
命令将创建一个与您的应用程序同名的目录。例如,将创建一个名为testapp_tras
的目录。
我们克隆只是为了检查我们的部署密钥是否正常工作,而不是每次我们推送新的更改时都需要克隆或拉取我们的存储库。我们会让卡皮斯特拉诺为我们处理这一切的。如果需要,您现在可以删除此克隆目录。
在您的本地计算机上打开终端。如果您没有本地计算机的SSH密钥,也可以为其创建一个。在您的本地终端会话中:
1ssh-keygen -t rsa
将您的本地SSH密钥添加到Droplet的授权密钥文件中(请记住将端口号替换为您自定义的端口号):
1cat ~/.ssh/id_rsa.pub | ssh -p your_port_num deploy@your_server_ip 'cat >> ~/.ssh/authorized_keys'
Step 6-在Rails App中添加部署配置
在您的本地机器上,在您的Rails应用程序中为nginx和Capstrano创建配置文件。首先,将这些行添加到Rails应用程序的Gemfile
中:
1[label Gemfile]
2
3group :development do
4 gem 'capistrano', require: false
5 gem 'capistrano-rvm', require: false
6 gem 'capistrano-rails', require: false
7 gem 'capistrano-bundler', require: false
8 gem 'capistrano3-puma', require: false
9end
10
11gem 'puma'
使用bundler
安装您刚才在Gemfile
中指定的gem。输入以下命令来捆绑您的Rails应用程序:
1bundle
绑定后,运行以下命令配置Capistrano:
1cap install
这将创建:
- Rails应用程序根目录中的
Capfile
config
目录下的ploy.rb
文件config
目录中的ploy
目录
用以下内容替换您的Capfile
的内容:
1[label Capfile]
2# Load DSL and Setup Up Stages
3require 'capistrano/setup'
4require 'capistrano/deploy'
5
6require 'capistrano/rails'
7require 'capistrano/bundler'
8require 'capistrano/rvm'
9require 'capistrano/puma'
10
11# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
12Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
这个Capfile
会将一些预定义的任务加载到你的Capistrano配置文件中,以使你的部署变得轻松,例如自动:
- 选择正确的Ruby
- 预编资产
- 将Git存储库克隆到正确的位置
- 在Gemfile更改时安装新的依赖项
将config/ploy.rb
的内容替换为以下内容,并使用您的应用程序和Droplet参数更新标记为红色的字段:
1[label config/deploy.rb]
2
3# Change these
4server 'your_server_ip', port: your_port_num, roles: [:web, :app, :db], primary: true
5
6set :repo_url, '[email protected]:username/appname.git'
7set :application, 'appname'
8set :user, 'deploy'
9set :puma_threads, [4, 16]
10set :puma_workers, 0
11
12# Don't change these unless you know what you're doing
13set :pty, true
14set :use_sudo, false
15set :stage, :production
16set :deploy_via, :remote_cache
17set :deploy_to, "/home/#{fetch(:user)}/apps/#{fetch(:application)}"
18set :puma_bind, "unix://#{shared_path}/tmp/sockets/#{fetch(:application)}-puma.sock"
19set :puma_state, "#{shared_path}/tmp/pids/puma.state"
20set :puma_pid, "#{shared_path}/tmp/pids/puma.pid"
21set :puma_access_log, "#{release_path}/log/puma.error.log"
22set :puma_error_log, "#{release_path}/log/puma.access.log"
23set :ssh_options, { forward_agent: true, user: fetch(:user), keys: %w(~/.ssh/id_rsa.pub) }
24set :puma_preload_app, true
25set :puma_worker_timeout, nil
26set :puma_init_active_record, true # Change to false when not using ActiveRecord
27
28## Defaults:
29# set :scm, :git
30# set :branch, :master
31# set :format, :pretty
32# set :log_level, :debug
33# set :keep_releases, 5
34
35## Linked Files & Directories (Default None):
36# set :linked_files, %w{config/database.yml}
37# set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
38
39namespace :puma do
40 desc 'Create Directories for Puma Pids and Socket'
41 task :make_dirs do
42 on roles(:app) do
43 execute "mkdir #{shared_path}/tmp/sockets -p"
44 execute "mkdir #{shared_path}/tmp/pids -p"
45 end
46 end
47
48 before :start, :make_dirs
49end
50
51namespace :deploy do
52 desc "Make sure local git is in sync with remote."
53 task :check_revision do
54 on roles(:app) do
55 unless `git rev-parse HEAD` == `git rev-parse origin/master`
56 puts "WARNING: HEAD is not the same as origin/master"
57 puts "Run `git push` to sync changes."
58 exit
59 end
60 end
61 end
62
63 desc 'Initial Deploy'
64 task :initial do
65 on roles(:app) do
66 before 'deploy:restart', 'puma:start'
67 invoke 'deploy'
68 end
69 end
70
71 desc 'Restart application'
72 task :restart do
73 on roles(:app), in: :sequence, wait: 5 do
74 invoke 'puma:restart'
75 end
76 end
77
78 before :starting, :check_revision
79 after :finishing, :compile_assets
80 after :finishing, :cleanup
81 after :finishing, :restart
82end
83
84# ps aux | grep puma # Get puma pid
85# kill -s SIGUSR2 pid # Restart puma
86# kill -s SIGTERM pid # Stop puma
这个ploy.rb
文件包含一些开箱即用的合理默认设置,可以帮助您管理应用程序版本,并在进行部署时自动执行一些任务:
- 使用
Production
作为您的Rails应用程序的默认环境 - 自动管理应用程序的多个版本
- 使用优化的SSH选项
- 检查您的GIT遥控器是否为最新
- 管理应用程序的日志
- 在管理彪马工作人员时将应用程序预加载到内存中
- 完成部署后启动(或重新启动)Puma服务器
- 在您的版本中的特定位置打开到Puma服务器的套接字
您可以根据需要更改所有选项。现在,需要配置nginx。在您的Rails项目目录中创建config/nginx.conf
,并在其中添加以下内容(再次替换为您的参数):
1[label config/nginx.conf]
2
3upstream puma {
4 server unix:///home/deploy/apps/appname/shared/tmp/sockets/appname-puma.sock;
5}
6
7server {
8 listen 80 default_server deferred;
9 # server_name example.com;
10
11 root /home/deploy/apps/appname/current/public;
12 access_log /home/deploy/apps/appname/current/log/nginx.access.log;
13 error_log /home/deploy/apps/appname/current/log/nginx.error.log info;
14
15 location ^~ /assets/ {
16 gzip_static on;
17 expires max;
18 add_header Cache-Control public;
19 }
20
21 try_files $uri/index.html $uri @puma;
22 location @puma {
23 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
24 proxy_set_header Host $http_host;
25 proxy_redirect off;
26
27 proxy_pass http://puma;
28 }
29
30 error_page 500 502 503 504 /500.html;
31 client_max_body_size 10M;
32 keepalive_timeout 10;
33}
与前面的文件一样,这个nginx.con
文件包含的默认设置与您的ploy.rb
文件中的配置一样,开箱即用。这将侦听端口80上的流量并将请求传递给您的Puma套接字,将nginx日志写入您的应用程序的当前版本,压缩所有资产并将它们缓存到最大到期时间的浏览器中,将公共文件夹中的HTML页面作为静态文件提供服务,并设置默认的最大Client Body Size
和`RequestTimeout‘值。
第7步-部署Rails应用程序
如果您使用的是您自己的Rails应用程序,请提交您刚才所做的更改,并将它们推送到本地计算机的远程位置:
1git add -A
2git commit -m "Set up Puma, Nginx & Capistrano"
3git push origin master
<$>[备注] 注意: 如果这是您第一次在本系统使用giHub,您可能需要通过您的giHub用户名和邮箱地址发出以下命令:
1git config --global user.name 'Your Name'
2git config --global user.email [email protected]
<$>
同样,从您的本地计算机进行第一次部署:
1cap production deploy:initial
这将把Rails应用推送到Droplet,安装应用所需的所有gem,并启动Puma Web服务器。这可能需要5-15分钟,具体取决于您的应用使用的宝石数量。在此过程中,您将看到调试消息。
如果一切顺利,我们现在已经准备好将您的Puma Web服务器连接到Nginx反向代理。
在Droplet上,将nginx.conf
符号链接到sites-enabled
目录:
1sudo rm /etc/nginx/sites-enabled/default
2sudo ln -nfs "/home/deploy/apps/appname/current/config/nginx.conf" "/etc/nginx/sites-enabled/appname"
重启Nginx服务:
1sudo service nginx restart
您现在应该能够将您的Web浏览器指向您的服务器IP,并看到您的Rails应用程序正在运行!
正常部署
每当您对应用程序进行更改,并希望在服务器上部署新版本时,提交更改,像往常一样推送到您的GIT遥控器,然后运行ploy
命令:
1git add -A
2git commit -m "Deploy Message"
3git push origin master
4cap production deploy
<$>[备注]
注意: 如果您修改了config/nginx.con
文件,则在部署您的应用程序后,您需要在服务器上重新加载或重启您的Nginx服务:
1sudo service nginx restart
<$>
结论
好了,现在你应该已经在你的Droplet上运行了一个Rails应用程序了,Puma作为你的Web服务器,以及配置了基本设置的Nginx和Capstrano。现在,您应该看看其他文档,这些文档可以帮助您优化配置,以最大限度地利用您的Rails应用程序:
- 彪马Configurations
- Capistrano中的彪马数字用户线
- Capistrano中的本地资产预编译
- 基于RAM自动重启彪马工人
- 优化NGINX实现高流量Loads