CapistranoでRailsをVPSにデプロイするとき詰まった点

# この記事について
この記事はインフラ初心者がWebページをVPS上で公開したい！って思ってやったことを備忘録として書き残したものです。素人が書いているため情報の信憑性は保証しません。詳細は各自で調べながらやることをおすすめします。記事のとおりにやっておかしなことになっても責任は取れませんのでご了承ください。

# Capistranoの設定
基本的にこのサイトの説明がとても分かりやすかったのでこれに従って進めていきます。この記事では詰まった点をいくつか書いていきます。
https://pikawaka.com/rails/capistrano

# 詰まった点1 データベース
私は普段postgresqlを使って開発を行っているため、VPS上でpostgresqlの設定をしなくてはなりませんでした。
インストールについては公式ページに書いてあるコマンドで
https://www.postgresql.org/download/linux/ubuntu/

自分のアカウントのロールがないため、ロールを作成します。このサイトに従って自分のアカウントのロールを作成。
https://qiita.com/sibakenY/items/407b721ad1bd0975bd00
```
su postgres
psql
CREATE ROLE rolename LOGIN CREATEDB CREATEROLE PASSWORD 'password';
```

時系列的には後の話になるのですが、`gem 'pg'`インストールしようとすると`Unable to find PostgreSQL client library.`と怒られ、
```
Please install libpq or postgresql client package like so:
      01   sudo apt install libpq-dev
      01   sudo yum install postgresql-devel
      01   sudo zypper in postgresql-devel
      01   sudo pacman -S postgresql-libs
```
と言われたので言われたとおりやります。
```
% sudo apt install libpq-dev
```

# 詰まった点2 SSH接続
`bundle exec cap production deploy`を実行すると`fingerprint xxxxxx does not match for xxx.xx.xxx.xxx`というエラーが出ました。`known_hosts`の中に接続先のものが登録されていないとか？

このサイトに従ってdeploy.rbを修正したら通りました。
https://www.appsloveworld.com/ruby/100/9/capistrano-error-netsshhostkeymismatch

# 詰まった点3 rubyのインストール
これに関しては詰まったというほどのことではないですが、VPSにrubyをインストールしておきましょう、と。
普段どおりrbenvからrubyをインストールします。

https://github.com/rbenv/rbenv

っと思いきや`sudo apt install rbenv`でインストールすると最新のバージョンがインストールできない様子だった。
```
% rbenv install 3.1.2
ruby-build: definition not found: 3.1.2

See all available versions with `rbenv install --list'.

If the version you need is missing, try upgrading ruby-build.
```

というわけで[この記事](https://qiita.com/tomono-t/items/5e5df47097658eaff01b)に書いてあるようにgit cloneする形でrbenvをインストールします。
```
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'eval "$(~/.rbenv/bin/rbenv init - zsh)"' >> ~/.zshrc # zshの場合
```

すると今度は`rbenv install`ができない、と。
```
% rbenv install -l
rbenv: no such command `install'
```
[公式](https://github.com/rbenv/rbenv#installing-ruby-versions)に書いてあるとおりにしてみるとできるようになった。(スペックが低いせいかやたらインストールに時間がかかった)
```
git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
```

# 詰まった点4 Permission Denied
`/var/www`への書き込み権限がないとかで怒られました。
```
mkdir:
cannot create directory ‘/var/www/rails_template’
: Permission denied
```

[この記事](https://stackoverflow.com/questions/24470520/capistrano-mkdir-permission-denied)に従ってディレクトリの所有者を変えます。
```
sudo chown -R username:username /var/www/
```

# 詰まった点5 not a valid object name: master
デフォルトブランチを`master`ではなく`main`にしてるせいと思われる。
```
Caused by:
SSHKit::Command::Failed: git exit status: 2
git stdout: Nothing written
git stderr: fatal: not a valid object name: master
tar: This does not look like a tar archive
tar: Exiting with failure status due to previous errors

Tasks: TOP => git:create_release
(See full trace by running task with --trace)
The deploy has failed with an error: Exception while executing as ansai@133.18.236.168: git exit status: 2
git stdout: Nothing written
git stderr: fatal: not a valid object name: master
tar: This does not look like a tar archive
tar: Exiting with failure status due to previous errors
```

[この記事](https://qiita.com/TO-TO/items/536ac203cfa082b8ac96)に従って`deploy.rb`を書き換えましょう。
```config/deploy.rb
set :branch, "main"
```

# 詰まった点6 Missing 'secret_key_base'
こんなエラーが出た。
```
ArgumentError: Missing `secret_key_base` for 'production' environment, set this string with `bin/rails credentials:edit`
```

master.keyとかをちゃんと送れてないとかかな？
[この記事](https://naka-no-mura.hateblo.jp/entry/capistrano_missing_secret_key_base)を参考に修正。

ローカルでこれを実行
```
$ rake secret
1111111111222222222233333333...
```
サーバーで`/var/www/app_name/shared/config/secrets.yml`を修正
```/var/www/app_name/shared/config/secrets.yml
production:
    secret_key_base: 1111111111222222222233333333...
```

# 詰まった点7 環境変数の設定
capistrano-unicornを使うと環境変数が読み込まれないっぽい。unicornはsystemdを使って起動することにします。今回はとりあえず手動で起動します。
まずは`/etc/environment`に環境変数を書きます。
```/etc/environment
HOGE=...
FUGA=...
```
deploy.rb・Capfileのunicornに関する記述を消し、Gemfileからcapistrano3-unicornを削除。
unicornは`/var/www/rails_app/current`で
```
RAILS_ENV=production bundle exec unicorn -c config/unicorn.rb -E production -D
```
を実行すると起動します。
unicornを停止するにはこれを実行。↓
```
kill -QUIT `cat /var/www/rails_app/shared/tmp/pids/unicorn.pid`
```

# 詰まった点8 Postgresとの接続
postgresを使う場合は[この記事](https://github.com/capistrano-plugins/capistrano-postgresql)に従って[capistrano-postgresql](https://github.com/capistrano-plugins/capistrano-postgresql)を入れる必要がある。
また、`/var/www/rails_app/shared/config/database.yml`に`config/database.yml`の内容をコピペする。その際`production`の部分の`username`、`password`を自分のアカウントのユーザー名とパスワードに変えておく。
そんでデータベースを作成。
```
sudo su postgres
psql
create database rails_app_production with owner=account_name;
```

# 詰まった点9 bundler: failed to load command: unicorn
appのディレクトリが違ってた。これ以外にもプロセスIDのパスとか全部修正した。
```
# アプリケーションのディレクトリ
working_directory root_path

# プロセスIDの保存先を指定
pid "/var/www/rails_app/shared/tmp/pids/unicorn.pid"

# ポート番号を指定
listen '/var/www/rails_app/shared/tmp/sockets/unicorn.sock'

# エラーのログを記録するファイルを指定
stderr_path '/var/www/rails_app/shared/log/unicorn.stderr.log'

# 通常のログを記録するファイルを指定
stdout_path '/var/www/rails_app/shared/log/unicorn.stdout.log'
```

# 詰まった点10 Missing service adapter for "GCS"
`gem 'google-cloud-storage'`をGemfileに追加する
https://qiita.com/kyamad/items/7516ac4c69e18324ed3c

# 補足1
`/etc/nginx/conf.d/*.conf`ファイルがnginxの設定ファイルとして読み込まれるため、[この記事](https://pro-broccoli.com/2021/08/14/virtualhost/)に従って`server_name`を自由に変えるとバーチャルホスティングができる。cloudflareを使っている場合はDNSの設定が必要。

# 補足2
githubレポジトリの中のサブディレクトリとしてRailsアプリを配置している場合は`deploy.rb`に以下を追加する必要がある。
参考: https://stackoverflow.com/questions/41983153/how-do-i-get-the-path-for-the-release-being-deployed-in-capistrano-3
```
# ワーキングディレクトリをrails_appに移す
after "deploy:set_current_revision", "deploy:checkout_subdir"
namespace :deploy do
  desc "Checkout subdirectory and delete all the other stuff"
  task :checkout_subdir do
    subdir = "rails_app" # ここをサブディレクトリ名にする
    on roles(:app) do
      last_release = capture(:ls, "-xt", releases_path).split.first
      last_release_path = releases_path.join(last_release)
      execute "rm -rf /tmp/#{subdir} && mv #{last_release_path}/#{subdir}/ /tmp && rm -rf #{last_release_path}/* && mv /tmp/#{subdir}/* #{last_release_path}"
    end
  end
end

```

# 参考資料
【Rails】 Capistranoを使ってデプロイを自動化しよう
https://pikawaka.com/rails/capistrano

postgresqlの設定
https://qiita.com/sibakenY/items/407b721ad1bd0975bd00

[SOLVED]-CAPISTRANO ERROR - NET::SSH::HOSTKEYMISMATCH-RUBY
https://www.appsloveworld.com/ruby/100/9/capistrano-error-netsshhostkeymismatch

rvenv install -lで欲しいrubyバージョンが見つからない時
https://qiita.com/tomono-t/items/5e5df47097658eaff01b

Capistrano mkdir permission denied
https://stackoverflow.com/questions/24470520/capistrano-mkdir-permission-denied

Capistrano自動デプロイ時のエラー。"fatal: not a valid object name: master"の解消メモ
https://qiita.com/TO-TO/items/536ac203cfa082b8ac96

【Rails×Capistrano】自動デプロイしようとしたら「ArgumentError: Missing `secret_key_base` for ‘production’ environment, set this string with `rails credentials:edit`」
https://naka-no-mura.hateblo.jp/entry/capistrano_missing_secret_key_base

Capistrano and environment variables
https://stackoverflow.com/questions/23672631/capistrano-and-environment-variables

capistrano-dotenv
https://jplethier.medium.com/capistrano-dotenv-68f107c91d7e

【Rails】本番環境構築で Missing service adapter for "GCS" と怒られる
https://qiita.com/kyamad/items/7516ac4c69e18324ed3c

【Nginx】バーチャルホストで複数のドメインを設定する
https://pro-broccoli.com/2021/08/14/virtualhost/

How do I get the path for the release being deployed in Capistrano 3?
https://stackoverflow.com/questions/41983153/how-do-i-get-the-path-for-the-release-being-deployed-in-capistrano-3