使用 docker 中的架构构建 mysql / mariadb 数据库

Building mysql / mariadb database with scema in docker

您好,我正在构建一项服务,我需要一个 Mysql/MariaDB 数据库。我一直在谷歌搜索不同的解决方案,并且由于 a 遵循了指南,我从创建的数据库开始了数据库(不幸的是再也没有找到 link)。

问题

我遇到的问题是没有创建表。我将 sql-scema 文件添加到 /docker-entrypoint-initdb.d/ (您可以在 docker 文件中查看它)但它似乎没有执行它(我已经尝试过复制和添加命令)。

当前输出

这是我当前来自容器的控制台输出:
[![图片][1]][1]

数据库已创建,但 SOW TABLES;命令 returns 空集。

期望的输出

由于此数据库将成为不同脚本连接的服务(当前 python),我需要能够创建数据库和 sql 模式(表、触发器等...),以便我的团队可以使用相同的配置。

我尝试过的一些解决方案(我找不到所有的 link 我只访问了几个)

项目结构

结构非常简单,我使用以下 docker-compose.yml

Docker-撰写

我还得试试这里是否需要 MARIADB_ 环境变量。
version: '3'

services:

    db-mysql:
        #image: mysql/mysql-server:latest
        build: ./mysql-db
        restart: always
        container_name : db-music
        ports: 
            - '3306:3306'
        
        environment:
            MYSQL_ROOT_PASSWORD: pwd
            MYSQL_DATABASE : audio_service
            MYSQL_USER : user
            MYSQL_PASSWORD : password

        environment:
            MARIADB_ROOT_PASSWORD: pwd
            MARIADB_DATABASE : audio_service
            MARIADB_USER : user
            MARIADB_PASSWORD : password
        #
        expose:
            - '3306:3306'
        volumes:
          - type: bind
            source : E:\python-code\Rockstar\volume\mysql
            target : /var/lib/mysql

          #- type: bind
            #source : E:\python-code\Rockstar\mysql-db\sql_scripts\tables.sql
            #target : /docker-entrypoint-initdb.d/init.sql

networks:
    net:
        ipam:
            driver: default
            config:
                - subnet: 212.172.1.0/30
    host:
        name: host
        external: true

Docker文件

FROM mariadb:latest as builder


# That file does the DB initialization but also runs mysql daemon, by removing the last line it will only init
RUN ["sed", "-i", "s/exec \"$@\"/echo \"not running $@\"/", "/usr/local/bin/docker-entrypoint.sh"]

# needed for intialization
ENV MYSQL_ROOT_PASSWORD=root
ENV MYSQL_ROOT_PASSWORD = pwd
ENV MYSQL_DATABASE = audio_service
ENV MYSQL_USER = user
ENV MYSQL_PASSWORD = password

COPY sql_scripts/tables.sql /docker-entrypoint-initdb.d/

# Need to change the datadir to something else that /var/lib/mysql because the parent docker file defines it as a volume.
# https://docs.docker.com/engine/reference/builder/#volume :
#       Changing the volume from within the Dockerfile: If any build steps change the data within the volume after
#       it has been declared, those changes will be discarded.
RUN ["/usr/local/bin/docker-entrypoint.sh", "mysqld", "--datadir", "/initialized-db", "--aria-log-dir-path", "/initialized-db"]

FROM mariadb:latest

# needed for intialization
ENV MARIADB_ROOT_PASSWORD=root
ENV MARIADB_ROOT_PASSWORD = pwd
ENV MARIADB_DATABASE = audio_service
ENV MARIADB_USER = user
ENV MARIADB_PASSWORD = password

COPY --from=builder /initialized-db /var/lib/mysql

EXPOSE 3306

SQL 模式文件

create database audio_service;
use audio_service;

CREATE TABLE audio
(
audio_id BINARY(16),
title TEXT NOT NULL UNIQUE,
content MEDIUMBLOB NOT NULL,
PRIMARY KEY (audio_id)
) COMMENT='this table stores sons';

DELIMITER ;;
CREATE TRIGGER `audio_before_insert` 
BEFORE INSERT ON `audio` FOR EACH ROW 
BEGIN
  IF new.audio_id IS NULL THEN
    SET new.audio_id = UUID_TO_BIN(UUID(), TRUE);
  END IF;
END;;
DELIMITER ;

官方 mysql / mariadb 镜像已经非常适合,因此无需构建您自己的镜像。您只需要按照 image documentations:

中的说明使用以下内容 运行 他们

因此,将您的 SQL* 存储到 docker-compose.yml 旁边的 schema.sql 文件中,以下内容足以实现您想要的:

# docker-compose.yml
services:
  db:
    image: mariadb
    environment:
      MARIADB_ROOT_PASSWORD: pwd
      MARIADB_DATABASE: audio_service
      MARIADB_USER: user
      MARIADB_PASSWORD: password
    volumes:
      # persist data files into `datadir` volume managed by docker
      - datadir:/var/lib/mysql
      # bind-mount any sql files that should be run while initializing
      - ./schema.sql:/docker-entrypoint-initdb.d/schema.sql

volumes:
  datadir:

*请注意,您可以从 schema.sql 中删除 CREATE DATABASEUSE 语句,因为无论如何初始化脚本都会自动为您完成这些语句


您自己的设置未按预期工作的原因有两个:

  1. COPY --from=builder /initialized-db /var/lib/mysql 将无法按预期工作,原因与您在其上方的评论中描述的原因相同:/var/lib/mysql 是一个卷,因此没有新文件a 定义后在构建步骤中存储在其中。

  2. 你是 bind-mounting E:\python-code\Rockstar\volume\mysql/var/lib/mysql docker-compose.yml。 但这将有效地覆盖图像 /var/lib/mysql 的任何内容,即虽然您自己的图像是从您的 Dockerfile 构建的 包含一个初始化的数据库,但它会被启动服务时 E:\python-code\Rockstar\volume\mysql 的内容。