質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Q&A

解決済

1回答

6223閲覧

docker導入後のMysql2::Error::ConnectionError (Unknown MySQL server host 'db' (0)):

lyon

総合スコア5

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

0グッド

0クリップ

投稿2021/02/07 08:01

編集2021/02/07 09:45

やりたいこと

既存のrailsアプリケーションにdockerを導入し、以下のことをできるようにしたいと考えています。

  • docker-composeを使ってdocker開発環境を構築したい
  • 同じアプリのホスト環境(dockerコンテナを起動していないlocal環境)にてrails sやdb関連のコマンドを使いたい
  • EC2にデプロイしたい(Capistranoを使って)

※docker導入前はcapistranoを使った自動デプロイはできている状態でした。

現状できないこと

docker環境にてアプリを立ち上げることはできるようになりましたが、
ホスト環境でのrails server立ち上げ、データベース操作を行うと下記エラーが出ます。

Mysql2::Error::ConnectionError (Unknown MySQL server host 'db' (0)):

またcapistranoを使って自動デプロイを試みたところ、deploy:migratingのところで下記エラーが出ます。

Mysql2::Error::ConnectionError: Unknown MySQL server host 'db' (2)

ソースコード

Dockerfile

1FROM ruby:2.6.5 2RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/* 3RUN apt-get update && apt-get install -y mariadb-client --no-install-recommends && rm -rf /var/lib/apt/lists/* 4RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs 5RUN apt-get install -y vim 6 7RUN mkdir /myproject 8 9WORKDIR /myproject 10 11ADD Gemfile /myproject/Gemfile 12ADD Gemfile.lock /myproject/Gemfile.lock 13 14RUN bundle install 15 16ADD . /myproject

dockercompose

1version: '3' 2services: 3 db: 4 image: mysql:5.6.50 5 command: mysqld --character-set-server=utf8 6 environment: 7 MYSQL_DATABASE: app_development 8 MYSQL_ROOT_PASSWORD: password 9 MYSQL_USER: root 10 ports: 11 - "3306:3306" 12 web: 13 build: 14 context: . 15 dockerfile: Dockerfile 16 command: bundle exec rails s -p 3000 -b '0.0.0.0' 17 tty: true 18 stdin_open: true 19 depends_on: 20 - db 21 ports: 22 - "3000:3000" 23 volumes: 24 - .:/myproject 25 environment: 26 - "SELENIUM_DRIVER_URL=http://selenium_chrome:4444/wd/hub" 27 selenium_chrome: 28 image: selenium/standalone-chrome-debug 29 logging: 30 driver: none

database

1default: &default 2 adapter: mysql2 3 encoding: utf8 4 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 5 username: root 6 password: password 7 host: db 8 9development: 10 <<: *default 11 database: app_development 12 13test: 14 <<: *default 15 database: app_test 16 17production: 18 <<: *default 19 database: app_production 20 username: root 21 password: <%= ENV['DATABASE_PASSWORD'] %> 22 socket: /var/lib/mysql/mysql.sock 23

行ったこと

エラーの内容からして、database.ymlのhost:dbが怪しいと思いdocker-compose.ymldatabase.ymlを下記の通り書き換えました。
docker環境からアクセスした場合と、それ以外の場合でmysqlの権限情報やホストを変えることができるようにするという考え方です。
考え方は下記Qiitaの記事を参考にしました。
https://qiita.com/waniwaninowani/items/21d677a6c455e5b76d45

dockercompose

1version: '3' 2services: 3 db: 4 image: mysql:5.6.50 5 command: mysqld --character-set-server=utf8 6 environment: 7 MYSQL_DATABASE: app_development 8 MYSQL_ROOT_PASSWORD: password 9 MYSQL_USER: root 10 MYSQL_HOST: db 11 ports: 12 - "3306:3306" 13 web: 14 build: 15 context: . 16 dockerfile: Dockerfile 17 command: bundle exec rails s -p 3000 -b '0.0.0.0' 18 tty: true 19 stdin_open: true 20 depends_on: 21 - db 22 ports: 23 - "3000:3000" 24 volumes: 25 - .:/myproject 26 environment: 27 - "SELENIUM_DRIVER_URL=http://selenium_chrome:4444/wd/hub" 28 selenium_chrome: 29 image: selenium/standalone-chrome-debug 30 logging: 31 driver: none

database

1default: &default 2 adapter: mysql2 3 encoding: utf8 4 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 5 username: <%= ENV['MYSQL_USERNAME'] || 'root' %> 6 password: <%= ENV['MYSQL_PASSWORD'] || '' %> 7 host: <%= ENV['MYSQL_HOST'] || 'localhost' %> 8 socket: /tmp/mysql.sock 9 10development: 11 <<: *default 12 database: app_development 13 14test: 15 <<: *default 16 database: app_test 17 18production: 19 <<: *default 20 database: app_production 21 username: root 22 password: <%= ENV['DATABASE_PASSWORD'] %> 23 socket: /var/lib/mysql/mysql.sock 24 host: localhost

結果

上記の変更を行ったところ、ホスト環境のrails serverのアクセスはできるようになりましたが、
今度はdocker環境で立ち上げを行う際に下記エラーが出てしまいました。

Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

エラー文からsocket通信の記載を外したらできるのでは、と思いリトライすると、

Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

となってしまいます。
またこの状態でcapistranoを試すのは怖くてできていないですし、そもそもdocker環境が正常に作動しないので仮にcapistranoを実行できても意味がない、という状況です。

ちなみにこの状態でdbのコンテナからシェルに入り、mysql -u rootを実行すると

Host '172.18.0.2' is not allowed to connect to this MySQL server

とエラーが吐かれ、mysqlに入れない状態でした。

質問

以下ポイントに関して教えを乞いたいと考えています

  1. そもそものゴールの設定が間違っていないか

当方はゴールを①docker環境での開発が可能 ②ホスト環境でも開発が可能 ③capistranoによる自動デプロイが可能
に設定していますが、考え方が間違っているということはありませんか?
※正直②ホスト環境での開発 は必要なければ飛ばしてしまえば良いと思っています。  
2. 上記1を踏まえ、以下をご教授願いたいです。
- ゴール設定が間違っていない場合
→上記ソースコードに対しご指摘をいただきたいです。
- ゴール設定が間違っている場合
→dockerを開発環境に導入した場合の開発の考え方(ホスト環境への接続の必要はないetc..)、または考え方を学べる記事や書籍等の情報ソースを教えてください。

ここまで参考にした書籍/記事等

書籍

  • Docker/Kubernetes 実践コンテナ開発入門(途中まで)

webサイト/記事

  • 入門Docker

https://y-ohgi.com/introduction-docker/

  • Dockerをrailsアプリに組み込む方法

https://qiita.com/kkyouhei/items/653760627bf9d4bc9e71
https://qiita.com/y-suna/items/e52b3af1d80c52b66b31

  • docker環境とホスト環境を両立する方法

https://qiita.com/waniwaninowani/items/21d677a6c455e5b76d45

環境

  • Ruby:2.6.5
  • Rails:6.0.0
  • Mysql:5.6.50
  • Docker:20.10.2
  • docker-compose:1.27.4

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

suama

2021/02/07 09:37

こんにちは。「ホスト環境」とありますが、これは別のサーバのことでしょうか?なにか情報を添えていただければと思います。 database.yml で host: xxxx としている箇所は、本来はデータベースを起動しているサーバーのIPアドレスやホスト名が入ります。
lyon

2021/02/07 09:49 編集

こんにちは。ここで言うホスト環境とは、dockerコンテナを起動しない状態で、rails sを入力し、PC上のいわゆるlocalhost:3000にアクセスしようとした時のことです。
suama

2021/02/07 11:41 編集

ありがとうございます!回答してみますね!
guest

回答1

0

ベストアンサー

こんばんは。docker-composeを使っての起動、PC上のターミナルからの直接起動ができるという条件ですね。ソースコードは問題ないので、docker-compose.ymldatabase.yml の調整で大丈夫だと思います。

database.yml

defaultは共通設定になります。
データベースへの接続でデータベースのサーバを指定するのは、host の箇所ですが、ここは host: <%= ENV['MYSQL_HOST'] || 'localhost' %> としておきます。

こうしておいて、

  • docker-compose内でのRailsのコンテナから見た場合は、環境変数がMYSQL_HOST=db となるように指定
  • PC上で直にターミナルからRailsを起動する場合は、特に指定しなければlocalhost(ソケット接続)での接続

となるようにすれば良いです。

ちなみに、PC上で直にRailsを起動する場合は、データベース側はどうされていますか?
同じくPC上で直接MySQLを起動していますでしょうか。
それとも、docker-composeで上げているMySQLを利用する形でしょうか。
その場合は、socket: /tmp/mysql.sock でなくて port: 3306を記載するといいかなと思います。

yaml

1 2default: &default 3 adapter: mysql2 4 encoding: utf8 5 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 6 username: <%= ENV['MYSQL_USERNAME'] || 'root' %> 7 password: <%= ENV['MYSQL_PASSWORD'] || '' %> 8 host: <%= ENV['MYSQL_HOST'] || 'localhost' %> 9 socket: /tmp/mysql.sock 10 11development: 12 <<: *default 13 database: app_development 14 15test: 16 <<: *default 17 database: app_test 18 19production: 20 <<: *default 21 database: app_production 22 username: root 23 password: <%= ENV['DATABASE_PASSWORD'] %> 24 socket: /var/lib/mysql/mysql.sock 25 host: localhost

docker-compose.yml

サービス: web がRailsのアプリケーションを動かすコンテナなので、この設定の箇所の environment のところに、MYSQL_HOST=db を追加します。
こうすることで、上記のdatabase.yml のところで host: <%= ENV['MYSQL_HOST'] || 'localhost' %> した箇所に、db というホスト名が入ります。
docker-compose内で起動したコンテナ同士、サービス名(web,db) で名前解決ができるので、接続できるようになります。

追記

また、database.yml のところで <%= ENV['MYSQL_PASSWORD'] || '' %> と記載があるので、ここも環境変数で渡すかパスワードなしでの接続となります。
docker-compose内で起動したMySQLは MYSQL_ROOT_PASSWORD や MYSQL_USERを明示しているので、これに対応するユーザ名 / パスワードをdatabase.ymlに渡す必要があります。

yaml

1 2version: '3' 3services: 4 db: 5 image: mysql:5.6.50 6 command: mysqld --character-set-server=utf8 7 environment: 8 MYSQL_DATABASE: app_development 9 MYSQL_ROOT_PASSWORD: password 10 MYSQL_USER: root 11 ports: 12 - "3306:3306" 13 web: 14 build: 15 context: . 16 dockerfile: Dockerfile 17 command: bundle exec rails s -p 3000 -b '0.0.0.0' 18 tty: true 19 stdin_open: true 20 depends_on: 21 - db 22 ports: 23 - "3000:3000" 24 volumes: 25 - .:/myproject 26 environment: 27 - "SELENIUM_DRIVER_URL=http://selenium_chrome:4444/wd/hub" 28 - MYSQL_HOST=db 29 - MYSQL_PASSWORD=password 30 selenium_chrome: 31 image: selenium/standalone-chrome-debug 32 logging: 33 driver: none

EC2にデプロイしたい(Capistranoを使って)

こちらに関しては、EC2上でのrails起動時の環境変数に MYSQL_HOST=接続させたいMySQLのアドレス を指定すれば大丈夫ですね。

dockerを開発環境に導入した場合の開発の考え方

ローカル開発環境や、サーバ(VirtualBox)に全てをインストールして同時に起動させる形式とは違い、1コンテナ1サービス単位で、必要なものを起動します。

それぞれ別々の環境として認識されるので、基本的には、localhost ではお互い接続できません。

docker-composeを利用する場合は、docker-compose内のネットワークで管理割り当てられた名前で接続し合う形になります。

投稿2021/02/07 12:04

編集2021/02/07 13:36
suama

総合スコア1997

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lyon

2021/02/07 13:13

丁寧なご回答ありがとうございました。 ご指導いただいたコードをそのまま使ってみたところ、PC上で直にRailsを起動するパターンは動いたのですが、docker-composeの方は 'docker-compose run web rails db:create' をすると 'Mysql2::Error::ConnectionError: Access denied for user 'root'@'172.18.0.5' (using password: NO)' というエラーが出てしまいました。 ネット上記事にはvolumeを削除するなどの方法が書いてありましたがそれも変わらずでしたし、webコンテナ内でmysqlにアクセスしようとしてもdb:createの時と同様のエラーが出てしまいます。 どこに着目して修正をはかれば良いでしょうか?
suama

2021/02/07 13:31

ご確認ありがとうございます。docker-composeの中で、MySQL側で MYSQL_ROOT_PASSWORD: password という設定がありますね。 docker-compose内でのRails (web) と MySQL (db) のやりとりは、この情報を使うので、同じく docker-compose.ymlにこの設定を渡す必要がありますね。 追記いたしますね。
lyon

2021/02/08 12:30

修正ありがとうございます。ご指摘の方針でやってみたところ、docker環境においても直のrails環境においてもサーバーを立ち上げることができました。ありがとうございます! また重ねての質問で大変恐縮ですが、EC2へのデプロイのところで「EC2上でのrails起動時の環境変数に MYSQL_HOST=接続させたいMySQLのアドレス を指定すれば大丈夫」とのコメントをいただきましたが、これはEC2上の環境変数にMYSQL_HOST=dbと設定する必要があると言うことでしょうか? 現在は特にEC2上の環境変数は手を加えずcapistranoを実行しましたが、見た目上は問題なくデプロイできているようです。またdatabase.ymlでもproductionのhostはlocalhostに設定しているので、localhostにアクセスすることになっているのでは?と思いますが、変更を行わないと問題が生じてしまうと言うことでしょうか?
suama

2021/02/09 02:12 編集

EC2上ではdocker-composeを使うのですか? 直にRailsを起動し、別途MySQLを起動するとかRDSを使う構成? それ次第でしょうか。 > 変更を行わないと問題が生じてしまうと言うことでしょうか? defaultの設定では、localhostか環境変数で渡したデータベースのアドレスをひきつぎます。 もちろん適切な接続先がいなければ、エラーになります。 > ※docker導入前はcapistranoを使った自動デプロイはできている状態でした。 と書かれていましたので、EC2上ではdockerを使っての起動でないのなら、その時の設定と同じになるだけです。情報を添えていただけると。 あとはやってみて、潰していくのが良いと思いますよ。 回答はここまでで。
lyon

2021/02/09 10:00

ありがとうございます。 今回はEC2上でMariaDBを立ち上げてRDSを使う構成にしているので、まずは設定はこのままで行こうと思います。 おかげさまでなんとか先へ進めそうです。本当にありがとうございました。ベストアンサーとさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問