【簡単に解決】Dockerコンテナ上のWordPressデータベースにアクセスできない!?対処法:「Can’t select database」「Access denied」「Unknown database」

PC作業のトラブルで疲れている女性のイラストDocker

dockerを使ってデータベースやwordpressを構築するときに、接続先のデータベース名前など設定をカスタマイズすると、データベースに接続できないというエラーが発生することがある。

しかも、以前は同じdocker-compose.ymlで問題なく動いていたのに、、急にエラーがでてきた、、なんで、、?という、あくまでdocker-compose.ymlに問題がない場合、原因はDocker上で起動するMySQLの性質にあります。

この症状の原因と対処法について解説します。

サクッと解決方法

原因や理由はどうでもいいという方のために、結論のみのサクッと解決する方法をまとめておきます。

※< >の部分を自分の設定に変更してください。

#MySQLのコンテナに入る
> docker exec -it <コンテナ名> bash

#ルートユーザー権限でMySQLの対話モードに入る
root@dab19e479a65:/# mysql -u <ルートユーザー名> -p<ルートユーザーのパスワード>

#対象ユーザーにデータベースへのアクセス権限を付与する
mysql> grant all privileges on *.* to '<ユーザー名>'@'<ホスト名>';

#対象のデータベースを作成する
mysql> create database <データベース名>;

あとは、ブラウザをリロードすればWordpressインストールのいつもの画面が表示されます。

エラーの内容、原因、対処法の詳細については以下。

エラー内容

エラーは、ログインのために指定したユーザーが、指定したデータベースにアクセスできないという症状。

Access denied for use ‘ユーザー名’@’ホスト名’ to database ‘データベース名’

Can’t select database

We were able to connect to the database server (which means your username and password is okay) but not able to select the データベース名 database.

Are you sure it exists?
Does the user wp_user have permission to use theデータベース名 database?
On some systems the name of your database is prefixed with your username, so it would be like username_データベース名. Could that be the problem?

If you don’t know how to set up a database you should contact your host. If all else fails you may find help at the WordPress Support Forums.

docker-compose.ymlの設定例は以下。

  p-wp:
    image: wordpress:latest 
    container_name: prograshi_wp
    #restart: always
    depends_on: 
     - db
    ports:
     - "10090:80" 
    environment:
      WORDPRESS_DB_HOST: db:3306 
      WORDPRESS_DB_USER: wp_user 
      WORDPRESS_DB_PASSWORD: root 
      WORDPRESS_DB_NAME: prograshi_db 
      WORDPRESS_DEBUG : 1  
    volumes:
       - ./prograshi:/var/www/html
      

発生原因

Dockerのコンテナを使ってWordpressのサイトを構築するとき、rootユーザー以外を指定した場合、そのユーザーに与えられるアクセス権限は初回に作成した1つのデータベースのみとなる。

このため、同じMySQLサーバーに複数のWordpressサイトのデータベースを作成するときに、同一ユーアーで異なるデータベース名を指定した場合に、アクセス権限がなく「Access denied for use ‘ユーザー名’@’ホスト名’ to database ‘データベース名’」というエラーが発生する。

エラーが発生する状況は以下の3つが重なった時。

エラー発生条件
  • 同じMySQLサーバーを使用
  • 異なるデータベースを使用
  • 同一ユーザー

逆に、以下の4つのうち、どれかに該当すれば同じdocker-compose.ymlで問題なくWordpressサイトを起動することができる。

エラー発生条件
  • 初回のWordpress構築
  • 異なるMySQLサーバー
  • 一つのデータベースの中に複数のWordpressを展開
  • 異なるユーザー

対処法

この問題は、データベースにアクセスしようとしているユーザーの権限を変更することで解決できる。

Dcoker上のコンテナに入り、権限を変更し、ブラウザをリロードしてWordpressを構築していきます。

Docker上のMySQLコンテナに入る

まずは 、dokcer ps コマンドで、現在起動しているコンテナを確認する。

