Docker部署FastAPI上传文件时出现Permission denied权限错误
Docker部署FastAPI上传文件权限拒绝问题解决
本地运行FastAPI文件上传接口时一切正常,但部署到Docker容器后出现权限错误,无法写入uploads目录。
报错信息
File "/app/main.py", line 26, in say_hello with open(file_path, "wb") as f: ^^^^^^^^^^^^^^^^^^^^^ PermissionError: [Errno 13] Permission denied: 'uploads/h.png'
上传端点代码
@app.post("/letter") async def say_hello(file: UploadFile = File(...)): file_path = f"uploads/{file.filename}" with open(file_path, "wb") as f: f.write(await file.read()) return process_image(file_path)
Dockerfile内容
# syntax=docker/dockerfile:1 ARG PYTHON_VERSION=3.12.3 FROM python:${PYTHON_VERSION}-slim as base ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 WORKDIR /app ARG UID=10001 RUN adduser \ --disabled-password \ --gecos "" \ --home "/nonexistent" \ --shell "/sbin/nologin" \ --no-create-home \ --uid "${UID}" \ appuser # Set the permissions for all files RUN chown -R appuser:appgroup /app RUN --mount=type=cache,target=/root/.cache/pip \ --mount=type=bind,source=requirements.txt,target=requirements.txt \ python -m pip install -r requirements.txt # Switch to the non-privileged user to run the application. USER appuser COPY . . EXPOSE 8000 CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
问题原因
- COPY指令权限问题:切换到
appuser后执行COPY . .,复制的文件/目录默认所有者为root,导致appuser对uploads目录无写入权限。 - uploads目录未提前创建:若本地代码目录中不存在
uploads文件夹,容器运行时代码尝试写入uploads/路径时,需要先创建目录,但appuser可能无权限在/app下创建新目录。 - 权限设置时机错误:
RUN chown -R appuser:appgroup /app执行在COPY之前,后续复制的文件会新增root权限的内容,导致之前的权限设置失效。
解决方案
方案1:COPY时指定文件所有者
修改COPY指令,添加--chown参数确保复制的文件归appuser所有:
# 替换原COPY指令 COPY --chown=appuser:appuser . .
方案2:提前创建uploads目录并设置权限
在切换用户前创建uploads目录,赋予appuser权限:
# 在USER appuser之前添加 RUN mkdir -p /app/uploads && chown -R appuser:appuser /app/uploads USER appuser COPY . .
方案3:代码中自动创建uploads目录
在写入文件前检查并创建目录,避免因目录不存在导致的错误:
import os @app.post("/letter") async def say_hello(file: UploadFile = File(...)): upload_dir = "uploads" # 自动创建目录(已存在则跳过) os.makedirs(upload_dir, exist_ok=True) file_path = f"{upload_dir}/{file.filename}" with open(file_path, "wb") as f: f.write(await file.read()) return process_image(file_path)
方案4:调整权限设置顺序
将chown命令移到COPY之后,确保所有文件都被赋予正确权限:
# 先复制文件,再设置权限 COPY . . RUN chown -R appuser:appuser /app # 再切换到非特权用户 USER appuser
内容的提问来源于stack exchange,提问作者dzmoxn
相关产品推荐
相关产品推荐

