更新Bedrock镜像时无需删除Docker卷,实现Nginx访问最新代码
解决Bedrock镜像更新后Nginx无法获取最新代码的问题
核心问题出在Docker命名卷的初始化规则:首次创建卷时,Docker会自动将容器镜像中对应挂载路径的内容复制到卷中,但后续容器重启或更新镜像时,卷内内容不会被镜像的新内容覆盖——因为卷的优先级高于镜像文件系统。
以下是几种可行的解决方案:
方案1:启动时自动同步镜像代码到共享卷
在Bedrock容器的启动流程中添加代码同步逻辑,每次容器启动时将镜像内的最新代码同步到共享卷,同时保留需要持久化的目录(如uploads、.env)。
具体操作:
- 修改Bedrock的Dockerfile,将代码放在镜像内的独立目录,并添加同步脚本作为入口点:
FROM php:8.2-fpm # 省略依赖安装、PHP扩展配置等步骤 # 将Bedrock代码复制到镜像的独立目录 COPY . /usr/local/bedrock # 创建代码同步脚本 RUN echo '#!/bin/sh' > /usr/local/bin/sync-code && \ echo 'rsync -av --exclude="web/app/uploads" --exclude=".env" /usr/local/bedrock/ /var/www/html/' >> /usr/local/bin/sync-code && \ chmod +x /usr/local/bin/sync-code # 设置入口点:先同步代码,再启动PHP-FPM ENTRYPOINT ["/usr/local/bin/sync-code"] CMD ["php-fpm"]
- 重新构建Bedrock镜像:
docker build -t my-site:latest .
- 重启容器:
docker-compose up -d --force-recreate bedrock
此后每次Bedrock容器启动(包括Watchtower自动更新镜像后),都会把镜像里的最新代码同步到wp卷,同时跳过已被本地挂载覆盖的目录,Nginx就能自动获取到最新代码。
方案2:调整挂载策略,仅共享必要目录
Nginx仅需要访问Bedrock的web目录(公开访问的静态资源和PHP入口文件),可以避免共享整个/var/www/html,改为仅共享web目录,Bedrock核心代码直接运行在镜像文件系统中。
修改docker-compose.yml:
volumes: wp-web: driver: local wp-uploads: driver: local services: nginx: image: nginx:latest restart: unless-stopped depends_on: - bedrock volumes: - wp-web:/var/www/html/web - wp-uploads:/var/www/html/web/app/uploads - ./vhost.conf:/etc/nginx/conf.d/default.conf expose: - 80 bedrock: image: my-site:latest restart: unless-stopped volumes: - wp-web:/var/www/html/web - wp-uploads:/var/www/html/web/app/uploads - ./.env:/var/www/html/.env - ./php.ini:/usr/local/etc/php/conf.d/php.ini labels: - "com.centurylinklabs.watchtower.enable=true"
同样需要给Bedrock添加启动同步脚本(参考方案1),将镜像内的web目录同步到wp-web卷,确保Nginx能获取到最新的静态资源和入口文件。
方案3:自动清理旧卷(不推荐)
如果不想修改容器配置,可以在Watchtower更新镜像后,自动删除并重建wp卷。可以编写一个简单的脚本,配合Watchtower的--post-update-command参数执行,但这种方式会导致服务短暂中断,且可能丢失未备份的卷内数据。
内容的提问来源于stack exchange,提问作者danivdwerf
相关产品推荐
相关产品推荐

