猿问

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 文件中定义的。

另一个表明 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。


暮色呼如
浏览 236回答 1
1回答

Helenr

简短回答:将映射到 /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 中更改 db 服务名称并重新运行,这不起作用。我还使用 删除了所有停止的容器docker container prune,这也无济于事。最后,我认为我所有的docker-compose ups中一定有一些不变的东西,这与服务名称无关。它是 docker-compose.yml 中的 mysql_data 卷容器。它似乎是一个在您重新部署时不会重新创建的数据层,在我的情况下,它在我第一次运行时初始化错误,可能是因为我没有提供环境变量。因此,我将名称更改为 db_data 并docker-compose up再次执行了中提琴!这次数据库被初始化,我能够访问我在初始化时在模式文件中引入容器的数据库表。
随时随地看视频慕课网APP
我要回答