MySQL docker-compose up 后如何执行脚本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42117362/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to execute scripts after docker-compose up?
提问by p0rter
I'm trying to make my dev process easier/maintainable using docker(-compose). I do not want to use any volumes (if that's possible). Why does import.sh not get executed after I run 'docker-compose up -d'?
我正在尝试使用 docker(-compose) 使我的开发过程更容易/可维护。我不想使用任何卷(如果可能的话)。为什么在我运行 'docker-compose up -d' 后没有执行 import.sh?
I have the following files:
我有以下文件:
docker-compose.yml
mysql
---- import.sh
---- db.sql
---- Dockerfile
in docker-compose.ymlthere is:
在docker-compose.yml 中有:
version: '2'
services:
database:
image: mysql
build:
context: ./mysql/
dockerfile: Dockerfile
container_name: mysqltest
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
in /mysql/Dockerfilethere is:
在/mysql/Dockerfile 中有:
ADD import.sh /tmp/import.sh
ADD db.sql /tmp/db.sql
RUN /tmp/import.sh
in /mysql/db.sqlthere is:
在/mysql/db.sql 中有:
CREATE DATABASE test1;
CREATE DATABASE test2;
CREATE DATABASE test3;
回答by fzgregor
You can use ENTRYPOINT
or CMD
in your Dockerfile to execute a command when the container starts. The difference between them is that ENTRYPOINT
is executed any time the container is started, while CMD
might be replaced with an command line option. Assuming the command you want to execute is X
您可以在 Dockerfile 中使用ENTRYPOINT
或CMD
在容器启动时执行命令。它们之间的区别是ENTRYPOINT
在容器启动时执行,而CMD
可能会被命令行选项替换。假设您要执行的命令是X
docker run my-image Y
will execute X
if ENTRYPOINT X
was in the Dockerfile and Y
if CMD X
was in the Dockerfile.
X
如果ENTRYPOINT X
在 Dockerfile 中,Y
如果CMD X
在Dockerfile 中,将执行。
However, there are two caveats:
但是,有两个警告:
- The command will be executed every time the container is started.
- After the command terminates the container is shut down.
- 每次启动容器时都会执行该命令。
- 命令终止后,容器将关闭。
Therefore, a typical solution is to have a docker-entrypoint
script. It checks whether it is run in a fresh container initiating its environment and afterwards executes the container's actual program.
Have a look at the official mysql Dockerfile and entrypointto get an idea.
因此,一个典型的解决方案是拥有一个docker-entrypoint
脚本。它检查它是否在启动其环境的新容器中运行,然后执行容器的实际程序。查看官方 mysql Dockerfile 和入口点以获得一个想法。
An example entrypoint script could look like this:
示例入口点脚本可能如下所示:
$ cat docker_entrypoint.sh
if [ ! -f .initialized ]; then
echo "Initializing container"
# run initializing commands
touch .initialized
fi
exec "$@"
First, it checks whether there is a file called .initialized
. If there is none, some commands are run to initialize the container environment. After which touch .initialized
creates .initialized
as an empty file. Therefore, subsequent container starts won't execute the initialization command again.
Secondly, it starts the actual service. Doing this with exec
will replace the shell process with the service's process. Hence, docker will keep the container running until the service terminates. "$@"
will contain the "container/image command". This is set with CMD X
in the Dockerfile and is overriden on the command, as I already pointed out above. By using exec "$@"
you will be able to start different programs in the container for inspection, e.g. bash
, and start the service by default, as specified in the Dockerfile's CMD
statement.
首先,它检查是否存在名为.initialized
. 如果没有,则运行一些命令来初始化容器环境。之后touch .initialized
创建.initialized
为一个空文件。因此,后续容器启动不会再次执行初始化命令。其次,它启动了实际的服务。这样做exec
会用服务的进程替换 shell 进程。因此,docker 将保持容器运行直到服务终止。"$@"
将包含“容器/图像命令”。这是CMD X
在 Dockerfile 中设置的,并在命令中被覆盖,正如我上面已经指出的那样。通过使用exec "$@"
您将能够在容器中启动不同的程序进行检查,例如bash
,并默认启动服务,如 Dockerfile 的CMD
语句中指定的那样。
回答by helsonxiao
If you just want to initialize your db in the very first time, you can use this easy way.
如果您只想在第一次初始化您的数据库,您可以使用这种简单的方法。
volumes:
- [the scripts dir]:/docker-entrypoint-initdb.d
Initializing a fresh instance When a container is started for the first time, a new database with the specified name will be created and initialized with the provided configuration variables. Furthermore, it will execute files with extensions .sh, .sql and .sql.gz that are found in /docker-entrypoint-initdb.d. Files will be executed in alphabetical order. You can easily populate your mysql services by mounting a SQL dump into that directory and provide custom images with contributed data. SQL files will be imported by default to the database specified by the MYSQL_DATABASE variable.
初始化一个新实例当一个容器第一次启动时,一个具有指定名称的新数据库将被创建并使用提供的配置变量进行初始化。此外,它将执行在 /docker-entrypoint-initdb.d 中找到的扩展名为 .sh、.sql 和 .sql.gz 的文件。文件将按字母顺序执行。您可以通过将 SQL 转储装载到该目录中并提供带有贡献数据的自定义图像来轻松填充您的 mysql 服务。默认情况下,SQL 文件将导入由 MYSQL_DATABASE 变量指定的数据库。
Doc is here: https://docs.docker.com/samples/library/mysql/