我有一个简单的 python 脚本,我想在 docker 容器内运行它。它打印一行消息“Hello {name}”。 python 脚本使用 click CLI 界面来定义收件人名称,如果我直接运行它(不使用 docker run 命令),它将如下所示:
python hello.py -n Smith
Docker build 命令:
docker build . -t hello:1.0.0
Docker run 命令:|| |使用此 docker run 命令时,我收到一条错误消息
docker run --rm -v $(pwd):/app hello -n Smith
完整的错误消息如下:
exec: "-n": executable file not found in $PATH:
Dockerfile:
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "-n": executable file not found in $PATH: unknown.
我的简单
FROM python:3.11.0-slim
RUN mkdir -p /app
WORKDIR /app
COPY . .
RUN python -m pip install --upgrade pip
RUN python -m pip install click
RUN chmod +x ./*
ENTRYPOINT [ "python", "hello.py" ]
使用单击的脚本:
hello.py
预期输出:
#!/usr/bin/env python3
import click
@click.command()
@click.option('-n', '--name', help='Name of message recipient')
def hello(name):
# Print to screen and to file
msg = f'Hello {name}'
print(msg)
with open("hello.txt", "w") as f:
f.write(msg)
if __name__ == '__main__':
hello()
我尝试将单击选项名称更改为其他名称,例如
Hello Smith
或
-r
,但我得到了相同的错误。
--recipient
当我从 docker run 命令中删除
时,我得到以下预期输出:
-n Smith
from the docker run command I get the following expected output:
Hello None
遇到的问题在于,正试图将 click 选项直接传递给
docker run
命令。
docker run
命令将传递给它的任何内容都解释为要运行的容器的
参数
。在这种情况下,它将
-n
和
Smith
解释为传递给
ENTRYPOINT
中定义的
python hello.py
命令的参数。由于
python
命令本身并不识别
-n
选项,因此它会引发错误。
可以通过以下两种方式解决此问题:
1. 将命令作为
docker run
的一部分传递:
docker run --rm -v $(pwd):/app hello:1.0.0 python hello.py -n Smith
此命令直接将
python hello.py -n Smith
作为要执行的命令传递给容器。
ENTRYPOINT
将被忽略,因为在命令行中显式指定了要运行的命令。
2. 使用
CMD
指令并覆盖默认值:
修改的 Dockerfile,将
ENTRYPOINT
更改为
CMD
:
FROM python:3.11.0-slim
RUN mkdir -p /app
WORKDIR /app
COPY . .
RUN python -m pip install --upgrade pip
RUN python -m pip install click
RUN chmod +x ./*
CMD [ "python", "hello.py" ]
然后,可以使用以下命令运行容器并传递 click 选项:
docker run --rm -v $(pwd):/app hello:1.0.0 -n Smith
在这种情况下,
CMD
指令定义了默认命令,但可以通过在
docker run
命令中提供参数来覆盖它。
总结
第一种方法更为直接,特别是在希望完全控制传递给脚本的参数时。第二种方法在希望为容器定义默认命令,但允许用户在需要时覆盖该命令时非常有用。 选择哪种方法取决于的具体需求。
标签:python,docker,python-click,docker-run From: 77632954