3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめてのアドベントカレンダーAdvent Calendar 2024

Day 3

Docker上の他のコンテナからMySQLコンテナに接続できなくて詰まった

Last updated at Posted at 2024-12-02

はじめに

Docker環境でMySQLコンテナを使用した際に、他のコンテナから接続できない旨のエラーが出力されて詰まったので備忘も兼ねて残しておこうと思います。

環境

OS:MacBookPro M3

使用コンテナのイメージ等

  • maven:3.6.3-adoptopenjdk-14
  • python:3.8
  • mysql:8.0

経緯

他のコンテナ(maven, python等)から、MySQLサーバーのコンテナに接続して機能テストを実行しようとしたところ、以下のようなエラーが発生しました。
いずれもDB関連のエラーなのでMySQLサーバーのコンテナ周りに問題がありそうでした。

sqlalchemy.exc.ProgrammingError: (mysql.connector.errors.ProgrammingError) 1044 (42000): Access denied for user 'user'@'%' to database 'sample_db1'
(Background on this error at: https://sqlalche.me/e/14/f405)

そこで、MySQLサーバーのコンテナを確認してみると、コンテナには接続できることと、sample_db1というデータベースが存在していることが確認できました。
続いて、権限を確認してみたところ、以下のように権限が足りていないことがわかりました。

mysql> SHOW GRANTS FOR 'user'@'%';
+----------------------------------+
| Grants for user@%                |
+----------------------------------+
| GRANT USAGE ON *.* TO user@% |
+----------------------------------+
1 row in set (0.01 sec)

問題の原因

コンテナをビルドする際に以下のSQLスクリプトを使用していたことが原因でした。

CREATE DATABASE IF NOT EXISTS sample_db1;
CREATE DATABASE IF NOT EXISTS sample_db2;
CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
GRANT ALL ON sample_db1.* TO 'user'@'localhost' WITH GRANT OPTION;
GRANT ALL ON sample_db2.* TO 'user'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;

この設定だと、ユーザー'user'@'localhost'はMySQLコンテナ内(localhost)からしか接続できません。他のコンテナからは'user'@'%'として接続しようとするため、権限が不足してエラーになります。

解決方法

ユーザーのホスト部分を修正して、任意のホストから接続できるようにします。
また、既存のユーザーがいる場合にエラーになってしまう可能性があるため、IF NOT EXISTSを使いました。

修正後のSQLスクリプト

CREATE DATABASE IF NOT EXISTS sample_db1;
CREATE DATABASE IF NOT EXISTS sample_db2;

CREATE USER IF NOT EXISTS 'user'@'%' IDENTIFIED BY 'password';
ALTER USER 'user'@'%' IDENTIFIED BY 'password';

GRANT ALL ON sample_db1.* TO 'user'@'%' WITH GRANT OPTION;
GRANT ALL ON sample_db2.* TO 'user'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

ポイント

  • CREATE USER IF NOT EXISTSでユーザーが存在しない場合のみ作成
  • ALTER USERでパスワードを再設定し、既存ユーザーでも確実にパスワードを適用
  • 'user'@'%'で任意のホストからの接続を許可

コンテナの再ビルドと確認

修正したスクリプトを使ってMySQLコンテナを再ビルドします。

docker compose up -d --build

MySQLコンテナに入り、ユーザーの権限を確認します。

docker exec -it mysql-container mysql -u root -p
SHOW GRANTS FOR 'user'@'%';

期待通りの権限が表示されればOKです。

注意点

  • 'user'@'%'は任意のホストからの接続を許可するため、セキュリティ上のリスクがあります。本番環境では接続元を限定することをおすすめします。
CREATE USER IF NOT EXISTS 'user'@'192.168.0.%' IDENTIFIED BY 'password';
ALTER USER 'user'@'192.168.0.%' IDENTIFIED BY 'password';
  • 既存のユーザーがいる場合、CREATE USERだけではエラーになるので、IF NOT EXISTSALTER USERを組み合わせています。

おわりに

この修正により、他のコンテナからMySQLコンテナへの接続が可能になりました。
同じ問題で困っている方の参考になれば幸いです。

参考リンク

3
0
0

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
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?