【デプロイ】CapistranoでVueアプリをサーバにデプロイ
概要
Capistranoというデプロイツールを知りました。処理をrubyで書いて拡張できます。Vueアプリのデプロイに利用したので、そのときのメモを記します。
作成したタスクは以下の処理を行うように作りました。
- SSHでサーバにログイン
- Bitbucketからソースを取得
- yarnでbuild
- 不要ファイル削除
- Webサーバの公開ディレクトリにシンボリックリンクを貼る(ブラウザで閲覧できるよう公開する)
このうち、1、2、5、はCapistranoが備える機能で実現でき、3、4をスクリプトとして追加しました。
詳細
Capistranoの準備
今回はVueアプリを配備するが、アプリの内容はJavaScriptでもRailsアプリなんでも良いです。
bundleを使います。
$ bundle init
Writing new Gemfile to /Users/user/appname/Gemfile
bundleでcapistranoをインストールします。
$ bundle add capistrano
Fetching gem metadata from https://rubygems.org/……….
Resolving dependencies…
Fetching gem metadata from https://rubygems.org/……….
Resolving dependencies…
Using rake 12.3.2
Using net-ssh 5.1.0
Using net-scp 1.2.1
Using sshkit 1.18.2
Using airbrussh 1.3.1
Using bundler 1.17.2
Using concurrent-ruby 1.1.4
Using i18n 1.5.3
Using capistrano 3.11.0
アプリのディレクトリ(Vueであればvue initしたディレクトリ、ここでは/Users/user/appname)で以下を実行します。
$ cap install
mkdir -p config/deploy
create config/deploy.rb
create config/deploy/staging.rb
create config/deploy/production.rb
mkdir -p lib/capistrano/tasks
create Capfile
Capified
基本的な設定
書き換えるファイルは大きく3点
- {アプリフォルダ]/Capfile
- {アプリフォルダ}/config/deploy.rb
- {アプリフォルダ}/config/deploy/production.rb|staging.rb
{アプリフォルダ}はcap installを実行したフォルダです。ここでは/Users/user/appnameです。
production.rbとstaging.rbがあり、環境による切り分けが可能ですが、とりあえず試すのであれば、production.rbに書いてしまえば良いです。
ファイルの説明
- Capfile – Capistrano全体の設定などを記述する
- deploy.rb – デプロイで共通する処理を記述する
- production.rbなど – SSH接続などの環境ごとに異なる設定を記述する
設定変更
Capfile
# require "capistrano/rvm"
require "capistrano/rbenv"
# require "capistrano/chruby"
# require "capistrano/bundler"
# require "capistrano/rails/assets"
# require "capistrano/rails/migrations"
# require "capistrano/passenger"
rbenvを使用しているため、コメントをはずしました。
production.rb
role :web, %w{user@xxx.xxx.xxx.xxx}
set :assets_roles, [:web]
server 'xxx.xxx.xxx.xxx', user: 'user', roles: %w{web}
set :ssh_options, {
port: 22,
keys: %w(~/.ssh/user.pem),
forward_agent: true,
}
ここではSSH接続の設定のため、接続先サーバのIPアドレス、及びユーザを指定します。keysのところは、パスワード認証ではなく秘密鍵認証としたため、秘密鍵の格納場所を指定しました。
deploy.rb
lock "~> 3.11.0"
set :rbenv_ruby, "2.5.1"
set :application, "appname"
set :branch, "master"
set :repo_url, "git@bitbucket.org:apps/#{fetch(:application)}.git"
set :deploy_to, "/var/www/#{fetch(:application)}"
set :keep_releases, 6
desc 'yarn build'
after 'deploy:updated', :build do
on roles :web do
within release_path do
execute :yarn
execute :yarn, 'build'
end
end
end
desc 'rm except dist dir' # ., .., dist以外を削除する
after 'deploy:updated', :rm do
on roles :web do
within release_path do
execute :ls, '-a|egrep -v \'^(.|..|dist)$\'|xargs rm -r'
end
end
end
この処理では、1つ目がyarn;yarn buildを、2つ目がdistディレクトリ以外の削除を行なっています。
repo_urlを設定することによってgitからソースを取得しています。
keep-releaseを設定することにより世代管理されます。最新アプリのディレクトリはcurrentとなり、実体はreleaseディレクトリ配下に世代管理されています。
SSH接続の準備
鍵ペアを2つ生成し、1つはサーバ接続用として、~/.ssh/配下に秘密鍵を格納し、接続先サーバに公開鍵を格納しました。
2つめは、~/.ssh/配下に秘密鍵を格納し、gitリポジトリに公開鍵を格納しました。
capistranoから鍵を使用するため、ssh-addで秘密鍵を追加します。
$ ssh-add ~/.ssh/repo_rsa
$ ssh-add ~/.ssh/appname_rsa
Identity added: /Users/user/.ssh/appname_rsa (/Users/user/.ssh/appname_rsa)
公開ディレクトリの設定
nginxの公開ディレクトリの設定を/var/www/appname/current/distとしました。
これにより、yarn buildされた結果がdistに含まれた状態でcurrent->release/2019xxxxxxxxxxを参照するようシンボリックリンクが貼られることで、参照可能になります。
実行
$ cap production deploy
00:00 git:wrapper
01 mkdir -p /tmp
✔ 01 user@XXX.XXX.XXX.XXX 0.069s
Uploading /tmp/git-ssh-appname-production-user.sh 100.0%
02 chmod 700 /tmp/git-ssh-appname-production-user.sh
✔ 02 user@XXX.XXX.XXX.XXX 0.078s
00:00 git:check
01 git ls-remote git@bitbucket.org:apps/appname.git HEAD
01 6fd3e4ccf1b29b3d2e8fc680a1f5eac5d3XXXXXX HEAD
✔ 01 user@XXX.XXX.XXX.XXX
〜〜省略〜〜
00:06 build
01 yarn
01 yarn install v1.13.0
01 [1/4] Resolving packages…
01 [2/4] Fetching packages…
01 info fsevents@1.2.7: The platform "linux" is incompatible with this module.
01 info "fsevents@1.2.7" is an optional dependency and failed compatibility check. Excluding it from installation.
01 [3/4] Linking dependencies…
01 [4/4] Building fresh packages…
01 Done in 13.69s.
✔ 01 appname@XXX.XXX.XXX.XXX 14.091s
02 yarn build
02 yarn run v1.13.0
02 $ vue-cli-service build
02
02 - Building for production…
〜〜省略〜〜
01:05 rm
01 ls -a|egrep -v '^(.|..|dist)$'|xargs rm -r
✔ 01 user@XXX.XXX.XXX.XXX 1.006s
01:06 deploy:symlink:release
01 ln -s /var/www/appname/releases/20190224174918 /var/www/appname/releases/current
✔ 01 appname@XXX.XXX.XXX.XXX 0.065s
02 mv /var/www/appname/releases/current /var/www/appname
✔ 02 appname@XXX.XXX.XXX.XXX 0.076s
まとめ
capistranoを使用して、Webサーバにデプロイするタスクを作成しました。
どうもcapistrano-yarnというものがあるようで、こちらは公式にyarnをサポートしているようです。機会があれば導入してみようと思います。
参考
capistrano -GitHub
https://github.com/capistrano/capistrano/blob/master/README.md