如何在docker-compose之后执行脚本?

我正在尝试使用docker(-compose)使我的开发过程更容易/可维护。 我不想使用任何卷(如果可能的话)。 为什么在运行'docker-compose up -d'后import.sh没有被执行?

我有以下文件:

docker-compose.yml mysql ---- import.sh ---- db.sql ---- Dockerfile 

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 

/ mysql / Dockerfile中有:

 ADD import.sh /tmp/import.sh ADD db.sql /tmp/db.sql RUN /tmp/import.sh 

/mysql/db.sql中有:

 CREATE DATABASE test1; CREATE DATABASE test2; CREATE DATABASE test3; 

您可以在Dockerfile中使用ENTRYPOINTCMD在容器启动时执行命令。 它们之间的区别在于ENTRYPOINT在容器启动时执行,而CMD可能被命令行选项replace。 假设你想要执行的命令是X

 docker run my-image Y 

如果ENTRYPOINT X位于Dockerfile中,则执行X如果CMD X位于Dockerfile中,则执行Y.

但是,有两个警告:

  1. 该命令将在每次启动容器时执行。
  2. 命令终止后,容器closures。

因此,一个典型的解决scheme是有一个docker-entrypoint脚本。 它检查它是否运行在启动其环境的新容器中,然后执行容器的实际程序。 看看官方的mysql的Dockerfile和入口点来得到一个想法。

示例入口点脚本可能如下所示:

 $ cat docker_entrypoint.sh if [ ! -f .initialized ]; then echo "Initializing container" # run initializing commands touch .initialized fi exec "$@" 

首先,它检查是否有一个名为.initialized的文件。 如果没有,则运行一些命令来初始化容器环境。 之后touch .initialized创build.initialized为空文件。 因此,后续的容器启动将不会再次执行初始化命令。 其次,开始实际的服务。 用exec来执行这个操作将会把服务进程replace成shell进程。 因此,docker将保持容器运行直到服务终止。 "$@"将包含“容器/图像命令”。 这是在Dockerfile中用CMD X设置的,并且在命令上被覆盖,正如我上面已经指出的那样。 通过使用exec "$@"你将能够在容器中启动不同的程序进行检查,例如bash ,默认启动服务,如Dockerfile的CMD语句所指定。