Mariadb Docker 容器拒绝使用数据库架构进行初始化

cod*_*bie 3 php mariadb docker docker-compose

我正在使用以下 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 }
Run Code Online (Sandbox Code Playgroud)

然后,我按如下方式构建并运行容器:

docker-compose build
docker-compose up
Run Code Online (Sandbox Code Playgroud)

正如您在日志中看到的,数据库 mydb 未初始化,这通过在容器内运行 shell 并尝试访问数据库来确认。因此,不会创建 root 用户,不会创建数据库,也不会导入模式。但有趣的是,环境变量已导入到容器中,因此它们可以在容器的 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)
Run Code Online (Sandbox Code Playgroud)

另一个证据表明 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;
}
 ?>
Run Code Online (Sandbox Code Playgroud)

该页面显示:

 <!-- language: plain -->
 Testing database
 SQLSTATE[HY000] [1045] Access denied for user 'dbuser'@'172.19.0.3' (using password: YES)
Run Code Online (Sandbox Code Playgroud)

另一方面,在命令行上运行 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 
Run Code Online (Sandbox Code Playgroud)

那么,我的 docker-compose.yml 有什么问题吗?Adam CulpYouTube视频使用了非常相似的 docker-compose.yaml。

cod*_*bie 6

简短回答
重命名映射到 /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,这也没有帮助。

最后,我想我的所有s中一定有一些不变的东西docker-compose up,与服务名称无关。它是 docker-compose.yml 中的 mysql_data 卷容器。它似乎是一个数据层,当您重新部署时不会重新创建,在我的例子中,它在我第一次运行它时被初始化错误,可能是因为我没有提供环境变量。所以,我将名称更改为 db_data 并docker-compose up再次进行了中提琴!这次数据库已初始化,我能够访问初始化时在模式文件中引入容器的数据库表。

  • 无需重命名任何内容。只需删除现有卷“docker volume rm &lt;volume-name&gt;”。查看所有卷:`docker volume ls`。 (2认同)