Rails Installation And Deployment
Installation
(最後更新: 2016-04-14)
[1] Update & Upgrade
sudo apt-get update
sudo apt-get upgrade -y
[2] Install RVM (Ruby Version Manager)
Install curl (MacOS doesn’t need to execute this)
sudo apt-get install curl
Install RVM
\curl -sSL https://get.rvm.io | bash -s stable
讀取 rvm
source ~/.rvm/scripts/rvm
安裝 rvm 自己相依的東西
rvm requirements
[3] Install Ruby
rvm install ruby
rvm use ruby --default
[4] Install RubyGems
rvm rubygems current
[5] Install rails
gem install rails
安裝 rails 的 doc 很久, 可以加上 -no-rdoc --no-ri
忽略 doc
[6] 安裝 node.js
sudo apt-get install nodejs
or mac
brew install node
[7] Test
cd /tmp
rails new rails_test
cd rails_test
rails s
預設 port 是 3000
Upgrade 己存在專案的 Rails 版本
安裝最新版本的 Rails
gem install rails
修改 Gemfile, 改成指定版本
gem 'rails', '4.2.3'
Update 專案引入的套件
bundle update
Deployment
(最後更新: 2016-04-14)
[1] 安裝 Passenger + Nginx
安裝 passenger
sudo apt-get install libcurl4-openssl-dev # passenger 需要
gem install passenger
安裝 nginx
rvmsudo passenger-install-nginx-module # 用 passenger 安裝 nginx
- 安裝在預設路徑
/opt/nginx
, 千萬不要改, 免得 nginx 指令會無效
- 如果有出現
export rvmsudo_secure_path=1
執行它
- 記憶體太少可能會導致安裝失敗, 如果顯示要你增加 swap 可參考此篇
如果安裝 passenger-install-nginx-module
發生錯誤
/home/web-admin/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/rubygems/specification.rb:2158:in `method_missing': undefined method `this' for #<Gem::Specification:0xdf627c passenger-5.0.27> (NoMethodError)
from /home/web-admin/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/rubygems/specification.rb:1057:in `find_active_stub_by_path'
from /home/web-admin/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:64:in `require'
from /home/web-admin/.rvm/gems/ruby-2.3.0/gems/passenger-5.0.27/bin/passenger-install-nginx-module:33:in `<top (required)>'
from /home/web-admin/.rvm/gems/ruby-2.3.0/bin/passenger-install-nginx-module:23:in `load'
from /home/web-admin/.rvm/gems/ruby-2.3.0/bin/passenger-install-nginx-module:23:in `<main>'
from /home/web-admin/.rvm/gems/ruby-2.3.0/bin/ruby_executable_hooks:15:in `eval'
from /home/web-admin/.rvm/gems/ruby-2.3.0/bin/ruby_executable_hooks:15:in `<main>'
看起來可能是我預設用 ruby-2.3 發生問題,所以先降回 ruby-2.2
rvm install ruby-2.2.4
rvm use ruby-2.2 --default
再安裝一次就成功了!
[2] 安裝成功後設定根目錄
建立 /var/www
目錄
設定 /opt/nginx/conf/nginx.conf
, 將 location / {
範圍內註解掉, 並在 http {
內加上 :
error_log /var/www/rails_app/log/nginx_error.log;
access_log /var/www/rails_app/log/nginx_access.log;
server {
listen 80;
server_name 106.185.47.26; # or domain name
root /var/www/rails_app/public;
passenger_enabled on;
}
- nginx 執行時的 user 可以不用特別指定, 預設是
- 如果要跑 development 環境則加上
rails_env development;
[3] 安裝 nginx 指令
如果有開 tmux 記得關掉再執行 :
cd /tmp
wget -O init-deb.sh https://www.linode.com/docs/assets/660-init-deb.sh
sudo mv init-deb.sh /etc/init.d/nginx
sudo chmod +x /etc/init.d/nginx
sudo /usr/sbin/update-rc.d -f nginx defaults
start
sudo /etc/init.d/nginx start
or
sudo service nginx start
[4] 把 code 放到 /var/www
bundle install
如果顯示 bundle 沒安裝,執行:gem install bundle
[5] 環境
development :
rake db:migrate RAILS_ENV=development
production :
-
產生 Key
rake secret # 產生key
-
設定 secret, 有兩種方式, 擇一就好
第一種
config/secrets.yml
production:
secret_key_base: cf2d4472039660a31a002b21cd3ded0cf7cc2c5a0d82f24dcdf5097b79c1900241f97eb85542f8e4a349f32fac37b618bc663b21f16de2706bb897885d6cc3f0
第二種
1) nginx.conf :
passenger_env_var SECRET_KEY_BASE "cf2d4472039660a31a002b21cd3ded0cf7cc2c5a0d82f24dcdf5097b79c1900241f97eb85542f8e4a349f32fac37b618bc663b21f16de2706bb897885d6cc3f0";
2) config/secrets.yml
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
- DB migrate + Assets precompile
First time :
RAILS_ENV=production rake db:create
RAILS_ENV=production rake db:migrate
Update code :
RAILS_ENV=production bundle exec rake assets:precompile
-
Restart web server
sudo service nginx restart
Troubleshootings
出現錯誤 500 We're sorry, but something went wrong.
-
判斷是 nginx 的 500 還是 Rails 的 500 (看頁面的 html 及 css 可以判斷)
-
500 的話先看, 目錄權限有沒有問題, www.example.com/robots.txt
讀取 public/robots.txt
看通不通
注意, 如果放在 /root
下, 因為 /root
的權限還是 root 的, 即使網站 foler 改成 www-data
也沒用, 建議放在 /var/www
下, /var/www
權限記得要給 www-data
nginx 預設 user 是 nobody, 建議改成 www-data, 並且確定網站根目錄的權限也是 www-data
-
當 nginx 及 rails log 都沒有異樣, 執行 RAILS_ENV=production rails c
看有沒有錯誤, 如果有錯誤會導致 nginx 的 500
-
檢查在 development 環境是否正常 rails s -b 0.0.0.0
-
檢查 production 是否正常 RAILS_ENV=production rails s -b 0.0.0.0
確定有做 assets precompile, 如果 public/assets
有檔案但 404
environments/production.rb, 改成 true :
config.assets.compile = true
確定網頁都沒有 404 等等之類的問題
- 再回去看
log/production.log
有沒有異常
很有可能會發生內建的 http server : WEBrick 執行的權限是夠的, 但 nginx 執行權限不夠導致錯誤
I18n 導致錯誤
I, [2015-08-22T06:53:22.272463 #7927] INFO -- : Completed 500 Internal Server Error in 490ms (ActiveRecord: 0.0ms)
F, [2015-08-22T06:53:22.273759 #7927] FATAL -- :
I18n::InvalidLocaleData (can not load translations from /usr/local/rvm/gems/ruby-2.2.1/gems/devise-i18n-views-0.3.4/lib/../locales/pt-PT.yml: #<Errno::EACCES: Permission denied @ rb_sysopen - /usr/local/rvm/gems/ruby-2.2.1/gems/devise-i18n-views-0.3.4/lib/../locales/pt-PT.yml>):
app/controllers/application_controller.rb:18:in `set_locale'
調整權限
chmod -R 777 /usr/local/rvm/gems/ruby-2.2.1/gems
沒有 permission 問題後, 網頁就能 work 了
403 Forbidden
以下有幾個方向可以找出問題在哪裡 :
- 重啟 nginx 看看有沒有出現什麼異常的訊息,有可能
passenger_root
路徑設定錯導致找不到檔
- 確定網站根目錄的權限是 nginx 可以執行的
- 去 nginx 的 error log 看看有沒有線索
完整的 nginx.conf
- 區分 dev (3000 port) / production 環境 / ssl
- passenger_root : 可用
passenger-config --root
得知
- passenger_ruby : 可用
passenger-config --ruby-command
得知
/opt/nginx/conf/nginx.conf
:
user web-admin;
worker_processes 1;
events {
worker_connections 1024;
}
http {
passenger_root /usr/local/rvm/gems/ruby-2.2.1/gems/passenger-5.0.15;
passenger_ruby /usr/local/rvm/gems/ruby-2.2.1/wrappers/ruby;
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
server {
listen 443 ssl;
ssl_certificate /opt/nginx/ssl/example_combined.crt;
ssl_certificate_key /opt/nginx/ssl/example.key;
client_max_body_size 50M;
listen 80;
server_name example.com;
# non-www redirect to www
if ($host = $server_name) {
return 301 https://www.$server_name$request_uri;
}
# 將 http 導到 https
if ($scheme = http) {
return 301 https://www.$server_name$request_uri;
}
# 注意 owner 可能引發 500
root /var/www/example/public;
passenger_enabled on;
rails_env production;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 3000;
server_name dev.example.com;
client_max_body_size 50M;
# 注意 owner 可能引發 500
root /var/www/example/public;
passenger_enabled on;
rails_env development;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
其他
關閉 Development 環境的錯誤訊息
config/environments/development.rb
config.consider_all_requests_local = false
重啟 Rails app
在網站根目錄下新增
touch tmp/restart.txt
Reload 頁面就會觸發重新啟動
Once Passenger has noticed that the file’s timestamp has changed, it will restart the application.