今回は初っ端から公式ドキュメントに当たったことで早く解決できた。
結論
対処法1
[mysqld] secure-file-priv = "" # 追加
Server System Variablesの secure-file-priv
を空にする。
空の場合、変数が無効となるためnotセキュアな設定になってしまう。
対処法2
FROM mysql:8.0.28 WORKDIR ./ ADD ./my.cnf /etc/mysql/my.cnf COPY hogehoge /var/lib/mysql-files # 追加
secure-file-priv
のデフォルト値を確認*1し、デフォルト値と同じ名前のディレクトリをコンテナ内に作る。
本記事では対処法2について見ていく。
開発環境
# ホスト > docker --version Docker version 20.10.8, build 3967b7d > docker-compose --version docker-compose version 1.29.2, build 5becea4c # コンテナ root@{CONTAINER_ID}:/# mysql --version mysql Ver 8.0.28 for Linux on x86_64 (MySQL Community Server - GPL)
エラー内容
> docker-compose logs -f db # (省略) elpis-db | mysqld: Error on realpath() on '/var/lib/mysql-files' (Error 2 - No such file or directory) elpis-db | 2022-03-06T01:25:22.939319Z 0 [ERROR] [MY-010095] [Server] Failed to access directory for --secure-file-priv. Please make sure that directory exists and is accessible by MySQL Server. Supplied value : /var/lib/mysql-files elpis-db | 2022-03-06 01:25:22+00:00 [ERROR] [Entrypoint]: Unable to start server. elpis-db exited with code 1
ディレクトリ構成
> tree . ├── README.md ├── db │ ├── Dockerfile │ └── my.cnf └── docker-compose.yml
CSVなどのインポートデータがまだ無い状態。
ソースコード
version: '3.8' services: db: build: context: ./db dockerfile: Dockerfile container_name: elpis-db environment: - MYSQL_ROOT_PASSWORD=root ports: - 3306:3306 volumes: - ./db:/db user: root
FROM mysql:8.0.28 WORKDIR ./ ADD ./my.cnf /etc/mysql/my.cnf
[mysql] default-character-set=utf8mb4 [mysqld] character-set-server=utf8mb4
[ERROR] [MY-010095] [Server] Failed to access directory for --secure-file-priv.
[ERROR] [MY-010095] [Server] Failed to access directory for --secure-file-priv. Please make sure that directory exists and is accessible by MySQL Server. Supplied value : /var/lib/mysql-files
--secure-file-priv とは
この変数は、LOAD DATA ステートメント、SELECT ... INTO OUTFILE ステートメントおよび LOAD_FILE() 関数によって実行される操作など、データインポートおよびエクスポート操作の影響を制限するために使用されます。 これらの操作は、FILE 権限を持つユーザーにのみ許可されます。
https://dev.mysql.com/doc/refman/8.0/ja/server-system-variables.html
今回はデータインポートもエクスポートもしていない段階でのエラー。
まだインポートもエクスポートもしていないのに何故エラーが起きる?
デフォルト値
--secure-file-priv
のデフォルト値を確認してみる。
https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html
ここでエラーメッセージに書かれている /var/lib/mysql-files
のディレクトリがあることが分かる。
使用しているMySQLのDockerイメージは mysql:8.0.28のため、OSはdebian。
そのため、デフォルト値は /var/lib/mysql-files
ということが分かる。
エラー解決
Please make sure that directory exists and is accessible by MySQL Server. Supplied value : /var/lib/mysql-files
ということで、上記のエラーメッセージの通り、「/var/lib/mysql-filesあるのか?確認しろ」と言われているので、最終的にデフォルト値と同じ名前のディレクトリがコンテナ内にあればOK。 デフォルトでは無かったため、コンテナ内に作る。
FROM mysql:8.0.28 WORKDIR ./ ADD ./my.cnf /etc/mysql/my.cnf COPY hogehoge /var/lib/mysql-files # 追加
デフォルトでインポートやエクスポートするファイルの置き場は /var/lib/mysql-files
が設定されているけど、/docker-entrypoint-initdb.d
で初期化処理を書く場合はそっちを指定するケースが多そう。
参考
- MySQL 8 docker-compose :Failed to access directory for --secure-file-priv · Issue #541 · docker-library/mysql
- MySQL :: MySQL 8.0 Reference Manual :: 5.1.8 Server System Variables
*1:デフォルト値はプラットフォーム固有のため公式ドキュメントで確認 > https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_secure_file_priv