繁体   English   中英

使用 docker compose 运行两个 python 脚本

[英]run two python scripts with docker compose

我的文件夹结构如下所示:

在此处输入图像描述

我的 Dockerfile 看起来像这样:

FROM python:3.8-slim-buster

WORKDIR /src

COPY src/requirements.txt requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

COPY src/ .

CMD [ "python", "main.py"] 

当我运行这些命令时:

docker build --tag FinTechExplained_Python_Docker .
docker run free

我的main.py文件运行并给出了正确的打印语句。 现在,我在src文件夹中添加了另一个文件tests.py 我想先运行tests.py ,然后再运行main.py

我尝试像这样修改cmd文件中的 cmd:

CMD [ "python", "test.py"]  && [ "python", "main.py"]

但它只给了我第一个test.py文件的打印语句。

我阅读了 docker-compose 并将这个docker-compose.yml文件添加到根文件夹:

version: '3'

services:
  main:
    image: free
    command: >
      /bin/sh -c 'python tests.py'

  main:
    image: free
    command: >
      /bin/sh -c 'python main.py'

然后我通过删除 cmd 更改了我的 docker 文件:

FROM python:3.8-slim-buster

WORKDIR /src

COPY src/requirements.txt requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

COPY src/ .

然后我运行了以下命令:

docker compose build
docker compose run tests
docker compose run main

当我分别运行这些命令时,我得到了testsmain的正确打印语句。 但是,我不确定我是否正确使用docker-compose

  • 我应该分别运行这两个脚本吗? 或者有没有办法使用单个 docker 命令一个接一个地运行?
  • 如果我从docker-compose.yml运行 python 脚本,我的 Dockerfile 应该是什么样子?

编辑:

理想寻找基于docker-compose的解决方案

在 Bourne shell 中,一般情况下,您可以通过在命令之间加上&&来依次运行两个命令。 听起来你已经意识到了这一点。

# without Docker, at a normal shell prompt
python test.py && python main.py

Dockerfile CMD有两个句法 forms。JSON 数组形式不运行 shell,因此效率稍微高一些,并且 escaping 规则稍微更一致。 如果它不是 JSON 数组,那么 Docker 会自动通过 shell 运行它。因此您可以使用 shell 形式:

CMD python test.py && python main.py

在对其他答案的评论中,您询问有关在docker-compose.yml文件中提供此作为覆盖的问题。 Compose 通常不会为您运行 shell,因此您需要将其明确指定为command: override。

command: /bin/sh -c 'python test.py && python main.py'

您的 Dockerfile 通常应指定CMD ,而docker-compose.yml通常不会包含command: 这使得在其他上下文中运行图像变得更加容易(通过docker run没有 Compose 的情况下运行;在 Kube.netes 中),因为您不必在想要运行容器的每个不同方式中重新键入命令。 @sytech 的答案中突出显示的入口点包装器模式通常非常有用,并且很容易添加到使用CMD而没有ENTRYPOINT的容器中; 但它需要 Dockerfile 将CMD用作正常的格式良好的 shell 命令。

您必须将CMD更改为ENTRYPOINT 并使用&在后台将第一个脚本作为守护进程运行。

ENTRYPOINT ["/docker_entrypoint.sh"]

docker_entrypoint.sh

#!/bin/bash

set -e

exec python tests.py &
exec python main.py 

一般来说,一个容器应该只有一个进程并且基本进程应该是 pid 1 是一个很好的经验法则

根据最佳实践指南,使用入口点可以帮助您在运行时执行多项操作,并可选择使用exec运行用户定义的命令。

例如,如果您始终希望在容器启动时运行测试,则执行 CMD 中定义的命令。

首先,创建一个入口点脚本(确保使用chmod +x使其可执行):

#!/usr/bin/env bash

# always run tests first
python /src/tests.py

# then run user-defined command
exec "$@"

然后配置 dockerfile 复制脚本并将其设置为入口点:

#...
COPY entrypoint.sh /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["python", "main.py"]

然后当你从这个 dockerfile 构建一个图像并运行它时,入口点将首先执行测试然后运行命令来运行 main.py

在运行图像时,用户仍然可以覆盖该命令,例如docker run... myimage <new command>这仍然会导致执行入口点测试,但用户可以更改正在运行的命令。

您可以通过创建包含 python 命令的 bash 脚本(让我们命名为 entrypoint.sh)来实现此目的。 如果需要,您可以创建它们的后台进程。

#!/usr/bin/env bash
set -e

python tests.py
python main.py

按如下方式编辑您的 docker 文件:

FROM python:3.8-slim-buster

# Create workDir
RUN mkdir code
WORKDIR code
ENV PYTHONPATH = /code

#upgrade pip if you like here
COPY requirements.txt .
RUN pip install -r requirements.txt

# Copy Code
COPY . .

RUN chmod +x entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]

在 docker 撰写文件中,将以下行添加到服务中。

entrypoint: [ "./entrypoint.sh" ]

你有没有在你的docker-compose.yaml中尝试过这个?

version: '3'

services:
  main:
    image: free
    command: >
      /bin/sh -c 'python3 tests.py & && python3 main.py &'

两者都将在后台运行

然后在终端运行

docker-compose up --build

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM