個人アプリ開発 AWS 自動デプロイ

今日は自動デプロイをする為に、capistranoを導入していきました。
ただ作業するだけでなく、自分なりに手順をまとめながら進めました。

Capistranoの導入準備

Gemをインストール
[Gemfile]
group :development, :test do
  gem 'capistrano'
  gem 'capistrano-rbenv'
  gem 'capistrano-bundler'
  gem 'capistrano-rails'
  gem 'capistrano3-unicorn'
end

→bundle install

ファイルの生成

bundle exec cap install
Capfileを編集
require "capistrano/setup"
require "capistrano/deploy"
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano3/unicorn'

Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
デプロイについての設定ファイルを編集

cap installコマンド
→config/deploy配下にproduction.rbとstaging.rbの2種類のファイルを生成

[config/deploy/production.rb]
server '<用意したElastic IP>', user: 'ec2-user', roles: %w{app db web}
[config/deploy.rb]
# config valid only for current version of Capistrano
# capistranoのバージョンを記載。固定のバージョンを利用し続け、バージョン変更によるトラブルを防止する
lock '<Capistranoのバージョン>'

# Capistranoのログの表示に利用する
set :application, '<自身のアプリケーション名>'

# どのリポジトリからアプリをpullするかを指定する
set :repo_url,  'git@github.com:<Githubのユーザー名>/<レポジトリ名>.git'

# バージョンが変わっても共通で参照するディレクトリを指定
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, '<このアプリで使用しているrubyのバージョン>' #カリキュラム通りに進めた場合、2.5.1か2.3.1です

# どの公開鍵を利用してデプロイするか
set :ssh_options, auth_methods: ['publickey'],
                  keys: ['<ローカルPCのEC2インスタンスのSSH鍵(pem)へのパス(例:~/.ssh/key_pem.pem)>'] 

# プロセス番号を記載したファイルの場所
set :unicorn_pid, -> { "#{shared_path}/tmp/pids/unicorn.pid" }

# Unicornの設定ファイルの場所
set :unicorn_config_path, -> { "#{current_path}/config/unicorn.rb" }
set :keep_releases, 5

# デプロイ処理が終わった後、Unicornを再起動するための記述
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
  task :restart do
    invoke 'unicorn:restart'
  end
end
[config/unicorn.rb]
# ../が一つ増えている
app_path = File.expand_path('../../../', __FILE__)

worker_processes 1
# currentを指定
working_directory "#{app_path}/current"

# それぞれ、sharedの中を参照するよう変更
listen "#{app_path}/shared/tmp/sockets/unicorn.sock"
pid "#{app_path}/shared/tmp/pids/unicorn.pid"
stderr_path "#{app_path}/shared/log/unicorn.stderr.log"
stdout_path "#{app_path}/shared/log/unicorn.stdout.log"
nginxの設定ファイル
[rails.conf]
upstream app_server {
  # sharedの中を参照するよう変更
  server unix:/var/www/<アプリケーション名>/shared/tmp/sockets/unicorn.sock;
}

server {
  listen 80;
  server_name <Elastic IPを記入>;

# クライアントからアップロードされてくるファイルの容量の上限を2ギガに設定。デフォルトは1メガなので大きめにしておく
  client_max_body_size 2g;

  # currentの中を参照するよう変更
  root /var/www/<アプリケーション名>/current/public;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
    # currentの中を参照するよう変更
    root   /var/www/<アプリケーション名>/current/public;
  }

  try_files $uri/index.html $uri @unicorn;

  location @unicorn {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://app_server;
  }

  error_page 500 502 503 504 /500.html;
}

Nginxの設定を変更したら、忘れずに再読込・再起動

[ec2-user@XXX]$ sudo service nginx reload
[ec2-user@XXX]$ sudo service nginx restart

MySQLを再起動

[ec2-user@XXX]$ sudo service mysqld restart

自動デプロイ

# アプリケーションのディレクトリで実行
$ bundle exec cap production deploy

躓き

デプロイ時エラー

上記実行したところ、エラーが発生。

00:00 git:check
      01 git ls-remote git@github.com:kogegoro0930/aquq-log.git HEAD
      01 ERROR: Repository not found.

→指定したリポジトリ名が違った。
▶︎修正したところ、うまくいきました。

画像が表示されなくなった

・config内ファイルの設定変更

config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
↓
config.public_file_server.enabled = true

→不可

▶︎capistranoを使用したことにより、画像を参照するパスが変わっているようなので、
S3を導入し画像をアップロードできるようにし、様子を見てみることにしました。


ちょっと今回は解決に時間をかけてしまいました。
よくエラー内容を確認すればすぐに分かったはずが、これまでのトリッキーなエラーに引っ張られ、複雑に考えてしまいました。

まずちゃんとエラー内容を把握してから仮説を立てることが大事だと再認識しました。(当たり前すぎますが、これも経験ですね・・・)

日々精進していきます。