如何在 Docker 容器中使用架构初始化 MySQL 数据库?

时间:2023-04-30
本文介绍了如何在 Docker 容器中使用架构初始化 MySQL 数据库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我正在尝试使用 MySQL 数据库创建一个容器并向这些数据库添加架构.

我当前的 Dockerfile 是:

来自 mysql维护者(我)<电子邮件># 将数据库模式复制到/data目录复制文件/epcis_schema.sql/data/epcis_schema.sql# 改变工作目录工作目录数据CMD mysql -u $MYSQL_USER -p $MYSQL_PASSWORD $MYSQL_DATABASE <epcis_schema.sql

为了创建容器,我遵循 Docker 上提供的文档并执行此命令:

docker run --name ${CONTAINER_NAME} -e MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD} -e MYSQL_USER=${DB_USER} -e MYSQL_PASSWORD=${DB_USER_PASSWORD} -e MYSQL_DATABASE=${DB_goname} -d mvp/epcisdb

但是当我执行这个命令时,Container并没有被创建,在Container状态下可以看到CMD没有执行成功,实际上只执行了mysql命令.>

无论如何,有没有办法用架构初始化数据库,或者我需要手动执行这些操作?

解决方案

对于这个超长的答案,我很抱歉,但是,您还有一段路要走才能到达您想要的地方.我会说通常你不会将数据库的存储放在与数据库本身相同的容器中,你要么挂载一个主机卷,以便数据保留在 docker 主机上,或者,也许可以使用一个容器来保存数据(/var/lib/mysql).另外,我是 mysql 的新手,所以,这可能不是非常有效.话说……

我认为这里可能存在一些问题.Dockerfile 用于创建映像.您需要执行构建步骤.至少,从包含 Dockerfile 的目录中,您可以执行以下操作:

docker build .

Dockerfile 描述了要创建的镜像.我对 mysql 不太了解(我是 postgres 粉丝),但是,我在互联网上搜索了如何初始化 mysql docker 容器".首先我创建了一个新目录来工作,我称之为 mdir,然后我创建了一个文件目录,我存放了一个 epcis_schema.sql 文件,该文件创建了一个数据库和一个表:

创建数据库测试;使用测试;创建表测试表(id INTEGER AUTO_INCREMENT,名称文本,主键 (id)) COMMENT='这是我的测试表';

然后我在文件目录中创建了一个名为 init_db 的脚本:

#!/bin/bash# 初始化 MySQL 数据库.# 通过Dockerfile将此文件添加到容器中.# 假设你在 `docker run` 命令上指定了一个 VOLUME ["/var/lib/mysql"] 或 `-v/var/lib/mysql` ......# 一旦构建完成,例如`docker run your_image/path/to/docker-mysql-initialize.sh`# 再次,确保 MySQL 将数据持久化到容器外以使其产生任何效果.设置 -e设置 -xmysql_install_db# 在后台启动 MySQL 守护进程./usr/sbin/mysqld &mysql_pid=$!直到 mysqladmin ping >/dev/null 2>&1;做echo -n ".";睡眠 0.2完毕# 允许从外部容器无需密码的 root 登录.mysql -e "GRANT ALL ON *.* TO root@'%' IDENTIFIED BY '' WITH GRANT OPTION"# 从添加的文件创建默认数据库.mysql </tmp/epcis_schema.sql# 告诉 MySQL 守护进程关闭.mysqladmin 关闭# 等待 MySQL 守护进程退出.等待 $mysql_pid# 使用当前存在的数据库创建一个 tar 文件tar czvf default_mysql.tar.gz/var/lib/mysql# tarfile 包含数据库的初始化状态.# 容器启动时,如果数据库为空(/var/lib/mysql)# 然后从 default_mysql.tar.gz 解压出来# 入口点/tmp/run_db 脚本

