php - Mariadb Docker 容器拒绝使用数据库模式进行初始化
问题描述
我正在使用以下 docker-compose 初始化数据库服务,该服务将由 Web 服务使用。
<!-- language: YAML -->
version: '3'
services:
web:
build:
context: .
dockerfile: container-build/web/Dockerfile
ports:
- "8080:80"
volumes:
- /home/johndoe/src/proj:/var/www/public_html
links:
- db
db:
image: mariadb:10.4.7
ports:
- "6603:3306"
restart: always
environment:
- MYSQL_DATABASE=mydb
- MYSQL_ROOT_PASSWORD=12345678
- MYSQL_USER=dbuser
- MYSQL_PASSWORD=12345678
volumes:
- "mysql_data:/var/lib/mysql"
- /home/johndoe/src/proj/data/schema.sql:/docker-entrypoint-initdb.d/schema.sql
volumes:
mysql_data: { driver: local }
然后我按如下方式构建和运行容器:
docker-compose build
docker-compose up
正如您在日志中看到的,数据库 mydb 未初始化,这通过在容器内运行 shell 并尝试访问数据库来确认。因此,没有创建 root 用户,没有创建数据库,也没有导入模式。有趣的是,环境变量已经被导入到容器中,所以它们在 cotainer 的 shell 中可用,例如 echo $MYSQL_USER prints dbuser
,这是我们在 docker-compose 文件中定义的。
<!-- language: plain -->
Recreating proj_db_1 ... done
Recreating proj_web_1 ... done
Attaching to proj_db_1, proj_web_1
db_1 | 2019-08-25 5:08:33 0 [Note] mysqld (mysqld 10.4.7-MariaDB-1:10.4.7+maria~bionic) starting as process 1 ...
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: Using Linux native AIO
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: Uses event mutexes
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: Number of pools: 1
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: Using SSE2 crc32 instructions
db_1 | 2019-08-25 5:08:33 0 [Note] mysqld: O_TMPFILE is not supported on /tmp (disabling future attempts)
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: Initializing buffer pool, total size = 256M, instances = 1, chunk size = 128M
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: Completed initialization of buffer pool
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: 128 out of 128 rollback segments are active.
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: Creating shared tablespace for temporary tables
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: Waiting for purge to start
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: 10.4.7 started; log sequence number 140016; transaction id 21
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
db_1 | 2019-08-25 5:08:33 0 [Note] Plugin 'FEEDBACK' is disabled.
db_1 | 2019-08-25 5:08:33 0 [Note] Server socket created on IP: '::'.
db_1 | 2019-08-25 5:08:33 0 [Warning] 'proxies_priv' entry '@% root@0d988a449cca' ignored in --skip-name-resolve mode.
db_1 | 2019-08-25 5:08:33 0 [Note] InnoDB: Buffer pool(s) load completed at 190825 5:08:33
db_1 | 2019-08-25 5:08:33 0 [Note] Reading of all Master_info entries succeeded
db_1 | 2019-08-25 5:08:33 0 [Note] Added new Master_info '' to hash table
db_1 | 2019-08-25 5:08:33 0 [Note] mysqld: ready for connections.
db_1 | Version: '10.4.7-MariaDB-1:10.4.7+maria~bionic' socket: '/var/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
web_1 | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.19.0.3. Set the 'ServerName' directive globally to suppress this message
web_1 | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.19.0.3. Set the 'ServerName' directive globally to suppress this message
web_1 | [Sun Aug 25 05:08:33.526373 2019] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.38 (Debian) PHP/7.2.21 configured -- resuming normal operations
web_1 | [Sun Aug 25 05:08:33.526419 2019] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
db_1 | 2019-08-25 5:08:46 8 [Warning] Access denied for user 'dbuser'@'172.19.0.3' (using password: YES)
web_1 | 172.19.0.1 - - [25/Aug/2019:05:08:46 +0000] "GET /test.php HTTP/1.1" 200 402 "-" "Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Safari/605.1.15"
db_1 | 2019-08-25 5:08:47 9 [Warning] Access denied for user 'dbuser'@'172.19.0.3' (using password: YES)
web_1 | 172.19.0.1 - - [25/Aug/2019:05:08:47 +0000] "GET /test.php HTTP/1.1" 200 401 "-" "Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Safari/605.1.15"
db_1 | 2019-08-25 5:08:49 10 [Warning] Access denied for user 'dbuser'@'172.19.0.3' (using password: YES)
web_1 | 172.19.0.1 - - [25/Aug/2019:05:08:49 +0000] "GET /test.php HTTP/1.1" 200 401 "-" "Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Safari/605.1.15"
db_1 | 2019-08-25 5:09:35 11 [Warning] Access denied for user 'root'@'localhost' (using password: NO)
显示 docker-compose.yml 没有做它应该做的另一个证据是,当我浏览http://localhost:8080/test.php时,它具有以下内容:
<!-- language: php -->
<?php
echo "Testing database<br>";
try{
$db = new PDO('mysql:dbname=mydb;host=db', 'dbuser', '12345678');
}catch(PDOException $e){
echo $e->getMessage();
return;
}
?>
此页面显示:
<!-- language: plain -->
Testing database
SQLSTATE[HY000] [1045] Access denied for user 'dbuser'@'172.19.0.3' (using password: YES)
另一方面,在命令行上运行 mariadb 映像并将这些环境变量和指向 schema.sql 的卷传递给命令行可以工作并初始化数据库。例如,以下命令有效:
<!-- language: lang-bash -->
docker run --name mariadbtest --rm -ti -d -e "MYSQL_ROOT_PASSWORD=12345678" -e "MYSQL_USER=dbuser" -e MYSQL_PASSWORD=12345678 -v /home/johndoe/src/proj/data/schema.sql:/docker-entrypoint-initdb.d/schema.sql mariadb
那么,我的 docker-compose.yml 有什么问题?Adam Culp的YouTube视频使用了非常相似的 docker-compose.yaml。
解决方案
简短答案:
重命名映射到 /var/lib/mysql 的数据卷,即将 mysql_data 重命名为 db_data 并docker-compose up
再次运行。
长答案:
我最终弄清楚了这个问题。MariaDB的 docker hub页面稍微提到了这样一个事实,即只有在第一次创建容器时,才会使用 /docker-entrypoint-initdb.d 中可用的数据库模式对其进行初始化。
首次启动容器时,将使用提供的配置变量创建并初始化具有指定名称的新数据库。此外,它将执行 /docker-entrypoint-initdb.d 中的扩展名为 .sh、.sql 和 .sql.gz 的文件。文件将按字母顺序执行。您可以通过将 SQL 转储安装到该目录中轻松填充 mariadb 服务,并提供带有贡献数据的自定义图像。SQL 文件将默认导入到 MYSQL_DATABASE 变量指定的数据库中。
这导致我在 docker-compose 中更改数据库服务名称并重新运行,但没有成功。我还用 删除了所有停止的容器docker container prune
,这也没有帮助。
最后,我认为我的所有docker-compose up
s中必须有一些不变的东西,这与服务名称无关。它是 docker-compose.yml 中的 mysql_data 卷容器。它似乎是一个在您重新部署时没有重新创建的数据层,在我的情况下,它在我第一次运行它时被初始化错误,可能是因为我没有提供环境变量。因此,我将名称更改为 db_data 并docker-compose up
再次中提琴!这次数据库已初始化,我能够访问在初始化时在模式文件中引入容器的数据库表。
推荐阅读
- google-maps - 启用地理编码 API 时,Google Maps JavaScript API 抛出“ExpiredKeyMapError”
- javascript - 如何修复这个简单的均值计算器以使其正常工作,以及如何制作它以便它需要尽可能多的数字?
- python - xlsxwriter pandas frame:如果列中有空白单元格,则突出显示行
- electron - Electron:如何删除不需要的模块?
- javascript - 谁将 mp4 文件转换为 Wav 音频文件?
- c# - 如何将 ping 的用户名和变量传递给机器人命令
- generics - 特质不能变成对象
- node.js - 如何将模型结果传递给节点 js 中的视图
- javascript - 如何在继续之前使用 JavaScript Fetch API 等待响应?
- mysql - (MySQL 和 .Net Core)选择在 where 子句中具有运行时值的查询不起作用