构建docker映像时初始化DB脚本的最佳方法

时间:2018-09-27 11:16:53

标签: mysql dockerfile

我正在使用镜像“ mysql”构建一个docker机器。我有一些安装脚本可在机器首次构建时运行。此设置脚本将创建具有指定权限的一些数据库和dabase用户。

以下是我文件的最小版本。

pcdb1.entrypoint.sh

#!/bin/sh

mysql -uroot -p'pass123' -e 'show databases MYENTRYDB;'

Dockerfile

FROM mysql:5.7

COPY ./pcdb1.entrypoint.sh /
ENTRYPOINT ["/pcdb1.entrypoint.sh"];

我在日志中遇到以下错误

  

错误2002(HY000):无法通过套接字'/var/run/mysqld/mysqld.sock'(2)连接到本地MySQL服务器

     

pcdb1以代码1退出

我的理解是,我的脚本正在尝试在启动mysql之前运行。但我不确定如何正确执行。我可以得到建议吗?

1 个答案:

答案 0 :(得分:2)

编辑:20181007

我已经找到了您提到的方法-在构建docker映像时初始化DB。但是有一点区别,我发现的方法似乎是从图像运行容器时初始化DB,尽管在构建图像时指定了初始化脚本。

根据官方information about mysql:5.7,有一段名为“初始化新实例”。我们可以将初始化脚本添加到目录/docker-entrypoint-initdb.d中,图像mysql:5.7的默认ENTRYPOINTCMD将在数据库启动后执行。

例如:

FROM mysql:5.7
COPY init-database.sql /docker-entrypoint-initdb.d/  

init-database.sql的内容:

create database light;
create user 'light'@'%' identified by 'abc123';
grant all privileges on light.* to 'light'@'%' identified by 'abc123';
grant all privileges on light.* to 'light'@'localhost' identified by 'abc123';  

建立新图像:

docker build -t light/mysql:5.7 .  

运行容器:

docker run -tid --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD='abc123' light/mysql:5.7  

检查初始化:

docker run -ti mysql /bin/bash
root@25e73d40c4ff:/# mysql -uroot -p
Enter password: (abc123)
Welcome to the MySQL monitor. 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;  

一切正常。

下面是以前的答案。

如何在容器中启动mysql damon?

首先,您对“尝试在mysql启动之前运行”部分正确。但是,仍然缺少“ MySQL如何完全启动”的信息。如果执行docker history mysql:5.7 --no-trunc,则会在输出中看到三个重要的记录,如下所示:

/bin/sh -c #(nop)  CMD ["mysqld"]
/bin/sh -c #(nop)  ENTRYPOINT ["docker-entrypoint.sh"]
/bin/sh -c ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh 

到目前为止,我们应该知道当我们使用下面的命令启动mysql容器时,容器中的确切初始命令是docker-entrypoint.sh mysqld

docker run -tid -e MYSQL_ROOT_PASSWORD='abc123' mysql:5.7

如何在容器中启动mysql?

其次,让我们来检查一下docker-entrypoint.sh脚本。
如下所示,在此脚本的大致中间位置有一行特殊的行,这意味着要启动mysql守护程序。

mysql=( mysql --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" )

启动mysql之后,我们可以在docker-entrypoint.sh脚本中看到许多初始化语句。例如,是否使用密码创建root用户,授予root特权,使用MYSQL_DATABASE env创建用户声明的数据库等等。

现在这是为您提供的解决方案。

自定义docker-entrypoint.sh脚本。

这样,您可以根据需要在mysql中合法使用任何内容。

  1. 在主机上获取整个entrypoint.sh脚本。
  2. 在脚本中添加您对mysql的自定义, 该脚本底部的自定义内容。我想你 不想把它与原始内容搞混。
  3. 使用下面的命令和Dockerfile为自己构建一个新的mysql映像。

    命令:docker build -t mysql:self。
    Dockerfile:
    来自mysql:5.7
    复制/path/to/your-entrypoint.sh /
    ENTRYPOINT [“ /your-entrypoint.sh”]
    CMD [“ mysqld”]

  4. 如果您不想要新图像,则有另一种更改方法 ENTRYPOINT,当您运行容器时。但是,仍然应该在容器中提供自己的脚本。
    docker运行-tid -v /path/to/your-entrypoint.sh:/entrypoint.sh -p 3306:3306 -e MYSQL_ROOT_PASSWORD ='abc123'mysql:5.7

使用mysql:5.7提供的默认ENV

这样,就有了一个限制,尤其是您提到的“指定权限”。
您需要的ENV是:MYSQL_DATABASEMYSQL_USERMYSQL_PASSWORD
该命令应如下所示:

docker run -tid -e MYSQL_ROOT_PASSWORD='abc123' -e MYSQL_DATABASE='apps' -e MYSQL_USER='light' -e MYSQL_PASSWORD='abc123' mysql:5.7 

这意味着将自动创建数据库apps和用户light,并且将向用户light授予数据库apps的超级用户权限。

hub.docker.com上的更多参考here