(此脚本的大部分内容来自此处:https://gist.github.com/pda/9697520)

这是我创建的 files/run_db 脚本:

# 启动数据库设置 -e设置 -x# 首先,如果/var/lib/mysql 目录为空,则从我们预定义的数据库中解压[$(ls -A/var/lib/mysql)"] &&echo "使用/var/lib/mysql 中的现有数据库运行" ||( echo '填充初始数据库'; tar xpzvf default_mysql.tar.gz )/usr/sbin/mysqld

最后,Dockerfile 将它们全部绑定:

来自 mysql维护者(我)<电子邮件># 将数据库模式复制到/data目录添加文件/run_db 文件/init_db 文件/epcis_schema.sql/tmp/# init_db 将创建默认值# 来自 epcis_schema.sql 的数据库,然后# 停止mysqld,最后复制/var/lib/mysql目录# 到 default_mysql_db.tar.gz运行/tmp/init_db# run_db 启动 mysqld,但首先它会检查# 查看/var/lib/mysql目录是否为空,如果# 之前是用default_mysql_db.tar.gz 播种的# mysql 启动入口点/tmp/run_db"

所以,我转到了我的 mdir 目录(其中包含 Dockerfile 和文件目录).然后我运行命令:

docker build --no-cache .

你应该看到这样的输出:

将构建上下文发送到 Docker 守护进程 7.168 kB将构建上下文发送到 Docker 守护进程第 0 步:从 mysql--->461d07d927e6第 1 步:维护者(我)<email>--->运行于 963e8de55299--->2fd67c825c34移除中间容器 963e8de55299第 2 步:添加文件/run_db 文件/init_db 文件/epcis_schema.sql/tmp/--->81871189374b卸下中间容器 3221afd8695a第 3 步:运行/tmp/init_db--->在 8dbdf74b2a79 中运行+ mysql_install_db2015-03-19 16:40:39 12 [注意] InnoDB:使用原子来引用计数缓冲池页面.../var/lib/mysql/ib_logfile0--->885ec2f1a7d5删除中间容器 8dbdf74b2a79第 4 步:入口点/tmp/run_db"--->在 717ed52ba665 中运行--->7f6d5215fe8d卸下中间容器 717ed52ba665成功构建7f6d5215fe8d

您现在拥有一张图片7f6d5215fe8d".我可以运行这个图像:

docker run -d 7f6d5215fe8d

图像开始,我看到一个实例字符串:

4b377ac7397ff5880bc9218abe6d7eadd49505d50efb5063d6fab796ee157bd3

然后我可以停止"它,然后重新启动它.

docker stop 4b377码头工人开始 4b377

如果您查看日志,第一行将包含:

docker 日志 4b377填充初始数据库变量/库/mysql/...

然后,在日志的末尾:

使用/var/lib/mysql 中的现有数据库运行

这些是来自/tmp/run_db 脚本的消息,第一个表示数据库是从保存的(初始)版本解压出来的,第二个表示数据库已经存在,所以使用了现有的副本.

这是我上面描述的目录结构的 ls -lR.请注意,init_db 和 run_db 是设置了执行位的脚本:

gregs-air:~ gfausak$ ls -Rl mdir共 8 个-rw-r--r-- 1 gfausak 轮 534 Mar 19 11:13 Dockerfiledrwxr-xr-x 5 gfausak 工作人员 170 Mar 19 11:24 文件目录/文件:共 24 个-rw-r--r-- 1 gfausak 工作人员 19 年 3 月 126 日 11:14 epcis_schema.sql-rwxr-xr-x 1 gfausak 工作人员 1226 年 3 月 19 日 11:16 init_db-rwxr-xr-x 1 gfausak 工作人员 284 Mar 19 11:23 run_db

I am trying to create a container with a MySQL database and add a schema to these database.

My current Dockerfile is:

FROM mysql
MAINTAINER  (me) <email>

# Copy the database schema to the /data directory
COPY files/epcis_schema.sql /data/epcis_schema.sql

# Change the working directory
WORKDIR data

CMD mysql -u $MYSQL_USER -p $MYSQL_PASSWORD $MYSQL_DATABASE < epcis_schema.sql

In order to create the container I am following the documentation provided on Docker and executing this command:

docker run --name ${CONTAINER_NAME} -e MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD} -e MYSQL_USER=${DB_USER} -e MYSQL_PASSWORD=${DB_USER_PASSWORD} -e MYSQL_DATABASE=${DB_NAME} -d mvpgomes/epcisdb

But when I execute this command the Container is not created and in the Container status it is possible to see that the CMD was not executed successfully, in fact only the mysql command is executed.

Anyway, is there a way to initialize the database with the schema or do I need to perform these operations manually?

解决方案

I am sorry for this super long answer, but, you have a little way to go to get where you want. I will say that normally you wouldn't put the storage for the database in the same container as the database itself, you would either mount a host volume so that the data persists on the docker host, or, perhaps a container could be used to hold the data (/var/lib/mysql). Also, I am new to mysql, so, this might not be super efficient. That said...

I think there may be a few issues here. The Dockerfile is used to create an image. You need to execute the build step. At a minimum, from the directory that contains the Dockerfile you would do something like :

docker build .

The Dockerfile describes the image to create. I don't know much about mysql (I am a postgres fanboy), but, I did a search around the interwebs for 'how do i initialize a mysql docker container'. First I created a new directory to work in, I called it mdir, then I created a files directory which I deposited a epcis_schema.sql file which creates a database and a single table:

create database test;
use test;

CREATE TABLE testtab
(
id INTEGER AUTO_INCREMENT,
name TEXT,
PRIMARY KEY (id)
) COMMENT='this is my test table';

Then I created a script called init_db in the files directory:

#!/bin/bash

# Initialize MySQL database.
# ADD this file into the container via Dockerfile.
# Assuming you specify a VOLUME ["/var/lib/mysql"] or `-v /var/lib/mysql` on the `docker run` command…
# Once built, do e.g. `docker run your_image /path/to/docker-mysql-initialize.sh`
# Again, make sure MySQL is persisting data outside the container for this to have any effect.

