
Docker 容器启动时生成的默认配置文件(如 Apache 的 httpd.conf、SSL 证书目录等)仅在镜像首次初始化时写入容器内部文件系统;当使用绑定挂载(bind mount)时,若宿主机对应路径为空或不存在,Docker 不会将容器内初始文件“反向复制”到宿主机,导致配置缺失。
docker 容器启动时生成的默认配置文件(如 apache 的 httpd.conf、ssl 证书目录等)仅在镜像首次初始化时写入容器内部文件系统;当使用绑定挂载(bind mount)时,若宿主机对应路径为空或不存在,docker 不会将容器内初始文件“反向复制”到宿主机,导致配置缺失。
这是 Docker 绑定挂载(bind mount)机制的核心行为:挂载是单向覆盖,而非双向同步。当你声明 - /mnt/data/apps/apache:/etc/apache2,Docker 会直接将宿主机 /mnt/data/apps/apache 目录的内容作为 /etc/apache2 的内容加载进容器——无论该目录是否为空。如果宿主机路径为空,容器启动后看到的就是一个空的 /etc/apache2,原始镜像中预置的配置文件(如 mods-enabled/、sites-available/、apache2.conf 等)将被完全屏蔽,不会自动“回填”到宿主机。
✅ 正确做法是:先让容器无挂载运行一次,提取默认配置,再挂载使用。以你的 php:5.6-apache 镜像为例:
# 1. 启动临时容器(不挂载任何卷) docker run --name tmp-apache -d php:5.6-apache && sleep 3 # 2. 将容器内默认配置复制到宿主机(确保目标目录存在) mkdir -p /mnt/data/apps/html /mnt/data/apps/ssl /mnt/data/apps/apache docker cp tmp-apache:/var/www/html/. /mnt/data/apps/html/ docker cp tmp-apache:/etc/ssl/. /mnt/data/apps/ssl/ docker cp tmp-apache:/etc/apache2/. /mnt/data/apps/apache/ # 3. 清理临时容器 docker rm -f tmp-apache
⚠️ 注意事项:
docker cp必须在容器运行中执行(-d后建议加sleep或用docker wait确保服务就绪);- 复制时推荐用
/.(如/etc/apache2/.)而非/etc/apache2,避免嵌套一层父目录;- 若宿主机路径已存在旧配置,复制前请备份,避免覆盖关键修改;
- 对于 SSL 目录,首次运行后可能需手动补全证书/密钥(如
server.crt、server.key),Apache 默认不自动生成。
完成上述步骤后,你原有的 docker-compose.yml 即可正常工作:
services:
apache:
image: 'php:5.6-apache'
container_name: apache
restart: always
ports:
- '80:80'
- '443:443'
volumes:
- /mnt/data/apps/html:/var/www/html
- /mnt/data/apps/ssl:/etc/ssl
- /mnt/data/apps/apache:/etc/apache2
? 补充说明:此行为并非 Bug,而是 Docker 设计使然——绑定挂载优先级高于镜像层,保障用户对配置的完全控制权。若需自动化流程,可将上述 docker cp 步骤封装为初始化脚本,或改用命名卷(named volume)配合 COPY --from 构建阶段预填充(适用于自定义镜像场景)。对于生产环境,强烈建议将配置管理纳入 CI/CD 或配置中心,而非依赖运行时提取。











