Docker中PHP镜像含全部源码,Nginx容器无法访问该如何处理?
问题描述
我通过Dockerfile创建PHP镜像时,用COPY ./ /app把本地源码复制到了镜像的/app目录,所有项目内容都存储在PHP容器里。之后我启动了第二个Nginx容器,使用如下配置:
location / { root /app/public; try_files $uri /index.php$is_args$args; } location ~ ^/index\.php(/|$) { client_max_body_size 50m; fastcgi_pass php:9000; }
但配置不生效,Nginx无法访问PHP容器内的文件。想确认:所有文件都存在PHP容器里的情况下,能不能正常运行Nginx?
解答
可以运行,但当前配置存在核心问题,无法高效处理静态资源,需要调整架构:
- 问题根源
Nginx的root /app/public;指令是让Nginx从自身容器的/app/public目录读取静态文件,但你的代码仅存在于PHP容器中,Nginx容器内没有这个目录,会导致:
- 静态资源(如CSS、JS、图片)直接返回404
try_files会错误地把所有静态资源请求转发到PHP容器处理,虽然PHP可能能返回文件,但完全浪费了Nginx处理静态资源的性能优势
- 可行解决方案
要让Nginx正常工作,必须让它能访问到项目的静态文件,推荐以下两种方式:
方式一:用Docker卷共享代码目录(最常用)
将本地代码目录同时挂载到PHP容器和Nginx容器,让两个容器都能访问/app目录下的文件:- 启动PHP容器:
docker run -v /本地代码路径:/app --name php 你的PHP镜像名 - 启动Nginx容器:
docker run -v /本地代码路径:/app --link php:php -p 80:80 你的Nginx镜像名
如果用Docker Compose管理,配置更清晰:
version: '3' services: php: build: ./php # 指向你的PHP Dockerfile所在目录 volumes: - ./code:/app # 本地code目录挂载到容器/app nginx: build: ./nginx # 指向你的Nginx Dockerfile所在目录 volumes: - ./code:/app ports: - "80:80" depends_on: - php这种方式下,Nginx直接返回静态文件,PHP请求转发到PHP容器处理,是最合理的架构。
- 启动PHP容器:
方式二:把代码同时复制到Nginx镜像(不推荐)
修改Nginx的Dockerfile,用COPY ./ /app把代码复制到Nginx镜像中。但这种方式会导致代码重复存储在两个镜像里,镜像体积变大,后续更新代码需要重新构建两个镜像,维护成本高,不建议使用。
- 总结
仅把代码放在PHP容器里,Nginx无法正常高效处理静态资源,必须让Nginx容器能访问到项目文件,最推荐的做法是用Docker卷共享代码目录。
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

