【Ruby】非RailsアプリをCapistranoでデプロイする

2020年8月4日Ruby

こんにちは、しきゆらです。
今回は、タイトル通り非Railsアプリのデプロイ作業をCapistranoで自動化するための手順をメモしておきます。

Capistranoといえば、Ruby製のデプロイツールです。
A remote server automation and deployment tool written in Ruby. | https://capistranorb.com/

Capistranoさん自体はRubyやRails専用ではなく、様々なものをデプロイすることができるように設計されています。
とはいえ、調べて出てくる情報の大半はRailsのデプロイについてばかり。
Sinatraのデプロイすら情報が少ないような状態です。
そんな中で、非Railsどころかただ単にCronなどで定期実行するだけの簡単なスクリプトを自動でデプロイするのを自動化する情報なんて見つけるのが難しい。

ということで、今回はフレームワークを使っていないただのRubyスクリプトをCapistranoを使ってサーバへデプロイする方法をメモしておきます。


準備

まずは、Capistranoさんをインストールします。
Gemfileに以下のように書いてbundle installします。

group :development do 
  gem "capistrano" # Capistrano本体
  gem "capistrano-bundler" # bundlerを使っているならあると便利
  gem "capistrano-rbenv" # rbenvを使っているなら便利
end

インストール後、以下のコマンドでCapistranoのセットアップをします。
必要な設定ファイルやディレクトリを作ってくれます。

bundle exec cap install

Capistranoさんの設定

Rails等のフレームワークを使っている場合は、それぞれに合った小難しい設定を追記する必要がありますが
今回のような単なるRubyスクリプトをデプロイするだけであればそんなのものは必要ありません。
Capistranoさん自体のデプロイ先の設定等の簡単な設定をしていきます。
以下のようなサイトを参考に、書いていきます。

参考
入門 Capistrano 3 ~ 全ての手作業を生まれる前に消し去りたい | エンジニアブログ | GREE Engineering | https://labs.gree.jp/blog/2013/12/10084/
Capistranoでデプロイ自動化 – kumilog.net | https://www.kumilog.net/entry/cap-deploy

# config/deploy.rb
 lock "~> 3.14.1"
 
 set :application, "app_name" # アプリ名を自由に設定 
 set :repo_url, "repository_url" # Gitなどで管理しているリポジトリのURL
 
 # Default branch is :master
 # ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp
 set :branch, :master # デプロイするブランチをmasterに設定
 
 set :deploy_to, "/path/to/app" # デプロイ先のパス
 
 set :password, ENV["PASSWORD"] # 今回はRSAではなくパスワード認証でサーバへアクセスするためパスワードを環境変数から取得
 set :ssh_options, {
   port: 22, # 別ポートで利用しているのであれば変更
   user: "user_name", # SSHで接続するユーザ
   auth_methods: %w[password], # 今回はPassword認証、危ないので公開鍵認証の方が良い
   password: fetch(:password) # 上で取得したパスワードを設定
 }
 
 set :rbenv_ruby, File.read(".ruby-version").strip
 set :bundle_jobs, 2 # 環境に応じてよしなに
# config/deploy/production.rb # デプロイ環境ごとにファイルを分ける
 # 今回はproductionのみなので、自動生成された物に記述する
 
 server "IP Addr or URL",
        user: fetch(:user),
        roles: %w[app]
 
 set :user, "user_name"

設定はこれだけ。
デプロイ先の設定と、デプロイ時のbundlerなどの設定だけです。

独自タスクの追加

追加でほしくなるのは、Gitで管理していないけど実行時には必要なファイルのアップロード。
Capistranoさんは、デプロイに必要なタスクは標準で用意してくれていますが、必要があれば独自のタスクを追加して手順に追加することができます。
今回は、Google Driveへアクセスするための認証ファイル(client_secret.json)をアップロードするためのタスクを追加してみます。

 # lib/capistrano/tasks/upload.rake
 namespace :upload do
   desc "gitにないファイルをアップする"
   task :client_secret do
     on roles(:app) do
       upload! "client_secret.json", "#{shared_path}/client_secret.json"
       append :linked_files, "client_secret.json"
     end
   end
 end

 after "deploy:set_current_revision", "upload:client_secret" # deploy:set_current_revisionの後に実行するよう指定

見ての通り、単なるRakeです。
書いたことがなくても、ほぼ素のRubyなので難しくはないかと思います。

注意すべきなのは、最後の部分。
定義したタスクをどのタイミングで実行させるかを指定する必要があります。
デプロイタスクの一覧はbundle exec cap production deploy --dry_runbundle exec cap -Tで確認できます。
特に、前者は実際のデプロイタスクの実行手順通りに表示されるので、必要なタイミングを確認して指定してあげればOK。

今回は必要ないのでファイル名を単純に指定しているだけですが、複数アップロードする場合は配列等にファイル名を入れてeachで回せばよいと思います。
簡単ですね。

デプロイしてみる

設定自体は上記で完了。
独自にタスクを組み込んでいる場合は、改めてbundle exec cap production deploy --dry-runで定義したタスクがきちんと呼び出されているかを確認しておくとよいかと思います。

問題なければ、デプロイしてみます。
bundle exec cap production deploy

あとは、デプロイタスクが流れるので見ながら終わるのを待ちましょう。
問題なく終了すれば完了です。
お疲れさまでした。

今回躓いたポイント

設定している中で、うまくいかなかったポイントをメモしておきます。
なお、上記の設定はこのポイントを踏まえたうえで書いてあります。

つまずいた状況を書いておくと、デプロイすると定義したアップロードタスクの中で「Not such as File or Directory」と怒られてしまうというもの。
この時の設定は、set :deploy_to, "/path/to/app"の設定に相対パスを指定していました。
絶対パスに書き換えると問題なく実行できました。
deploy_toの設定は、絶対パスで書きましょう。

まとめ

今回は、単なるRubyスクリプトをCapistranoを使ってデプロイする方法をメモしました。
前述の通り、CapistranoさんはRubyやRails専用ではないのでこのような簡単なスクリプトをサーバへデプロイすることも容易にできます。
今回はやっていませんが、サーバへ特定のコマンドをたたく、なんてこともできるので、
手でリモートサーバへの行っているコマンド実行等も独自タスクを使って自動化するなんてこともできそうです。
夢が広がります。

今回は、ここまで。
おわり

Posted by しきゆら