如何在 Ubuntu 14.04 上使用 Unicorn 和 Nginx 部署 Rails 应用

简介: 如何在 Ubuntu 14.04 上使用 Unicorn 和 Nginx 部署 Rails 应用

介绍

当你准备部署你的 Ruby on Rails 应用程序时,有许多有效的设置需要考虑。本教程将帮助你在 Ubuntu 14.04 上部署你的 Ruby on Rails 应用程序的生产环境,使用 PostgreSQL 作为数据库,并使用 Unicorn 和 Nginx。

Unicorn 是一个应用服务器,类似于 Passenger 或 Puma,它使你的 Rails 应用程序能够并发处理请求。由于 Unicorn 不是设计为直接被用户访问,我们将使用 Nginx 作为反向代理,用于在用户和你的 Rails 应用程序之间缓冲请求和响应。

先决条件

本教程假设你已经在 Ubuntu 14.04 服务器上以部署应用程序的用户身份安装了以下软件:

  • 使用 rbenv 的 Ruby on Rails
  • 带有 Rails 的 PostgreSQL

如果你还没有进行设置,请按照上面链接的教程进行设置。我们将假设你的用户名称为 deploy

另外,本教程不涵盖如何设置开发或测试环境。如果你需要帮助,请按照 PostgreSQL with Rails 教程中的示例进行设置。

创建 Rails 应用程序

理想情况下,你已经有一个要部署的 Rails 应用程序。如果是这种情况,你可以跳过本节,并在跟随过程时进行适当的替换。如果没有,第一步是创建一个使用 PostgreSQL 作为其数据库的新 Rails 应用程序。

以下命令将创建一个名为 “appname” 的新 Rails 应用程序,该应用程序将使用 PostgreSQL 作为数据库。请随意用其他内容替换下面突出显示的 “appname”:

rails new appname -d postgresql

然后切换到应用程序目录:

cd appname

让我们花点时间来创建将在你的 Rails 应用程序的生产环境中使用的 PostgreSQL 用户。

创建生产数据库用户

为了简化事务,让我们将生产数据库用户的名称与你的应用程序名称相同。例如,如果你的应用程序名为 “appname”,你应该像这样创建一个 PostgreSQL 用户:

sudo -u postgres createuser -s appname

我们希望设置数据库用户的密码,因此像这样进入 PostgreSQL 控制台:

sudo -u postgres psql

然后像这样为数据库用户(在示例中为 “appname”)设置密码:

\password appname

输入你想要的密码并确认。

使用以下命令退出 PostgreSQL 控制台:

\q

现在我们准备使用正确的数据库连接信息配置你的应用程序。

配置数据库连接

确保你在应用程序的根目录中(cd ~/appname)。

使用你喜欢的文本编辑器打开应用程序的数据库配置文件。我们将使用 vi:

vi config/database.yml

default 部分下,找到一行写着 “pool: 5” 的行,并在其下添加以下行(如果尚不存在):

host: localhost

如果你滚动到文件底部,你会注意到 production 部分被设置如下:

username: appname
  password: <%= ENV['APPNAME_DATABASE_PASSWORD'] %>

如果你的生产用户名与之前创建的数据库用户不匹配,现在设置它。

请注意,数据库密码被配置为通过环境变量 APPNAME_DATABASE_PASSWORD 读取。最佳实践是将生产密码和密钥保存在应用程序代码库之外,因为如果你使用分布式版本控制系统(如 Git),它们很容易被暴露。接下来,我们将介绍如何使用环境变量设置数据库身份验证。

安装 rbenv-vars 插件

在部署生产 Rails 应用程序之前,你应该使用环境变量设置生产密钥和数据库密码。管理环境变量的一种简单方法是使用 rbenv-vars 插件,我们可以使用它在运行时将密码和密钥加载到我们的应用程序中。

要安装 rbenv-vars 插件,只需切换到 .rbenv/plugins 目录并从 GitHub 克隆它。例如,如果 rbenv 安装在你的主目录中,运行以下命令:

cd ~/.rbenv/plugins
git clone https://github.com/sstephenson/rbenv-vars.git

设置环境变量

现在 rbenv-vars 插件已安装,让我们设置所需的环境变量。

首先,生成用于验证已签名 cookie 完整性的密钥:

cd ~/appname
rake secret

