django - Django 将 FileField 中的文件保存在 docker 容器中
问题描述
我有一个带有 FileField 的模型。我的应用程序在使用 dockerfile 创建的 docker 容器中运行。当我保存文件时,它会保存在我的本地路径而不是容器的基础根目录中。但是,当我尝试检索文件并将其作为电子邮件附件发送时,我收到一个未找到文件的错误。媒体根目录基于 Dockerfile 的基本根目录。电子邮件作为异步任务在另一个容器中构建和发送。Dockerfile 看起来像这样:
# pull official base image
FROM python:3.9.1-alpine
# set work directory
#ENV APP_HOME=/code
#RUN mkdir $APP_HOME
#RUN mkdir $APP_HOME/static
#RUN mkdir $APP_HOME/media
#WORKDIR $APP_HOME
WORKDIR /code
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
COPY requirements.txt /code/
RUN apk --update --upgrade --no-cache add \
postgresql-libs make gdal-dev geos-dev g++ python3-dev cairo-dev pango-dev gdk-pixbuf-dev ttf-ubuntu-font-family
RUN \
apk add --virtual .build-deps gcc musl-dev postgresql-dev jpeg-dev zlib-dev libffi-dev && \
pip3 install --no-cache-dir -r /code/requirements.txt && \
apk --purge del .build-deps
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
# copy project
COPY . /code/
我有一个 docker-compose 文件来构建图像并运行容器。它看起来像这样:
version: "3.9"
services:
db:
image: postgis/postgis:13-3.0-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
# TODO remove ports for production
ports:
- "5432:5432"
environment:
- POSTGRES_DB=DB
- POSTGRES_USER=USER
- POSTGRES_PASSWORD=PW
api:
build: .
image: app/api
command: python manage.py runserver 0.0.0.0:8000 --settings=api.settings.production
volumes:
- .:/code
- static:/code/static
- media:/code/media
ports:
- "8000:8000"
env_file:
- ./.env.dev
depends_on:
- db
entrypoint: /entrypoint.sh
mail:
image: app/api
command: python manage.py qcluster --settings=api.settings.production
depends_on:
- api
volumes:
postgres_data:
static:
media:
示例模型如下所示:
def order_nested_item_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/orders/user_<id>/<filename>
user_id = instance.order.user.id if instance.order.user else 'anonymous'
return f'orders/user_{user_id}/order_{instance.order.id}/{filename}'
class Invoice(TimeStampedModel):
order = models.ForeignKey(Order, related_name='invoices', on_delete=models.CASCADE)
number = models.CharField(max_length=100)
pdf = models.FileField(upload_to=order_nested_item_directory_path)
使用媒体根设置:
BASE_DIR = Path(__file__).resolve().parent.parent.parent
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
任何人都可以帮助如何将文件保存在 Dockerfile 的基本根目录中?
解决方案
我不确定它是否能解决您的问题,但如果您想使用 docker-compose 在容器之间共享命名卷中的数据,您需要将这些卷添加到所有这些容器或使用扩展字段。
由于第一件事更容易,只需添加
volumes:
- media:/code/media
到您mail
在 docker-compose 中的服务。
之后重建你的容器。
然后,当它运行时,运行docker exec -it <image id> sh
并检查是否/code/media
存在。
推荐阅读
- javascript - 使用 jquery 获取附加的 href 链接
- javascript - react js中的切片问题
- javascript - 如何使用 Jest 对入口点 Node.js 文件进行单元测试
- python-3.x - 如何在 Google Colab 的同一个项目中引用 py 文件?
- typescript - 使常量值断言其逻辑
- c# - 在结束会话 URI 中使用 IP 地址时,OpenId Connect 用户未注销(发现文档 end_session_endpoint)。使用 Gluu 身份服务器
- powerbi - PowerBI:根据度量过滤器从列中获取值
- spring - 是否有 Maven 插件可以从 swagger 端点生成客户端代码?
- node.js - react-express 应用程序的 ec2 部署,nodemailer 不使用 .env 变量
- html - 我如何将物品与居中的 UL 分开?