🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

Ruby on Rails 5

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

MySQL

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Docker

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

Q&A

解決済

1回答

5593閲覧

Mysql2::Error::ConnectionError: Unknown MySQL server host 'db' (0)の解決方法について

Harluz

総合スコア19

docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

Ruby on Rails 5

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

MySQL

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Docker

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

0グッド

0クリップ

投稿2020/08/13 07:40

docker+Mysql+railsにてrials db:migrateを実行するもMysql2::Error::ConnectionError:Unknown MySQL server host 'db' (0)となりポートフォリオ制作が進まない状態です。(Rspecも動作しません)
いつも通りネットから情報を仕入れて解決しようとするも良い情報にヒットせず、ここ何日間か解決できずにいます。
(サーバーは立ち上がるが、Mysqlとの接続がうまくいっていないと思われます)

Dockerfile

1FROM ruby:2.6.3 2 3# リポジトリを更新し依存モジュールをインストール 4RUN apt-get update -qq && \ 5 apt-get install -y build-essential \ 6 nodejs 7 8# ルート直下にmy_appという名前で作業ディレクトリを作成(コンテナ内のアプリケーションディレクトリ) 9RUN mkdir /my_app 10WORKDIR /my_app 11 12# ホストのGemfileとGemfile.lockをコンテナにコピー 13ADD Gemfile /my_app/Gemfile 14ADD Gemfile.lock /my_app/Gemfile.lock 15 16# bundle installの実行 17RUN bundle install 18 19# ホストのアプリケーションディレクトリ内をすべてコンテナにコピー 20ADD . /my_app 21 22# puma.sockを配置するディレクトリを作成 23RUN mkdir -p tmp/sockets 24

Dockercompose

1version: '3' 2services: 3 app: 4 build: 5 context: . 6 env_file: 7 - ./environments/db.env 8 command: bundle exec puma -C config/puma.rb 9 volumes: 10 - .:/my_app 11 - public-data:/my_app/public 12 - tmp-data:/my_app/tmp 13 - log-data:/my_app/log 14 depends_on: 15 - db 16 tty: true 17 db: 18 image: mysql:5.7 19 env_file: 20 - ./environments/db.env 21 volumes: 22 - db-data:/var/lib/mysql 23 ports: 24 - "3306:3306" 25 tty: true 26 web: 27 build: 28 context: containers/nginx 29 volumes: 30 - public-data:/my_app/public 31 - tmp-data:/my_app/tmp 32 ports: 33 - "3000:80" 34 depends_on: 35 - app 36volumes: 37 public-data: 38 tmp-data: 39 log-data: 40 db-data: 41

database

1default: &default 2 adapter: mysql2 3 encoding: utf8 4 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 5 username: <%= ENV.fetch('MYSQL_USER') { 'root' } %> 6 password: <%= ENV.fetch('MYSQL_ROOT_PASSWORD') { 'db_root_password' } %> 7 host: <%= ENV.fetch('DATABASE_HOST') { 'db' } %> 8 port: <%= ENV.fetch('DATABASE_PORT') { 3306 } %> 9 10development: 11 <<: *default 12 database: my_app_development 13 14test: 15 <<: *default 16 database: my_app_test

dbenv

1MYSQL_ROOT_PASSWORD=db_root_password 2MYSQL_USER=root 3MYSQL_PASSWORD=password 4DATABASE_HOST=db

docker-compose ps
my_app_app_1 bundle exec puma -C config ... Up
my_app_db_1 docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp, 33060/tcp
my_app_web_1 /bin/sh -c /usr/sbin/nginx ... Up 0.0.0.0:3000->80/tcp

なお、独学者かつ駆け足で環境構築したこともあり、基本的な知識が欠如しております。
根本的に間違っている場合は、それを教えて頂くだけでも構いません。
また、実際にMysqlよりpostgresqlの方が扱いやすかったりするのでしょうか?
二重の質問になってしまい申し訳ありませんが、どうかご教示ください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

追記

次の記事を参照している前提で回答します
Docker + Rails + Puma + Nginx + MySQL - Qiita

MYSQL_USER には root 以外を設定

MYSQL_USER には root を設定することはできません:

console

1db_1 | 2020-08-14 09:42:31+00:00 [Note] [Entrypoint]: Creating user root 2db_1 | ERROR 1396 (HY000) at line 1: Operation CREATE USER failed for 'root'@'%' 3db_1 | 4test-docker-compose_db_1 exited with code 1

