[英]Run Python package with multiple .py scripts in docker-compose.yml
[英]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
当我分别运行这些命令时,我得到了tests
和main
的正确打印语句。 但是,我不确定我是否正确使用docker-compose
。
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.