はじめに
現在プログラミングスクール卒業後、ポートフォリオ作成をしており、
Capistranoを使用した自動デプロイで発生したエラーを備忘録として投稿します。
■開発環境
- Rails 5.0.7.2
- ruby 2.5.1
- AWS EC2
- Nginx
- Unicorn
- capistrano
Capistrano導入について
下記の記事を参考に、導入しました。
導入方法が分からない方は、私と同様に参考にしてみてください。
自動デプロイツール(Capistrano)導入方法
発生したエラーについて
上記の記事を参考にCapistranoを導入し、自動デプロイを実行したところ、途中でエラーが発生しました。
# アプリケーションのディレクトリで、下記の自動デプロイコマンドを実行する。
$ bundle exec cap production deploy
自動デプロイコマンド実行後の、エラー内容はこちら。
$ bundle exec cap production deploy
[Deprecation Notice] Future versions of Capistrano will not load the Git SCM
plugin by default. To silence this deprecation warning, add the following to
your Capfile after `require "capistrano/deploy"`:
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git
00:00 git:wrapper
01 mkdir -p /tmp
✔ 01 ec2-user@52.193.230.41 0.239s
Uploading /tmp/git-ssh-smot-production-nakayakouyuu.sh 100.0%
02 chmod 700 /tmp/git-ssh-smot-production-nakayakouyuu.sh
✔ 02 ec2-user@52.193.230.41 0.291s
00:00 git:check
01 git ls-remote git@github.com:nakaya-kousuke/smot.git HEAD
01 5e943870f1583d9775b045f3c40d418324d8ad8a HEAD
✔ 01 ec2-user@52.193.230.41 2.098s
00:02 deploy:check:directories
01 mkdir -p /var/www/smot/shared /var/www/smot/releases
✔ 01 ec2-user@52.193.230.41 0.132s
00:03 deploy:check:linked_dirs
01 mkdir -p /var/www/smot/shared/log /var/www/smot/shared/tmp/pids /var/www/smot/shared/tmp/cache /var/www/smot/shared/tmp/sockets /var/www/smot/sha…
✔ 01 ec2-user@52.193.230.41 0.224s
00:03 git:clone
The repository mirror is at /var/www/smot/repo
00:03 git:update
01 git remote set-url origin git@github.com:nakaya-kousuke/smot.git
✔ 01 ec2-user@52.193.230.41 0.237s
02 git remote update --prune
02 Fetching origin
✔ 02 ec2-user@52.193.230.41 2.093s
00:06 git:create_release
01 mkdir -p /var/www/smot/releases/20201103133334
✔ 01 ec2-user@52.193.230.41 0.226s
02 git archive master | /usr/bin/env tar -x -f - -C /var/www/smot/releases/20201103133334
02 fatal: not a valid object name: master
02 tar:
02 これは tar アーカイブではないようです
02
02 tar:
02 前のエラーにより失敗ステータスで終了します
02
#<Thread:0x00007f9e5507c1f0@/Users/nakaya-kousuke/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sshkit-1.21.0/lib/sshkit/runners/parallel.rb:10 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /Users/nakaya-kousuke/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sshkit-1.21.0/lib/sshkit/runners/parallel.rb:11:in `block (2 levels) in execute'
/Users/nakaya-kousuke/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sshkit-1.21.0/lib/sshkit/runners/parallel.rb:15:in `rescue in block (2 levels) in execute': Exception while executing as ec2-user@52.193.230.41: git exit status: 2 (SSHKit::Runner::ExecuteError)
git stdout: Nothing written
git stderr: fatal: not a valid object name: master
tar: これは tar アーカイブではないようです
tar: 前のエラーにより失敗ステータスで終了します
(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as ec2-user@52.193.230.41: git exit status: 2
git stdout: Nothing written
git stderr: fatal: not a valid object name: master
tar: これは tar アーカイブではないようです
tar: 前のエラーにより失敗ステータスで終了します
Caused by:
SSHKit::Command::Failed: git exit status: 2
git stdout: Nothing written
git stderr: fatal: not a valid object name: master
tar: これは tar アーカイブではないようです
tar: 前のエラーにより失敗ステータスで終了します
Tasks: TOP => git:create_release
(See full trace by running task with --trace)
The deploy has failed with an error: Exception while executing as ec2-user@52.193.230.41: git exit status: 2
git stdout: Nothing written
git stderr: fatal: not a valid object name: master
tar: これは tar アーカイブではないようです
tar: 前のエラーにより失敗ステータスで終了します
上記のエラー内容を確認すると、git:create_releaseの部分でエラーが発生していることが分かります。
00:06 git:create_release
01 mkdir -p /var/www/smot/releases/20201103133334
✔ 01 ec2-user@52.193.230.41 0.226s
02 git archive master | /usr/bin/env tar -x -f - -C /var/www/smot/releases/20201103133334
02 fatal: not a valid object name: master
02 tar:
02 これは tar アーカイブではないようです
02
02 tar:
02 前のエラーにより失敗ステータスで終了します
02
fatal: not a valid object name: master
こちらの内容が、今回のエラーの原因のようですので、
「masterが有効なオブジェクト名ではありません」と言われています。
fatal: not a valid object name: master の解決方法を調べてみる!
fatal: not a valid object name: masterを検索して調べると、下記のような記事がたくさん出てきました。
Git エラー「fatal: Not a valid object name: 'master'.」の対処法
【Git】fatal: Not a valid object name: 'master'.の解決方法
fatal: Not a valid object name: 'master'. て言われたときどうした?
【Git】fatal: Not a valid object name: 'master'って怒られた【大体そんなもん】
こちらの記事を読んでみると、fatal: not a valid object name: masterはGitで発生しているエラーのようです。
ほとんどの記事に「マスターブランチにコミット」するように言われているので、下記のように実行。
# コミットしたいファイルを全て選択する
$ git add .
# masterブランチへコミット
$ git commit -m "fatal: not a valid object name: masterエラー解消のため"
# 自動デプロイコマンドを実行
$ bundle exec cap production deploy
しかし、これでもfatal: not a valid object name: masterエラーは解決できませんでした!
ほかに何が原因か仮説を立ててみる!
Capistranoで、fatal: not a valid object name: master のエラーが出ている記事がひとつも出てこないので、仮説を立ててみました。
「masterが有効なオブジェクト名ではありません」と言われていて、Gitのエラーであることは分かりました。
そもそもGitを使っていて、masterブランチにもpush、commit、pullもできているのになぜ??
エラー文の中にあるこれは tar アーカイブではないようですを調べてみると、下記の記事を見つけました。
capistranoエラーtar:これはtarアーカイブのようには見えません
こちらの記事のベストアンサーに、**「gitから存在しないブランチを引っ張っている」**と書かれていて、もしかしてmasterブランチがgitに存在していないからエラーが発生しているのか?と仮説を立てて調べてみました。
エラー解決!!
さっそく開発中のGitHubを調べてみると、デフォルトブランチが「master」ではなく、**「main」**になっていました!!!
そのため、Capistranoのgitのブランチを「main」に変更。
# config valid only for current version of Capistrano
# capistranoのバージョンを記載。固定のバージョンを利用し続け、バージョン変更によるトラブルを防止する
lock '3.14.1'
# Capistranoのログの表示に利用する
set :application, 'smot'
# どのリポジトリからアプリをpullするかを指定する
set :repo_url, 'git@github.com:nakaya-kousuke/smot.git'
---------- 追記 ----------
# ブランチを指定する
set :branch, "main"
--------------------------
# バージョンが変わっても共通で参照するディレクトリを指定
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'public/uploads')
set :rbenv_type, :user
set :rbenv_ruby, '2.5.1' #カリキュラム通りに進めた場合、2.5.1か2.3.1です
# どの公開鍵を利用してデプロイするか
set :ssh_options, auth_methods: ['publickey'],
keys: ['~/.ssh/smot.pem']
# プロセス番号を記載したファイルの場所
set :unicorn_pid, -> { "#{shared_path}/tmp/pids/unicorn.pid" }
# Unicornの設定ファイルの場所
set :unicorn_config_path, -> { "#{current_path}/config/unicorn.rb" }
set :keep_releases, 5
# secrets.yml用のシンボリックリンクを追加
set :linked_files, %w{ config/secrets.yml }
# 元々記述されていた after 「'deploy:publishing', 'deploy:restart'」以下を削除して、次のように書き換え
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
task :restart do
invoke 'unicorn:restart'
end
desc 'upload secrets.yml'
task :upload do
on roles(:app) do |host|
if test "[ ! -d #{shared_path}/config ]"
execute "mkdir -p #{shared_path}/config"
end
upload!('config/secrets.yml', "#{shared_path}/config/secrets.yml")
end
end
before :starting, 'deploy:upload'
after :finishing, 'deploy:cleanup'
end
# 自動デプロイコマンドを実行
$ bundle exec cap production deploy
これで自動デプロイに成功することができました!!!
補足情報
なぜGitHubのデフォルトブランチが「main」になっていたのか???を調べてみました。
■参考記事
GitHub、これから作成するリポジトリのデフォルトブランチ名が「main」に。「master」から「main」へ変更
なんとGitHubのデフォルトブランチが「master」から「main」へ変更になっていました!
この変更には、2020年5月25日に米国ミネソタ州ミネアポリスでの事件をきっかけとした人権運動を背景にしたものとなっています。
このような事件が、IT業界にも影響されることもあると勉強になりました。
ちなみにGitHubの設定によって新規に作成するリポジトリのデフォルトブランチ名は任意に変更可能のようです。