Docker部署Django应用无法修改模板文件,如何不重启容器解决?
问题描述
在Docker中运行Django应用时,能修改.py文件但无法保存模板文件修改,怀疑是Docker权限限制导致,求无需停止容器的解决办法。
部署环境:群晖NAS(Synology NAS)共享文件夹
配置文件
docker-compose.yml
version: '3.8' services: web: build: ./app command: gunicorn -w 3 myapp.wsgi:application --bind 0.0.0.0:8000 --reload volumes: - ./app/:/usr/src/app - ./static/:/home/app/web/static - ./media/:/home/app/web/media expose: - 8000 env_file: - ./.env restart: unless-stopped nginx: build: ./nginx volumes: - ./static/:/home/app/web/static - ./media/:/home/app/web/media ports: - 7000:80 depends_on: - web
Dockerfile
########### # BUILDER # ########### # pull official base image FROM python:3.9.6-alpine as builder # set work directory WORKDIR /usr/src/app # set environment variables ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 # install psycopg2 dependencies RUN apk update \ && apk add postgresql-dev gcc python3-dev musl-dev # install dependencies RUN pip install --upgrade pip COPY . . COPY ./requirements.txt . RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt ######### # FINAL # ######### # pull official base image FROM python:3.9.6-alpine # create directory for the app user RUN mkdir -p /home/app # create the app user RUN addgroup -S app && adduser -S app -G app # create the appropriate directories ENV HOME=/home/app ENV APP_HOME=/home/app/web RUN mkdir $APP_HOME RUN mkdir $APP_HOME/static RUN mkdir $APP_HOME/media WORKDIR $APP_HOME # install dependencies RUN apk update && apk add libpq COPY --from=builder /usr/src/app/wheels /wheels COPY --from=builder /usr/src/app/requirements.txt . RUN pip install --no-cache /wheels/* # copy project COPY . $APP_HOME # chown all the files to the app user RUN chown -R app:app $APP_HOME # change to the app user USER app
无需停止容器的解决办法
1. 先排查容器内模板文件的权限与路径
先进入web容器的shell:
docker exec -it <你的web容器名称/ID> sh
查看模板目录的权限(假设模板在$APP_HOME/templates下):
ls -l $APP_HOME/templates
如果文件所有者是root而非app,或权限显示无写入权限,就是核心问题。
2. 临时调整容器内模板目录权限
因为当前容器运行用户是app,无修改权限,需切换到root用户操作:
docker exec -it -u root <web容器名称/ID> sh # 将模板目录所有者改为app用户 chown -R app:app $APP_HOME/templates # 测试阶段也可直接开放全权限(不建议长期使用) chmod -R 777 $APP_HOME/templates
退出容器后再尝试修改本地模板文件,验证是否能保存生效。
3. 匹配群晖NAS的UID/GID(长期解决方案)
群晖共享文件夹的用户UID/GID通常和容器内app用户不一致,导致挂载后无法写入:
- 先在群晖SSH终端查看共享文件夹的UID/GID:
ls -n /volume1/你的共享文件夹路径/app/templates
输出的第一列是UID,第二列是GID。
- 回到容器的root shell,修改
app用户的UID/GID匹配群晖:
# 替换为你查到的群晖GID groupmod -g 1001 app # 替换为你查到的群晖UID usermod -u 1001 app # 重新设置目录权限 chown -R app:app $APP_HOME
完成后本地群晖的权限就能和容器内用户匹配,挂载目录可正常写入。
4. 排查Django模板加载路径
检查settings.py中的模板配置,确保指向挂载的本地目录而非容器内副本:
TEMPLATES = [ { ... 'DIRS': [BASE_DIR / 'templates'], ... }, ]
如果本地./app挂载到了/usr/src/app,但容器内BASE_DIR是/home/app/web,需把模板目录改为/usr/src/app/templates,确保加载的是本地挂载的文件。
内容的提问来源于stack exchange,提问作者Viktor
相关产品推荐
相关产品推荐

