聊聊 PHP 容器应用的最佳实践

2022-08-16 09:48:11 +08:00
 dzdh
最近公司正在推进容器化建设,主要是扩容方便。
然后有几个问题,问一下。

项目是 laravel 。那么附带的还有他的 queue 和 cron artisan schedule:run 。

是都放在一个容器里吗?弄个 supervisor 启动 nginx 、fpm 、cron -f 、和 queue:work ?

总觉得哪里不对,有啥最佳实践推荐一下吗?
3425 次点击
所在节点    问与答
38 条回复
XiLingHost
2022-08-16 12:29:30 +08:00
@shoaly 这就是一个基于 docker 的 php laravel 项目
gesse
2022-08-16 13:43:27 +08:00
容器里应该少用 supervisor ,用 s6 多
iyaozhen
2022-08-16 13:46:30 +08:00
容器里面不要用 supervisor ,挂了就让容器自己重启

nginx 可以放进去,但应该轻量点,只是本地和 php 配合,把更多的功能做到网关层

cron 啥的单独建集群和接受 http 请求的分开
superchijinpeng
2022-08-16 13:47:06 +08:00
拆到多个容器中
superchijinpeng
2022-08-16 13:47:25 +08:00
富容器没有意义
toomoy
2022-08-16 14:21:03 +08:00
https://github.com/imbossa/docker_dev
这个就包含 supervisor
luyaolu
2022-08-16 16:22:08 +08:00
我现在的就是一个 docker 中 大半年了 没啥问题
shuimugan
2022-08-16 16:30:04 +08:00
@dzdh nginx unit 说白了就是更容易编程化的 nginx ,你也可以把 json 写到文件,然后给 post json 文件的 curl 命令做个 alias ,就能达到修改配置文件 + nginx -s reload 的效果
dzdh
2022-08-16 17:08:41 +08:00
@shuimugan #28 那我的配置一辈子不变就不能直接读取个文件吗? docker file 也好写啊

CMD ["unitd","-c","/etc/service.json"] 他不香吗。。。。
dzdh
2022-08-16 17:08:57 +08:00
@shuimugan 我在容器里为啥要 reload 啊
xiaochong0302
2022-08-16 20:41:53 +08:00
酷瓜云课堂的实践: https://gitee.com/koogua/course-tencent-cloud-docker

php + cron + workerman (supervisor)
nginx
mysql
redis
xunsearch
wangningkai
2022-08-16 23:15:34 +08:00
GitHub 搜 dnmp ,用 docker- compose 编排
shuimugan
2022-08-17 05:55:53 +08:00
@dzdh 我觉得主要看你们是否把调整配置当成一次发版(更新容器)进行操作,如果不会线上 reload 那的确可以直接单个文件一把梭。

reload 用于一般用于蓝绿部署,nginx unit 的条件路由可以很好的控制流量,比如通过特定 header 字段和值进行流量切换,比如把测试账号引流到特定节点。

另外不建议把 nginx 和 php-fpm 分开部署,因为 php 的 curl 功能过于强大,如果代码逻辑不严谨或者缺乏安全团队测试,不恰当使用 curl 的话,会被和 gopher 组合构造出任意代码给 php-fpm 执行(相当于后门)。
julyclyde
2022-08-17 12:14:14 +08:00
在容器内就没必要 supervisord 或者 systemd 了

该出错的时候能正确的出错,是一种较佳实践
julyclyde
2022-08-17 12:16:17 +08:00
@shuimugan 换个说法就是,把容器当作短期的“运行”还是当作长期的“机器”
如果是后者,各种操作产生的结果会累积起来形成状态,这个状态不一定是期望的
gaoxu387
2023-09-18 17:36:26 +08:00
@reter 很赞同你的观点,容器的 12 要素的也提到了一个关键的点,一个进程: https://12factor.net/zh_cn/processes
而 supervisor 的模式是违反了这种理念,虽然也可以用但不是最佳的方法。

对于 PHP 的容器化特别是 Laravel 的容器化的个人建议:
1 、打包成一个镜像
2 、nginx 运行 pod 、php-fpm 运行一个 pod 、laravel 的 schedule:run 运行一个 cron 的镜像

业务流量是 Ingress (不配置规则)-> service -> nginx (具体规则) -> php-fpm (中间件不要部署在 k8s 里)
cron 单独运行一个常驻的 pod ,启动 crond ,并配置一分钟运行一次 schedule:run
dzdh
2023-09-18 18:30:24 +08:00
@gaoxu387 nginx 运行 pod 、php-fpm 运行一个 pod 代码在放在哪里。

nginx 有个 try_files , 必须要能访问到.php 文件。

php-fpm fcgi 协议是 nginx 传递过来的 filepath 。

那么程序代码放在哪里?
gaoxu387
2023-09-19 15:42:25 +08:00
@dzdh 代码运行在 php-fpm 这个 pod 里啊,nginx 通过服务名称转发 proxy_pass 到 php-fpm 的容器. nginx 一般用这个配置转发:
location ~ \.php$ {
fastcgi_pass php-fpm:9000;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
如果你需要用 try_files 那你把代码也打包一份在 nginx 的 pod 也是可以的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/873113

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX