はじめに
Capistranoは、サーバへのデプロイを自動化するオープンソースソフトウェアです。 Rubyで書かれており、Railsアプリケーションのデプロイによく用いられますが、Rails以外でも使うことができます。 今回はアプリケーションの種類を限定せずGitHubなどからソースを持ってきてデプロイすることを考えてみます。
サーバ側での作業
まずはじめにデプロイするサーバの準備を行います。 Ubuntu 18.04 を用いましたが、他のOSでも大丈夫だと思います。
デプロイ用のユーザの作成
デプロイ用のユーザdeployを作成します。
$ sudo adduser deploy $ sudo gpasswd -a deploy sudo
ローカルからsshログインできるように公開鍵の登録をしておきます。
$ sudo su - deploy $ mkdir ~/.ssh $ echo 'ssh-rsa xxx' >> ~/.ssh/authorized_keys $ chmod 700 ~/.ssh $ chmod 600 ~/.ssh/authorized_keys
以降、サーバ側の作業は、deployユーザで行います。
アプリケーションディレクトリの作成
アプリケーションを格納するディレクトリを用意しておきます。
Webアプリケーションを想定して/var/www/にしていますが、場所はどこでも良いです。
$ sudo mkdir -p /var/www/myapp $ sudo chown deploy:deploy /var/www/myapp
アプリケーション名はmyappとしていますが、適宜修正してください。
以降も、アプリケーション名はmyappとなっています。
(任意)Githubへの公開鍵の登録
GithubやGitLabのプライベートリポジトリにあるアプリケーションをデプロイする場合は、このサーバからリポジトリへアクセスできるように公開鍵をGithubなどに登録しておきます。
ローカル側での作業
デプロイを実行するローカルの準備をしていきます。
なお、Rubyがインストールされている必要があります。今回用いたバージョンは2.5.1です。
デプロイ用のディレクトリの作成
Capistranoをインストールするディレクトリを作成します。
$ mkdir myapp-deploy $ cd myapp-deploy
bundle initを行うと、Gemfileが生成されます。
$ bundle init
Capistranoのインストール
Gemfileに以下を加筆します。
gem 'capistrano', '~> 3.11', require: false
bundle installでインストールを行うと、Capistranoと依存関係にあるGemが指定したパス./vendor/bundleにインストールされます。
$ bundle install --path ./vendor/bundle
以下のコマンドで、Capfileの他いくつかのファイルが生成されます。
$ bundle exec cap install
Capistranoの設定
config/deploy.rb がデプロイの共通設定ファイルになります。以下のように記載します。
# アプリケーション名 set :application, "myapp" # GtiリポジトリのURL set :repo_url, "git@github.com:me/myapp.git" # デプロイするブランチ(デフォルトはmasterブランチ) set :branch, master # デプロイ先のディレクトリ set :deploy_to, "/var/www/myapp"
config/deploy/に環境ごとの設定ファイルが入っています。
今回はprodctionのみ設定してみます。config/deploy/prodction.rbに以下のように記載します。
# サーバのホスト名とユーザ名 server "example.com", user: "deploy", roles: %w{app} # SSHの設定 set :ssh_options, { keys: %w(~/.ssh/id_rsa), forward_agent: true, auth_methods: %w(publickey) }
デプロイ実行
設定が完了したので、いよいよデプロイの実行です。
その前にドライランを行うとどのような処理が実行されるか確認できます。
$ bundle exec cap production deploy --dry-run
00:00 git:wrapper
01 mkdir -p /tmp
02 #<StringIO:0x00007fc227afc648> /tmp/git-ssh-myapp-production-username.sh
03 chmod 700 /tmp/git-ssh-myapp-production-username.sh
00:00 git:check
01 git ls-remote git@gitlab.com:me/myapp.git HEAD
00:00 deploy:check:directories
01 mkdir -p /var/www/myapp/shared /var/www/myapp/releases
00:00 git:clone
The repository mirror is at /var/www/myapp/repo
00:00 git:update
01 git remote set-url origin git@gitlab.com:me/myapp.git
02 git remote update --prune
00:00 git:create_release
01 mkdir -p /var/www/myapp/releases/20181128130637
02 git archive master | /usr/bin/env tar -x -f - -C /var/www/myapp/releases/20181128130637
00:00 deploy:set_current_revision
01 echo "" > REVISION
00:00 deploy:symlink:release
01 ln -s /var/www/myapp/releases/20181128130637 /var/www/myapp/releases/current
02 mv /var/www/myapp/releases/current /var/www/myapp
00:00 deploy:log_revision
01 echo "Branch master (at ) deployed as release 20181128130637 by username" >> /var/www/myapp/revisions.log
問題なければ、実際にデプロイしてみます。
$ bundle exec cap production deploy
/var/www/myapp/releases/20180930060858 のようなフォルダにGitからクローンされ、最新版が/var/www/myapp/currentにシンボリックリンクが貼られます。
共通ファイルとフォルダの設定
設定ファイルやログのようにgitで管理しないファイルやフォルダについては、共通フォルダに格納しておいたほうが都合が良いです。
config/deploy.rbに設定するファイルやフォルダを以下のように記載します。
# 共通ファイル append :linked_files, "config.yml" # 共通フォルダ append :linked_dirs, "log"
改めてデプロイすると、/var/www/myapp/currentから/var/www/myapp/shared/へシンボリックリンクが貼られます。
トラブルシューティング
SSH接続できない
最初のタスクのgit:wrapperで以下のようなエラーが発生する場合、ローカルからサーバへSSH接続ができていないです。
SSHKit::Runner::ExecuteError: Exception while executing as deploy@example.com: Authentication failed for user deploy@example.com
Capistranoを使わずに普通にSSHできるか確かめてみます。
ssh deploy@example.com
sshコマンドで接続できる場合、config/deploy/prodction.rbのSSH設定が誤っていると思われます。鍵の場所なども確認しましょう。
Gitクローンできない
git:checkでSSHKit::Runner::ExecuteErrorが発生する場合、サーバ側からGitリポジトリへアクセスできていない可能性があります。
これはプライベートリポジトリの場合のみ発生すると思いますが、サーバの鍵がGitリポジトリのあるサーバに登録されていないと思われます。
まとめ
Capistranoを用いたデプロイの方法について説明しました。Capistranoには周辺ライブラリもいくつかあり、次回はそれらを用いてRailsアプリケーションのデプロイについてお話したいと思います。