Capistrano3によるEC2へのデプロイ失敗を起点とした袋小路

once upon a time……

現在作成中のアプリケーションにおいて、paperclipを使用してユーザのアイコン画像の取り扱いを設定していたため、 こちらの本番環境におけるアップロード先をAWSのS3に設定しようとしていた私がおりました。

Uploading Files to S3 in Ruby with Paperclip | Heroku Dev Center

paperclipとS3で画像をアップロード - Qiita

carrierwaveかpaperclipを使って画像URLからS3にアップロードする - hatappi.blog

この辺とか見た感じ、どうやらaws-sdkというGemを導入すれば良さそう。

GitHub - aws/aws-sdk-ruby: The official AWS SDK for Ruby.

早速Gemfileに以下の記述をし、ローカルでbundle install。

gem 'aws-sdk', '~> 3'

f:id:osouonna:20181005230427p:plain

スクショ範囲外にも広がるaws-sdkから始まるあれやこれやの数々に若干引きつつも、無事にインストール完了。


S3対応のため諸々のコードを書き、いざ本番環境へデプロイ。

今回はあらかじめCapistrano3による自動デプロイを設定していたため、ローカルで以下のコマンドを打てば後は野となれ山となれ!……のはずだった。

bundle exec cap production deploy

00:07 bundler:install
      01 $HOME/.rbenv/bin/rbenv exec bundle install --path /var/www/final-project/shared/bundle --without development test --deployment --quiet
^C(Backtrace restricted to imported tasks)
cap aborted!
Interrupt: 

Tasks: TOP => deploy:updated => bundler:install
(See full trace by running task with --trace)
The deploy has failed with an error: 


** DEPLOY FAILED
** Refer to log/capistrano.log for details. Here are the last 20 lines:

(略)

 DEBUG [3a97f586]   Install missing gems with `bundle install`

 DEBUG [3a97f586] Finished in 0.413 seconds with exit status 1 (failed).

  INFO [a570a080] Running $HOME/.rbenv/bin/rbenv exec bundle install --path /var/www/final-project/shared/bundle --without development test --deployment --quiet as ec2-user@18.182.82.245

(略)

MidorinoMacBook-Pro:final-project fujitami$ bundle exec cap production deploy
^C(Backtrace restricted to imported tasks)
cap aborted!
Interrupt:

非常にわかりにくくて恐縮ですが、何が起こった、また何をやってしまったのかというと、

デプロイ中のbundler:installで無限に処理が停止してしまう→Ctrl + Cでデプロイ停止→エラー出ているのはとりあえずおいといて、再度デプロイ→一向に処理が始まらず……

といったような状態になり、ダメ元でElastic IPをアドレスバーに打ち込んでみても『このサイトにアクセスできません』というメッセージが表示される(ERR_CONNECTION_REFUSED)ばかり。


ここで私、ひとまずEC2のインスタンスを再起動する(たぶんこのへんを見た)。

するとなぜかページの表示がされるように!

……ここで治ったものと勘違いしたのが地獄の始まりだったかもしれない。


ページは表示されるようになったものの、アイコン画像を投稿しようとするとエラーが発生していたため、

Capistranoのdeploy:rollbackコマンドで上記を行う前と思しき場所まで戻し、足りない記述を補完して再度デプロイ。

……先述の状態に。

しかも、今回はなぜか再起動じゃなくてインスタンスの停止→起動をしてしまっていた。疲れていたんだと思う。

慌てて再起動を試みるも、今度は一向にページの表示が復活する気配がない。


対処療法1 : aws-sdkの一部をインストール

aws-sdkの公式GitHubを確認すると、以下のようなインストール方法が紹介されていた。

gem 'aws-sdk-s3', '~> 1'
gem 'aws-sdk-ec2', '~> 1'

現状必要なのはS3の機能なのだから、これでもいいのでは?となり、Gemfileの記述をこちらに変更。

paperclip側でも紹介されてますね。

すると、bundler:installで止まってしまっていたデプロイ処理が動くように。

aws-sdkの古いバージョンは、Capistranoと競合する部分があったらしい。今回も?

Capistrano 3とaws-sdk 2でELB配下にあるインスタンスへデプロイする奴 - Qiita

……しかし、依然としてブラウザでのアプリケーションページの表示はできぬまま。


対処療法2 : Elastic IPの新規発行&EC2インスタンスへの再関連付け

再起動と停止→起動って違うことなのでは?と思い当たる。

インスタンスのライフサイクル - Amazon Elastic Compute Cloud

やっぱり違うもののようで、後者だとIPが変わってしまうというようなことが書いてあるような……?

その方針でググっていて見つけたのが以下のページ。

Amazon Elastic IP の割り当てとインスタンスへの関連付け—AWS における ArcGIS Enterprise | ArcGIS Enterprise

インスタンスを停止する必要がある場合は、インスタンスを再起動した後、Elastic IP に再度関連付ける必要があります。

先述した通り、インスタンスの停止をしてしまったため、Elastic IPの関連付けが必要だったのかもしれない。

ということでEC2インスタンスに関連づいていたElastic IPを解除&新規に発行したElastic IPを関連付けし、Elastic IPの記述を慎重に置き換えて、デプロイ。

新しいElastic IPをアドレスバーに打ち込む。

……アプリケーションのページが表示された!

しかもS3対応までちゃんとできてる!なんで!?

とりあえず状態回復できたので、めでたし、めでたし。


としてしまうと、以降これがどう関わってくるかわからないので、解明の方向に進んでいかなければならないのがこの本番環境。

自分なりに問題だったかなあというところ(必要のないGemは入れない、インスタンスの再起動と停止→起動は違うということを把握する)を当たって応急処置できたのは良かったけれど、

かといって今回のこれがベストプラクティスなのかというと……わからない……いや違うと思う……。

本番環境での立ち振る舞いを含め、スクールのメンターさんに確認しよう。