Docker化Laravel应用为何需两次复制源码?
为什么Docker中要同时给PHP和Nginx容器挂载同一份源码?
先澄清:这不是“复制”,是绑定挂载
你看到的- ./:/var/www是Docker的绑定挂载,根本不是把源码复制到容器里——它相当于给容器开了个“直通窗口”,让容器可以直接访问宿主机上的当前目录文件。两个容器共享的是宿主机上的同一份源码,只是各自在容器内把这个目录映射到了/var/www路径,不会占用双倍存储空间。
为什么要给两个容器都挂载?
两个容器的分工不同,都得接触源码,但用途不一样:
- Nginx容器:一方面要直接返回静态资源(比如样式表、JS、图片、静态页面),这些文件都在源码目录里,必须挂载进来才能读取;另一方面处理
.php请求时,得告诉PHP容器文件在容器内的路径,所以自己得先能定位到这个路径。 - PHP容器:里面运行的是PHP-FPM服务,它要读取
.php文件执行代码、生成动态内容,自然也得能访问到源码目录。
Nginx和PHP容器怎么配合干活?
因为在同一个docker-compose服务里,它们默认处于同一个Docker桥接网络,能直接互相通信,具体流程是:
- 客户端发送HTTP请求到Nginx的对外端口(比如80端口)。
- Nginx根据请求路径判断:
- 如果是静态资源,直接从挂载的
/var/www目录读取文件返回给客户端。 - 如果是
.php文件,就通过FastCGI协议把请求转发到PHP容器的9000端口(PHP-FPM默认监听端口),同时把文件在容器内的路径(比如/var/www/index.php)传递给PHP。
- 如果是静态资源,直接从挂载的
- PHP-FPM从自己容器的
/var/www路径找到对应的.php文件,执行代码生成内容后,把结果回传给Nginx。 - Nginx把这个动态内容转发给客户端。
这里必须让两个容器的挂载路径一致(都是/var/www),不然Nginx告诉PHP的文件路径,PHP在自己容器里找不到,就会抛出“文件不存在”的错误。
和传统服务器有啥不一样?
- 传统服务器上,Nginx和PHP-FPM都安装在同一个操作系统里,共享本地文件系统,所以只需要一份源码,两者都能直接访问。
- Docker是按单一职责拆分服务:Nginx只管代理和静态资源分发,PHP只管代码执行。这么做的好处很实在:
- 单独升级方便,比如要换PHP版本,直接替换PHP容器的镜像就行,不用改动Nginx。
- 单独扩容简单,PHP服务压力大时,直接多启动几个PHP容器,Nginx就能自动完成负载均衡。
- 环境完全隔离,PHP可以用轻量的Alpine系统,Nginx用Debian系统,互相不影响,也不会因乱装依赖搞坏运行环境。
内容的提问来源于stack exchange,提问作者vpu65529
相关产品推荐
相关产品推荐