复制生成的密钥,然后使用你喜欢的编辑器打开 .rbenv-vars 文件。我们将使用 vi:

vi .rbenv-vars

你在这里设置的任何环境变量都可以被你的 Rails 应用程序读取。

首先,设置 SECRET_KEY_BASE 变量如下(用你刚生成和复制的密钥替换下面突出显示的文本):

SECRET_KEY_BASE=your_generated_secret

接下来,设置 APPNAME_DATABASE_PASSWORD 变量如下(用你的应用程序名称替换下面突出显示的 “APPNAME”,用你的生产数据库用户密码替换 “prod_db_pass”):

APPNAME_DATABASE_PASSWORD=prod_db_pass

保存并退出。

你可以通过运行以下命令使用 rbenv-vars 插件查看为你的应用程序设置了哪些环境变量:

rbenv vars

如果你更改了密钥或数据库密码,请更新你的 .rbenv-vars 文件。请注意保持此文件私密,并不要将其包含在任何公共代码库中。

创建生产环境数据库

现在你的应用程序已经配置好与 PostgreSQL 数据库通信,让我们来创建生产环境数据库:

RAILS_ENV=production rake db:create

生成控制器

如果你正在按照示例进行操作,我们将生成一个脚手架控制器,这样我们的应用程序就有东西可以展示了:

rails generate scaffold Task title:string note:text

现在运行以下命令来更新生产环境数据库:

RAILS_ENV=production rake db:migrate

预编译资源

此时,应用程序应该可以运行,但是你需要预编译它的资源,以便任何图片、CSS 和脚本都能加载。为此,请运行以下命令:

RAILS_ENV=production rake assets:precompile

测试应用程序

要测试应用程序是否正常工作,你可以运行生产环境,并将其绑定到服务器的公共 IP 地址(替换为你服务器的公共 IP 地址):

RAILS_ENV=production rails server --binding=server_public_IP

现在在 Web 浏览器中访问以下 URL:

http://server_public_IP:3000/tasks

如果一切正常,你应该能看到这个页面:

!Tasks controller

返回到你的 Rails 服务器,按 Ctrl-c 停止应用程序。

安装 Unicorn

现在我们准备安装 Unicorn。

一个简单的方法是将它添加到你的应用程序的 Gemfile 中。在你喜欢的编辑器中打开 Gemfile(确保你在应用程序的根目录下):

vi Gemfile

在文件末尾添加以下行来添加 Unicorn gem:

gem 'unicorn'

保存并退出。

要安装 Unicorn 和任何未解决的依赖项,请运行 Bundler:

bundle

Unicorn 现在已安装,但我们需要对其进行配置。

配置 Unicorn

让我们将 Unicorn 配置添加到 config/unicorn.rb。在文本编辑器中打开该文件:

vi config/unicorn.rb

将以下配置复制并粘贴到文件中:

# 设置应用程序路径
app_dir = File.expand_path("../..", __FILE__)
shared_dir = "#{app_dir}/shared"
working_directory app_dir
# 设置 Unicorn 选项
worker_processes 2
preload_app true
timeout 30
# 设置套接字位置
listen "#{shared_dir}/sockets/unicorn.sock", :backlog => 64
# 日志
stderr_path "#{shared_dir}/log/unicorn.stderr.log"
stdout_path "#{shared_dir}/log/unicorn.stdout.log"
# 设置主进程 ID 位置
pid "#{shared_dir}/pids/unicorn.pid"

保存并退出。这将配置 Unicorn,指定应用程序的位置以及其套接字、日志和进程 ID 的位置。你可以随意修改文件,或添加任何其他你需要的选项。

现在创建配置文件中提到的目录:

mkdir -p shared/pids shared/sockets shared/log

创建 Unicorn 启动脚本

让我们创建一个启动脚本,这样我们就可以轻松地启动和停止 Unicorn,并确保它会在启动时启动。

使用以下命令创建脚本并打开它进行编辑(如果需要,请将高亮部分替换为你的应用程序名称):

sudo vi /etc/init.d/unicorn_appname

将以下代码块复制并粘贴到其中,并确保用适当的值替换 USERAPP_NAME(高亮部分):