> docker ps
CONTAINER ID   IMAGE                          COMMAND                  CREATED        STATUS        PORTS                                     NAMES
db17e4d0fc2b   wordpress:latest               "docker-entrypoint.s…"   42 hours ago   Up 28 hours   0.0.0.0:10090->80/tcp, :::10090->80/tcp   wp
d01dd3b83a41   phpmyadmin/phpmyadmin:latest   "/docker-entrypoint.…"   42 hours ago   Up 28 hours   0.0.0.0:10099->80/tcp, :::10099->80/tcp   phpmyadmin
dab19e479a65   mysql:5.6                      "docker-entrypoint.s…"   42 hours ago   Up 28 hours   3306/tcp                                  wp_mysql

上記例の場合、3つのコンテナが起動している。(1)WordPress, (2)phpMyAdmin, (3)MySQL。この中でMySQLの対話モードに入れるのは(3)MySQL コンテナ。(phpMyAdminではない)

コンテナの中に入るコマンドは以下。

$docker exec -it コンテナ名 bash

> docker exec -it wp_mysql bash
root@dab19e479a65:/#

「root@dab19e479a65:/#」のように表示されれば、コンテナの中に入ることに成功。

MySQLの対話モードを起動する

コンテナに入ったら、まずはMySQLが存在するか確認する。

$ mysql –version でバージョン情報が表示されれば、MySQLがインストールされている。

root@dab19e479a65:/# mysql --version
mysql  Ver 14.14 Distrib 5.6.51, for Linux (x86_64) using  EditLine wrapper

バージョンが確認できたら、ルートユーザーとしてMySQLにログインする。(※注 docker-compose.ymlで指定したユーザーではない)

以下コマンドを実行。

$ mysql -u ルートユーザー名 -h ホスト名 -pパスワード

オプション内容必要性デフォルト
-uユーザー名必須root
-hホスト名省略可(localhostとみなす)localhost
-pパスワード必須root
「-p」のパスワード指定時の注意点
  • 「-p」の後に空白を入れずにパスワードを記述する
  • 「Warning: Using a password on the command line interface can be insecure.」セキュリティの警告がでるが問題ない。警告を出したくない場合は以下で対応可能。
  • 「-p」の後ろに空白を入れ、パスワードを指定しなければ、コマンド実行後にパスワードを聞かれる。入力している文字は表示されないが、パスワードを入力してEnterをクリックすればログインできる。
  • 「-p」は「–password」と同じ。

デフォルトの設定の場合

もし、MySQLの設定がデフォルトのままで、ルートユーザーの情報などを変更していない場合は以下の設定になっている。

  • ルートユーザー名: root
  • ホスト名: localhost ※省略可能
  • パスワード: root

次のコマンドを実行すればルートユーザーとしてログインできる。

# mysql -u root -proot
ルートユーザーとしてログインに成功した例

以上でDocker上のMySQLコンテナの対話モードの起動が完了。これでSQLが実行できる。

ユーザーに権限を付与する

ルートユーザーとしてログインできたら、まずは、現在登録されているユーザーと権限を確認する。同時に確認できないので、ユーザーの一覧を確認してから、個別に権限を確認する。

ユーザーの一覧を確認

mysql> select user, host from mysql.user;

コマンドを実行するとユーザーの一覧が表示される。

+---------+-----------+
| user    | host      |
+---------+-----------+
| root    | %         |
| wp_user | %         |
| root    | localhost |
+---------+-----------+
3 rows in set (0.00 sec)

上記例では、rootユーザーと、wp_userの2つのユーザーが存在する。

なお、hostの「%」はワイルドカードで、すべてのホストを許容するという意味。

ユーザーの権限を確認

ユーザーの権限を確認するには、以下コマンドを実行する。

mysql> show grants for 'ユーザー名'@'ホスト名';

例えば、以下のようになる。

mysql> show grants for 'wp_user'@'%';
+--------------------------------------------------------------------------------------------------------+
| Grants for wp_user@%                                                                                   |
+--------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'wp_user'@'%' IDENTIFIED BY PASSWORD '******'                                    |
| GRANT ALL PRIVILEGES ON `wp\_db`.* TO 'wp_user'@'%'                                                    |
+--------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

