投稿日
CapistranoでReact + Railsなアプリケーションをデプロイする
西日本テクノロジー&イノベーション室のうらがみ(@backpaper0)です。
Javaとゼルダの伝説 ブレス オブ ザ ワイルドを愛しています。
はじめに
ReactとRailsを使ってサービス開発を行なっています。
私を始めとしてチームメンバー全員にRailsの経験はありませんでした。 なるべくはじめての要素を減らすためwebpackerは使用せずRailsをAPI onlyにしました。
そのため、数日間の学習期間を設けましたが、Railsで学習すべきことを少なく抑えられました。 また、Rails側とReact側で完全に独立して開発を進められるようになりました。
アプリケーションのデプロイはCapistranoを使用することにしました。 ソースコードはGitLabで管理しているのでGitLab CI/CDでビルドパイプラインを組んでいます。
この記事ではReactとRails(API only)で構築されたアプリケーションをどのようにCapistranoでデプロイしたのかを記載します。
プロジェクトのディレクトリ構成
プロジェクトのディレクトリ構成は次のようになっています。
. ├── Capfile ├── Gemfile ├── config │ ├── deploy │ │ ├── production.rb │ │ └── staging.rb │ └── deploy.rb ├── api #Railsアプリケーション └── ui #Reactアプリケーション
一般的なRailsアプリケーションだとおそらくRailsアプリケーションのディレクトリ(上記の構成だとapi
ディレクトリ)の中にconfig/deploy.rb
やconfig/deploy/production.rb
が置かれるのだと思いますが、前述のような理由からRailsとReactで完全に分離しており、かつそれらが影響しあわないようにapi
ディレクトリとui
ディレクトリを並べて置いています。 Capistranoに関するファイルはそれらに並ぶように置いています。
アプリケーションの配置構成
RailsアプリケーションもReactアプリケーションも1つのEC2へ配置しています。
配置先のディレクトリの構成はある程度Capistranoのデフォルトに沿っています。 具体的には次のように配置しています。
- Railsアプリケーションは
/var/www/app/current/api
に配置してsystemdで実行している - Reactアプリケーションはビルドして得たHTMLやJavaScriptファイルを
/var/www/app/current/html
へ配置して、そのディレクトリをNginxでホスティングしている
Capistranoで行なっていることはGitリポジトリのデプロイの他、ビルド済みReactアプリケーションのアップロードやDBマイグレーション、Railsアプリケーションの再起動です。
GitLab CI/CDの流れ
GitLab CI/CDでビルドが実行されると次のような流れでパイプラインが進みます。
- Reactアプリケーションがビルド&テストされる
- Railsアプリケーションがテストされる
- Capistranoでデプロイされる
- Gitリポジトリがデプロイされる(つまりRailsアプリケーションがデプロイされる)
- ビルドされて得たHTMLファイルやJSファイルがアップロードされる
- DBマイグレーションが行われる
- Railsアプリケーションが再起動される
ビルドされて得たHTMLファイルやJSファイルのアップロードするタスクは、deploy.rb
に次のように書いて定義しています。
desc "Upload UI"
task :upload_ui do
on roles(:all) do
upload! "./ui/build", "#{release_path}/html", recursive: true
end
end
after "deploy:publishing", :upload_ui
DBマイグレーションは次のように定義しています。
desc "Setup Rails"
task :setup_rails do
on roles(:all) do
within("/var/www/app/current/api") {
with(RAILS_ENV: ENV['RAILS_ENV']) {
execute :bundle, "install", "--with=production"
execute :rails, "db:migrate"
}
}
end
end
after "deploy:published", :setup_rails
Railsアプリケーションの再起動は次のように定義しています。
desc "Restart Rails"
task :restart_rails do
on roles(:all) do
execute :sudo, :systemctl, "restart", "rails"
end
end
after "deploy:published", :restart_rails
sudo
したくない場合はexecute :rails, "s", "-d"
というふうに直接rails
コマンドを実行しても良いと思います。
以上でCapistranoを使ってReact + Railsアプリケーションのデプロイができました。
今後やりたいこと
私がもっとも得意とするのはJavaのサーバーサイドアプリケーションですので、そこでもCapistranoを使ってデプロイしてみたいです。 ただ、Java(Spring Boot)はRuby on Railsと異なりソースコードをデプロイするのではなくコンパイルをして1つのJARファイルへまとめてデプロイします。 CapistranoはデフォルトでGitリポジトリをそのままデプロイするので、それをどう活用するかは考えどころだと思います。
また、今回はデプロイ先が1つのサーバーのみだったのでrole
を使い分けていませんでした。 今後は複数のサーバーへのデプロイを扱うこともあると思いますが、その際はrole
をうまく活用したいと思います。
本コンテンツはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。