繁体   English   中英

如何在 Flask 应用程序中的 Docker 容器外上传文件

[英]How to upload file outside Docker container in Flask app

我是 Docker 的新手。 我在 Docker 中包含的 Flask 应用程序中上传文件并访问它时遇到问题。

假设我有一个采用这种结构的项目:

/home
| /myProjects
  | /myDockers
  | | /myApp
  | | | /controller
  | | | ...
  | | | wsgi.py
  | | | .gitlab-ci.yml
  | | | DockerFile
  | | | gunicorn.sh
  | /uploads

我的 Flask 应用程序位于 /MyApp 中,而我想将文件上传到 /uploads。 该应用程序部署在 Docker 上,配置如下:

.gitlab-ci.yml

stages:
  - build
  - deploy

build-image:
  stage: build
  only:
    refs:
      - dev
  script:
    - cd /home/myProjects/myDocker/myApp/
    - git checkout dev
    - git pull origin dev
    - docker container rm -f myApp
    - docker image rm -f myApp
    - docker build -t myApp -f 20021_DockerfileLmsGeneralRepositoryService .

deploy-container:
  stage: deploy
  only:
    refs:
      - dev
  script:
    - docker run -d --network host -e DATABASE_URL=$DATABASE_URL -e REDIS_HOST=$REDIS_HOST --name myApp myApp

DockerFile

FROM python:3.8.7-slim-buster AS compile-image
RUN apt-get update && apt-get install -y --no-install-recommends build-essential gcc libpq-dev && apt-get install -y apt-utils

COPY ./requirements.txt .
RUN pip install --upgrade --user -r requirements.txt
RUN pip install injector


COPY . /code

FROM python:3.8.7-slim-buster AS build-image
COPY --from=compile-image /code/ /code
COPY --from=compile-image /root/.local /root/.local

# Make sure scripts in .local are usable:
ENV PATH=/root/.local/bin:$PATH
WORKDIR /code

RUN chmod a+x gunicorn.sh
ENTRYPOINT ["sh","./gunicorn.sh"]

gunicorn.sh

#!/bin/sh
gunicorn wsgi:application -w 2 --threads 2 --preload -b 0.0.0.0:20021

我已经在我的 Flask 应用程序中创建了一个 API 来上传文件并在本地(Windows)PC 上成功,但是当我将它部署到开发服务器时,文件夹的结构与我的预期不同。 当我使用脚本检查项目结构时,它返回:

"/code/controller"

这与服务器中项目的结构不同,所以我问我的前辈,他说我应该学习Docker中的Volume,因为项目包含在Docker容器中,但我从来没有使用过ZC5FD214CDD0D2B3B4272E73B02BA。

我也已经尝试将.gitlab-ci.yml中的脚本更改为此(我从这个问题尝试过),是的,它不起作用:

- docker run -d --network host -e DATABASE_URL=$DATABASE_URL -e REDIS_HOST=$REDIS_HOST --name myApp -v /home/myProjects/:/root/.local/code myApp

在我们的谈话之后,我可以看到另一个更简单的解决方案。 我的其他答案的一部分仍然适用。


从您的工作文件夹结构来看,您的应用似乎尝试写入../../uploads文件夹,目录结构提高了 2 级。 因此我们可以在容器中创建一个文件夹结构来适应这个。

Dockerfile中进行以下更改:

  • 编辑COPY --from=compile-image /code/ /codeCOPY --from=compile-image /code/ /code/app
  • WORKDIR /code编辑为WORKDIR /code/app
  • FROM.. AS build-image之后但ENTRYPOINT之前的任何位置添加RUN mkdir /uploads

我们将应用程序 2 级复制到容器深处,并将上传文件夹添加到根目录中。

现在运行将您的运行命令更改为:

docker run -d --network host -e DATABASE_URL=$DATABASE_URL -e REDIS_HOST=$REDIS_HOST --name myApp -v /home/myProjects/uploads:/uploads myApp

我们将主机中的上传文件夹绑定挂载到容器中的上传文件夹中。 您可以将绑定设置为-v path_to_your_uploads_folder_in_host:/uploads

您在 CI 文件和COPY. /code中使用cd /home/myProjects/myDocker/myApp/ COPY. /code

这意味着“无论您在主机的/home/myProjects/myDocker/myApp/文件夹中看到什么,都将它们全部复制到容器的/code文件夹中”。 因此您的...myApp/*变为/code/*

但你的痛苦不仅如此。 从应用程序的角度来看,您正在将上传的文件写入../../uploads但您的容器中没有这样的文件夹。 另请注意,您的主机中有 2 个父级别,并且您的应用程序正在寻找这样的路径,并且无论如何都不会在容器内找到,因为您的项目距离根级别只有 1 级深。

在后一种情况下,将您的代码更改为从环境( os.environ? )读取上传文件夹路径,将默认设置为../../uploads以进行开发,在容器内创建一个文件夹,例如/uploads ,添加它在您的 docker 文件中的路径与ENV然后 map 主机和容器上传文件夹路径与音量命令,可能-v home/myProjects/uploads:/uploads

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM