docker-compose nginx.conf以volume形式映射到容器内部,外部修改容器内未更新?

问题

env

  • docker-compose + volume

Docker 使用中非常经典的问题,主要原因通常与 文件系统的 Inode(索引节点) 变化或 Nginx 未重新加载配置有关。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
services:
ngx:
image: xxx/public/tengine:3.1.0
container_name: ngx
restart: always
ports:
- "80:80"
volumes:
- ./logs:/var/log/nginx
- ./nginx.conf:/etc/nginx/nginx.conf ## 问题点
#- ./conf.d/:/etc/nginx/conf.d/

networks:
- apps

networks:
apps:
external: true

修改本地nginx.conf,容器里面nginx.conf未发生变化?

分析解决

1. 为什么内容没有同步?(核心原因)

当你使用 volumes: - ./nginx.conf:/etc/nginx/nginx.conf 挂载单个文件时,Docker绑定的是该文件在硬盘上的 Inode ID

  • 问题所在: 很多编辑器(如 Vim, Notepad++, 或某些 IDE)在保存文件时,并不是直接修改原文件,而是先创建一个临时文件,完成后再进行替换。这会导致主机的 nginx.conf Inode ID 发生了改变
  • 后果: Docker 容器仍然盯着旧的 Inode,因此容器内部的文件内容停留在修改前,不会发生变化。

2.解决办法

  • 最稳妥的做法: 挂载目录而不是单个文件。
1
2
3
volumes:
# 这样修改文件夹里的任何文件,Inode 变化都不会影响同步
- ./conf.d/:/etc/nginx/conf.d/ # 挂载目录
  • 临时生效: 重启容器可以强制重新绑定。
1
docker-compose restart tengine