Docker - 使用模式初始化mysql数据库 [英] Docker - Initialize mysql database with schema

查看:199
本文介绍了Docker - 使用模式初始化mysql数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个带有MySQL数据库的容器,并向这些数据库添加一个模式。



我目前的Dockerfile是:

  FROM mysql 
MAINTAINER(me)< email>

#将数据库模式复制到/ data目录
COPY文件/ epcis_schema.sql /data/epcis_schema.sql

#更改工作目录
WORKDIR数据

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_NAME} -d mvpgomes / epcisdb 

但是当我执行该命令时,不会创建Container,并且在Container状态中可以看到CMD没有成功执行,实际上只执行 mysql 命令。



无论如何,是否可以使用模式初始化数据库,还是需要手动执行这些操作?

解决方案

我很抱歉这个超长的答案,但是,你有一些方法去找到你想要的地方。我会说,通常你不会把数据库的存储与数据库本身放在同一个容器中,你可以装载一个主机卷,以便数据在docker主机上持续存在,也可以使用一个容器保存数据(/ var / lib / mysql)。另外,我是mysql的新手,所以这可能不是超级有效。那就是说...



我认为这里可能有一些问题。 Dockerfile用于创建一个图像。您需要执行构建步骤。至少,从包含Docker文件的目录中,您将执行以下操作:

  docker build。 

Dockerfile描述要创建的图像。我不太了解mysql(我是一个postgres fanboy),但是,我做了一个搜索周围的interwebs为'我如何初始化一个mysql docker容器'。首先我创建了一个新的目录,我称之为mdir,然后我创建了一个文件目录,它存放了一个创建数据库和一个表的epcis_schema.sql文件:

 创建数据库测试; 
使用测试;

CREATE TABLE testtab

id INTEGER AUTO_INCREMENT,
name TEXT,
PRIMARY KEY(id)
)COMMENT ='这是我的测试表';

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

 #!/ bin / bash 

#初始化MySQL数据库。
#通过Dockerfile将此文件添加到容器中。
#假设您在`docker run`命令上指定了一个VOLUME [/ var / lib / mysql]或`-v / var / lib / mysql` ...
#一旦构建, `docker运行your_image / path / to / docker-mysql-initialize.sh`
#再次确保MySQL在容器之外持久化数据以使其有效果。

set -e
set -x

mysql_install_db

#在后台启动MySQL守护程序。
/ usr / sbin / mysqld&
mysql_pid = $!

直到mysqladmin ping> / dev / null 2>& 1; do
echo -n。;睡觉0.2
done

#从外部容器中允许root登录,无密码。
mysql -eGRANT ALL ON *。* TO root @'%'IDENTIFIED BY''WITH GRANT OPTION

#从ADDed文件创建默认数据库。
mysql< /tmp/epcis_schema.sql

#告诉MySQL守护程序关闭。
mysqladmin shutdown

#等待MySQL守护程序退出。
等待$ mysql_pid

#创建与目前存在的数据库的tar文件
tar czvf default_mysql.tar.gz / var / lib / mysql

#tarfile包含数据库的初始化状态。
#当容器启动时,如果数据库为空(/ var / lib / mysql)
#,那么它将从
#中的default_mysql.tar.gz解压缩#ENTRYPOINT / tmp / run_db脚本

(大部分此脚本已从此处撤销: https://gist.github.com/pda/9697520



这是文件/ run_db我创建的脚本:

 #start db 

set -e
set -x

#首先,如果/ var / lib / mysql目录为空,则从我们预定义的db
[$(ls -A / var / lib / mysql)] &安培; echo使用/ var / lib / mysql中的现有数据库运行|| (echo'填充初始db'; tar xpzvf default_mysql.tar.gz)

/ usr / sbin / mysqld

最后,Dockerfile绑定它们全部:

  FROM mysql 
MAINTAINER我)< email>

#将数据库模式复制到/ data目录
ADD文件/ run_db文件/ init_db文件/ epcis_schema.sql / tmp /

#init_db将创建默认
#数据库从epcis_schema.sql,然后
#停止mysqld,最后将/ var / lib / mysql目录
#复制到default_mysql_db.tar.gz
RUN / tmp / init_db

#run_db启动mysqld,但首先检查
#以查看/ var / lib / mysql目录是否为空,如果
#正在播种default_mysql_db.tar.gz之前
#mysql被启动

ENTRYPOINT/ tmp / run_db

所以,我cd'ed到我的mdir目录(其中有Docker文件以及files目录)。然后我运行命令:

  docker build --no-cache。 

你应该看到这样的输出:



<$将构建上下文发送到Docker守护程序7.168 kB
将构建上下文发送到Docker守护程序
步骤0:FROM mysql
---> 461d07d927e6
步骤1:MAINTAINER(me)< email>
--->运行在963e8de55299
---> 2fd67c825c34
删除中间容器963e8de55299
步骤2:ADD文件/ run_db文件/ init_db文件/ epcis_schema.sql / tmp /
---> 81871189374b
删除中间容器3221afd8695a
步骤3:RUN / tmp / init_db
--->运行在8dbdf74b2a79
+ mysql_install_db
2015-03-19 16:40:39 12 [注意] InnoDB:使用atomics引用计数缓冲池页面
...
/ var / lib / mysql / ib_logfile0
---> 885ec2f1a7d5
删除中间容器8dbdf74b2a79
步骤4:ENTRYPOINT/ tmp / run_db
--->运行在717ed52ba665
---> 7f6d5215fe8d
删除中间容器717ed52ba665
成功构建7f6d5215fe8d

您现在有一个图像'7f6d5215fe8d'。我可以运行这个图像:

  docker run -d 7f6d5215fe8d 

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

  4b377ac7397ff5880bc9218abe6d7eadd49505d50efb5063d6fab796ee157bd3 

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

 停靠站停止4b377 
停靠点开始4b377

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

  docker logs 4b377 

填充初始db
var / lib / mysql /
...

然后,在日志结尾处:

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

这些是/ tmp / run_db脚本中的消息,第一个表示数据库已从保存的(初始)版本,第二个表示数据库已经存在,因此使用了现有的副本/ p>

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

  gregs-air:〜gfausak $ ls -Rl mdir 
共8
-rw-r - r-- 1 gfausak wheel 534 3月19日11:13 Dockerfile
drwxr-xr-x 5 gfausak staff 170 3月19日11:24文件

mdir / files:
total 24
-rw-r - r-- 1 gfausak staff 126 Mar 19 11:14 epcis_schema.sql
-rwxr-xr-x 1 gfausak工作人员1226 3月19日11:16 init_db
-rwxr-xr-x 1 gfausak工作人员284 3月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数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