困っていること
個人開発でCapistranoを用いてRailsアプリを本番環境であるEC2サーバへ自動デプロイしようとしましたが、ローカルから「bundle exec cap production deploy」を実行すると「deploy:migrating」のタスクのところで、
「Mysql2::Error::ConnectionError: Access denied for user 'ec2-user'@'localhost' (using password: NO)」というエラーが出ます。
⇒これに対し**「適切なDB接続の指定をするためにはどうすべきか」**を中心に、エラー解消方法をお伺いしたくご質問させていただきました。
環境
・ローカル:DockerのRailsコンテナ
・本番環境:AWS EC2(Amazon Linux2)⇒Webサーバ:Nginx、APサーバ:Puma
・本番DB環境:AWS RDS for MySQL(MySQL5.7)
・Ruby 2.6.5、Rails 5.2.4
同環境にて、手動デプロイにて同じRailsアプリをGitHubからクローンし、
各サーバを起動の上、ローカルのブラウザからHTTPアクセスでき、CRUDの操作もできることは確認済です。(DBへの反映も確認)
その上で、自動デプロイができるよう取り組んでいる次第です。
EC2上からDB(RDS側)への接続もできる状態です。
Capistrano関連のファイル
・deploy.rb
ruby
1lock "3.7.0" 2set :application, "myfavrest-app" 3set :user, "ec2-user" 4set :repo_url, "git@github.com:(省略)" 5set :log_level, :debug 6set :deploy_to, "/home/#{fetch(:user)}/var/www/#{fetch(:application)}" 7 8set :linked_files, fetch(:linked_files, []).push("config/master.key") 9append :linked_files, "config/database.yml" 10append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets" 11 12set :keep_releases, 3 13 14# ----------カスタマイズしたタスク------------ 15namespace :deploy do 16 # linked_filesで使用するファイルをアップロードするタスク。deploy前に実行する。 17 desc 'upload linked_files' 18 task :upload do 19 on roles(:app) do |_host| 20 execute :mkdir, '-p', "#{shared_path}/config" 21 upload!('config/database.yml', "#{shared_path}/config/database.yml") 22 upload!('config/master.key', "#{shared_path}/config/master.key") 23 24 # puma.rbをデプロイ時に毎回作成する 25 invoke 'puma:config' 26 end 27 end 28end 29 30# nginxの起動・停止・再起動 31namespace :nginx do 32 %w[start stop restart].each do |command| 33 desc "#{command} nginx" 34 task command.to_s do 35 on roles(:web) do 36 sudo "service nginx #{command}" 37 end 38 end 39 end 40end 41 42# capistrano内の変数一覧表示 43namespace :config do 44 desc 'show variables' 45 task :display do 46 Capistrano::Configuration.env.keys.each do |key| 47 puts "#{key} => #{fetch(key)}" 48 end 49 end 50end 51 52# デプロイ開始前のサーバ停止タスク(nginx => puma) 53before 'deploy:starting', 'nginx:stop' 54after 'nginx:stop', 'puma:stop' 55after 'puma:stop', 'deploy:upload' 56 57# デプロイ完了後のサーバ起動タスク(puma => nginx) 58after 'puma:start', 'nginx:start'
・production.rb
Ruby
1server '(省略)', user: 'ec2-user', roles: %w[app db web], ssh_options: { 2 keys: %w(~/.ssh/(省略)), 3 forward_agent: true, 4 auth_methods: %w(publickey) 5}
・Capfile
Ruby
1require "capistrano/setup" 2require "capistrano/deploy" 3require 'capistrano/scm/git' 4install_plugin Capistrano::SCM::Git 5 6require 'capistrano/bundler' 7require 'capistrano/rbenv' 8require 'capistrano/rails/assets' 9require 'capistrano/rails/migrations' 10require 'capistrano/puma' 11install_plugin Capistrano::Puma 12install_plugin Capistrano::Puma::Nginx 13 14Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r } 15
エラー事象のキャプチャ
試したこと①
「'ec2-user'@'localhost' (using password: NO)」と出ていますが、DB接続時のユーザ、ホスト名、パスワードは、database.ymlに定義している本来のものとは違っています。
**database.ymlが本番サーバへアップロードできていないのか?**と思い確認しましたが、shared配下にローカルと同じ内容のファイルが存在しました。
[ec2-user@ip-10-0-10-10 myfavrest-app]$ ls -l shared/config/ total 8 -rwxrwxr-x 1 ec2-user ec2-user 1950 Nov 28 01:50 database.yml -rwxrwxr-x 1 ec2-user ec2-user 32 Nov 28 01:50 master.key
・database.yml(ローカルもサーバ上も内容同じ)
yml
1default: &default 2 adapter: mysql2 3 charset: utf8 4 encoding: utf8 5 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 6 username: mydev 7 password: (省略) 8 socket: /var/run/mysqld/mysqld.sock 9 host: db 10 11development: 12 <<: *default 13 database: myfavrest-app_development 14 15test: 16 <<: *default 17 host: 127.0.0.1 18 # host: test-db 19 database: myfavrest-app_test 20 21production: 22 <<: *default 23 database: <%= ENV['DB_NAME_PRODUCTION'] %> 24 username: <%= ENV['DB_USER_PRODUCTION'] %> 25 host: <%= ENV['DB_HOST_PRODUCTION'] %> 26 password: <%= ENV['DB_PW_PRODUCTION'] %> 27 socket: /var/lib/mysql/mysql.sock
⇒productionの各環境変数はサーバ上にも定義しており、確認できます。
[ec2-user@ip-10-0-10-10 config]$ echo $DB_NAME_PRODUCTION $DB_USER_PRODUCTION $DB_HOST_PRODUCTION $DB_PW_PRODUCTION myfavrestapp_production admin (省略)(省略)
試したこと②
エラーメッセージにて、DB接続先が「localhost」となっていることから推測し、
productionが指定できていないのではと考え、設定ファイルに下記追記して実行しましたが、
エラー事象は全く変わりませんでした。
・deploy.rb
Ruby
1set :stages, %(production, staging) 2set :default_stage, "production"
・production.rb
Ruby
1set :stage, :production
現在推測している原因
ec2-user@localhost、かつパスワードなしで接続しにいってしまっているということから、
db:migrateのタスクでの対象DB指定がうまくいっていないと推測しており、
Capistranoのソースを見たりして調査中なのですが、
よく理解できておらず、進展がないため、質問させていただいた次第です。
Capistrano:migrationタスクのソース
ご不明点等あればご教示いただけますと幸いです。
お手数をおかけしますが、よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/11/28 03:45
2020/11/28 05:11