You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker中运行Django collectstatic触发[Errno 13]权限拒绝问题

解决Docker中Django collectstatic权限拒绝问题

问题重现

执行collectstatic命令时触发权限错误:

docker-compose exec web python manage.py collectstatic

错误日志片段:

Traceback (most recent call last):
  File "/code/manage.py", line 22, in <module>
    main()
  File "/code/manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
...
PermissionError: [Errno 13] Permission denied: '/code/static/admin/img/tooltag-arrowright.bbfb788a849e.svg.gz'

当前配置文件

Dockerfile

# Pull base image
FROM python:3.11.4-slim-bullseye

# Set environment variables
ENV PIP_NO_CACHE_DIR off
ENV PIP_DISABLE_PIP_VERSION_CHECK 1
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
ENV COLUMNS 80

# Install Debian dependencies for Python apps
RUN apt-get update \
  && apt-get install -y --force-yes python3-pip ffmpeg git libmagic-dev libpq-dev gcc \
  && rm -rf /var/lib/apt/lists/*

# Set working directory
WORKDIR /code/

# Install Python dependencies
COPY requirements.txt .
RUN pip install -r requirements.txt

# Copy project files
COPY . .

# Create non-root user
RUN useradd -m example-user

# Create media/static directories and set permissions
RUN mkdir -p /code/media /code/static && \
    chown -R example-user:example-user /code/media /code/static

# Set directory permissions
RUN chmod -R 755 /code

# Switch to non-root user
USER example-user

docker-compose.yml

#version: "3.9"
services:
  web:
    build: .
    command: gunicorn mysite.wsgi -b 0.0.0.0:8000 --reload
    volumes:
      - .:/code
    ports:
      - 8000:8000
    depends_on:
      - db
      - redis
      - celery
    environment:
      - "DJANGO_SECRET_KEY=scret_key"
      - "DJANGO_DEBUG=True"
      - "DJANGO_SECURE_SSL_REDIRECT=False"
      - "DJANGO_SECURE_HSTS_SECONDS=0" 
      - "DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS=False"
      - "DJANGO_SECURE_HSTS_PRELOAD=False"
      - "DJANGO_SESSION_COOKIE_SECURE=False"
      - "ACCESS_KEY_ID=scret_id"
      - "SECRET_ACCESS_KEY=scret_key"
      - "STORAGE_BUCKET_NAME=bucket"
      - "S3_CUSTOM_DOMAIN=domain"
      - CELERY_BROKER_URL=redis://redis:6379/0
      - CELERY_RESULT_BACKEND=redis://redis:6379/0
      
    user: example-user
  db:
    image: postgres:13
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - "POSTGRES_HOST_AUTH_METHOD=trust"
  redis:
    image: redis:6
    ports:
      - 6379:6379
  celery:
    build: .
    command: celery -A mysite worker --loglevel=info
    volumes:
      - .:/code
    depends_on:
      - redis
      - db
    environment:
      - "DJANGO_SECRET_KEY=scret_key"
      - "DJANGO_DEBUG=True"
      - "DJANGO_SECURE_SSL_REDIRECT=False"
      - "DJANGO_SECURE_HSTS_SECONDS=0" 
      - "DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS=False"
      - "DJANGO_SECURE_HSTS_PRELOAD=False"
      - "DJANGO_SESSION_COOKIE_SECURE=False"
      - "ACCESS_KEY_ID=scret_id"
      - "SECRET_ACCESS_KEY=scret_key"
      - "STORAGE_BUCKET_NAME=name"
      - "S3_CUSTOM_DOMAIN=domain"
      - CELERY_BROKER_URL=redis://redis:6379/0
      - CELERY_RESULT_BACKEND=redis://redis:6379/0

    user: example-user
volumes:
  postgres_data:

排查结果

执行docker-compose exec web ls -l /code/static后确认,static目录下除staticfiles.json外,其余文件/目录的属主均为root:

total 16
drwxrwxrwx 1 root      root       4096 Apr  5 05:42 admin
drwxrwxrwx 1 root      root       4096 Sep 21 22:36 css
drwxrwxrwx 1 root      root       4096 Sep 21 22:36 human
drwxrwxrwx 1 root      root       4096 Sep 18 18:42 img
-rw-r--r-- 1 user-mani user-mani 13091 Sep 21 22:36 staticfiles.json
drwxrwxrwx 1 root      root       4096 Sep 21 22:36 transcribe

解决方案

核心原因

Docker Compose中挂载的本地目录./覆盖了容器内/code目录的权限设置,本地static目录的文件由root创建,容器内非root用户example-user无写入权限。

修复步骤

  1. 调整Dockerfile权限设置顺序
    将目录创建、权限设置放到项目文件复制之后,确保容器内文件属主正确:

    # Create non-root user
    RUN useradd -m example-user
    
    # Copy project files
    COPY . .
    
    # Create media/static directories if not exist
    RUN mkdir -p /code/media /code/static
    
    # Grant ownership to non-root user
    RUN chown -R example-user:example-user /code
    
    # Set proper read/write permissions
    RUN chmod -R 755 /code/media /code/static
    
  2. 解决挂载目录权限冲突

    • 方法一:同步本地与容器用户UID/GID
      先查询容器内example-user的UID:
      docker-compose exec web id -u example-user
      
      然后在本地主机执行:
      sudo chown -R <查询到的UID>:<查询到的GID> ./static ./media
      
    • 方法二:使用Docker命名卷挂载static/media
      修改docker-compose.yml,将static和media目录单独挂载为命名卷:
      services:
        web:
          # ...其他配置
          volumes:
            - .:/code
            - static_volume:/code/static
            - media_volume:/code/media
          # ...其他配置
      volumes:
        postgres_data:
        static_volume:
        media_volume:
      
      此方式下,static/media目录使用Docker管理的存储,容器内权限设置会正常生效。
  3. 临时应急方案
    若需快速解决,可临时以root身份执行命令并修正权限:

    docker-compose exec -u root web python manage.py collectstatic
    docker-compose exec -u root web chown -R example-user:example-user /code/static
    

内容的提问来源于stack exchange,提问作者tthheemmaannii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 06:07:02