在docker-compose启动时创建数据库

Ped*_*rog 21 mysql docker-compose

我想在docker-compose.yml文件中使用环境变量创建一个MySQL数据库,但它无法正常工作.我有以下代码:

# The Database
database:
  image: mysql:5.7
  volumes:
    - dbdata:/var/lib/mysql
  restart: always
  environment:
    MYSQL_ROOT_PASSWORD: secret
    MYSQL_DATABASE: homestead
    MYSQL_USER: root
    MYSQL_PASSWORD: secret
  ports:
    - "33061:3306"
Run Code Online (Sandbox Code Playgroud)

有人可以解释这个变量的功能吗?

小智 39

还有一个选项可以为mysql容器提供init文件,每次创建容器时都会应用该文件.

database:
    image: mysql:5.7
    ports:
        - "33061:3306"
    command: --init-file /data/application/init.sql
    volumes:
        - ./init.sql:/data/application/init.sql
    environment:
        MYSQL_ROOT_USER: root
        MYSQL_ROOT_PASSWORD: secret
        MYSQL_DATABASE: homestead
        MYSQL_USER: root
        MYSQL_PASSWORD: secret
Run Code Online (Sandbox Code Playgroud)

此类文件可能包含您的初始数据库结构和数据 - 例如:

CREATE DATABASE IF NOT EXISTS dev;
CREATE DATABASE IF NOT EXISTS test;
USE dev;
CREATE TABLE IF NOT EXISTS (...);
Run Code Online (Sandbox Code Playgroud)

  • 我可以运行多个sql文件吗? (2认同)
  • 这将在容器上产生一个名为`/data/application/init.sql` 的**目录**,除非_该文件已经存在于容器中。关于挂载主机文件以显示为容器中的文件,请阅读 [docker docs](https://docs.docker.com/storage/bind-mounts/) 上的 **bind mounts**。 (2认同)

小智 18

数据库可能已经初始化并且配置存储在中/var/lib/mysql.由于您为该位置定义了卷,因此配置将在重新启动后继续存在.MySQL映像不会一遍又一遍地重新配置数据库,它只执行一次.

volumes: - dbdata:/var/lib/mysql

如果数据库为空,则可以通过执行删除卷部分中定义的卷的docker-compose down -v位置来重置数据库-v.请参阅https://docs.docker.com/compose/reference/down/.接下来docker-compose up,MySQL映像将重新开始,并将使用您通过环境部分提供的配置初始化数据库.


Jas*_* M. 18

官方 MySQL docker 镜像在其基础镜像中添加了对 init 脚本的支持。他们在 Docker Hub 页面上的“初始化新实例”下记录了该功能。

以下是我为解决在 MySQL docker 映像中创建多个数据库和用户而采取的步骤:

  1. 创建init文件(泊坞窗图像识别.SH,.SQL和.sql.gz文件)命名的setup.sql本地目录命名.docker
  2. 将命令放在里面setup.sql(参见下面的示例)
  3. 将安装脚本挂载到文件f内的docker-compose.yaml目录中(参见下面的示例)
  4. 运行docker-compose up -d,MySQL 会运行里面的代码setup.sql

注意:脚本将按字母顺序运行文件,因此请记住这一点。

示例 docker-compose.yaml

version: "3.5"
services:
    mysql:
        image: mysql
        ports:
            - 3306:3306
        environment:
            MYSQL_ROOT_PASSWORD: SomeRootPassword1!
            MYSQL_USER: someuser
            MYSQL_PASSWORD: Password1!
            MYSQL_DATABASE: somedatabase
        volumes:
            - .docker/setup.sql:/docker-entrypoint-initdb.d/setup.sql
            - db_data:/var/lib/mysql
volumes:
    db_data:
Run Code Online (Sandbox Code Playgroud)

示例 setup.sql

-- create the databases
CREATE DATABASE IF NOT EXISTS projectone;

-- create the users for each database
CREATE USER 'projectoneuser'@'%' IDENTIFIED BY 'somepassword';
GRANT CREATE, ALTER, INDEX, LOCK TABLES, REFERENCES, UPDATE, DELETE, DROP, SELECT, INSERT ON `projectone`.* TO 'projectoneuser'@'%';

FLUSH PRIVILEGES;
Run Code Online (Sandbox Code Playgroud)


Roh*_*cha 10

此处的“初始化新实例” https://hub.docker.com/_/mysql/表示将所有 .sql、.sh、.sql.gz 文件复制到/docker-entrypoint-initdb.d文件夹中。下面是我在很多项目中使用的 docker-compose 文件,并且在最新版本的 MySQL 上运行良好

version: '3.6'
services:   
  mysql:
      environment:
          - MYSQL_DATABASE=root
          - MYSQL_ROOT_PASSWORD=changeme
          - MYSQL_USER=dbuser
          - MYSQL_PASSWORD=changeme
      command: 
         - --table_definition_cache=100
         - --performance_schema=0
         - --default-authentication-plugin=mysql_native_password
         - --innodb_use_native_aio=0
      volumes: 
          - ./init:/docker-entrypoint-initdb.d
      container_name: mysqldb
      image: mysql  
Run Code Online (Sandbox Code Playgroud)

我的 init 文件夹有一个init.sql文件,其中包含我需要在容器启动时重新创建的整个 SQL 数据转储。

以下命令用于将 MySQL 容器消耗的内存限制为 100 MB:

         - --table_definition_cache=100
         - --performance_schema=0
Run Code Online (Sandbox Code Playgroud)

注意:如果您希望保留数据,则这不会保留您的 MySQL 数据,然后使用以下配置

         - --table_definition_cache=100
         - --performance_schema=0
Run Code Online (Sandbox Code Playgroud)

其中dbdata是您需要在主机系统上创建的文件夹。


lvt*_*llo 9

对于docker-compose的第2版,你.yml或者.yaml可以看起来像这样:

version: '2'
volumes:
 dbdata:

services:
 mysql:
  image: mysql:5.7
  container_name: mysql
  volumes:
    - dbdata:/var/lib/mysql
  restart: always
  environment:
    - MYSQL_ROOT_PASSWORD=secret
    - MYSQL_DATABASE=homestead
    - MYSQL_USER=root
    - MYSQL_PASSWORD=secret
  ports:
    - "33061:3306"
Run Code Online (Sandbox Code Playgroud)

启动它docker-compose up -d 并检查:

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
a3567fb78d0d        mysql:5.7           "docker-entrypoint..."   2 minutes ago       Up 2 minutes        0.0.0.0:33061->3306/tcp   mysql

docker exec -it a3567fb78d0d bash
root@a3567fb78d0d:/# mysql -u root -p homestead
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.17 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| homestead          |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

您的音量将保留在泊坞窗音量nameoffolder_dbdata(/var/lib/docker/volumes/...)中


jon*_*hid 8

回答您的问题...

构建新的Docker容器时,我常做的一件事是了解构建时从中提取的映像的作用。

在您的docker-compose.yml头中有这个

# The Database
database:
  image: mysql:5.7
Run Code Online (Sandbox Code Playgroud)

这是您从“ mysql:5.7”中提取的图像

Dockerhub是一个存储库,您可以在其中找到该映像的信息。

用谷歌搜索“ mysql:5.7 dockerhub”

第一个结果是https://hub.docker.com/_/mysql/

那里有图像5.7,如果单击5.7,则有图像

https://github.com/docker-library/mysql/blob/607b2a65aa76adf495730b9f7e6f28f146a9f95f/5.7/Dockerfile

这是镜像中的Dockerfile,您可以查看构建镜像时发生的有趣事情。

其中之一是ENTRYPOINT [“ docker-entrypoint.sh”]

这是映像准备就绪时执行的文件

我在仓库中向上一级,您将看到此文件

https://github.com/docker-library/mysql/tree/607b2a65aa76adf495730b9f7e6f28f146a9f95f/5.7

您会看到您的环境变量正在用于创建新数据库等。

file_env 'MYSQL_DATABASE'
        if [ "$MYSQL_DATABASE" ]; then
            echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" | "${mysql[@]}"
            mysql+=( "$MYSQL_DATABASE" )
fi
Run Code Online (Sandbox Code Playgroud)


Gen*_*e S 7

如果我正确理解您的问题,您希望拥有一个包含特定数据库的容器.就像有一个CREATE DATABASE mydb已经执行过的MySQL容器等.如果需要,您需要使用docker-entrypoint-initdb.d:https: //docs.docker.com/samples/library/mysql/#docker-secrets

当第一次启动官方MySQL容器时,将首先创建一个新的数据库.然后它将执行扩展名为.sh,.sql和.sql.gz的文件/docker-entrypoint-initdb.d.所以你需要做的就是创建/docker-entrypoint-initdb.d目录并将初始化脚本放在那里.


Mik*_*ski 7

此设置意味着您的数据库已经存在。否则,您必须使用初始化脚本或手动创建它。

初始化脚本(任何.sh和文件)应位于docker 容器内的文件夹.sql中。.sql.gz/docker-entrypoint-initdb.d/

您所要做的就是简单地将此 init 脚本作为卷添加到您的 docker-compose 文件中。

database:
 image: mysql:latest
  volumes:
    - ./init-script.sql:/docker-entrypoint-initdb.d/init-script.sql

  ...
Run Code Online (Sandbox Code Playgroud)

您的init-script.sql文件可能如下所示:

CREATE DATABASE IF NOT EXISTS some_name;
USE some_name;
Run Code Online (Sandbox Code Playgroud)


Ale*_*x K 5

请记住,如果您想 docker-compose 自动从 MYSQL_DATABASE 创建数据库,您的数据文件夹(dbdata)必须为

    # The Database
    database:
      image: mysql:5.7
      volumes:
        - dbdata:/var/lib/mysql   <--- check local dbdata is empty!
      restart: always
      environment:
        MYSQL_ROOT_PASSWORD: secret
        MYSQL_DATABASE: homestead 

    etc...
Run Code Online (Sandbox Code Playgroud)

不需要初始脚本,只需:

docker-compose down -v
Run Code Online (Sandbox Code Playgroud)

清理数据库数据

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

./dbdata/homestead - 存在