Ruby on Rails 终极部署方案 nginx+mina+puma
搭建工具介紹
Ruby on Rails作為一款十分優秀的web開發框架,在當前web領域中慢慢占據了越來越重要,秉承rails快速開發的特點,很多快速部署rails的方案也越來越多。這篇文章中所選的方案是我個人認為十分優秀的部署方案。這套部署方案的結構是,nginx作為反向代理服務器負責負載均衡,mina作為自動化部署工具,puma作為rails的web服務器
nginx
nginx是一款優秀的代理服務器,其高效的性能已經得到了業界的廣泛認可,相信作為web開發人員不會沒聽說過他的大名
mina
mina是一款由ruby開發的自動化部署工具,其目的是為了簡化每次rails代碼提交時的部署,一鍵完成部署,杜絕了提交到git服務器后,又去服務器上git pull的情況
puma
puma是一款專門針對rails的并發服務器,相對于passenger,puma可配置面更廣,而且性能比passenger更高,是rails web服務器的不二之選
部署前言
由于這篇文章需要很多鋪墊,包括rails的安裝下載,git的配置等等,需要讀者自己去查閱資料或者查閱之前我寫過的一些文章,如果期間有什么問題,請留言。。
mina
首先在你的rails項目的Gemfile中加上
rubygem mina運行bundle 安裝 mina,接著在你的rails項目根目錄初始化mina
mina init這是在你項目的config目錄下會有一個deploy.rb,配置deploy.rb,列出重點部分,每一行的解釋會附在代碼的注釋里
ruby#服務器地址,是使用ssh的方式登錄服務器 set :domain, 'root@192.168.0.103' #服務器中項目部署位置 set :deploy_to, '/var/www/ruby_sample' #git代碼倉庫 set :repository, 'https://github.com/gameFu/ruby_sample.git' #git分支 set :branch, 'master'# 中括號里的文件 會出現在服務器項目附錄的shared文件夾中,這里加入了secrets.yml,環境密鑰無需跟開發計算機一樣 set :shared_paths, ['config/database.yml', 'log', 'config/secrets.yml']# 這個塊里面的代碼表示運行 mina setup時運行的命令 task :setup => :environment do# 在服務器項目目錄的shared中創建log文件夾queue! %[mkdir -p "#{deploy_to}/#{shared_path}/log"]queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/log"]# 在服務器項目目錄的shared中創建config文件夾 下同queue! %[mkdir -p "#{deploy_to}/#{shared_path}/config"]queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/config"]queue! %[touch "#{deploy_to}/#{shared_path}/config/database.yml"]queue! %[touch "#{deploy_to}/#{shared_path}/config/secrets.yml"]# puma.rb 配置puma必須得文件夾及文件queue! %[mkdir -p "#{deploy_to}/shared/tmp/pids"]queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/tmp/pids"]queue! %[mkdir -p "#{deploy_to}/shared/tmp/sockets"]queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/tmp/sockets"]queue! %[touch "#{deploy_to}/shared/config/puma.rb"]queue %[echo "-----> Be sure to edit 'shared/config/puma.rb'."]# tmp/sockets/puma.statequeue! %[touch "#{deploy_to}/shared/tmp/sockets/puma.state"]queue %[echo "-----> Be sure to edit 'shared/tmp/sockets/puma.state'."]# log/puma.stdout.logqueue! %[touch "#{deploy_to}/shared/log/puma.stdout.log"]queue %[echo "-----> Be sure to edit 'shared/log/puma.stdout.log'."]# log/puma.stdout.logqueue! %[touch "#{deploy_to}/shared/log/puma.stderr.log"]queue %[echo "-----> Be sure to edit 'shared/log/puma.stderr.log'."]queue %[echo "-----> Be sure to edit '#{deploy_to}/#{shared_path}/config/database.yml'."] end#這個代碼塊表示運行 mina deploy時執行的命令 desc "Deploys the current version to the server." task :deploy => :environment doto :before_hook doenddeploy do#重新拉git服務器上的最新版本,即使沒有改變invoke :'git:clone'#重新設定shared_path位置invoke :'deploy:link_shared_paths'invoke :'bundle:install'invoke :'rails:db_migrate'invoke :'rails:assets_precompile'invoke :'deploy:cleanup'to :launch doqueue "mkdir -p #{deploy_to}/#{current_path}/tmp/"# queue "chown -R www-data #{deploy_to}"queue "touch #{deploy_to}/#{current_path}/tmp/restart.txt"endend end
這樣一來mina的基本配置就完成,接下來只要將你開發環境的項目上傳到git服務器,然后運行下面的命令就完成了
mina deploy完成部署后,你就可以在指定的服務器目錄下看到你的項目,目錄結構如下
- current -當前版本目錄也就是項目目錄
- last_version -版本號
- releases/ -過去的版本
- scm/
- shared/ 先前shared_path所設定另外拉出來的文件都在這里
- tmp/
這里需要注意的幾點
1.shared_path里面的文件不僅僅是表示這些文件會在服務器目錄中出現在另外的目錄里,也表示這些文件或者目錄不會受到git版本庫的控制,也就是說這些文件的配置必須在你服務器中手動去配置,這兩個文件包括database.yml和secrets.yml,在shared/config目錄下
2.針對deploy最好在服務器創建一個使用者,并針對他創建一個ssh authorized_keys,這里直接使用了root身份,參考centos7 服務器部署ssh證書授權登錄,這樣做能避免每次部署的時候都需要輸入服務器賬號密碼
可能會遇到的問題
由于生產環境一般會搭配類似于postgresql等成熟數據庫,這里我就舉出一個搭建postgresql,首先是啟動數據庫時(centos 7下),如果遇到問題請使用下面的命令就能看到詳細的錯誤信息
systemctl status postgresql-9.4.service -l然后在跑mina deploy時可能會報類似于這樣的一個錯誤
Gem::LoadError: Specified 'postgresql' for database adapter, but the gem is not loaded. Add `gem 'pg'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord).從錯誤信息上能很明顯的看出是因為沒有安裝pg這個包導致的,但是有一種情況是明明在項目的Gemfile上寫上了pg但還是跑不過,造成這個的原因,可能是由于你的服務器環境缺少了pg的頭文件導致的,如果是在centos下,只需要執行下面命令就能解決
yum install postgresql-libs yum install postgresql-develPuma
首先在你的Gemfile里加上
rubygem puma
然后在config目錄下手動創建一個puma.rb文件,配置puma.rb文件
ruby#!/usr/bin/env puma#rails的運行環境 environment 'production' threads 2, 64 workers 4#項目名 app_name = "ruby_sample" #項目路徑 application_path = "/var/www/#{app_name}" #這里一定要配置為項目路徑下地current directory "#{application_path}/current"#下面都是 puma的配置項 pidfile "#{application_path}/shared/tmp/pids/puma.pid" state_path "#{application_path}/shared/tmp/sockets/puma.state" stdout_redirect "#{application_path}/shared/log/puma.stdout.log", "#{application_path}/shared/log/puma.stderr.log" bind "unix://#{application_path}/shared/tmp/sockets/#{app_name}.sock" activate_control_app "unix://#{application_path}/shared/tmp/sockets/pumactl.sock"#后臺運行 daemonize true on_restart doputs 'On restart...' end preload_app!
這里需要注意的地方
- threads - puma的線程數,第一個參數是最小的線程數,第二個參數是最大線程數
- bind - 這個指定的是puma運行時產生的socket,后面nginx會用到
- 這里所有對應的目錄是在deploy配置中配置的,如果需要更改配置目錄,deploy.rb也需要相應的更改
Nginx
下載安裝nginx后,打開nginx的配置文件nginx.conf進行配置
nginx worker_processes 1;error_log /var/log/nginx/error.log warn;pid /var/run/nginx.pid;events {worker_connections 1024;}http {include /etc/nginx/mime.types;default_type application/octet-stream;log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log /var/log/nginx/access.log main;sendfile on;#tcp_nopush on;keepalive_timeout 65;#gzip on;#include /etc/nginx/conf.d/*.conf;upstream deploy {server unix:///var/www/ruby_sample/shared/tmp/sockets/ruby_sample.sock;}server {listen 80;server_name your.server.domain.ip; # change to match your URLroot /var/www/ruby_sample/current/public; # I assume your app is located at this locationlocation / {proxy_pass http://deploy; # match the name of upstream directive which is defined aboveproxy_set_header Host $host;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}location ~* ^/assets/ {# Per RFC2616 - 1 year maximum expiryexpires 1y;add_header Cache-Control public;# Some browsers still send conditional-GET requests if there's a# Last-Modified header or an ETag header even if they haven't# reached the expiry date sent in the Expires header.add_header Last-Modified "";add_header ETag "";break;}}}這里只需要注意的是
- upstream中 server 要配置成你在puma中bind的 socket就行了
- root要設置成你服務器項目的根目錄,也就是puma.rb中的 directory
接下里只需要重啟nginx服務器,整個rails的環境就搭建完成了
nginx -s reload
如果完成了配置后訪問站點是504,那么可能是兩種情況,一是服務器防火墻問題,二是rails環境密鑰的問題,請在使用passenger在Centos7部署nginx+Ruby on Rails中尋找答案
總結
以上是生活随笔為你收集整理的Ruby on Rails 终极部署方案 nginx+mina+puma的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 13年前买iPhone 4都舍不得!张一
- 下一篇: 【IT之家评测室】ROG 幻 16 经典