![](/img/trans.png)
[英]How to pass a CSV file to a Flask app running inside a Docker container?
[英]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/ /code
到COPY --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.