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

p0r*_*ter 18 mysql docker docker-compose

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

我有以下文件:

docker-compose.yml
  mysql
  ---- import.sh
  ---- db.sql
  ---- Dockerfile
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

/ mysql/Dockerfile中有:

ADD import.sh /tmp/import.sh
ADD db.sql /tmp/db.sql
RUN /tmp/import.sh
Run Code Online (Sandbox Code Playgroud)

/mysql/db.sql中有:

CREATE DATABASE test1;
CREATE DATABASE test2;
CREATE DATABASE test3;
Run Code Online (Sandbox Code Playgroud)

fzg*_*gor 23

您可以在Dockerfile中使用ENTRYPOINTCMD在容器启动时执行命令.它们之间的区别在于,只要ENTRYPOINT容器启动就会执行,而CMD可能会被命令行选项替换.假设您要执行的命令是X

docker run my-image Y
Run Code Online (Sandbox Code Playgroud)

将执行X,如果ENTRYPOINT X是在Dockerfile和Y如果CMD X是在Dockerfile.

但是,有两点需要注意:

  1. 每次启动容器时都将执行该命令.
  2. 命令终止后,容器将关闭.

因此,典型的解决方案是使用docker-entrypoint脚本.它检查它是否在启动其环境的新容器中运行,然后执行容器的实际程序.看看官方的mysql Dockerfile和入口点来了解一下.

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

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

exec "$@"
Run Code Online (Sandbox Code Playgroud)

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

  • 有人可以编辑这个吗?“X”和“Y”是脚本吗?这两个警告中哪些适用于“CMD”和“ENTRYPOINT”? (2认同)