首页 > 解决方案 > Docker不保存使用python创建的文件 - Flask应用程序

问题描述

我创建了一个 Flask 应用程序。此应用程序从 url 接收 XML 并保存它:

  response = requests.get(base_url)
  with open('currencies.xml', 'wb') as file:
      file.write(response.content)

当我在没有 Docker 的情况下运行应用程序时,该文件currencies.xml会在我的应用程序文件夹中正确创建。但是,当我使用 docker 时不会发生这种行为。

在 docker 中,我运行以下命令:

docker build -t my-api-docker:latest .
docker run -p 5000:5000 my-api-docker ~/Desktop/myApiDocker # This is where I want the file to be saved: inside the main Flask folder

当我运行第二个命令时,我得到:

docker:来自守护进程的错误响应:OCI 运行时创建失败:container_linux.go:345:启动容器进程导致“exec:\”/Users/name/Desktop/myApiDocker\”:stat /Users/name/Desktop/myApiDocker:没有这样的文件或目录”:未知。ERRO [0001] 错误等待容器:上下文已取消

但是如果我运行:

docker build -t my-api-docker:latest .
docker run -p 5000:5000 my-api-docker # Without specifying the PATH

我可以访问该网站(但没有文件它非常没用currencies.xml

Dockerfile

FROM python:3.7
RUN pip install --upgrade pip

COPY ./requirements.txt /app/requirements.txt

WORKDIR /app

RUN pip install -r requirements.txt

COPY . /app

EXPOSE 5000

CMD [ "flask", "run", "--host=0.0.0.0" ]

标签: dockerflask

解决方案


当你

docker run -p 5000:5000 my-api-docker ~/Desktop/myApiDocker

Docker 将镜像名称 ( my-api-docker) 之后的所有内容解释为要运行的命令。它/Users/name/Desktop/myApiDocker作为命令运行,而不是CMD在 Dockerfile 中所拥有的,当容器中不存在该路径时,您会看到您看到的错误。

您不太可能将此路径flask run作为命令行参数传递给您的命令。处理此问题的典型方法是使用环境变量。在您的代码中,

download_dir = os.environ.get('DOWNLOAD_DIR', '.')
currencies_xml = os.path.join(download_dir, 'currencies.xml')
with open(currencies_xml, 'wb') as file:
  ...

然后,当您启动容器时,您可以将其作为环境变量与docker run -e选项一起传递。请注意,这会命名容器内的路径;没有特别需要它来匹配主机上的路径。

docker run \
  -p 5000:5000 \
  -e DOWNLOAD_DIR=/data \
  -v $HOME/Desktop/myApiDocker:/data \
  my-api-docker

ENV在您的 Dockerfile中放置一条语句或为此选择一个固定路径也是相当常见的,并且只需指定您的图像的接口是将文件下载到安装在/data.


推荐阅读