nginx php image,[Docker]应该把 nginx 和 PHP 放在一个 image 里还是分开?

因为老板想搞 K8S,但是我连 Docker 都不懂,就觉得还是要学一点点 Docker 的,之前还是看了一点点的,甚至折腾过一个开发环境的方案,但是,很长时间不弄了以后,就全都还回去了。

这次我又想自己搭建一个基于 Docker 的开发环境,以前只是把 Docker 当成一个易于分发的开发环境来思考,所以,我记得以前费了很大的力气,做出了一个单一的 image,把 PHP + nginx + Redis + Memcahed 全部压到一个 image 里面了,然后用 Volume 映射代码,MySQL 连接本地网络公用的实例,形成一个开箱即用的开发环境。

这次,因为稍微看了点编排的概念,开始纠结,这些东西真的应该压到一个 image 里面么?为啥不是多个 docker image,然后,怎么想办法编排一下子?不是传说有个最优实践是一个 container 里面只放一个服务嘛?

第一个纠结的就是 nginx 和 PHP 到底应该放在一个 image 里面还是不同的 image 里面呢?

网上搜了一下,发现还是有不少文章讲 nginx 和 PHP 分开放无法访问的问题。看来,显然有人做过尝试了,而且遇到了问题。就看看他们遇到了什么问题。经过一番分析,我感觉我想明白了这个事情,到底应该放在一起,还是分开放。

分开或者合并的原理

其实,经常配置 nginx 和 PHP 的话,就会知道,这俩在原理上,分开和合并都是完全可能的。而且,从提供的接口层面,我们看不出来到底鼓励怎么做。

常见的配置方法是,使用 fastcgi 的方式来配合 nginx 和 PHP,我这两年的经验,用 debian 的 apt-get 安装的默认配置看,nginx 和 PHP 的连接方式,是用的 UNIX sock 文件,这种情况下显然是必须在一台机器上了。但是,显然,我们知道 fastcgi 是支持 TCP 协议的,就是大家很熟悉的 9000 端口,流行的配置文件都是 tcp://127.0.0.1:9000 这样的编写方式。这个本地 IP 地址,看起来也是部署在一台机器的。

不过呢,既然支持 TCP,就必然可以分布在不同的机器上面,原理上完全成立的。

网上流行的问题是什么?

那么那些把 nginx 和 PHP 放到不同 image 的同学遇到了什么问题呢?其实,是路径问题。

其实,我想,因为部署在一起的方式太过于流行了(可能的根本原因是互联网的绝大部分网站的规模很小,都在单台服务器上),以至于很多人没有注意过路径这个问题。

nginx 是一个服务器应用程序,每次要伺服的时候,都要从一个文件根目录出发,寻找需要伺服的文件路径。而 PHP 的 FPM 进程,也是一个服务器应用程序,它也有一个问题,就是需要从一个文件根目录出发,去寻找需要解释的文件路径。

因为最为流行的部署方式是放在一起的,往往也包含了静态文件和动态文件部署在一起的问题(前后端不分离是更为流行的做法),所以,用到的文件根目录,都是在一起的,所以,很显然,如果分开部署 nginx 和 PHP 的话,一定会遇到文件路径寻址的问题。

nginx 配置文件里,会用 root 变量指定一个 server 寻址的根目录,合并部署的时候,和 PHP 的根目录是一样的,用 document_root 变量(就是 root 的别名)传递给 fastcgi,但是,分开部署的时候,一个 server 的 root 变量,指的 nginx 所在的计算机的路径,但是 fastcgi 需要使用的 SCRIPT_FILENAME 参量,里面的路径,要用的是 PHP 所在的计算机的路径。既然是两台计算机,路径可以吻合,也可以不吻合,所以,分开部署的话,还能正确使用,是有一定概率的。你怎么知道 nginx 的 image 和 PHP 的 image 正好基于一个发型版?在 Docker 的世界下,两个 image 来自天南海北的两个人制作的可能性很高。

怎么解决路径问题?

要说怎么解决这个问题,其实,说到这里,知道了原理,就非常好解决,梳理好两个服务器程序应该使用的路径参数就好了。

document_root 这个变量,一般会继承 server 段落的 root 变量的配置,或者 http 段落的 root 的配置。如果这个 root 和 PHP 所在的机器,驴唇不对马嘴,那么可以猜测一定跑不起来。

解决方法是,把 PHP 所在机器的 root 在 location 段落里重新设定。或者,设置 SCRIPT_FILENAME 这个 fastcgi_param 的时候,用绝对路径直接写,不要用 $document_root$script_name 这种变量的写法。

然而,像我这么纠结的人,还是很不满意的,因为这种写法让我觉得恶心。为什么呢?因为耦合了。

nginx 在一台机器上,以服务的面貌提供自己的服务,而 PHP 在另一台机器上,也以服务的面貌提供自己的服务。但是,如果 nginx 的配置,必须知道 PHP 那台机器的文件路径,我想,这就是它知道了它理该不知道的事实,这就是耦合,这就是丑陋。

其实,nginx 作为一个服务,从客户端那里得到了 script_name,当然,它自己解释不了,也不拥有这个文件,所以,用 fastcgi 把 script_name 传递给 PHP 所在的服务就行了。这是最最必要的操作了。能不能不用搞清楚 PHP 所在的计算机的路径呢?当然可以,只要使用相对路径就行了。

那就需要 PHP 的 fastcgi 启动的时候,知道自己的根目录在什么地方,然后传过来相对路径,都可以自己找到正确的位置,从而解决了一个耦合。PHP 的 FPM 当然可以这么配置,只是因为一起部署的缺省配置太过流行,咱们从没注意过这个可能性而已。

到底应该放在一个 image 里还是分开?

答案是:视情况而定。(KAO!跟没说一样)

其实,PHP 的 FPM 是支持一个叫 pool 的特性的,我们可以在一个 pool 里面通过 chroot 和 chdir 之类的特性来把访问限制在一个特定的路径里,就是代码所在的根目录。

但是,那样的话,如果你一台机器上有多个网站的源代码,你就必须把根路径指向多个网站的共同根目录,不然的话,PHP 就只能伺服其中一个。

我们知道,世界上绝大多数网站的规模很小,所以,一台 Linux 可以同时支持很多网站的使用,所以,绝大多数缺省配置,FPM 只配置了一个 pool。这种情况下,nginx 传递相对路径的时候,必须加一个网站名的前缀。懂道理的话,会很简单啦,怎么都不会搞混。但是,显然增加了这套架构的学习成本,不是每个人都能很快搞那么明白的。

所以,详细回答一下“到底应该放一个 image 还是分开?”这个问题。

如果,你只是在本地,做一个给自己用的开发环境,我强烈建议放在一个 image 里面。一个程序员,往往会开发 N 多个网站的代码,放在一个里面,最省资源。配置也最为熟悉和简单,网上随手一搜,搜出来的配置很大概率可以部署成功。

如果,在线上环境,部署一个流量弹性范围很广,或者增长可能性很高的服务的时候,分开部署的优势比较大。因为,nginx 的性能是非常好的,远远好于 PHP。分开部署后,PHP 的 FPM 进程不够用了以后,可以不断扩容,增加 container 数量就行了。但是,这种方案的话,学习成本较高,需要程序员对这几个服务的配置有比较深的理解,就算自动扩容,执行动作感觉也不是单纯增加一个 container 就行的,毕竟一个 container 就有一个入口 IP,还要把扩容出来的入口 IP 告诉 nginx 所在的 container。

结论