wp_userは「GRANT USAGE ON *.*」ですべてのDBに何も権限を与えない(USAGE)とした上で、「GRANT ALL PRIVILEGES ON ‘wp_db’」として、データベース名 wp_db のみ全ての権限を与えるとしている。

つまり、最初に作成した1つ目のDBしかアクセスする権限を持たないということ。次でこれを変更する。

(参考)MySQL公式 権限一覧

ユーザーの権限を変更する

ユーザー名と現在与えられている権限が確認できたので、次に、権限の変更を行う。

権限の変更・付与は「grant」コマンドを使う。ここでは、対象のユーザーにすべてのデータベースにアクセスする権限を付与する。

grant all privileges on *.* to 'ユーザー名'@'ホスト名';

実際の適用例は以下のようになる。

mysql> grant all privileges on *.* to 'wp_user'@'%';
Query OK, 0 rows affected (0.00 sec)


mysql> show grants for 'wp_user'@'%';
+-----------------------------------------------------------------------------------------------------------------+
| Grants for wp_user@%                                                                                            |
+-----------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'wp_user'@'%' IDENTIFIED BY PASSWORD '******'                                    |
| GRANT ALL PRIVILEGES ON `wp\_db`.* TO 'wp_user'@'%'                                                             |
+-----------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

グローバル「*.*」にすべての権限「ALL PRIVILEGES」を与えることができた。

これで、このユーザーでデータベースを作成することが可能になる。

grantコマンドと権限付与の設計

今回はすべてのデータベースにアクセスする権限を付与したが、対象のデータベースやテーブルを指定することも可能。

grantコマンドについてもう少し詳しく解説すると以下のようになる。

権限を変更・付与するコマンド

grant <与える権限名> on <対象のDB>.<対象のテーブル> to ‘<ユーザー名>’@'<ホスト名>’ identified by ‘<パスワード>’;

主な権限の種類

最初に指定する「与える権限名」には種類がかなりある。ここでは主要なもののみをご紹介。

権限名内容
ALL PRIVILEGESすべての権限
CREATEDBやテーブルの作成
DROPDBやテーブルの削除
DELETEテーブルから行を削除
INSERTテーブルに行を挿入
SELECTSELECTコマンドの使用を許可
UPDATEテーブルの行の更新
GRANT OPTION他のユーザーへの権限付与または削除

詳細は MySQL公式 権限一覧 にて。

<対象のDB>.<対象のテーブル>

  • ワイルドカード「*」が使える。
  • 「*.*」はすべてのDBのすべてのテーブルが対象。グローバルという。
  • 「DB名.*」は、指定したDBの中のすべてのテーブルが対象。

identified by ‘<パスワード>’

identified by ‘<パスワード>’ の記述は省略可能。省略した場合はもともと設定してあるパスワードが適用される。

データベースを作成する

これまでの処理で、対象ユーザーにデータベースにアクセスする権限は付与できた。

しかし、データベース名が初回作成時と異なる場合は、そもそもMySQLに対象のデータベースが存在していないことになる。

この状態で、ブラウザをリロードすると「Unknown database ‘データベース名’」と表示されアクセスすることができない。

このため、対象のデータベースを作成しておく必要がある。(とても簡単で1分でできる)

MySQLのコンテナに入り対話モードで「database create データベース名」を実行する。

#現在作成されているデータベース一覧を表示
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| wp_db              |
+--------------------+
4 rows in set (0.00 sec)

#データベースを新規作成
mysql> create database prograshi_db;
Query OK, 1 row affected (0.00 sec)

#確認
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| wp_db              |
| prograshi_db       |
+--------------------+
5 rows in set (0.00 sec)

これでデータベース周りの必要な設定は完了。

ブラウザをリロードする

ブラウザをリロードすると、いつものWordpressインストールの画面が表示される。

あとは、画面表示に沿って入力していけば、Wordpressサイトを起動することができる。

お疲れさまでした~

タイトルとURLをコピーしました