root でも良いですが、データベースの標準的な利用法に則って
アプリケーションがアクセスするための一般ユーザーを作成しましょう:

ini

1MYSQL_ROOT_PASSWORD=db_root_password 2MYSQL_USER=app 3MYSQL_PASSWORD=password 4DATABASE_HOST=db

database.yml は passwordMYSQL_ROOT_PASSWORD から MYSQL_PASSWORD に変更します:

yaml

1default: &default 2 adapter: mysql2 3 encoding: utf8 4 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 5 username: <%= ENV.fetch('MYSQL_USER') { 'root' } %> 6 password: <%= ENV.fetch('MYSQL_PASSWORD') { 'db_root_password' } %> 7 host: <%= ENV.fetch('DATABASE_HOST') { 'db' } %> 8 port: <%= ENV.fetch('DATABASE_PORT') { 3306 } %>

nginx.conf のディレクトリー設定

ディレクトリーを記事の設定から変更されているので、
次の 2 箇所の変更も必要になります:

diff

1 # ソケット通信したいのでpuma.sockを指定 2- server unix:///webapp/tmp/sockets/puma.sock; 3+ server unix:///my_app/tmp/sockets/puma.sock; 4 5 # ドキュメントルートの指定 6- root /webapp/public; 7+ root /my_app/public;

データベースの作成

記事ではコマンドで作成する手順となっています:

DBの作成 | Docker + Rails + Puma + Nginx + MySQL - Qiita

console

1$ docker-compose exec app rails db:create

しかし、これは MySQL 公式イメージの正しい使い方ではありません
MySQL 公式イメージでは環境変数 MYSQL_DATABASE でデータベース名を指定することで
コンテナー起動時に自動的にデータベースを作成します:

ini

1MYSQL_ROOT_PASSWORD=db_root_password 2MYSQL_USER=app 3MYSQL_PASSWORD=password 4DATABASE_HOST=db 5MYSQL_DATABASE=my_app_development

参考: mysql - Docker Hub

元の回答

ぱっと見問題なさそうに見えますね
次の点について確認してみるとどうでしょうか?

1
docker-compose ps を実行したとき、 my_app_db_1 は exit していませんか?

2
docker-compose logs を実行すると、特に my_app_db_1 について、どのようなログが表示されますか?db.env

投稿2020/08/13 09:31

編集2020/08/14 15:26
y_shinoda

総合スコア3272

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

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

Harluz

2020/08/13 09:40

ご回答ありがとうございます。 先程、下記URLを参考にした結果、動いた?感じです。 https://teratail.com/questions/234727?link=qa_related_pc 具体的には、database.ymlのホスト名を host: 127.0.0.1 としたところ少なくとも、Unknown MySQL server host 'db' (0) は消えました。 しかし、本当に問題が解決したのか確認しているところでございます。 いずれ、嬉しすぎて近くにあったハンカチを壁に思いっきり投げつけた次第でございます。
y_shinoda

2020/08/14 12:29

回答に追記しました こちらで動作確認取っておきました host を 127.0.0.1 に設定するのは、よりゴールから遠ざかってしまっていると思います 127.0.0.1 は app コンテナー自体を指します app コンテナーの中には MySQL は起動していません
Harluz

2020/08/14 12:51 編集

おっしゃる通りで、mysqlのerrorの堂々巡りをしておりました。苦笑い まさしく、mysqlユーザーの権限によるエラー?も発生しておりましたので、y_shinodaさんの回答を試してみます
Harluz

2020/08/14 13:26

試した結果、確かにwebページ自体は正常に起動しているように思いますが、bin/rspecやrails db:migrateコマンドを実行した際に、またMysql2::Error::ConnectionError: Unknown MySQL server host 'db' (0) のエラーが発生しました。 要は、質問時と同じ状態に戻りました。 知識不足で申し訳ありませんが、これはdocker-composeの問題ではなく、railsやrspecの設定やそもそものディレクトリ構造が異なっているとかの問題になるのでしょうか? さらにご教示いただけるのでありましたら、他の確認したいファイル等、なんなりと申しください。 よろしくお願いいたします。 (因みに参考にしたqiitaの記事は上記URLの通りでして、勉強も含めディレクトリ構造を故意に変更しております。)
Harluz

2020/08/14 13:41

