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

时间:2017-04-10 11:30:50

标签: 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"

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

9 个答案:

答案 0 :(得分:27)

还有一个选项可以为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

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

CREATE DATABASE IF NOT EXISTS dev;
CREATE DATABASE IF NOT EXISTS test;
USE dev;
CREATE TABLE IF NOT EXISTS (...);

答案 1 :(得分:17)

数据库可能已经初始化,配置存储在/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图像将重新开始,并将使用您通过环境部分提供的配置初始化数据库。

答案 2 :(得分:13)

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

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

  1. 在名为setup.sql的本地目录中创建名为.docker的初始化文件(Docker映像可识别.sh,.sql和.sql.gz文件)
  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:

示例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;

答案 3 :(得分:7)

回答你的问题......

在构建新的docker容器时,我要做的一件事就是了解构建时所拍摄的图像的作用。

在你的docker-compose.yml中有这个

# The Database
database:
  image: mysql:5.7

这是你从中提取的图像," mysql:5.7"

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

进行谷歌搜索" mysql:5.7 dockerhub"

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

如果你点击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

答案 4 :(得分:6)

对于docker-compose的第2版,您{l} .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"

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)

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

答案 5 :(得分:6)

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

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

答案 6 :(得分:3)

此处的“初始化新实例”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  

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

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

         - --table_definition_cache=100
         - --performance_schema=0

注意:如果您希望保留数据,则这不会保留您的 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
          - ./dbdata:/var/lib/mysql
      container_name: mysqldb
      image: mysql  

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

答案 7 :(得分:2)

您应该简单地将此卷添加到您的数据库描述中。原因是它将执行扩展名为 .sh、.sql 和 .sql.gz 的文件,这些文件位于 docker 容器内的 /docker-entrypoint-initdb.d/ 文件夹中。

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

  ...

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

CREATE DATABASE IF NOT EXISTS db;
USE db;

答案 8 :(得分:0)

如果要创建数据库 您的docker-compose.yml看起来像 如果要使用Dockerfile

if

您的docker-compose.yml看起来像 如果要使用映像而不是Dockerfile

version: '3.1'

services:
  php:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 80:80
    volumes:
      - ./src:/var/www/html/
  db:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example
    volumes:
      - mysql-data:/var/lib/mysql

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080
volumes:
  mysql-data:

如果要存储或保存mysql的数据,则 必须记住在docker-compose.yml中添加两行

version: '3.1'   

services:
  php:
    image: php:7.4-apache
    ports:
      - 80:80
    volumes:
      - ./src:/var/www/html/
  db:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example
    volumes:
      - mysql-data:/var/lib/mysql

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080
volumes:

volumes:
  - mysql-data:/var/lib/mysql

之后使用此命令

volumes:
  mysql-data:

现在,您的数据将保持不变,即使使用此命令也不会被删除

docker-compose up -d

额外:-但如果要删除所有数据,则将使用

docker-compose down