Django应用保存文件至/vol/web/media时遇权限拒绝问题求助
Django Docker环境下保存文件提示Permission denied: '/vol/web/media'
在Django应用中尝试保存包含文件的模型时,遇到权限错误:Permission denied: '/vol/web/media',相关配置及问题详情如下:
相关配置代码
Dockerfile
FROM python:3.9-alpine3.13 ENV PYTHONUNBUFFERED 1 COPY ./requirements.txt /requirements.txt COPY ./electron /electron COPY ./scripts /scripts WORKDIR /electron EXPOSE 8000 RUN apk add --no-cache --virtual .build-deps gcc musl-dev RUN python3.9 -m venv /py && \ /py/bin/pip install --upgrade pip setuptools wheel && \ apk add --update --no-cache postgresql-client && \ apk add --update --no-cache --virtual .temp-deps \ build-base postgresql-dev musl-dev linux-headers && \ mkdir -p /vol/web/media && \ /py/bin/pip install -r /requirements.txt && \ adduser --disabled-password --no-create-home ozangue && \ chown -R ozangue:ozangue /vol && \ chmod -R 755 /vol && \ chown -R ozangue:ozangue /vol/web/media && \ chmod -R 755 /vol/web/media && \ chmod -R +x /scripts ENV PATH="/scripts:/py/bin:$PATH" USER ozangue CMD ["run.sh"]
views.py 出错代码片段
file = request.FILES["excel_file"] file_obj = FileModelXSL(file=excel_file) fichier_obj = fichier_obj.save()
settings.py 配置
STATIC_URL = '/static/static/' MEDIA_URL = '/static/media/' MEDIA_ROOT = '/vol/web/media' STATICFILES_DIRS = (BASE_DIR / 'static',) STATIC_ROOT = '/vol/web/static'
docker-compose.yml 容器配置
version: '3' services: app: container_name: ozangue build: context: . command: > python manage.py makemigrations --noinput && python manage.py migrate --noinput && python manage.py runserver 0.0.0.0:8000" ports: - 8000:8000 volumes: - ./electron:/electron - ./data/web:/vol/web
容器构建无报错,但保存文件时触发权限拒绝,怀疑目录权限存在问题。
问题原因及解决方法
核心原因
docker-compose中挂载了本地./data/web到容器/vol/web,该操作会覆盖容器构建阶段创建的/vol/web/media目录及权限设置。本地目录的所有者、权限与容器内运行Django的ozangue用户不匹配,导致写入权限不足。
具体修复步骤
调整Dockerfile并优化启动脚本
简化Dockerfile中的权限配置,并在启动脚本中确保挂载后的目录权限正确:
修改Dockerfile的RUN块:RUN python3.9 -m venv /py && \ /py/bin/pip install --upgrade pip setuptools wheel && \ apk add --update --no-cache postgresql-client && \ apk add --update --no-cache --virtual .temp-deps \ build-base postgresql-dev musl-dev linux-headers && \ /py/bin/pip install -r /requirements.txt && \ adduser --disabled-password --no-create-home ozangue && \ mkdir -p /vol/web/media /vol/web/static && \ chown -R ozangue:ozangue /vol && \ chmod -R 755 /vol && \ chmod -R +x /scripts在
scripts/run.sh中添加目录权限检查:#!/bin/sh mkdir -p /vol/web/media /vol/web/static chown -R ozangue:ozangue /vol/web python manage.py makemigrations --noinput python manage.py migrate --noinput python manage.py runserver 0.0.0.0:8000修复宿主机挂载目录权限
让本地目录的用户ID与容器内ozangue用户匹配:# 查看容器内ozangue的UID docker exec -it ozangue id -u ozangue # 替换下面的1000为上面输出的UID sudo chown -R 1000:1000 ./data/web简化docker-compose命令
将command改为直接调用启动脚本:command: run.sh
额外代码检查
views.py中存在变量名错误,需修正:
file = request.FILES["excel_file"] file_obj = FileModelXSL(file=file) # 将excel_file改为file file_obj.save()
内容的提问来源于stack exchange,提问作者leauradmin
相关产品推荐
相关产品推荐