set -e
set -x

mysql_install_db

# Start the MySQL daemon in the background.
/usr/sbin/mysqld &
mysql_pid=$!

until mysqladmin ping >/dev/null 2>&1; do
  echo -n "."; sleep 0.2
done

# Permit root login without password from outside container.
mysql -e "GRANT ALL ON *.* TO root@'%' IDENTIFIED BY '' WITH GRANT OPTION"

# create the default database from the ADDed file.
mysql < /tmp/epcis_schema.sql

# Tell the MySQL daemon to shutdown.
mysqladmin shutdown

# Wait for the MySQL daemon to exit.
wait $mysql_pid

# create a tar file with the database as it currently exists
tar czvf default_mysql.tar.gz /var/lib/mysql

# the tarfile contains the initialized state of the database.
# when the container is started, if the database is empty (/var/lib/mysql)
# then it is unpacked from default_mysql.tar.gz from
# the ENTRYPOINT /tmp/run_db script

(most of this script was lifted from here: https://gist.github.com/pda/9697520)

Here is the files/run_db script I created:

# start db

set -e
set -x

# first, if the /var/lib/mysql directory is empty, unpack it from our predefined db
[ "$(ls -A /var/lib/mysql)" ] && echo "Running with existing database in /var/lib/mysql" || ( echo 'Populate initial db'; tar xpzvf default_mysql.tar.gz )

/usr/sbin/mysqld

Finally, the Dockerfile to bind them all:

FROM mysql
MAINTAINER  (me) <email>

# Copy the database schema to the /data directory
ADD files/run_db files/init_db files/epcis_schema.sql /tmp/

# init_db will create the default
# database from epcis_schema.sql, then
# stop mysqld, and finally copy the /var/lib/mysql directory
# to default_mysql_db.tar.gz
RUN /tmp/init_db

# run_db starts mysqld, but first it checks
# to see if the /var/lib/mysql directory is empty, if
# it is it is seeded with default_mysql_db.tar.gz before
# the mysql is fired up

ENTRYPOINT "/tmp/run_db"

So, I cd'ed to my mdir directory (which has the Dockerfile along with the files directory). I then run the command:

docker build --no-cache .

You should see output like this:

Sending build context to Docker daemon 7.168 kB
Sending build context to Docker daemon 
Step 0 : FROM mysql
 ---> 461d07d927e6
Step 1 : MAINTAINER (me) <email>
 ---> Running in 963e8de55299
 ---> 2fd67c825c34
Removing intermediate container 963e8de55299
Step 2 : ADD files/run_db files/init_db files/epcis_schema.sql /tmp/
 ---> 81871189374b
Removing intermediate container 3221afd8695a
Step 3 : RUN /tmp/init_db
 ---> Running in 8dbdf74b2a79
+ mysql_install_db
2015-03-19 16:40:39 12 [Note] InnoDB: Using atomics to ref count buffer pool pages
...
/var/lib/mysql/ib_logfile0
 ---> 885ec2f1a7d5
Removing intermediate container 8dbdf74b2a79
Step 4 : ENTRYPOINT "/tmp/run_db"
 ---> Running in 717ed52ba665
 ---> 7f6d5215fe8d
Removing intermediate container 717ed52ba665
Successfully built 7f6d5215fe8d

You now have an image '7f6d5215fe8d'. I could run this image:

docker run -d 7f6d5215fe8d

and the image starts, I see an instance string:

4b377ac7397ff5880bc9218abe6d7eadd49505d50efb5063d6fab796ee157bd3

I could then 'stop' it, and restart it.

docker stop 4b377
docker start 4b377

If you look at the logs, the first line will contain:

docker logs 4b377

Populate initial db
var/lib/mysql/
...

Then, at the end of the logs:

Running with existing database in /var/lib/mysql

These are the messages from the /tmp/run_db script, the first one indicates that the database was unpacked from the saved (initial) version, the second one indicates that the database was already there, so the existing copy was used.

Here is a ls -lR of the directory structure I describe above. Note that the init_db and run_db are scripts with the execute bit set:

gregs-air:~ gfausak$ ls -Rl mdir
total 8
-rw-r--r--  1 gfausak  wheel  534 Mar 19 11:13 Dockerfile
drwxr-xr-x  5 gfausak  staff  170 Mar 19 11:24 files

mdir/files:
total 24
-rw-r--r--  1 gfausak  staff   126 Mar 19 11:14 epcis_schema.sql
-rwxr-xr-x  1 gfausak  staff  1226 Mar 19 11:16 init_db
-rwxr-xr-x  1 gfausak  staff   284 Mar 19 11:23 run_db

这篇关于如何在 Docker 容器中使用架构初始化 MySQL 数据库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:尝试授予权限时,用户 'root'@'localhost' 的访问被拒绝.如何授予权限? 下一篇:MySQL中的for循环示例

相关文章