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
相关产品推荐
相关产品推荐

