在Docker容器中将参数传递给Python argparse

Bri*_*eer 6 python command-line-arguments docker

我正在着手利用码头工人集装箱.我有一个python脚本调用一对API并解析一个文件.该脚本获取API的服务器URL,API密钥以及要解析的文件的文件路径的参数.我使用argparse在脚本中处理这些.

我如何将这些传递到Docker?我不想硬编码任何东西,因为我希望将此脚本交给需要定期运行并根据结果采取措施的工程师.

谢谢你的帮助.我一直在搜索,但似乎硬编码到dockerfile中的东西是建议 - 我希望用户能够在运行时将这些内容放入.或许我找到了答案,我只是不理解它......

如果我的术语不对,我很抱歉 - 这是我第一次尝试使用Docker.

Tar*_*ani 15

所以我们假设您的命令在下面

python app.py "URL" "APIKEY" "filepath"
Run Code Online (Sandbox Code Playgroud)

所以你将把你的Dockerfile放在下面

FROM python:3.6
WORKDIR /app
COPY app.py .
ENTRYPOINT ["python", "app.py"]
Run Code Online (Sandbox Code Playgroud)

那么运行docker容器的人会像下面那样做

docker run -v /home/tarun/project/filetoparse.yaml:/config.yaml <yourimagename> "URL" "APIKEY" /config.yaml
Run Code Online (Sandbox Code Playgroud)

如果你想提供更多的灵活性,你甚至可以使用环境变量

docker run -v /home/tarun/project/filetoparse.yaml:/config.yaml -e APIKEY="XYZ" <dockerimage> "URL" /config.yaml
Run Code Online (Sandbox Code Playgroud)

然后在您的脚本中,您可以使用它来阅读它 os.environ['APIKEY']


Chr*_*ris 10

你的方式取决于你使用docker的方式.如果要在已经运行的容器中运行脚本,可以使用exec:

docker exec <yourContainerName> python <yourScript> <args>
Run Code Online (Sandbox Code Playgroud)

或者,如果您的脚本是ENTRYPOINT,那么您传递给docker run命令的任何参数都将添加到入口点.

所以,如果你的docker文件看起来像这样:

FROM yourbase
....
ENTRYPOINT <yourScript>
Run Code Online (Sandbox Code Playgroud)

然后你可以通过运行容器本身来运行脚本:

docker run --rm <yourImageName> <args>
Run Code Online (Sandbox Code Playgroud)

根据您在下面的评论,您似乎想要这个选项.您应该更改dockerfile以指定

ENTRYPOINT ["python","./script.py"]
Run Code Online (Sandbox Code Playgroud)

(而不是使用CMD)然后你可以运行:

docker run --rm <yourImageName>  -a API_KEY - f FILENAME -o ORG_ID
Run Code Online (Sandbox Code Playgroud)

  • 值得一提的是,您需要使用 exec 形式 `ENTRYPOINT ["python","./script.py"]` 而不是 shell 形式 `ENTRYPOINT python ./script.py` 才能传播将参数导入到 python 中。 (6认同)

Ale*_*oya 6

在里面Dockerfile,我像这样使用CMD命令:

FROM python:3
COPY ./app /app
WORKDIR /app
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r req.pip
CMD ["python","start.py","(api-url) ","(api-key)","(file-path)"]
Run Code Online (Sandbox Code Playgroud)

注意每个参数/参数,用昏迷分开

如果您使用标志,则需要拆分

CMD ["python","start.py","-u","(api-url) ","-k","(api-key)","-f","(file-path)"]
Run Code Online (Sandbox Code Playgroud)


小智 5

这个答案有点晚了,但对于任何未来的读者,我想更倾向于提出的问题,即关于 argparse。

像@Chris 指出的基本思想就是它。实现解决方案的一种方法是将参数传递给imagein docker run 命令本身。然后将这些参数传递给您的ENTRYPOINT,从而传递给 python 脚本。

这些文件通常看起来像这样..

文件.py

import argparse
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('pos', type=str, help='Example Positional Argument') # will be accesible under args.POS
parser.add_argument('--opt', type=str , help='Example Optional Argument') # will be accesible with args.OPT

args = parser.parse_args()

# do something with pos and OPT

Run Code Online (Sandbox Code Playgroud)

如果没有 docker,你会运行这个文件(假设它在 pwd 中) python file.py --opt opt_val pos_val

文件

FROM python:<your_tag>
COPY ./file.py ./ # Assuming your Dockerfile and file.py are in the same directory

# some custom build steps

ENTRYPOINT ["python","./file.py"]
Run Code Online (Sandbox Code Playgroud)

Docker 构建和运行命令

你用这个构建: docker build --tag example:0.0.1 <dir>

下面显示了多行(为了更好的可读性)运行命令,

运行 Docker

docker run --rm \
   --name example.container \
   example:0.0.1 \
   --opt=opt_val \
   POS=pos_value
Run Code Online (Sandbox Code Playgroud)

Docker 运行(powershell)

docker run --rm `
   --name example.container `
   example:0.0.1 `
   --opt=opt_val `
   POS=pos_value
Run Code Online (Sandbox Code Playgroud)

所以这里有一些要点要记住:

  • Argparse具有用于添加位置和可选参数,应作相应传递到支撑imagedocker run命令。
  • 上面指出的解决方案有效,但不像 id 通常喜欢的那样灵活。最好使用环境变量并使用os.environ().
  • 使用此解决方案,您无需对 Dockerfile 进行任何“硬编码”