LoginSignup
2
2

More than 1 year has passed since last update.

AWS(ECS)上でデータベースが作成されない!? Dockerで環境構築したRails6をRDSと連携できない問題を解決!

Posted at

開発環境をDockerで開発していたRails6アプリケーションをAWS(ECS)にデプロイしている実装で、AWS上にデータベースが作成できない問題が発生したので解決までの手順を残しておこうと思います。

開発環境

  • RubyMine
  • Ruby 3.0.1
  • Ruby on Rails 6.1.3
  • Docker 20.10.7
  • AWS (ECS fargate/ECR/VPC/RDS/ACM/ALB/S3/Route53)

発生していた問題

オリジナルアプリをDockerで開発していたので、デプロイ先をAWS(ECS fargate)にしたいと思い実装を進めているなかで、本番環境でデータベースが作成されないエラーが起きました。

エラー内容(ECSタスク上のログ)

2021-07-26 19:26:48Tasks: TOP => db:create
2021-07-26 19:26:48(See full trace by running task with --trace)
2021-07-26 19:26:48rails aborted!
2021-07-26 19:26:48ActiveRecord::ConnectionNotEstablished: Unknown MySQL server host 'db' (-2)
2021-07-26 19:26:48Caused by:
2021-07-26 19:26:48Mysql2::Error::ConnectionError: Unknown MySQL server host 'db' (-2)
2021-07-26 19:26:48Unknown MySQL server host 'db' (-2)
2021-07-26 19:26:48Couldn't create 'locat' database. Please check your configuration.

エラー文を調べたところ、サーバーホスト名dbが本番環境で見つからないというエラー内容だとわかりました。

修正前のdatabase.yml

# MySQL. Versions 5.5.8 and up are supported.
#
# Install the MySQL driver
#   gem install mysql2
#
# Ensure the MySQL gem is defined in your Gemfile
#   gem 'mysql2'
#
# And be sure to use new-style password hashing:
#   https://dev.mysql.com/doc/refman/5.7/en/password-hashing.html
#
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  socket: /tmp/mysql.sock
  host: db

development:
  <<: *default
  database: locat_development

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *default
  database: locat_test

production:
  <<: *default
  database: <%= Rails.application.credentials.db[:database] %>
  username: <%= Rails.application.credentials.db[:username] %>
  password: <%= Rails.application.credentials.db[:password] %>
  socket: <%= Rails.application.credentials.db[:socket] %>

# As with config/credentials.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is
# ever seen by anyone, they now have access to your database.
#
# Instead, provide the password or a full connection URL as an environment
# variable when you boot the app. For example:
#
#   DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
#
# If the connection URL is provided in the special DATABASE_URL environment
# variable, Rails will automatically merge its configuration values on top of
# the values provided in this file. Alternatively, you can specify a connection
# URL environment variable explicitly:
#
#   production:
#     url: <%= ENV['MY_APP_DATABASE_URL'] %>
#
# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full overview on how database connection configuration can be specified.
#

エラー原因

エラー原因は、ローカルのmysqlサーバーホスト名'db'でECS上で設定しているRDSとの連携をしようとしていたことが原因でした。

つまり、ローカルの接続先ホストをRDSのエンドポイントにして連携させてあげる必要がある。

ローカルのホスト名と本番環境のRDSを同じにしてあげないと、RDS上にはない'db'で接続しようとしてしまいデータベースが作成できないエラーが発生してしまうということでした。

解決方法

ローカルの接続先ホストをRDSのエンドポイントに指定してあげることでデータベースの作成ができました。

修正方法

% EDITOR=vim bin/rails credentials:edithostを作成してRDSのエンドポイントを指定する

#aws:
#   access_key_id: AKIAU2S6QQYAB4JOXSO6
#   secret_access_key: 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

# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

db:
    database: RDSのデータベース名
    username: RDSのユーザー名
    password: RDSのパスワード
    socket: xxxxxxxxxxxxxxxxxxxxxxxxx
    host: ここにRDSのエンドポイントを指定してあげる

  • credential.ymlにエンドポイントを指定すると、ECSで作成するコンテナの環境変数にエンドポイントを設定する必要はなくなる(設定しても可)

credential.ymlに必要なエンドポイントを指定したあとは、database.ymlを下記のように編集する

database.yml

production:
  <<: *default
  database: <%= Rails.application.credentials.db[:database] %>
  username: <%= Rails.application.credentials.db[:username] %>
  password: <%= Rails.application.credentials.db[:password] %>
  socket: <%= Rails.application.credentials.db[:socket] %>
  host: <%= Rails.application.credentials.db[:host] %>
  • host: <%= Rails.application.credentials.db[:host] %>を設定する

ここまで修正したらECRに設定したリポジトリのlatestを削除後にプッシュを行う。
(Rails側のDockerfileをプッシュ)

  • CircleCIを導入している方は自動デプロイで可能。

タスク定義のリビジョンでコンテナの再定義を行う。再定義後にクラスターのサービス名の設定内のリビジョンを変更した最新のlatestに変更。

  • ここまで修正したらタスクのログでデータベースが作成できているか確認をしてみる。(おそらくデータベースの作成ができているでしょう。)

まとめ

初めてECSに触れたので、デプロイまでの実装でかなりつまずきました。ひとまずデータベースの作成ができたので一安心。

インフラ周りが自分の中で最も難しい分野だと感じているので、知識を増やして正しく構築できるように勉強していこうと思います!

2
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2