Docker 撰写 - Python 实例

Docker Compose - Python Instances

我需要 运行 相同的 python 代码,但启动参数与 docker 不同。 因此,在主目录下,我设置了一个名为 docker 的文件夹,其中包含不同的文件夹,每个文件夹都有相同的 docker 文件,但参数设置不同。下面是 test_1 和 test_2 的例子,其中 test_x 在不同的文件夹之间变化,以及 test_1 变成 test_2 等等:

Dockerfiledocker/test_1 文件夹下找到

FROM python:3.7
RUN mkdir /app/test_1
WORKDIR /app/test_1
COPY ./env/requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY ../ .
CMD ["python", "main.py","-t","test_1"]

Dockerfiledocker/test_2 文件夹下找到

FROM python:3.7
RUN mkdir /app/test_2
WORKDIR /app/test_2
COPY ./env/requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY ../ .
CMD ["python", "main.py","-t","test_2"]

在主目录下,我设置了一个 docker 启动不同容器的组合文件(所有 运行 使用相同的代码)并在 shared_folder 中共享一个 txt 文件:

services:
  test_1:
    container_name: test_1
    build: ./docker/test_1
    volumes:
      - output:/app/shared_folder
    restart: unless-stopped

  test_2:
    container_name: test_2
    build: ./docker/test_2
    volumes:
      - output:/app/shared_folder
    restart: unless-stopped

所以我的问题是 docker,在使用不同参数设置同一代码的多个 py 执行时,这是正确的方法吗?还是有另一种推荐的方法。确实要提一下,他们需要共享 shared_folder 中的文件,这是一项要求,并且所有实例都可以 read/write 访问 shared_folder 中的同一文件(这是必须具备的) .

首先删除 Dockerfile 中的 CMD ["python", "main.py","-t","test_2"],然后在 docker-compose 中添加 entrypoint。yaml 将是构建图像的更好方法,因为代码都是相同的。如果你有更多的容器启动,它会为你节省很多时间。

关于你问的问题,你要分享的shared_folder是否是一个read-only文件,没关系,如果不是,比如,你想从实例中放入的日志文件out 到主机,你应该注意日志文件名,不能在两个容器中相同。

我肯定会干它,使用单个 Dockerfile 并使用 ARG 来构建它们。

您可以执行以下操作:

docker/Dockerfile:

FROM python:3.7

ARG FOLDER

## We need to duplicate the value of the ARG in an ENV
## because the arguments are only visible through the build
## so, it won't be accessible to our command
ENV FOLDER=$FOLDER

RUN mkdir -p /app/$FOLDER
WORKDIR /app/$FOLDER
COPY ./$FOLDER/env/requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .

CMD ["sh", "-c", "python main.py -t $FOLDER"]

并在您的 docker-compose.yml 中定义这些构建参数:

version: "3.9"
services:
  test1:
    container_name: test_1
    build:
      context: ./docker
      args:
        FOLDER: test1
    volumes:
      - output:/app/shared_folder
    restart: unless-stopped

  test2:
    container_name: test_2
    build:
      context: ./docker
      args:
        FOLDER: test2
    volumes:
      - output:/app/shared_folder
    restart: unless-stopped

docker run command-line 参数或 Compose command: 覆盖 Dockerfile CMD 非常容易。所以,我只会构建一个图像,并给它一个有用的默认值 CMD.

FROM python:3.7
WORKDIR /app
COPY ./env/requirements.txt ./
RUN pip install -r requirements.txt
COPY ./ ./
CMD ["./main.py"]

(确保你的脚本是可执行的——可能是 运行 chmod +x main.py 在主机上——并且以“shebang”行开始 #!/usr/bin/env python3,所以你不必明确命名解释器。)

现在在您的 docker-compose.yml 文件中,让两个服务 build: 具有相同的图像。从技术上讲,您将在 docker images 输出中得到两个图像,但它们将具有相同的图像 ID,并且第二个图像构建将 运行 非常快(它将完全来自图层缓存)。根据需要使用 Compose command: 覆盖整个 CMD

version: '3.8'
services:
  test_1:
    build: .
    command: ./main.py -t test_1
    volumes:
      - output:/app/shared_folder
    restart: unless-stopped

  test_2:
    build: .
    command: ./main.py -t test_2
    volumes:
      - output:/app/shared_folder
    restart: unless-stopped

如果您只是想验证事物,您也可以在 Compose 之外手动 运行 使用相同的方法

docker build -t myapp .
docker run --rm myapp \
  ./main.py --help

使用这种方法,您不需要为您想要 运行 的每个不同命令重建图像,也不需要与 docker run --entrypoint.

的语法复杂性争论不休