Be in trouble

I tried to automatically deploy a Rails application to the EC2 server which is the production environment using Capistrano in personal development, but when I execute "bundle exec cap production deploy" locally, at the task of "deploy: migrating",
I get the error "Mysql2 :: Error :: ConnectionError: Access denied for user'ec2-user' @'localhost' (using password: NO)".
⇒ On the other hand"What should I do to specify an appropriate DB connection?"I would like to ask you a question about how to resolve the error.


· Local: Docker Rails container
-Production environment: AWS EC2 (Amazon Linux2) ⇒ Web server: Nginx, AP server: Puma
-Production DB environment: AWS RDS for MySQL (MySQL5.7)
・ Ruby 2.6.5, Rails 5.2.4

In the same environment, clone the same Rails application from GitHub by manual deployment,
It has been confirmed that after starting each server, HTTP access can be performed from a local browser, and CRUD operations can also be performed. (Confirm reflection in DB)
On top of that, we are working on automatic deployment.
It is also possible to connect to the DB (RDS side) from EC2.

Capistrano related files

・ Deploy.rb

lock "3.7.0"
set: application, "myfavrest-app"
set: user, "ec2-user"
set: repo_url, "[email protected]: (omitted)"
set: log_level,: debug
set: deploy_to, "/ home/# {fetch (: user)}/var/www/# {fetch (: application)}"
set: linked_files, fetch (: linked_files, []). push ("config/master.key")
append: linked_files, "config/database.yml"
append: linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets"
set: keep_releases, 3
# ---------- Customized tasks ------------
namespace: deploy do
    The task of uploading files for use with # linked_files. Run before deploy.
    desc'upload linked_files'
    task: upload do
        on roles (: app) do | _host |
            execute: mkdir,'-p', "# {shared_path}/config"
            upload! ('config/database.yml', "# {shared_path} /config/database.yml")
            upload! ('config/master.key', "# {shared_path} /config/master.key")
            Create # puma.rb every time you deploy
            invoke'puma: config'
# nginx start/stop/restart
namespace: nginx do
    % w [start stop restart] .each do | command |
        desc "# {command} nginx"
        task command.to_s do
            on roles (: web) do
                sudo "service nginx # {command}"
List of variables in #capistrano
namespace: config do
    desc'show variables'
    task: display do
        Capistrano :: Configuration.env.keys.each do | key |
        puts "# {key} =># {fetch (key)}"
# Server stop task before starting deployment (nginx =>puma)
before'deploy: starting','nginx: stop'
after'nginx: stop','puma: stop'
after'puma: stop','deploy: upload'
# Server startup task after deployment is complete (puma =>nginx)
after'puma: start','nginx: start'

・ Production.rb

server'(omitted)', user:'ec2-user', roles:% w [app db web],

 ssh_options: {
  keys:% w (~/.ssh/(omitted)),
  forward_agent: true,
  auth_methods:% w (publickey)

・ Capfile

require "capistrano/setup"
require "capistrano/deploy"
install_plugin Capistrano :: SCM :: Git
install_plugin Capistrano :: Puma
install_plugin Capistrano :: Puma :: Nginx
Dir.glob ("lib/capistrano/tasks/*. rake"). each {| r | import r}
Capture of error events

The tasks before this task are in normal operation.

What I tried ①

It says "'ec2-user' @'localhost' (using password: NO)", but the user, host name, and password when connecting to the DB are different from the original ones defined in database.yml. I will.
Is database.yml not being uploaded to the production server?I confirmed that, but there was a file with the same contents as the local under 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 (same content both locally and on the server)

  adapter: mysql2
  charset: utf8
  encoding: utf8
  pool:<% = ENV.fetch ("RAILS_MAX_THREADS") {5}%>username: mydev
  password: (omitted)
  socket: /var/run/mysqld/mysqld.sock
  host: db
<<: * default
  database: myfavrest-app_development
test: test:
<<: * default
  # host: test-db
  database: myfavrest-app_test
<<: * default
  database:<% = ENV ['DB_NAME_PRODUCTION']%>username:<% = ENV ['DB_USER_PRODUCTION']%>host:<% = ENV ['DB_HOST_PRODUCTION']%>password:<% = ENV ['DB_PW_PRODUCTION']%>socket: /var/lib/mysql/mysql.sock

⇒Each environment variable of production is also defined on the server and can be confirmed.

myfavrestapp_production admin (omitted) (omitted)
What I tried ②

In the error message, guess from the fact that the DB connection destination is "localhost",
I thought that production could not be specified, so I added the following to the configuration file and executed it,
The error event did not change at all.
・ Deploy.rb

set: stages,% (production, staging)
set: default_stage, "production"

・ Production.rb

set: stage,: production
Currently guessing cause

Since ec2-user @ localhost and I went to connect without a password,
I'm guessing that the target DB specification in the db: migrate task is not working,
I'm investigating by looking at the source of Capistrano,
I didn't understand it well and there was no progress, so I asked a question.
Capistrano: Source of migration task

If i have any questions, please let us know.
We apologize for the inconvenience, and thanks for your cooperation.

  • Answer # 1

    Maybe the environment variables aren't passed.
    The connection user to the DB is admin in the environment variable, but it is ec2-user in the error.

    Where are the environment variables set?
    Is that where it goes when booting with cap?

    Let's use Dotenv even in production.
    If you don't like
    Please refer to