简介
设计简单的应用服务器可以在部署基于 Rails 的 Web 应用程序时让您在几分钟内即可上手运行。然而,如果您希望对服务器设置有更多控制,或者想尝试一些更灵活的新东西,使用一组分层组件可以帮助您实现目标 - 无论是未来保护部署还是需要引入缓存服务器等第三方元素。
在这篇 DigitalOcean 文章中,我们将探讨如何组装多层部署安装以托管基于 Rails 的 Ruby Web 应用程序。对于这种安排,我们将使用功能强大、灵活且非常成功的 Unicorn 应用服务器在 Nginx 后面运行。虽然我们将为演示目的在单个服务器上构建这个结构,但您可以轻松地使用多个 droplets 来扩展和横向纵向扩展 - 无论是横向还是纵向!
术语表
1. Web 应用部署、服务器及其角色
- Unicorn 应用服务器
- 作为前端反向代理运行的 Nginx HTTP 服务器
2. 准备部署服务器
- 更新和准备操作系统
- 设置 Ruby 环境和 Rails
- 安装 Nginx
- 安装 Unicorn
3. 为部署准备 Rails 应用程序
- 创建一个示例应用程序
- 上传您的源代码
4. 配置服务器
- Unicorn
- Nginx
- 管理服务器
5. 进一步阅读
Web 应用部署、服务器及其角色
在部署 Web 应用程序时,通常涉及多个应用程序,分层设置并相互配合。这种真实世界的部署设置与使用设计用于测试目的的单一开发服务器大不相同,因为它们无法在实际网站流量的负载下工作,因为缺乏功能和特性。
谈到功能,应该注意到有一些流行的服务器可供选择,每个服务器都提供不同的功能:有些侧重于简单性,有些侧重于速度,还有一些可以配置选项以满足复杂的生产需求。
在本文中,我们选择的应用服务器是 Unicorn。Unicorn 是一个非常成熟的用于 Ruby/Rack 的 Web 应用程序服务器。它功能齐全,但设计上拒绝尝试做所有事情。Unicorn 的原则是通过 Web 应用程序服务器执行需要执行的任务,并委托其余的责任。
Unicorn 的 master 进程根据您的需求生成 workers 来处理请求。该进程还监视工作进程,以防止内存和进程相关的问题。这对系统管理员意味着,如果例如一个任务花费太长时间或出现内存问题,它将终止一个进程。
如上所述,Unicorn委托任务的一个领域是使用操作系统进行负载平衡。这允许请求不堆积在繁忙的工作进程中。
Unicorn 应用服务器
Unicorn 是一个非常成熟的用于 Ruby/Rack 的 Web 应用程序服务器。它功能齐全,但设计上拒绝尝试做所有事情。Unicorn 的原则是通过 Web 应用程序服务器执行需要执行的任务,并委托其余的责任。
Unicorn 的 master 进程根据您的需求生成 workers 来处理请求。该进程还监视工作进程,以防止内存和进程相关的问题。这对系统管理员意味着,如果例如一个任务花费太长时间或出现内存问题,它将终止一个进程。
如上所述,Unicorn委托任务的一个领域是使用操作系统进行负载平衡。这允许请求不堆积在繁忙的工作进程中。
作为前端反向代理运行的 Nginx HTTP 服务器
Nginx 是一个非常高性能的 Web 服务器 / (反向) 代理。它因为轻量级、相对易于使用和易于扩展(使用附加组件/插件)而广受欢迎。由于其架构,它能够处理大量的请求(几乎无限),这取决于您的应用程序或网站负载,使用其他一些较老的替代方案可能会非常难以处理。
请记住: “处理”连接在技术上意味着不丢弃它们并且能够用某些东西为客户端提供服务。为了使 Nginx 提供客户端不是错误消息的响应,您仍然需要您的应用程序和数据库正常运行。
要了解更多关于 Nginx 的信息,您可以访问其官方网站位于 nginx.com。
准备部署服务器
在本节中,我们将执行以下步骤:
- 更新操作系统
- 获取部署所需的基本工具
- 安装 Ruby、Rails 和库
- 安装应用程序(即 Unicorn)和 HTTP 服务器(Nginx)
更新和准备操作系统
为了安装 Ruby 和其他必要的应用程序(例如我们的服务器),我们需要首先准备最小化的 CentOS droplet,并配备一些在此过程中需要的开发工具。
运行以下命令来更新您的 CentOS VPS 的默认工具:
yum -y update
这个命令将更新 CentOS 默认提供的所有基本应用程序。这些应用程序大多是为操作系统保留的。
通过执行以下命令安装包含开发工具的捆绑包:
yum groupinstall -y 'development tools'
对于较新版本的 CentOS(例如我们的情况下是 6.5),您可以简单地运行:
yum groupinstall -y development
这个捆绑包包含各种工具,例如:gcc、make、automake、binutils、git 等。
本教程所需的一些软件包(例如 libyaml-devel、nginx 等)不在官方的 CentOS 软件仓库中。为了简化事情,我们将添加 EPEL 软件仓库,以供 YUM 软件包管理器使用。
# 启用 EPEL 软件仓库 sudo su -c 'rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm' # 再次更新所有内容 yum -y update
最后,我们需要为本教程获取 curl-devel
和其他一些工具和库(例如 Rails 需要 sqlite-devel)。
为了安装它们,请运行以下命令:
yum install -y curl-devel nano sqlite-devel libyaml-devel
设置 Ruby 环境和 Rails
注意: 本节是我们专门文章《如何在 CentOS 6.5 上安装 Ruby 2.1.0》的摘要。
我们将使用 Ruby Version Manager(RVM)来下载和安装 Ruby 解释器。
运行以下两个命令来安装 RVM 并为 Ruby 创建系统环境:
gpg --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3 \curl -sSL https://get.rvm.io | bash -s stable source /etc/profile.d/rvm.sh
最后,为了在我们的系统上完成安装 Ruby,让 RVM 下载并安装 Ruby 版本 2.1.0:
rvm reload rvm install 2.1.0
由于 Rails 首先需要一个 JavaScript 解释器才能工作,我们还需要设置 Node.js
。为此,我们将使用默认的系统软件包管理器 YUM。
运行以下命令使用 yum
下载和安装 nodejs
:
yum install -y nodejs
执行以下命令使用 gem
下载和安装 rails
:
gem install bundler rails
安装 Nginx
由于我们已经启用了 EPEL 软件仓库,可以使用 yum 获取 Nginx。
运行以下命令使用 yum
下载和安装 Nginx:
yum install -y nginx
注意: 我们将在接下来的部分中配置这个工具。
安装 Unicorn
有几种简单地下载 Unicorn 的方法。由于它是一个与应用程序相关的依赖项,最合乎逻辑的方式是使用 RubyGems。
运行以下命令使用 gem
下载和安装 Unicorn:
gem install unicorn
注意: 我们将在接下来的部分中看到如何使用这个工具。
为部署准备 Rails 应用程序
注意: 在本节中,我们将以一个非常简单的 Ruby On Rails 应用程序作为示例。对于您的应用程序的实际部署,您应该上传您的代码库并确保安装了所有的依赖项(即 bundle
)。
创建一个示例应用程序
让我们从在我们的主目录内创建一个非常基本的 Rails 应用程序开始,以便使用 Unicorn 进行服务。
执行以下命令让 Rails 创建一个名为 “my_app” 的新应用程序:
# 创建一个示例 Rails 应用程序 cd /var mkdir www cd www rails new my_app # 进入应用程序目录 cd my_app # 创建一个示例资源 rails generate scaffold Task title:string note:text # 创建一个示例数据库 RAILS_ENV=development rake db:migrate RAILS_ENV=production rake db:migrate # 创建一个目录来保存 PID 文件 mkdir pids
为了测试您的应用程序是否设置正确并且一切正常工作,进入应用程序目录并使用 rails s
运行一个简单的服务器:
# 进入应用程序目录 cd /var/www/my_app # 运行一个简单的服务器 rails s # 您现在应该能够通过访问:http://[您的 droplet 的 IP]:3000/tasks # 来访问它 # 为了终止服务器进程,按下 CTRL+C
上传您的源代码
在实际部署中,您当然希望将代码库上传到服务器。为此,您可以使用 SFTP 或图形工具(如 FileZilla)来安全地传输和管理远程文件。同样,您可以使用 Git 和 Github 等中央存储库来下载和设置您的代码。
- 要了解如何使用 SFTP,请查看文章:如何使用 SFTP。
- 要了解有关 FileZilla 的信息,请查看有关主题的文章:如何使用 FileZilla。
配置服务器
Unicorn
Unicorn 可以通过多种方式进行配置。在本教程中,我们将重点关注关键元素,我们将从头开始创建一个文件,该文件将在启动应用程序服务器守护进程时由 Unicorn 使用。
打开一个空白的 unicorn.rb
文档,将其保存在 config/
目录中:
nano config/unicorn.rb
放置下面的代码块,并根据需要进行修改:
# 设置工作应用程序目录 # working_directory "/path/to/your/app" working_directory "/var/www/my_app" # Unicorn PID 文件位置 # pid "/path/to/pids/unicorn.pid" pid "/var/www/my_app/pids/unicorn.pid" # 日志路径 # stderr_path "/path/to/log/unicorn.log" # stdout_path "/path/to/log/unicorn.log" stderr_path "/var/www/my_app/log/unicorn.log" stdout_path "/var/www/my_app/log/unicorn.log" # Unicorn 套接字 listen "/tmp/unicorn.[app name].sock" listen "/tmp/unicorn.myapp.sock" # 进程数 # worker_processes 4 worker_processes 2 # 超时 timeout 30
按 CTRL+X
保存并退出,然后确认选择 Y
。
注意: 要简单测试您的应用程序是否与 Unicorn 兼容,可以在应用程序目录中运行 unicorn_rails
。
Nginx
接下来,我们需要告诉 Nginx 如何与 Unicorn 通信。在这个级别上,只需编辑默认配置文件:default.conf
,并保留 nginx.conf
如所提供的那样 – 它已经设置为包含默认配置。
nano /etc/nginx/conf.d/default.conf
用下面的内容替换文件内容,并根据需要进行修改:
upstream app { # Unicorn SOCK 文件的路径,如前面定义的 server unix:/tmp/unicorn.myapp.sock fail_timeout=0; } server { listen 80; server_name localhost; # 应用程序根目录,如前面定义的 root /root/my_app/public; try_files $uri/index.html $uri @app; location @app { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://app; } error_page 500 502 503 504 /500.html; client_max_body_size 4G; keepalive_timeout 10; }
按 CTRL+X
保存并退出,然后确认选择 Y
。
注意: 要了解更多关于 Nginx 的信息,请参阅如何在 VPS 上配置 Nginx Web 服务器。
管理服务器
在完成配置两个服务器之后,现在是时候上线了!
让我们启动 Unicorn 并使用配置文件作为守护进程运行:
# 确保您在应用程序目录中 # 即 /my_app unicorn_rails -c config/unicorn.rb -D # 您可以通过链接 -E 标志来设置环境 # 即 unicorn_rails .. .. .. -E [env. name]
接下来,我们准备重新加载和重启 Nginx:
service nginx restart
就是这样!您现在可以通过转到您的 droplet 的 IP 地址(或与其关联的域名)来检查您的部署。
http://[Your droplet's IP addr]/tasks # 列出任务 # 标题 注释 # 新任务
进一步阅读
防火墙:
使用 IP Tables 设置防火墙
保护 SSH:
如何在 Ubuntu 上使用 fail2ban 保护 SSH
如何在 CentOS 6 上使用 fail2ban 保护 SSH
创建警报:
如何在 CentOS VPS 上发送电子邮件警报进行系统监控
每日监视和查看服务器访问日志:
如何安装和使用 Logwatch 日志分析器和报告生成器
优化 Unicorn Workers:
如何在 Ruby on Rails 应用程序中优化 Unicorn Workers