在 Ubuntu 20 安裝 Rails 6 (Apache, Passenger, Ruby 3, PostgreSQL)
2021.4.23-27
Mac Local 端開發、測試
使用 asdf 做 Ruby 版本管理
參考 asdf 的文件說明,使用 Homebrew 在 mac 上安裝 asdf:
$ brew install coreutils curl git
$ brew install asdf
參考 asdf-ruby 安裝 plugin
asdf plugin-add ruby https://github.com/asdf-vm/asdf-ruby.git
使用 asdf 安裝 ruby 3.0.0
$ asdf install ruby 3.0.0
將 3.0.0 設為 ruby 預設版本
$ asdf global ruby 3.0.0
檢視 ruby 版本
$ ruby -v
更新 bundler
$ gem update --system
$ bundle -v
安裝 Rails
$ gem install rails -v 6.1.3.1
檢視 rails 版本
$ rails --version
創建新的 rails 專案,假設專案名稱為 xxx
$ rails new xxx
編輯 Gemfile
把 sqlite3 gem 移到 development 或 test 環境裡:
group :development, :test do
gem 'sqlite3', '~> 1.4'
end
在 mac 上開發,所以 Gemfile 的最後一行可以 mark 掉:
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
#gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
指定 Ruby 版本的這一行也可以去掉:
ruby '3.0.0'
改用 asdf 在 rails 專案資料夾下建檔 .tool-versions, 設定本專案使用的 Ruby 版本:
$ asdf local ruby 3.0.0
開始在 development 環境開發、測試。
設定 alias for bundle exec
編輯 .zshrc
alias be='bundle exec'
Local 端安裝、設定 Capistrano
參考
Capistrano: https://github.com/capistrano/rails
Passenger Deployment: installations
edit local Gemfile
group :development do
gem "capistrano", "~> 3.10", require: false
gem "capistrano-rails", "~> 1.6", require: false
gem 'capistrano-passenger'
gem 'capistrano-asdf'
end
group :production do
gem 'pg'
end
設定 bundle 在 local 不要安裝 production gems
$ bundle config set --local without 'production'
安裝
$ bundle install
Capistrano 初始化
$ be cap install
Capfile
編輯 Capfile
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano/passenger'
require 'capistrano/asdf'
Credentials
使用 Visual Studion Code 做為編輯器
EDITOR="code --wait" bin/rails credentials:edit
編輯內容:
secret_key_base: xxx
上面的 xxx 要取代為真正的 key.
deploy.rb
在 config/deploy.rb 裡設定 deploy 到各個環境(stage)的共用資訊 (假設專案名稱為 xxx)
# 下面的 xxx 改為專案名稱
set :application, 'xxx'
# 專案 Source 的 GitHub 網址
set :repo_url, 'git@github.com:MyGitHubAccount/xxx.git'
# 本來的 Default branch 是 :master
# 但是 GitHub 從 2020-10 起的預設 branch 由 master 改為 main
# 所以這裡的設定改成預設為 current branch, 並先詢問確認
ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp
# deploy_to 是 server 上要放置本專案的路徑。要在 server 上把這個資料夾建好。
set :deploy_to, '/project/path/on/server'
# linked_files, 會建一個 symbolic link 由 current/config/database.yml 指到 shared/config/database.yml.
append :linked_files, "config/database.yml", "config/master.key"
# 設定 passenger restart app 的方法是 touch restart.txt
set :passenger_restart_with_touch, true
# 上傳 master.key 到 server 上
namespace :deploy do
namespace :check do
before :linked_files, :set_master_key do
on roles(:app), in: :sequence, wait: 10 do
unless test("[ -f #{shared_path}/config/master.key ]")
upload! 'config/master.key', "#{shared_path}/config/master.key"
end
end
end
end
end
production.rb
編輯 config/deploy/production.rb
server 'example.com.tw', user: 'UserName', roles: %w{app db web}
上面的 example.com.tw 要換成 server 的網址。
UserName 要換成連上 server 的 user name.
把 application 放上 GitHub
在 GitHub 新建一個 project
在 local 端將 rails app project 初始化為 git repository
cd [ProjectRoot]
git init
gitignore
編輯 .gitignore 設定哪些東西不要放進 git
/config/database.yml
/config/master.key
.DS_Store
database.yml 裡面有密碼,不要放上 git.
.DS_Store 是 mac 產生的檔,也可以使用以下命令設為 global ignore:
git config --global core.excludesfile '~/.gitignore_global'
push
在 project root 下執行以下命令,push 到 GitHub:
git add .
git commit -m 'first commit'
git remote add origin git@github.com:xxx/xxx.git
git push -u origin master
上面的 git@github.com:xxx/xxx.git 要改成真正的 git repository path.
Server 安裝 apache, passenger
參考 Phusion Passenger 說明文件 Installing Passenger, Server 選擇 Ubuntu 20.04 LTS
安裝 Ubuntu 過程中就選擇安裝 apache server.
Install Passenger PGP key and add HTTPS support for APT
$ sudo apt-get install -y dirmngr gnupg
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
$ sudo apt-get install -y apt-transport-https ca-certificates
Add Passenger APT repository
$ sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger focal main > /etc/apt/sources.list.d/passenger.list'
$ sudo apt-get update
Install Passenger + Apache module
sudo apt-get install -y libapache2-mod-passenger
enable the Passenger Apache module and restart Apache
sudo a2enmod passenger
sudo apache2ctl restart
check installation
sudo /usr/bin/passenger-config validate-install
最後,檢查 Apache 是否啟動 Passenger core processes.
執行以下命令,應該要看到 Apache processes 以及 Passenger processes:
sudo /usr/sbin/passenger-memory-stats
Server 安裝 asdf, ruby, rails
參考 https://asdf-vm.com/#/core-manage-asdf
安裝 asdf
$ git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.8.0
編輯 ~/.bashrc
. $HOME/.asdf/asdf.sh
. $HOME/.asdf/completions/asdf.bash
logout 再 login, 確認 asdf 裝好了
$ asdf --version
v0.8.0-c6145d0
參考 asdf-ruby 安裝 plugin
asdf plugin-add ruby https://github.com/asdf-vm/asdf-ruby.git
使用 asdf 安裝 ruby 3.0.0
$ asdf install ruby 3.0.0
將 3.0.0 設為 ruby 預設版本
$ asdf global ruby 3.0.0
檢視 ruby 版本
$ ruby -v
設定安裝 ruby gem 時不要安裝 documentation, 編輯 ~/.gemrc
gem: --no-document
Check the Gem Manager
$ gem update --system
安裝 Nokogiri
$ gem update
$ gem install nokogiri
安裝 rails 6.1.3.1
gem install rails -v 6.1.3.1
如果希望在 server 上執行 rake 命令時都是 production mode, 可以編輯 ~/.bashrc
export RAILS_ENV=production
安裝 gem pg
如果不先安裝 libpq-dev 的話,安裝 pg 會有問題。
sudo apt-get install libpq-dev
gem install pg
PostgreSQL 設定
查看目前 server 上的 PostgreSQL 版本:
psql --version
安裝 PostgreSQL
sudo apt-get update
sudo apt-get install postgresql postgresql-contrib
新增資料庫 user
參考:PostgreSQL add or create a user account and grant permission for database
sudo adduser pgxxx
上面的 pgxxx 請改為真正的 user name, 通常我都是在 pg 後面加上專案名稱。
執行過程中要設定密碼,假設密碼設為 1234,後面會用到這個密碼。
新增 database, 並設權限
change to the postgres unix user
sudo su - postgres
執行
psql
create user pgxxx with password '1234';
create database xxx;
grant all privileges on database xxx to pg_xxx;
ALTER DATABASE xxx OWNER TO pgxxx;
ALTER USER pgxxx CREATEDB;
\q
上面的 xxx 請改為專案名稱。
要給 create database 的權限,才能執行 rake db:reset。(如果沒有 create database 權限,db:reset 在 create database 時會失敗,但是好像也沒關係,因為它還是重建所有 table,而且在 create database 之前,通常 drop database 就會失敗了,因為有其他 connection 存在。)
切換為原 user
exit
測試連線
sudo su - pgxxx
psql -d xxx -U pgxxx
成功後,輸入 \q 離開 psql,輸入 exit 切換回原 user。
在 server 上安裝 git
Ubuntu 20 似乎是預設就安裝了 git, 可以執行以下命令確認:
$ git --version
如果還沒有 git, 可使用如命令安裝:
$ sudo apt-get update
$ sudo apt-get install git
將 rails project 從 Local 端 deploy 到 server 上
參考:Deploying a Ruby app on a Linux/Unix production server with Passenger in Apache mode on Ubuntu 16.04 LTS (with APT)
ssh private key 要放在 ~/.ssh 裡面,這樣才能由 server 連到 gitlab 取得 source.
設權限,取消其他使用者的權限,否則後面的步驟會有錯誤:
chmod 600 ~/.ssh/id_rsa
前面 config/deploy.rb 裡有設 deploy_to,這是 server 上要放本專案路徑,要先建好。然後在 local 端 project root 下執行
cap production deploy
它會在 server 端建立專案資料夾,但是它會抱怨找不到 database.yml。
設定 database.yml
rails 根據 database.yml 來連上資料庫。下一步在 server 上的 project root 建立 shared/config/database.yml
production:
adapter: postgresql
encoding: unicode
database: xxx
host: localhost
pool: 5
username: pg_xxx
password: 1234
資料庫初始化
一開始可能需要手動在 server 上 project root 的 current 資料夾裡執行:
rake db:migrate
設定 apache
決定 Passenger 要使用的 Ruby
執行以下命令:
$ passenger-config about ruby-command
把結果裡的「To use in Apache」的這段複製起來,下面會用到:
PassengerRuby /home/ray/.asdf/installs/ruby/3.0.0/bin/ruby
網址是獨立 DNS
例如 http://xxx.dila.edu.tw
新增 /etc/apache2/sites-available/xxx.conf,內容範例:
<VirtualHost *:80>
ServerName xxx.dila.edu.tw
DocumentRoot /var/www/xxx/current/public
PassengerRuby /home/ray/.asdf/installs/ruby/3.0.0/bin/ruby
<Directory "/var/www/xxx/current/public">
Allow from all
Options -MultiViews
</Directory>
</VirtualHost>
enable
sudo a2ensite xxx
重新啟動 apache
sudo service apache2 restart
網址使用 subdirectory
例如 http://xxx.dila.edu.tw/SubURI
假設 rails project root: /var/www/ProjectName/current
編輯 /etc/apache2/sites-available/ProjectName.conf
Alias /SubURI /var/www/ProjectName/current/public
<Location /SubURI>
PassengerBaseURI /SubURI
PassengerAppRoot /var/www/ProjectName/current
PassengerRuby /home/ray/.asdf/installs/ruby/3.0.0/bin/ruby
</Location>
<Directory /var/www/ProjectName/current/public>
Allow from all
Options -MultiViews
</Directory>
或編輯 /etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
...
Include sites-available/ProjectName.conf
...
</VirtualHost>
或編輯 /etc/apache2/sites-available/000-default-le-ssl.conf
<VirtualHost *:443>
...
Include sites-available/ProjectName.conf
...
</VirtualHost>
重新啟動 apache2
sudo service apache2 restart
Bootstrap, jQuery
參考 How to install Bootstrap and jQuery on Rails 6, 2020-04-27