在 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

參考

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