最初の回答でいただいたdocker-compose logsが下記の通りです。 ErrorはなくWarningが何点かありますので、それのみを抜粋させていただきます。 [Warning] CA certificate ca.pem is self signed. [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory. [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details). 以上になります。
y_shinoda

2020/08/14 15:31

失礼しました、ひとつ手順が抜けていました database.yml は `password` を `MYSQL_ROOT_PASSWORD` から `MYSQL_PASSWORD` に変更します これで db:migrate は動作します rspec はもしかするとテスト用データベースが必要になってできないかもしれません その場合は、こちらで教えていただければ、 いくつか解決のための選択肢を示すことができるかもしれません
Harluz

2020/08/14 16:00

私も、一つ勘違いしており、Iniファイルをdatabase.fileと勘違いしておりました。記載漏れもあり大変恐縮でありますが、私は macを使用しておりますので、my.cnfを修正すれば良いという解釈で問題ないでしょうか? 下記の通りに修正しました。 # Default Homebrew MySQL server config [mysqld] # Only allow connections from localhost explicit_defaults_for_timestamp = 1 bind-address = 127.0.0.1 mysqlx-bind-address = 127.0.0.1 MYSQL_ROOT_PASSWORD=db_root_password MYSQL_USER=app MYSQL_PASSWORD=password DATABASE_HOST=db MYSQL_DATABASE=my_app_development しかし、 MYSQL_ROOT_PASSWORD=db_root_password より上のコードは不要でしょうか? また、この設定で試したところ、 Access denied for user 'root'@'172.18.0.3' (using password: YES) という新しいエラーが発生しました。 時間もあれなので、明日このエラーについて、調べることとします。 夜遅くまで気にかけていただきありがとうございます。
y_shinoda

2020/08/14 16:42

この Docker の手順では Mac にインストールした MySQL は使いません my_app_db_1 というコンテナーが MySQL です このコンテナーに app などの別のコンテナーから接続するときは docker-compose.yml で定義している "db" というサービス名でアクセスします また、エラーメッセージ: Access denied for user 'root'@'172.18.0.3' (using password: YES) からすると、app から db にアクセスするときに root ユーザーとしてアクセスしてしまっているようです これは、 database.yml の次の設定あたりに原因があります: username: <%= ENV.fetch('MYSQL_USER') { 'root' } %> または、./environments/db.env の MYSQL_USER の設定が root もしくは未設定になっているなどが考えられます
Harluz

2020/08/15 23:00 編集

https://qiita.com/fumi_042/items/7d1c14e335ab1c226e0f 上記URLの記事を参考に実行した結果、 Access denied for user 'app'@'%' to database 'my_app_development' のエラー文に変わりました。 因みに、grant_user.sqlは下記のとおりになっております。 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'; FLUSH PRIVILEGES; 余計なことをしてしまったのでしょうか?
y_shinoda

2020/08/16 01:55

Access denied for user 'app'@'%' to database 'my_app_development' このメッセージは MySQL ユーザー名: app でデータベース: my_app_development に接続しようとしています db サービスにこのユーザーとテーブルを作成する環境変数を与えているかを 確認しましょう MYSQL_USER=app MYSQL_DATABASE=my_app_development これでブラウザからのアクセスや db:migrate は動作することを確認しています rspec のみ動作しない場合は、別途方法を検討しますので教えてください
Harluz

2020/08/16 02:41 編集

----db.env----- MYSQL_ROOT_PASSWORD=db_root_password MYSQL_USER=app MYSQL_PASSWORD=password DATABASE_HOST=db ------database.yml------- default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: <%= ENV.fetch('MYSQL_USER') { 'app' } %> password: <%= ENV.fetch('MYSQL_PASSWORD') { 'db_root_password' } %> host: <%= ENV.fetch('DATABASE_PORT') { 'db' } %> port: <%= ENV.fetch('DATABASE_PORT') { 3306 } %> development: <<: *default database: my_app_development test: <<: *default database: my_app_test USER等は修正しております。 コンテナ内のDBのユーザーを確認しますと mysql> select user, host from mysql.user; +---------------+-----------+ | user | host | +---------------+-----------+ | app | % | | root | % | | mysql.session | localhost | | mysql.sys | localhost | | root | localhost | +---------------+-----------+ 5 rows in set (0.00 sec) この設定の場合、app@% で接続されていることを期待しているのですが、実際に接続されているのは mysql> select user(), current_user(); +----------------+----------------+ | user() | current_user() | +----------------+----------------+ | root@localhost | root@localhost | +----------------+----------------+ 1 row in set (0.00 sec) となっており、おっしゃる通り、root@localhostで接続されてます。 また、データベース自体の有無が気になりましたので確認した結果、 mysql> SELECT database(); +------------+ | database() | +------------+ | NULL | +------------+ 1 row in set (0.00 sec) となり、私の予想(間違えている可能性あり)では database.ymlに記載したmy_app_developmentとmy_app_test が存在するはずでは?と考えているのですが、、 実際に、rails db:migrate及びbin/rspecでは ConnectionError: Unknown MySQL server host 'db' (0) となり、DB自体が存在していないということが濃厚と思われます。
y_shinoda

2020/08/16 02:49

mysql> select user(), current_user(); このコマンドは現在の接続に使用しているユーザーを返すので、 Rails から実行しなければ Rails が接続に使用しているユーザーが表示されません この SQL を実行するために MySQL クライアントで root として接続しているために root が返されています データベースは環境変数で MYSQL_DATABASE=my_app_development を与えると db サービスのコンテナー新規作成時の初期化処理で作成されます ただし、volume が残っていると初期化処理が実行されないので、 docker-compose down -v で volume を削除します
Harluz

2020/08/16 03:15

volumeを削除後に、up -dで起動するも mysql> SELECT database(); +------------+ | database() | +------------+ | NULL | +------------+ 1 row in set (0.00 sec) んん〜〜 git hubにコードを上げて欲しい場合は、申しください。
y_shinoda

2020/08/16 03:23

もし GitHub にコードを公開して構わないのであれば、 適当にブランチを切っていただいてコミット、プッシュしていただき、 URL を教えてください 環境変数など機密情報はコミット、プッシュする必要はありません、 後でこちらで必要なものだけお尋ねします
y_shinoda

2020/08/16 05:36

PR を作成しておきました: https://github.com/harluz/my_app/pull/39 開発中に rspec を実行すると my_app_development のデータがテストデータに変更されるのが どうしても嫌な場合は、別途何かしらの対処が必要です これは、Docker の公式 MySQL イメージの仕様と Rails の仕様が競合しているためです データベースの分離に関してうまく対処できない場合は別途質問を投稿お願いします
Harluz

2020/08/16 14:44

すいません。 エラーが変わりません。 私のgitのpushの仕方が悪かったのも原因ですが、yoshidaさんの環境ではview及びdb:migrateは問題なかったのでしょうか?
y_shinoda

2020/08/16 18:41

こちらでは view も db:migrate も問題なく動作しました rspec も一応動作するようにしています ちなみに、今はどのエラーが出ていますか? PR に各コミットの変更内容とその目的を書いていますので、 今表示されているエラーと照らし合わせて、 各コミットの内容が今動かしているコードに適用されているか確認してみるとどうでしょう? https://github.com/harluz/my_app/pull/39 また、変更内容を適用するためには docker-compose down で、既存のコンテナーを削除することも必要です
Harluz

2020/08/17 15:03 編集

viewにおいては、Access denied for user 'app'@'%' to database 'my_app_development' bin/rspecとrails db:migrateにおいては、 Mysql2::Error::ConnectionError: Unknown MySQL server host 'db' (0) です。 申し訳ありません、もう一度現在のコードをgithubに載せて確認して頂くことは可能でしょうか? 色々とコードをいじってしまったこともあり、何がなんだか、、、、
y_shinoda

2020/08/17 15:56

それをやってしまうと永遠に終わらなくなってしまうので、 PR をマージした直後に戻って動作確認を行って、一旦こちらの質問は解決した後、 変更後の動作確認については新たに質問を立て直してください 新たに質問を投稿すると次のようなメリットがあります: - 質問者も回答者も新たにポイントを取得できます - すべての回答者が質問を確認し、回答が得られる確率が上がります - 検索でこの質問にたどり着いた人が質問のタイトルに対するシンプルな回答を得ることができ、質問に高評価が得られやすくなります 次のコマンドでマージ直後の状態を確認できます: git branch after-merge d864baf36232b95d0fb3e4cd143229d3fd2923c2 git checkout after-merge
Harluz

2020/08/18 14:57

マージ直後の状態を確認した結果、やはりエラーが変わりませんでした。 y_shinodaさんのおっしゃる通り新たに質問を立て直したいと思います。 dockerに対する知識やgitのコミットの作法など勉強になることがたくさんありました。ど素人に分かりやすく簡潔に教えてくださり、大変ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問