はじめに
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アプリケーションのデプロイについてお話したいと思います。