首页 > 解决方案 > 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 CulpYouTube视频使用了非常相似的 docker-compose.yaml。

标签: phpdockerdocker-composemariadb

解决方案


简短答案
重命名映射到 /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 ups中必须有一些不变的东西,这与服务名称无关。它是 docker-compose.yml 中的 mysql_data 卷容器。它似乎是一个在您重新部署时没有重新创建的数据层,在我的情况下,它在我第一次运行它时被初始化错误,可能是因为我没有提供环境变量。因此,我将名称更改为 db_data 并docker-compose up再次中提琴!这次数据库已初始化,我能够访问在初始化时在模式文件中引入容器的数据库表。


推荐阅读