#!/bin/sh
### BEGIN INIT INFO
# Provides:          unicorn
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the unicorn app server
# Description:       starts unicorn using start-stop-daemon
### END INIT INFO
set -e
USAGE="Usage: $0 <start|stop|restart|upgrade|rotate|force-stop>"
# 应用程序设置
USER="deploy"
APP_NAME="appname"
APP_ROOT="/home/$USER/$APP_NAME"
ENV="production"
# 环境设置
PATH="/home/$USER/.rbenv/shims:/home/$USER/.rbenv/bin:$PATH"
CMD="cd $APP_ROOT && bundle exec unicorn -c config/unicorn.rb -E $ENV -D"
PID="$APP_ROOT/shared/pids/unicorn.pid"
OLD_PID="$PID.oldbin"
# 确保应用程序存在
cd $APP_ROOT || exit 1
sig () {
  test -s "$PID" && kill -$1 `cat $PID`
}
oldsig () {
  test -s $OLD_PID && kill -$1 `cat $OLD_PID`
}
case $1 in
  start)
    sig 0 && echo >&2 "Already running" && exit 0
    echo "Starting $APP_NAME"
    su - $USER -c "$CMD"
    ;;
  stop)
    echo "Stopping $APP_NAME"
    sig QUIT && exit 0
    echo >&2 "Not running"
    ;;
  force-stop)
    echo "Force stopping $APP_NAME"
    sig TERM && exit 0
    echo >&2 "Not running"
    ;;
  restart|reload|upgrade)
    sig USR2 && echo "reloaded $APP_NAME" && exit 0
    echo >&2 "Couldn't reload, starting '$CMD' instead"
    $CMD
    ;;
  rotate)
    sig USR1 && echo rotated logs OK && exit 0
    echo >&2 "Couldn't rotate logs" && exit 1
    ;;
  *)
    echo >&2 $USAGE
    exit 1
    ;;
esac

保存并退出。这将允许你使用 service unicorn_appname 来启动和停止 Unicorn 和你的 Rails 应用程序。

更新脚本的权限并启用 Unicorn 在启动时启动:

sudo chmod 755 /etc/init.d/unicorn_appname
sudo update-rc.d unicorn_appname defaults

现在启动它:

sudo service unicorn_appname start

现在你的 Rails 应用程序的生产环境正在使用 Unicorn 运行,并且它正在监听 shared/sockets/unicorn.sock 套接字。在你的应用程序对外开放给用户之前,你必须设置 Nginx 反向代理。

安装和配置 Nginx

使用 apt-get 安装 Nginx:

sudo apt-get install nginx

现在用文本编辑器打开默认的服务器块:

sudo vi /etc/nginx/sites-available/default

用以下代码块替换文件的内容。确保用适当的用户名和应用程序名称替换高亮部分:

