Docker Python脚本找不到文件

Lou*_*tiz 5 python docker dockerfile

我已经成功构建了一个Docker容器并将我的应用程序文件复制到Dockerfile中的容器中。但是,我试图执行一个引用输入文件的Python脚本(该文件在Docker构建期间复制到了容器中)。我似乎无法弄清楚为什么我的脚本告诉我它无法找到输入文件。我在下面包括用于构建容器的Dockerfile,以及正在寻找其找不到的输入文件的Python脚本的相关部分。

Dockerfile:

FROM alpine:latest

RUN mkdir myapplication

COPY . /myapplication

RUN apk add --update \
    python \
    py2-pip && \
    adduser -D aws

WORKDIR /home/aws

RUN mkdir aws && \
    pip install --upgrade pip && \
    pip install awscli && \
    pip install -q --upgrade pip && \
    pip install -q --upgrade setuptools && \
    pip install -q -r /myapplication/requirements.txt

CMD ["python", "/myapplication/script.py", "/myapplication/inputfile.txt"]
Run Code Online (Sandbox Code Playgroud)

Python脚本的相关部分:

if len(sys.argv) >= 2:
    sys.exit('ERROR: Received 2 or more arguments. Expected 1: Input file name')

elif len(sys.argv) == 2:
    try:
        with open(sys.argv[1]) as f:
            topics = f.readlines()
    except Exception:
        sys.exit('ERROR: Expected input file %s not found' % sys.argv[1])
else:
    try:
        with open('inputfile.txt') as f:
            topics = f.readlines()
    except:
        sys.exit('ERROR: Default inputfile.txt not found. No alternate input file was provided')
Run Code Online (Sandbox Code Playgroud)

主机上的Docker命令导致错误:

sudo docker run -it -v $HOME/.aws:/home/aws/.aws discursive python \
    /discursive/index_twitter_stream.py
Run Code Online (Sandbox Code Playgroud)

来自上面命令的错误:

错误:找不到默认的inputfile.txt。没有提供替代输入文件

AWS内容来自于有关如何将主机的AWS凭证传递到Docker容器以与AWS服务进行交互的教程。我从这里使用了元素:https : //github.com/jdrago999/aws-cli-on-CoreOS

Tag*_*agc 4

到目前为止我已经发现了两个问题。Maya G 在下面的评论中指出了第三个。

条件逻辑不正确

您需要更换:

if len(sys.argv) >= 2:
    sys.exit('ERROR: Received 2 or more arguments. Expected 1: Input file name')
Run Code Online (Sandbox Code Playgroud)

和:

if len(sys.argv) > 2:
    sys.exit('ERROR: Received more than two arguments. Expected 1: Input file name')
Run Code Online (Sandbox Code Playgroud)

请记住,给予脚本的第一个参数始终是它自己的名称。这意味着您应该期待 1 或 2 个参数sys.argv

查找默认文件的问题

另一个问题是你的 docker 容器的工作目录是/home/aws,因此当您执行 Python 脚本时,它将尝试解析与此相对的路径。

这意味着:

with open('inputfile.txt') as f:
Run Code Online (Sandbox Code Playgroud)

将被解析为/home/aws/inputfile.txt, 不/home/aws/myapplication/inputfile.txt

您可以通过将代码更改为以下方式来解决此问题:

with open('myapplication/inputfile.txt') as f:
Run Code Online (Sandbox Code Playgroud)

或者(首选):

with open(os.path.join(os.path.dirname(__file__), 'inputfile.txt')) as f:
Run Code Online (Sandbox Code Playgroud)

来源上述变体的

使用CMDENTRYPOINT

您的脚本似乎也没有收到myapplication/inputfile.txt作为参数。这可能是一个怪癖CMD

我不是 100% 清楚这两个操作之间的区别,但我总是ENTRYPOINT在我的 Dockerfiles 中使用它,这并没有给我带来任何悲伤。请参阅此答案并尝试替换:

CMD ["python", "/myapplication/script.py", "/myapplication/inputfile.txt"]
Run Code Online (Sandbox Code Playgroud)

和:

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

(感谢玛雅G)