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

如何正确配置docker-compose让多容器共享volume且不覆盖镜像内置文件

解决方案

核心问题原因

你遇到的404确实是挂载逻辑导致的:Docker命名卷如果已经被初始化过(哪怕是空的),挂载到容器的/var/www路径时,会直接用卷内的内容覆盖路径下的文件,不会再同步镜像内的文件。同时你把composer update放在镜像构建阶段执行,此时运行时的volume还没挂载,生成的依赖只存在于镜像里,不符合你要求的在volume上执行的需求。


具体操作步骤

1. 调整php-fpm镜像构建逻辑

修改php-fpm/Dockerfile:

  • 不要直接把代码拷贝到/var/www,先存到镜像内的临时目录
  • 移除Dockerfile里的composer update命令
  • 新增启动入口脚本,代码如下:
# 原有其他配置保持不变
COPY ./app/ /tmp/app/
COPY entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

在php-fpm配置目录下新增entrypoint.sh启动脚本:

#!/bin/sh
set -e

# 检查卷内是否已经存在项目文件,避免重复覆盖
if [ ! -f /var/www/artisan ]; then
    # 把镜像内临时存储的代码同步到挂载的volume中
    cp -R /tmp/app/* /var/www/
    # 生产环境建议用composer install替代update,配合composer.lock保证依赖版本一致
    cd /var/www && composer install --no-dev --optimize-autoloader
    # 按需追加权限配置,比如storage/bootstrap目录写权限
    chown -R www-data:www-data /var/www/storage /var/www/bootstrap/cache
fi

# 启动php-fpm主进程
php-fpm

2. 调整docker-compose.yml配置

保留原有的app-data命名卷配置,同时给nginx容器也挂载同一个卷,示例配置如下:

services:
  php-fpm:
    # 其他原有配置不变
    volumes:
      - app-data:/var/www/
  nginx:
    # 其他原有配置不变
    volumes:
      # 给nginx只读挂载即可,满足静态资源和php文件读取需求,安全性更高
      - app-data:/var/www/:ro
# 声明全局共享的命名卷,所有服务挂载同一份
volumes:
  app-data:

3. 清理旧卷重新启动

因为之前的app-data卷已经有旧数据,需要先删除再启动才会走初始化逻辑:

# 注意:该命令会删除当前项目关联的所有卷,确认卷内无需要保留的数据后再执行
docker-compose down -v
# 重新构建镜像并启动服务
docker-compose up -d --build

效果验证

启动完成后:

  • php-fpm容器内/var/www路径下的代码和依赖都存储在app-data卷中
  • nginx和php-fpm读取的是同一份卷内的文件,不会出现404
  • 后续重新构建镜像启动时,不会覆盖卷内已经存在的代码、用户上传的文件等数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 09:57:03