关于yaml:使用Docker-Compose,如何执行多个命令

Using Docker-Compose, how to execute multiple commands

我想做这样的事情,我可以按顺序运行多个命令。

1
2
3
4
5
6
7
8
9
10
11
12
db:
  image
: postgres
web
:
  build
: .
  command
: python manage.py migrate
  command
: python manage.py runserver 0.0.0.0:8000
  volumes
:
   - .:/code
  ports
:
   -"8000:8000"
  links
:
   - db

明白了,用bash -c

例子:

1
command: bash -c"python manage.py migrate && python manage.py runserver 0.0.0.0:8000"

多行中的相同示例:

1
2
3
command: >
   bash -c"python manage.py migrate
    && python manage.py runserver 0.0.0.0:8000"


我在一个单独的临时容器中运行启动前的东西,比如迁移(注意,撰写文件必须是'2'版本类型):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
db:
  image
: postgres
web
:
  image
: app
  command
: python manage.py runserver 0.0.0.0:8000
  volumes
:
   - .:/code
  ports
:
   -"8000:8000"
  links
:
   - db
  depends_on
:
   - migration
migration
:
  build
: .
  image
: app
  command
: python manage.py migrate
  volumes
:
   - .:/code
  links
:
   - db
  depends_on
:
   - db

这有助于保持清洁和分离。有两件事要考虑:

  • 您必须确保正确的启动顺序(使用取决于)

  • 您希望避免使用build和image在第一轮中对其进行标记,从而实现多个构建;然后可以在其他容器中引用image。


  • 我建议使用sh而不是bash,因为它在大多数基于Unix的映像(alpine等)上更容易获得。

    下面是一个示例docker-compose.yml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    version: '3'

    services
    :
      app
    :
        build
    :
          context
    : .
        command
    : >
         sh -c"python manage.py wait_for_db &&
                 python manage.py migrate &&
                 python manage.py runserver 0.0.0.0:8000"

    这将按顺序调用以下命令:

    • python manage.py wait_for_db—等待数据库准备就绪
    • python manage.py migrate运行任何迁移
    • python manage.py runserver 0.0.0.0:8000-启动我的开发服务器


    另一个想法:

    如果像在本例中一样,构建容器,只需在其中放置一个启动脚本,然后用命令运行它。或者将启动脚本作为卷装入。


    你可以在这里使用入口点。docker中的entrypoint在命令之前执行,而command是容器启动时应运行的默认命令。因此,大多数应用程序通常在入口点文件中执行设置过程,最后允许运行命令。

    生成一个shell脚本文件可以是docker-entrypoint.sh(名称不重要),其中包含以下内容。

    1
    2
    3
    #!/bin/bash
    python manage.py migrate
    exec"$@"

    在docker-compose.yml文件中,将其与entrypoint: /docker-entrypoint.sh一起使用,并将register命令作为command: python manage.py runserver 0.0.0.0:8000使用。注意:不要忘记复制docker-entrypoint.sh和您的代码。


    这对我很有用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    version: '3.1'
    services
    :
      db
    :
        image
    : postgres
      web
    :
        build
    : .
        command
    :
         - /bin/bash
          - -c
          - |
           python manage.py migrate
            python manage.py runserver 0.0.0.0:8000

        volumes
    :
         - .:/code
        ports
    :
         -"8000:8000"
        links
    :
         - db


    *更新*

    我认为运行一些命令的最佳方法是编写一个自定义dockerfile,在从图像运行正式的cmd之前完成我想要的所有操作。

    docker-compose.yaml:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    version: '3'

    # Can be used as an alternative to VBox/Vagrant
    services
    :

      mongo
    :
        container_name
    : mongo
        image
    : mongo
        build
    :
          context
    : .
          dockerfile
    : deploy/local/Dockerfile.mongo
        ports
    :
         -"27017:27017"
        volumes
    :
         - ../.data/mongodb:/data/db

    dockerfile.mongo文件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    FROM mongo:3.2.12

    RUN mkdir -p /fixtures

    COPY ./fixtures /fixtures

    RUN (mongod --fork --syslog && \
         mongoimport --db wcm-local --collection clients --file /fixtures/clients.json && \
         mongoimport --db wcm-local --collection configs --file /fixtures/configs.json && \
         mongoimport --db wcm-local --collection content --file /fixtures/content.json && \
         mongoimport --db wcm-local --collection licenses --file /fixtures/licenses.json && \
         mongoimport --db wcm-local --collection lists --file /fixtures/lists.json && \
         mongoimport --db wcm-local --collection properties --file /fixtures/properties.json && \
         mongoimport --db wcm-local --collection videos --file /fixtures/videos.json)

    这可能是最干净的方法。

    *旧路*

    我用命令创建了一个shell脚本。在这种情况下,我想启动mongod,运行mongoimport,但调用mongod会阻止您运行其余的。

    docker-compose.yaml:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    version: '3'

    services
    :
      mongo
    :
        container_name
    : mongo
        image
    : mongo:3.2.12
        ports
    :
         -"27017:27017"
        volumes
    :
         - ./fixtures:/fixtures
          - ./deploy:/deploy
          - ../.data/mongodb:/data/db
        command
    : sh /deploy/local/start_mongod.sh

    开始_mongod.sh:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    mongod --fork --syslog && \
    mongoimport --db wcm-local --collection clients --file /fixtures/clients.json && \
    mongoimport --db wcm-local --collection configs --file /fixtures/configs.json && \
    mongoimport --db wcm-local --collection content --file /fixtures/content.json && \
    mongoimport --db wcm-local --collection licenses --file /fixtures/licenses.json && \
    mongoimport --db wcm-local --collection lists --file /fixtures/lists.json && \
    mongoimport --db wcm-local --collection properties --file /fixtures/properties.json && \
    mongoimport --db wcm-local --collection videos --file /fixtures/videos.json && \
    pkill -f mongod && \
    sleep 2 && \
    mongod

    所以这个分叉的蒙古人,做monogimport,然后杀死分离的分叉的蒙古人,然后再次启动它而不分离。不确定是否有一种方法可以连接到分叉的进程,但这确实有效。


    如果需要运行多个守护进程,docker文档中有一个建议,建议在非分离模式下使用supervisor,这样所有子守护进程都将输出到stdout。

    从另一个这样的问题中,我发现您可以将子进程输出重定向到stdout。这样你就可以看到所有的输出!


    使用一个工具,如等待或Dockerize。这些是可以包含在应用程序映像中的小包装脚本。或者编写自己的包装脚本来执行更特定于应用程序的命令。根据:https://docs.docker.com/compose/startup-order/


    我在试图让我的詹金斯容器建立起来,以建立码头集装箱作为詹金斯的用户。

    我需要触摸docker file中的docker.sock文件,稍后在docker compose文件中链接它。除非我先碰它,它还不存在。这对我有用。

    Dockerfile:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    USER root
    RUN apt-get update && \
    apt-get -y install apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common && \
    curl -fsSL https://download.docker.com/linux/$(. /etc/os-release;
    echo"$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && \
    add-apt-repository \
    "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo"$ID") \
    $(lsb_release -cs) \
    stable"
    && \
    apt-get update && \
    apt-get -y install docker-ce
    RUN groupmod -g 492 docker && \
    usermod -aG docker jenkins  && \
    touch /var/run/docker.sock && \
    chmod 777 /var/run/docker.sock

    USER Jenkins

    docker-compose.yml:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    version: '3.3'
    services
    :
    jenkins_pipeline
    :
        build
    : .
        ports
    :
         -"8083:8083"
          -"50083:50080"
        volumes
    :
           - /root/pipeline/jenkins/mount_point_home:/var/jenkins_home
            - /var/run/docker.sock:/var/run/docker.sock


    如果您在verion 2中,请尝试使用";"分隔命令例如

    command:"sleep 20; echo 'a'"