其实吧,最流行的方案,恰恰是最正确的方案。比如,你可以直接下载到 LNMP 完备的 image,这种东西需求量最大,所以最流行。因为都是单个程序员用来解决自己开发环境的。就算拿去用在生产,问题也不大,小流量的服务和网站,才是这个世界的主流。不过想明白为什么是这个样子,就要花点心思。

相关阅读

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/533577.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python pep8模块_读懂PEP8,让你的Python代码更加优雅

PEP8《8 号 Python 增强规范》(Python Enhacement Proposal #8),简称PEP8通俗的来讲 PEP8 是针对 python 代码格式而编订的风格指南,令代码更加易读易懂。像谷歌这样的大公司是有自己内部的风格规范Google Style,目的就是为了提高开发效率。据…

python数值模拟教程_数值模拟必备random模块

该模块实现了各种分布的伪随机数生成器。可以在区间内抽取一个随机数,可以在列表中抽取一个元素,可以从分布中抽取样本 。random模块不能直接访问,需要导入 random 模块,然后通过 random 静态对象调用该方法。import random1 生成…

php版本哪个没有面向对象,php面向对象的方法重载两种版本比较

多个函数用同一个名字,但参数表,即参数的个数或(和)数据类型可以不同,调用的时候,虽然方法名字相同,但根据参数表可以自动调用对应的函数。PHP4 中仅仅实现了面向对象的部分的、简单的功能,而 PHP5 以后对对…

python实现录音小程序 界面_小程序如何实现录音 播放功能

第二步:编辑文件首先在src下创建一个test包并在test包下新建一个类MyRecord具体步骤代码如下所示:package test;import java.awt.*;import javax.swing.*;import java.awt.event.*;import java.io.*;import javax.sound.sampled.*;public class MyRecord…

织梦php网站修改教程,织梦DEDEcms织梦软件模型增加图集功能教程(含修改文件下载)...

这篇文章主要为大家详细介绍了织梦DEDEcms织梦软件模型增加图集功能教程(含修改文件下载),具有一定的参考价值,感兴趣的小伙伴们可以参考一下,有需要的朋友可以收藏方便以后借鉴。织梦DEDEcms织梦软件模型增加图集功能,这是今天361模板要给大家分享的。下…

python自动截图发送邮件_PhantomJS按尺寸截取页面,并用python发送邮件

前言:当前有个任务是要把几个网站的日志返回状态码进行汇总,用饼图展示,并每天发送邮件。一、分析问题画出饼图,这个我用kibana给画出来了,下面不做讲解;截取饼图,因为kibana是用js展示出来的&a…

nikita popov php,PHP中对performance的考虑点

Nikita Popov 在他的演讲中谈了几个PHP 程序中和performance相关的point。1.PHP使用shared memory, preload的方式事先分配,而只有在所有的处理结束之后,share memory 才会断开和所有进程或者thread之间的联系。光是opcode,FPM的设定还不足以…

python建模仿真 matlab_清华大学出版社-图书详情-《仿真建模与MATLAB实用教程》

MATLAB语言是目前世界上最为流行的科学计算语言之一,它的特点是能够快速地完成诸如矩阵运算、微分、寻优等计算任务。由于它配备了很多应用领域的专业工具箱,诸如金融、信号处理、图像处理、神经网络、嵌入式系统、仿真建模等,而且每个工具箱都包含了该应…

java web使用jquery,JAVA_Web_JQuery

简介:jquery 全称 javaScript Query.是js的一个框架。本质上仍然是js。特点:支持各种主流的浏览器、使用特别简单、拥有便捷的插件扩展机制和丰富的插件。一、JQuery内部封装原理介绍:匿名闭包。下面这两行代码是jquery包下的已经封装的代码&…

python语法学习_Python学习1——语法

Python语法包括了行、缩进、注释、标识符、保留关键字等方面。打印语句:>>> print(hello,world!)hello,world!输入语句:>>> input(请输入你的名字:)请输入你的名字:哈哈#”哈哈”是你自己输入的名字哈哈 #打印出…

java 两个页面传递数据,请问Cookie怎么在两个页面间传递数据?

参考代码如下://如果请求的Cookie对象为空if (Request.Cookies["userCookie"] null){//创建一个Cookie对象HttpCookie userCookie new HttpCookie("userCookie");//给对象赋值userCookie.Values["userName"] userInfo.UserName.ToS…

优化matlab作业,现代设计优化算法MATLAB实现

开篇语前阵子做现代设计方法的时候,发现网上很是缺乏这种作业形式的简易算法实现,所以特地来简书写一篇。有两份,一份是我的(说来惭愧,我的大部分都是在网上找的代码,然后在自己的电脑上跑一次,跑出来了就行…

怎样用python画玫瑰花的简笔画_玫瑰花简笔画素描作品图片

玫瑰原产是中国。在古时的汉语,“玫瑰”一词原意是指红色美玉。玫瑰花这么漂亮,素描怎么画得好看呢?你知道玫瑰花的简笔画素描是怎样的吗?今天先和学习啦小编一起欣赏这些玫瑰花简笔画素描图片,希望你会有所收获的。玫瑰花简笔画素描图片欣…

多因子选选股MATLAB代码,金工研报:利用卷积神经网络进行多因子选股

首先,我们先来看一下通过卷积神经网络选股模型的整体流程,然后再根据每一步流程进行介绍,具体如下图所示:1、数据获取用于历史回测数据来自所有A股股票,其中剔除了ST股以及上市3个月的股票,另外&#xff0c…

python list tuple 打包 解包_python的打包与解包

python的*与**,在函数的定义与调用过程中,有着不同的作用打包参数:一、函数定义时,形参前加*号(如:*args):收集实参中所有的位置参数,打包成新元组并将该元组赋值给args变量实参位置参数&#x…

python 成员函数 泛型函数_【一点资讯】白学这么多年 Python?连泛型函数都不会写? www.yidianzixun.com...

泛型,如果你尝过java,应该对他不陌生吧。但你可能不知道在 Python 中(3.4 ),也可以实现 简单的泛型函数。在Python中只能实现基于单个(第一个)参数的数据类型来选择具体的实现方式,官方名称 是single-dispatch。你或许听不懂&…

matlab bad apple,【bad apple】matlab制作矩阵苹果~

有屏幕的地方就有bad apple那么作为一名工科生,熟练的操♂作马桶萝卜(matlab)是一项基本技能下面开始讲解如何用matlab制作别具一格的“矩阵苹果”~实验环境matlab R2018a原版bad apple视频技术要求可以即时演算图形可以将处理后的每帧图形合并成新的视频先上代码%t…

服务器ip直接访问php怎么写,php - 如何实现用公网ip访问到服务器上的网页?

服务器系统是Windows Server 2012 R2,已经部署了IIS、PHP和MySQL,能够在云服务器上通过localhost打开php网页,(放在服务器wwwroot上的index.php)已在ISS管理器中添加网站,但编辑网站绑定时,在ip地址中填入了服务器的公…

vb6 打印选项对话框_图纸打印次数太多,不知道哪次才是最新的?用打印戳记区分效果好...

原创:就说我在开发区使用AutoCAD从事设计工作的朋友们不知道有没遇到过这种情况:图纸在反复修改打印的过程中,由于图纸内容高度相似,往往搞不清究竟哪个才是最新版本的图纸了。这种情况下,细致入微地去核对非常麻烦&am…

安卓文本编辑器php cpp,用安卓原生控件封装一个简易的富文本编辑器

最近接到项目需求:移动端原生写一个富文本编辑器。 ( ⊙ o ⊙ )从没遇到过富文本要用原生写的,然后就查阅各种资料。然后结合自己的思路:其实安卓的富文本编辑器就是一个 “容器”。那么接下来我就带给大家说一说我自定义这个富文本编…