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

Docker-Compose内创建Django TDD应用遇只读权限问题求助

问题描述

学习《Django Celery权威指南》时,执行以下命令在容器内创建TDD应用:

$ docker-compose exec web bash

(container)$ ./manage.py startapp tdd

创建后的应用文件处于只读状态,PyCharm无法修改权限。已知问题出在以root用户创建应用,但不知道具体解决办法。

当前配置文件

docker-compose.yml

version: '3.3'

services:
  web:
    build:
      context: .
      dockerfile: ./compose/local/django/Dockerfile
    image: testdriven_web
    # '/start' is the shell script used to run the service
    command: /start
    # this volume is used to map the files and folders on the host to the container
    # so if we change code on the host, code in the docker container will also be changed
    volumes:
      - .:/app
    ports:
      - 8010:8000
    # env_file is used to manage the env variables of our project
    env_file:
      - ./.env/.dev-sample
    depends_on:
      - redis
      - db
  db:
    image: postgres:14-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - POSTGRES_DB=hello_django
      - POSTGRES_USER=hello_django
      - POSTGRES_PASSWORD=hello_django

  redis:
    image: redis:7-alpine

  celery_worker:
    build:
      context: .
      dockerfile: ./compose/local/django/Dockerfile
    image: testdriven_celery_worker
    command: /start-celeryworker
    volumes:
      - .:/app
    env_file:
      - ./.env/.dev-sample
    depends_on:
      - redis
      - db

  celery_beat:
    build:
      context: .
      dockerfile: ./compose/local/django/Dockerfile
    image: testdriven_celery_beat
    command: /start-celerybeat
    volumes:
      - .:/app
    env_file:
      - ./.env/.dev-sample
    depends_on:
      - redis
      - db

  flower:
    build:
      context: .
      dockerfile: ./compose/local/django/Dockerfile
    image: testdriven_celery_flower
    command: /start-flower
    volumes:
      - .:/app
    env_file:
      - ./.env/.dev-sample
    ports:
      - 5557:5555
    depends_on:
      - redis
      - db

volumes:
  postgres_data:

Dockerfile

FROM python:3.10-slim-buster

ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1

RUN apt-get update \
  # dependencies for building Python packages
  && apt-get install -y build-essential \
  # psycopg2 dependencies
  && apt-get install -y libpq-dev \
  # Translations dependencies
  && apt-get install -y gettext \
  # Additional dependencies
  && apt-get install -y procps \
  # cleaning up unused files
  && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
  && rm -rf /var/lib/apt/lists/*

# Requirements are installed here to ensure they will be cached.
COPY ./requirements.txt /requirements.txt
RUN pip install -r /requirements.txt

COPY ./compose/local/django/entrypoint /entrypoint
RUN sed -i 's/\r$//g' /entrypoint
RUN chmod +x /entrypoint

COPY ./compose/local/django/start /start
RUN sed -i 's/\r$//g' /start
RUN chmod +x /start

COPY ./compose/local/django/celery/worker/start /start-celeryworker
RUN sed -i 's/\r$//g' /start-celeryworker
RUN chmod +x /start-celeryworker

COPY ./compose/local/django/celery/beat/start /start-celerybeat
RUN sed -i 's/\r$//g' /start-celerybeat
RUN chmod +x /start-celerybeat

COPY ./compose/local/django/celery/flower/start /start-flower
RUN sed -i 's/\r$//g' /start-flower
RUN chmod +x /start-flower

WORKDIR /app

ENTRYPOINT ["/entrypoint"]

此前尝试过在Dockerfile中创建非root用户,但未成功。


解决方案

问题核心是容器默认以root用户运行,挂载宿主机目录后创建的文件权限属于root,导致宿主机无法修改。需修改Dockerfile和启动配置,让容器以非root用户运行。

步骤1:修改Dockerfile添加非root用户

在WORKDIR /app之前插入以下代码:

# 创建系统用户组和用户
RUN addgroup --system django && adduser --system --ingroup django django

# 把/app目录权限转移给django用户
RUN chown -R django:django /app

# 切换到django用户执行后续命令
USER django

修改后的完整Dockerfile:

FROM python:3.10-slim-buster

ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1

RUN apt-get update \
  # dependencies for building Python packages
  && apt-get install -y build-essential \
  # psycopg2 dependencies
  && apt-get install -y libpq-dev \
  # Translations dependencies
  && apt-get install -y gettext \
  # Additional dependencies
  && apt-get install -y procps \
  # cleaning up unused files
  && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
  && rm -rf /var/lib/apt/lists/*

# Requirements are installed here to ensure they will be cached.
COPY ./requirements.txt /requirements.txt
RUN pip install -r /requirements.txt

COPY ./compose/local/django/entrypoint /entrypoint
RUN sed -i 's/\r$//g' /entrypoint
RUN chmod +x /entrypoint

COPY ./compose/local/django/start /start
RUN sed -i 's/\r$//g' /start
RUN chmod +x /start

COPY ./compose/local/django/celery/worker/start /start-celeryworker
RUN sed -i 's/\r$//g' /start-celeryworker
RUN chmod +x /start-celeryworker

COPY ./compose/local/django/celery/beat/start /start-celerybeat
RUN sed -i 's/\r$//g' /start-celerybeat
RUN chmod +x /start-celerybeat

COPY ./compose/local/django/celery/flower/start /start-flower
RUN sed -i 's/\r$//g' /start-flower
RUN chmod +x /start-flower

# 创建系统用户组和用户
RUN addgroup --system django && adduser --system --ingroup django django

# 把/app目录权限转移给django用户
RUN chown -R django:django /app

# 切换到django用户执行后续命令
USER django

WORKDIR /app

ENTRYPOINT ["/entrypoint"]

步骤2:调整entrypoint脚本(可选)

如果entrypoint中有需要root权限执行的操作,比如初始化目录权限,可修改脚本在执行完root命令后切换到django用户:

#!/bin/sh

# 这里放需要root权限的操作,比如:
# chown -R django:django /app

# 切换到django用户执行启动命令
exec su django -c "$@"

步骤3:重新构建并启动容器

执行以下命令:

# 停止当前容器
docker-compose down

# 重新构建镜像
docker-compose build

# 启动容器
docker-compose up -d

步骤4:重新创建应用

进入容器执行startapp命令:

docker-compose exec web bash

(container)$ ./manage.py startapp tdd

此时创建的文件权限与宿主机用户一致,PyCharm可正常修改。

如果已有只读文件,可在宿主机手动调整权限:

sudo chown -R $USER:$USER ./tdd

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 05:45:38