はじめに
EC2インスタンスを使用してインフラ構築しようとしたら、DB作成の時に以下2つのエラー沼にハマったので、その解決とDocker・docker-composeを用いたEC2によるデプロイのDB作成までの流れを解説します。
エラー①
$ docker-compose run web rails db:create RAILS_ENV=production
ArgumentError: Missing `secret_key_base` for 'production' environment, set this string with `rails credentials:edit’
エラー②
$ docker-compose run web rails db:create RAILS_ENV=production
Mysql2::Error::ConnectionError: Access denied for user 'root'@'172.18.0.4' (using password: NO)
開発環境
Ruby 2.6.5
Bundler 2.1.4
Rails 6.0.0
MySQL 5.6.50
前提
この記事での作業を行うにあたり、前提として開発環境・EC2にDocker及びdocker-composeがインストールされていることを前提とします。
ここではEC2におけるDockerとdocker-composeのインストールだけ解説します。
EC2へのDockerインストール
作業内容はDocker の基本 - Amazon EC2 Container Serviceに基づいて行っていきます。
次にDockerをインストールしていきます。
# yum の更新
$ sudo yum update -y
# yum から docker をインストール
$ sudo yum install -y docker
# docker サービスの起動
$ sudo service docker start
Starting cgconfig service: [ OK ]
Starting docker: [ OK ]
# ec2-user を docker グループに追加する
$ sudo usermod -a -G docker ec2-user
一度ログアウトし、再度ログインするとdocker
コマンドが使えるようになります。
$ docker info
なぜグループに追加するかは【Docker】 ERROR: Couldn’t connect to Docker daemon at http+docker://localhost – is it running? を参考にしてください。
EC2へのDocker Composeのインストール
Install Docker Compose - Docker Documentation に基づき作業していきます。
# 一時的にスーパーユーザーになる
$ sudo -i
# ここから一時的にスーパーユーザー
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# docker-compose コマンドに実行権限付与
$ chmod +x /usr/local/bin/docker-compose
# スーパーユーザーを抜ける
$ exit
# docker-compose コマンドの実行確認
$ docker-compose --version
docker-compose version 1.11.2, build dfed245
EC2のDocker内にDB作成
ここからはec2にdocker環境を構築してみたを参考にして進めました。
まずdockerコンテナを作成し、バックグラウンドで起動します。
# コンテナ作成(バックグラウンドで起動)
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ docker-compose up -d
# 起動しているか確認
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ docker ps -a
起動できていたら、いよいよ本題のDBを作成していきます。
作成前に必ずリモートの変更をcommit→pushし、本番環境にも適用させましょう。
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ git pull origin master
続いてDBを作成していきます。
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ docker-compose run web rails db:create RAILS_ENV=production
以下のようになれば成功です。
created database 'アプリ名_production'
順当に行けば、このようになりますが、僕の場合は、以下のエラーが出ました。
エラー① ArgumentError: Missing secret_key_base
for 'production' environment, set this string with `rails credentials:edit’
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ docker-compose run web rails db:create RAILS_ENV=production
ArgumentError: Missing `secret_key_base` for 'production' environment, set this string with `rails credentials:edit’
このエラーの解決には(AWS) ArgumentError: Missing 'secret_key_base' for 'production' environment, set this string with 'rails credentials:edit'を参考にしました。
エラー原因はconfig/credentials.yml.enc
というファイルがローカル環境と本番環境であっていないため上記エラーが発生するようです。
なので**本番環境(EC2)**で一度、credentials.yml.enc
ファイルを削除して作り直すことで解決することができるようです。
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ cd /var/www/アプリ名/config
[ec2-user@ip-XXX-XX-XX-XXX config]$ ls
application.rb database.yml locales storage.yml
boot.rb environment.rb puma.rb unicorn.rb
cable.yml environments routes.rb webpack
credentials.yml.enc # このファイル
initializers spring.rb webpacker.yml
[ec2-user@ip-XXX-XX-XX-XXX config]$ rm credentials.yml.enc
# rmコマンドで削除
# lsコマンドで削除されている確認してみましょう
無事削除できていたら作成し直しましょう。
[ec2-user@ip-XXX-XX-XX-XXX config]$ EDITOR=vim rails credentials:edit
Adding config/master.key to store the encryption key: 54xx0x9xx86x4x754x9x0xxxxx10x492
Save this in a password manager your team can access.
If you lose the key, no one, including you, can access anything encrypted with it.
create config/master.key
File encrypted and saved.
# create と save ができていれば成功
よし、これで解決した!!
DB作成だ!!と思い、作成するコマンドを実行すると、今度は次のようなエラーが出ました。
エラー② Mysql2::Error::ConnectionError: Access denied for user 'root'@'172.18.0.4' (using password: NO)
エラー内容を要約すると**「DBにログインするためのパスワードがないよ」**と怒っているということになります。
ここで僕はDockerのコンテナを削除したり、停止・再起動したり、作り直したりと、色々やりましたが、解決できず沼にハマりました(笑)
原因はdatabase.yml
に記述した、本番環境(production)の記述でした。
それもそのはずで、Docker導入のためにdatabase.yml
の設定を変更していたためです。
default: &default
adapter: mysql2
encoding: utf8
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
# ここから設定変更
username: <%= ENV.fetch('DB_USERNAME', 'root') %>
password: <%= ENV.fetch('DB_PASSWORD', 'password') %>
socket: /tmp/mysql.sock
host: <%= ENV.fetch('DB_HOST', 'db') %>
DB_USERNAME='root'
DB_PASS='password'
DB_HOST='db'
MYSQL_ROOT_PASS='password'
.env
での環境変数設定はこちらを見てみてください。
ローカルでの設定は上記のようになっていますが、本番環境では下記のようになっています。
production:
<<: *default
database:アプリ名_production
username: root
password: <%= ENV['DATABASE_PASSWORD'] %>
socket: /var/lib/mysql/mysql.sock
つまり、このままの記述ではローカルと本番でのデーターベースに差異が生まれており、データーベースを作れないということになります。
この本番環境の記述とローカルの記述を合わせることで、このエラーは解決できます。
production:
<<: *default
database: tumlog_production
host: <%= ENV.fetch('DB_HOST', 'db') %>
username: <%= ENV.fetch('DB_USERNAME', 'root') %>
password: <%= ENV.fetch('DB_PASSWORD', 'password') %>
socket: /var/lib/mysql/mysql.sock
以上のように記述し直したら、gitでcommit→pushしターミナルでgit pull origin masterを実行します。
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ git pull origin master
* branch master -> FETCH_HEAD
6f883e9..99c894d master -> origin/master
Updating 6f883e9..99c894d
Fast-forward
config/database.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[ec2-user@ip-XXX-XX-XX-XXX リポジトリ名]$ docker-compose run web rails db:create RAILS_ENV=production
created database 'アプリ名_production'
以上のように本番環境でDBを作成できました。
最後に、意外と忘れがちなのがgit pull origin masterなので、それを忘れて、自分からエラー沼にはまらないようにしましょう(笑)
参考文献
① ec2にdocker環境を構築してみた
②AWS EC2 Amazon LinuxでDocker, Docker Composeをインストールする
③ (AWS) ArgumentError: Missing 'secret_key_base' for 'production' environment, set this string with 'rails credentials:edit'