laradock 环境下,PHP 该如何实现本地域名通信啊?
知识背景:
- windows 下使用 laradock 作为开发环境
- 使用 phpstrom IDE,并且通过 ssh 的方式连接 workspace 来实现了单元测试
- 有两个本地域名 a.test 、b.test,在宿主机均可访问(大前提)
- 但是但是但是,在项目中却无法使用 curl 来相互访问,着实令人抓狂
- 为了探索答案,梳理知识的过程,顿悟了以下知识,希望对你们也有所帮助
阅读收获:
- 梳理 laradock 环境下, php-fpm、cgi 模式运行时各容器之间的关系
- 解决本地域名间无法通信问题
- 查看 laradock 容器的IP
梳理两种模式
1、PHP-FPM模式
- 宿主机访问 a.test
- 由于宿主机做了映射
127.0.0.1 a.test
,请求实际访问的是宿主机的 80 端口 - laradock 环境下,因 nginx 容器的 80 端口映射到宿主机的 80 端口,那实际提供 web 服务的是 nginx 容器中监听了 80 端口的 nginx
- 进入 nginx 容器查看 a.test 站点的 nginx 配置,要点配置有 站点域名,目录,主页,以及 fastcgi pass 指定的 php-upstream 处理程序(此时很懵逼,究竟是什么程序处理了代码?)
- 查看 nginx 容器的 Dockerfile 文件,看到如下代码
RUN echo "upstream php-upstream { server ${PHP_UPSTREAM_CONTAINER}:${PHP_UPSTREAM_PORT}; }" > /etc/nginx/conf.d/upstream.conf \ && rm /etc/nginx/conf.d/default.conf
- nginx 容器中执行
cat /etc/nginx/conf.d/upstream.conf
得到upstream php-upstream {server php-fpm:9000;}
,这不就是使用 php-fpm 容器来的提供解析嘛(新的问题又来了,那 php-fpm 又是哪里来的?) - 最后发现,在 laradock 的 docker-compose.yml 中,其 nginx 服务配置项中指定了依赖配置 depends_on,其值包含 php-fpm
- 也就是说,nginx 通过来访域名,找到代码文件,然后递交给 php-fpm 处理并拿到返回值,最后响应给在宿主机中访问了 80 端口的应用,一般是浏览器、post man 等应用
2、CGI 模式
- 宿主机在 a.test 站点的映射代码中执行单元测试代码
- 我配置的解析器是使用 ssh 方式连接 workspace 的,并且做好了目录映射
- 也就是说运行测试代码就相当于在 workspace 当中执行单元测试 ,即直接使用 workspace 容器中的 php 来解析代码并返回结果
实现通信:
- 上述的 CGI 模式下:直接在 a.test 项目中使用 curl 访问 b.test 项目的接口,会收到无法解析 b.test 域名的报错。这是因为程序是在 workspace 容器中运行的。我们必须让 workspace 容器知道 b.test 对应的IP。我们知道 b.test 在 nginx 容器中,所以可以在 workspace 容器中执行
ping nginx
来获取 nginx 容器的 IP,然后修改 workspace容器 的/etc/hotst
文件实现 b.test 域名到 IP 的映射即可 - 上述的 PHP-FPM 模式下:如果在 a.test 项目中使用 curl 访问 b.test 项目接口,解决方案同上,不过有点小坑。 要搞明白,nginx 容器只负责转发而已,且由配置 fastcgi pass 可知实际处理代码的是 php-fpm 容器,所以,我们需要去到 php-fpm 容器中添加映射而不是 nginx 容器(希望读者不要学我也在这里卡了好久,555)。同理,我们需要执行
ping nginx
来获取 nginx 容器的 IP,然后修改 php-fpm 容器 的/etc/hotst
文件实现 b.test 域名到 IP 的映射即可
温情提示:
- php-fpm、nginx 等容器中可能无法执行
ping nginx
,这时我们可以去功能相对较全面 workspace 容器中执行。由于它们都被绑定到一个名叫 backend 的网络下,所以该命令得到的结果基本是相同的