使用docker compose watch的sync动作报错‘文件已存在’,rebuild正常
问题
我正尝试配置Django项目,通过docker compose watch将代码变更同步至容器化的Django应用。对应的compose文件如下:
include: - compose-db-dev.yaml services: webapp: environment: - DJANGO_SETTINGS_MODULE=app.settings.dev build: . ports: - 3000:8080 develop: watch: - action: sync path: . target: /app depends_on: db: condition: service_healthy
当设置action为sync时,出现以下错误:
Syncing webapp after changes were detected: - /home/jb/myapp/main/views.py tar: app/main/views.py: Cannot open: File exists tar: Exiting with failure status due to previous errors WARN[0023] Error handling changed files for service webapp: 1 error occurred: * copying files to 47b692a96cf0e7b8edd3922f27aaa05fd63d511176cfe1362126828a28d9f030: exit code 2
将watch动作设置为rebuild时无此错误,能正常更新应用,但镜像重建耗时数秒,资源利用效率不佳。修改Django应用的视图无需重建服务,sync动作本应更合适,但同步针对已存在的文件却出现“文件已存在”的错误,这是为什么?
原因与修复
这个错误的核心是Docker Compose的sync动作默认通过tar命令同步文件,若容器内的目标文件被进程锁定(比如Django开发服务器正占用视图文件),tar无法打开并覆盖它,从而抛出“文件已存在”的错误。
以下是几种可行的解决方法:
添加force参数强制覆盖
在sync配置中加入force: true,让tar使用--overwrite选项强制替换已存在的文件:develop: watch: - action: sync path: . target: /app force: true结合sync与轻量重启
若强制覆盖仍无效,可针对变更文件触发服务重启(比重建镜像快得多):develop: watch: - action: sync path: . target: /app force: true - action: restart path: ./main/views.py修复容器内文件权限
若容器内文件由root用户拥有,sync动作的运行用户可能无写入权限。可在Dockerfile中设置工作目录权限:WORKDIR /app RUN chown -R app:app /app USER app排除冗余文件
同步时排除__pycache__、虚拟环境等不需要的文件,避免冲突:develop: watch: - action: sync path: . target: /app force: true exclude: - "__pycache__/" - "venv/" - ".git/"
内容的提问来源于stack exchange,提问作者Julian Beggs
相关产品推荐
相关产品推荐

