我正在使用图像“mysql”构建一个 docker 机器。我有一些安装脚本可以在第一次构建机器时运行。此设置脚本将创建一些具有指定权限的数据库和数据库用户。
以下是我文件的最小化版本..
pcdb1.entrypoint.sh
#!/bin/sh
mysql -uroot -p'pass123' -e 'show databases MYENTRYDB;'
Docker 文件
FROM mysql:5.7
COPY ./pcdb1.entrypoint.sh /
ENTRYPOINT ["/pcdb1.entrypoint.sh"];
我在日志中收到以下错误
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
pcdb1 exited with code 1
我的理解是,我的脚本试图在 mysql 启动之前运行。但我不确定如何正确地做到这一点。我可以得到建议吗?
最佳答案
编辑:20181007
我找到了您提到的问题的方法——在构建 docker 镜像时初始化数据库。但有一点不同,我发现的方式似乎是在从图像运行容器时初始化数据库,尽管在构建图像时指定了初始化脚本。
据官方information about mysql:5.7 ,有一段名为“初始化新实例”的段落。我们可以在目录/docker-entrypoint-initdb.d
中添加一个初始化脚本,默认的ENTRYPOINT
和CMD
镜像mysql:5.7将在数据库启动后执行它。
例如:
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中合法的东西。
- 在您的主机上获取整个 entrypoint.sh 脚本。
- 在脚本中加入你自定义的mysql,使你的 此脚本底部的自定义内容。我假设你 不想与原始内容混淆。
使用下面的命令和 Dockerfile 为您自己构建一个新的 mysql 镜像。
命令:docker build -t mysql:self .
码头文件:
来自 mysql:5.7
COPY/path/to/your-entrypoint.sh/
入口点 ["/your-entrypoint.sh"]
CMD ["mysqld"]如果您不想要新图像,还有另一种方法可以更改
ENTRYPOINT
运行容器时。但是,您仍然应该在容器中提供您自己的脚本。
docker run -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_DATABASE
、MYSQL_USER
、MYSQL_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
将被授予数据库的 super 用户权限应用
。
更多引用here在 hub.docker.com 上。
关于mysql - 构建 docker 镜像时初始化数据库脚本的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52535725/