upstream app {
    # Path to Unicorn SOCK file, as defined previously
    server unix:/home/deploy/appname/shared/sockets/unicorn.sock fail_timeout=0;
}
server {
    listen 80;
    server_name localhost;
    root /home/deploy/appname/public;
    try_files $uri/index.html $uri @app;
    location @app {
        proxy_pass http://app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }
    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}

保存并退出。这将配置 Nginx 作为反向代理,因此 HTTP 请求将通过 Unix socket 转发到 Unicorn 应用程序服务器。随意根据需要进行任何更改。

重新启动 Nginx 以使更改生效:

sudo service nginx restart

现在,你可以通过服务器的公共 IP 地址或 FQDN 访问你的 Rails 应用程序的生产环境。要访问之前创建的 Tasks 控制器,请在 Web 浏览器中访问你的应用程序服务器:

http://server_public_IP/tasks

你应该看到与第一次测试应用程序时相同的页面,但现在它是通过 Nginx 和 Unicorn 提供的。

结论

恭喜!你已经使用 Nginx 和 Unicorn 部署了你的 Ruby on Rails 应用程序的生产环境。

如果你想改进生产环境中的 Rails 应用程序部署,你应该查看我们的教程系列《如何使用 Capistrano 自动化部署》。该系列基于 CentOS,但在自动化部署方面仍然应该有所帮助。


相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
3月前
|
应用服务中间件 网络安全 nginx
手把手教你使用 Docker 部署 Nginx 教程
本文详解Nginx核心功能与Docker部署优势,涵盖镜像拉取、容器化部署(快速、挂载、Compose)、HTTPS配置及常见问题处理,助力高效搭建稳定Web服务。
1295 4
|
4月前
|
人工智能 Ubuntu 前端开发
Dify部署全栈指南:AI从Ubuntu配置到HTTPS自动化的10倍秘籍
本文档介绍如何部署Dify后端服务及前端界面,涵盖系统环境要求、依赖安装、代码拉取、环境变量配置、服务启动、数据库管理及常见问题解决方案,适用于开发与生产环境部署。
875 1
|
3月前
|
应用服务中间件 Linux nginx
在虚拟机Docker环境下部署Nginx的步骤。
以上就是在Docker环境下部署Nginx的步骤。需要注意,Docker和Nginix都有很多高级用法和细节需要掌握,以上只是一个基础入门级别的教程。如果你想要更深入地学习和使用它们,请参考官方文档或者其他专业书籍。
174 5
|
3月前
|
Ubuntu API C++
C++标准库、Windows API及Ubuntu API的综合应用
总之,C++标准库、Windows API和Ubuntu API的综合应用是一项挑战性较大的任务,需要开发者具备跨平台编程的深入知识和丰富经验。通过合理的架构设计和有效的工具选择,可以在不同的操作系统平台上高效地开发和部署应用程序。
163 11
|
11月前
|
应用服务中间件 PHP nginx
今日小结通过aliyun的本地容器镜像部署我的nginx和php环境
简介: 本教程介绍如何基于 Dragonwell 的 Ubuntu 镜像创建一个运行 Nginx 的 Docker 容器。首先从阿里云容器镜像服务拉取基础镜像,然后编写 Dockerfile 确保 Nginx 作为主进程运行,并暴露 80 端口。最后,在包含 Dockerfile 的目录下构建自定义镜像并启动容器,确保 Nginx 在前台运行,避免容器启动后立即退出。通过 `docker build` 和 `docker run` 命令完成整个流程。
411 25
今日小结通过aliyun的本地容器镜像部署我的nginx和php环境
|
8月前
|
Ubuntu 网络协议 应用服务中间件
在 Ubuntu 上安装 Nginx
在 Ubuntu 上安装和配置 Nginx 非常简单。首先更新系统包,然后通过 `apt` 安装 Nginx,检查服务状态并配置防火墙规则。访问服务器 IP 测试是否成功显示默认页面。还可管理服务、创建虚拟主机及排查常见问题,适合新手快速上手部署高性能 Web 服务。
923 0
|
5月前
|
存储 数据采集 监控
ubuntu(linux)系统主要应用于哪些工业场景中?研维三防ubuntu系统的手持工业三防平板电脑在哪些行业中有实际应用
Ubuntu 系统凭借其独特的优势,在众多工业场景中得到了广泛应用,为工业数字化、智能化发展提供了有力支持。而研维三防基于 Ubuntu 定制系统的手持工业三防平板电脑,更是将 Ubuntu 系统的优势与工业级的性能、坚固耐用性完美结合,在电力、物流、制造等多个行业中展现出强大的应用价值,助力企业提高生产效率、优化管理流程、提升产品质量,成为推动工业现代化发展的重要力量。随着技术的不断进步与创新,相信 Ubuntu 系统以及研维三防这类工业级设备将在更多的工业领域中发挥更大的作用,为工业发展带来更多的机遇与变革。
|
7月前
|
Ubuntu 安全 数据安全/隐私保护
在Docker容器中部署GitLab服务器的步骤(面向Ubuntu 16.04)
现在,你已经成功地在Docker上部署了GitLab。这就是我们在星际中的壮举,轻松如同土豆一样简单!星际旅行结束,靠岸,打开舱门,迎接全新的代码时代。Prepare to code, astronaut!
500 12
|
7月前
|
Ubuntu 定位技术
Ubuntu 20.04应用部署:Beyond Compare 4.4.7安装教程
这样,你就成功在Ubuntu 20.04上安装了Beyond Compare 4.4.7。就像一个探险者,你有了罗盘,有了地图,熟能生巧,你就可以在未知的世界中探索,发现,享受这个过程。这是一次成功的探险,你做得很好!
864 7
|
8月前
|
应用服务中间件 Linux 网络安全
技术指南:如何把docsify项目部署到基于CentOS系统的Nginx中。
总结 与其他部署方法相比,将docsify项目部署到基于CentOS系统的Nginx中比较简单。以上步骤应当帮助你在不花费太多时间的情况下,将你的项目顺利部署到Nginx中。迈出第一步,开始部署你的docsify项目吧!
352 14