使用 Nginx + Puma 部署 Rails 應(yīng)用

以前部署 Rails 應(yīng)用使用的是 Nginx + Passenger,非常方便。這次沒用這個(gè)方案是因?yàn)槲屹I了一個(gè)每月2.5刀的最低配的 VPS,根本安裝不了 Passenger......。于是我在網(wǎng)上搜了一下其他方案,Rails 應(yīng)用服務(wù)器大概常見的有這么3種:unicorn、puma、passenger。3 個(gè)都支持集群, puma 和 passenger 企業(yè)版支持多線程,unicorn 不支持多線程。passenger 除了支持 ruby on rails 外也支持其他的語言,如 python、nodejs??雌饋韨€(gè)人使用 puma 是一個(gè)非常不錯(cuò)的選擇,免費(fèi)開源,功能強(qiáng)大,可配置性也很好,而且它是 rails 默認(rèn)的服務(wù)器。

大概的原理

Nginx 作為反向代理服務(wù)器,負(fù)責(zé)監(jiān)聽主機(jī)域名的 HTTP 請求。接到客戶端的請求后,通過 upstream 指令將請求交給 Puma 應(yīng)用服務(wù)器處理,它們之間通過 unix socket 建立連系。Puma 負(fù)責(zé)監(jiān)聽 sockets,接到請求后調(diào)用 APP 生成頁面,將結(jié)果返回給 Nginx 服務(wù)器,Nginx 再把結(jié)果返回給客戶。

Nginx + Puma 配置

1. 安裝 Nginx

unbuntu 下直接通過 apt-get 安裝就可以了。

sudo apt-get install nginx

nginx 配置文件 /etc/nginx/sites-enabled/default

upstream app {
    // 改成實(shí)際 puma.sock 的文件路徑
    server unix:/home/vagrant/foo/shared/sockets/puma.sock;
}

server {
    listen 80;
    // 改成實(shí)際服務(wù)器域名
    server_name 192.168.1.2;

    // 改成實(shí)際 APP 路徑
    root /home/vagrant/foo/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;
    keepalive_timeout 10;
}
安裝 Puma

在 Gemfile 文件里添加,rails 5 是默認(rèn)的,就不需要了。

gem 'puma', '~> 3.7'

執(zhí)行 bundle install。

puma 配置文件 config/puma.rb。

# workers 數(shù)改成實(shí)際 CPU 數(shù),可通過 grep -c processor /proc/cpuinfo 查詢
workers 1
threads 1, 6
daemonize true
rails_env = ENV['RAILS_ENV'] || "production"
environment rails_env
app_dir = File.expand_path("../..", __FILE__)
shared_dir = "#{app_dir}/shared"
bind "unix://#{shared_dir}/sockets/puma.sock"
stdout_redirect "#{shared_dir}/log/puma.stdout.log", "#{shared_dir}/log/puma.stderr.log", true
pidfile "#{shared_dir}/pids/puma.pid"
state_path "#{shared_dir}/pids/puma.state"

on_worker_boot do
  require "active_record"
  ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
  ActiveRecord::Base.establish_connection(YAML.load_file("#{app_dir}/config/database.yml")[rails_env])
end

新建 puma 的日志、PID、和 Sockets 文件夾。

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

設(shè)置 rails 生成環(huán)境的 SECRET_KEY。

生成 key
$ rake secret

打開 bash 配置文件
$ vim ~/.bashrc

添加環(huán)境變量
export SECRET_KEY_BASE="這里是 rake secret 生成的字符串"

重新加載 bash 配置
$ source ~/.bashrc

如果只是臨時(shí)試試,也可以在命令行上執(zhí)行
$ export SECRET_KEY_BASE="`rake secret`"
新建 puma 控制腳本

在 APP 目錄下新建 pumactrl.sh 文件
$ vim pumactrl.sh

#!/bin/bash

case "$1" in
    "")
        echo -n "please provide a parameter (start, stop, reload)."
        ;;
    start)
        echo -n "starting puma..."
        puma
        ;;
    stop)
        echo "stoping puma..."
        kill `cat "shared/pids/puma.pid"`
        ;;
    reload)
        echo "reloading puma..."
        kill `cat "shared/pids/puma.pid"`
        puma
        ;;
esac
重啟服務(wù)器

重啟 Nginx
$ sudo service nginx restart

啟動(dòng) puma 服務(wù)器
$ ./pumactrl.sh start

如果一切正常,打開瀏覽器就可以看到你的網(wǎng)站首頁了。不過我是反復(fù)試了很多次才成功的......。有時(shí)候編程的復(fù)雜性不在于代碼邏輯本身,而是其他很多繁雜瑣碎的東西同時(shí)揉在一起產(chǎn)生的。

有幾個(gè)點(diǎn)需要注意:

  • 仔細(xì)檢查配置里的各種路徑
  • puma 配置里的 bind "unix://#{shared_dir}/sockets/puma.sock" 前綴是雙斜杠
  • 如果是生產(chǎn)環(huán)境下,需要先執(zhí)行一下 rails assets:precompile
  • 出現(xiàn)問題的時(shí)候檢查日志
    // nginx 日志
    /var/log/nginx/error.log
    
    // puma日志
    shared/log/puma.stderr.log
    
    // rails app 日志
    log/production.log
    

小結(jié)

服務(wù)器雖然能正常跑起來了,但是沒有做更細(xì)致的配置,可能性能不是很好,這個(gè)得更深一步的研究才能做了。為了方便部署,可以將 capistrano3-puma Gem 添加進(jìn)來,這個(gè)留待下次完成。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容