为所有PHP-FPM容器构建单独的NGinx Dock镜像
最近,原文作者一直在使用Docker容器来开发PHP微服务套件。一个问题是PHP应用已经搭建,可以和PHP-FPM和Nginx(取代了简单的Apche/PHP环境)一起工作,因此每个PHP微服务需要两个容器(以及两个Docker镜像):一个PHP-FPM容器和一个NGinx容器。
\\
这个应用运行了6个以上的服务,如果做个乘法,在开发和生产之间会有约30个容器。作者决定构建一个单独的NGinx Docker镜像,它可以使用PHP-FPM的主机名作为环境变量并运行单独的配置文件,而没有为每个容器构建单独的NGinx镜像。
\\
\在本文中,原文作者简要说明从上图中的方法1到方法2的转换,最后采用的方案中采用了一种新的定制Docker镜像。该镜像的代码是开源的,如果读者碰到类似问题,可以随时签出该部分代码。
\\
为什么用 NGinx?
\\
NGinx和PHP-FPM配合使用能使PHP应用的性能更好,但不好的是和PHP Apache镜像不同,PHP-FPM Docker镜像缺省并没有和NGinx进行绑定。如果需要通过NGinx容器和PHP-FPM连接,需要在NGind配置里为该后端增加DNS记录。比如,如果名为php-fpm-api的PHP-FPM容器正在运行,NGinx配置文件应该包含下面部分:
\\
\location ~ \\.php$ {\ fastcgi_split_path_info ^(.+\\.php)(/.+)$;\ # This line passes requests through to the PHP-FPM container\ fastcgi_pass php-fpm-api:9000;\ fastcgi_index index.php;\ include fastcgi_params;\ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\ fastcgi_param PATH_INFO $fastcgi_path_info;\ }
\\
如果只服务于单独的NGinx容器,NGinx配置中容器名字写死还可以接受,但如上所述,需要允许多个NGinx容器,每个对应于一个PHP服务。创建一个新的NGinx镜像(以后需要进行维护和升级)会有些痛苦,即使管理一批不同的数据卷,仅仅改变变量名看起来也有很多工作。
\\
第一种方案: 使用Docker文档中的方法
\\
最初,作者认为这会很简单。Docker文档中有少许的几个章节讨论如何使用envsubst来完成该工作,但不幸的是,在其NGinx配置文件中,这种方法不奏效。
vhosts.conf
\\
\server {\ listen 80;\ index index.php index.html;\ root /var/www/public;\ client_max_body_size 32M;\ location / {\ try_files $uri /index.php?$args;\ }\ location ~ \\.php$ {\ fastcgi_split_path_info ^(.+\\.php)(/.+)$;\ fastcgi_pass ${NGINX_HOST}:9000;\ fastcgi_index index.php;\ include fastcgi_params;\ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\ fastcgi_param PATH_INFO $fastcgi_path_info;\ }\}
\\
该vhosts.conf
文件使用了NGinx内置变量,因此当依照文档运行Docker命令(/bin/bash -c \"envsubst \u0026lt; /etc/nginx/conf.d/mysite.template \u0026gt; /etc/nginx/conf.d/default.conf \u0026amp;\u0026amp; nginx -g 'daemon off;'\"
)时,得到错误提示$uri
和$fastcgi_script_name
没有定义。这些变量通常通过NGinx传入,因此不能简单的识别出它们是什么并传给自身,而且这使容器的动态性变差。
\\
用另一个Docker镜像来救急,差点成功
\\
接下来,作者开始研究不同的NGinx镜像。找到的两个,但它们都在随后的几年中都没有任何更新。作者开始使用martin/nginx,试图找到可以工作的原型。
Dockerfile:
\Martin镜像和其它镜像有点不一样,因为它要求特定的文件夹结构。在root下增加
\\
\\
FROM martin/nginx
\\
接下来,我添加了一个
app/空目录和conf/
目录,conf/
目录下只有一个文件vhosts.conf
:
\\
\\
server {\ listen 80;\ index index.php index.html;\ root /var/www/public;\ client_max_body_size 32M;\ location / {\ try_files $uri /index.php?$args;\ }\ location ~ \\.php$ {\ fastcgi_split_path_info ^(.+\\.php)(/.+)$;\ fastcgi_pass $ENV{\"NGINX_HOST\"}:9000;\ fastcgi_index index.php;\ include fastcgi_params;\ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\ fastcgi_param PATH_INFO $fastcgi_path_info;\ }\}
\\
这个文件和之前的配置文件几乎一样,除了有一行的改动:
\\
fastcgi_pass $ENV{\"NGINX_HOST\"}:9000;
。现在想要启动带命名为php-fpm-api的PHP容器的NGinx容器,就可以构建一个新的镜像,让它在以下环境变量下运行:
\\
\\
docker build -t shiphp/nginx-env:test .\docker run -it --rm -e NGINX_HOST=php-fpm-api shiphp/nginx-env:test
\\
它可以正常工作了。但是,这种方法有两个困扰的地方:
\\
正在使用的基础镜像已经有两年了。这会引入安全和性能风险。
\\t有个空的
/app目录看起来并不必需,因为文件会被存储在一个不同的目录中。\
最终解决方案
\\
作者认为作为定制解决方案,从Martin镜像开始比较好,因此给项目建了分叉,创建了新的NGinx基础镜像并修复了上述两个问题。现在,如果要在NGinx容器中允许动态命名的后端,可以参照:
\\
\\
# 从Docker Hub得到最新版本\docker pull shiphp/nginx-env:latest\# 运行名为\"php-fpm-api\"的PHP容器 \docker run --name php-fpm-api -v $(pwd):/var/www php:fpm\# 允许链接到PHP-FPM容器的NGinx容器\docker run --link php-fpm-api -e NGINX_HOST=php-fpm-api shiphp/nginx-env
\\
如果想增加自己的文件或NGinx配置文件,来定制镜像,用
Dockerfile来扩展它就可以:
\\
\\
FROM shiphp/nginx-env\ONBUILD ADD \u0026lt;PATH_TO_YOUR_CONFIGS\u0026gt; /etc/nginx/conf.d/\...
\\
现在所有的PHP-FPM容器都使用了它们自己的Docker镜像实例,这样在升级NGinx,改变权限或做某些调整时,就变得非常轻松了。
\\
所有的代码都在Github上,如果读者看到任何问题或有改进建议,可以直接创建一个问题单。如果有疑问或任何Docker相关的,可以在Twitter上找到我继续探讨。
\\
查看英文原文: https://www.shiphp.com/blog/2018/nginx-php-fpm-with-env
\\
感谢张婵对本文的审校。
为所有PHP-FPM容器构建单独的NGinx Dock镜像相关推荐
- Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境
在编辑Dockerfile过程中参考了以下相关范例:https://hub.docker.com/_/php/.https://hub.docker.com/_/mysql/.https://hub. ...
- docker容器构建_我如何容器化构建系统
docker容器构建 构建系统由用于从源代码过渡到正在运行的应用程序的工具和过程组成. 这种过渡还涉及将代码的读者从软件开发人员更改为最终用户,无论最终用户是运营方面的同事还是部署系统的同事. 在使用 ...
- 【Jenkins】Jenkins容器构建脚本以及容器瘦身docker-slim使用
说明 当前为构建的脚本,部署脚本后面有时间再编写然后发出来,然后里面包含容器瘦身工具 docker-slim 的配置,具体的部署使用方式后面再单独写,话不多说,直接上代码(我的风格喜欢直接上代码) d ...
- Docker/Podman使用入门---从容器构建镜像 提交镜像到服务器UCloud dockerhub
文章目录 1.docker commit 提交镜像命令 2.将镜像提交到UCloud服务器 step1: 先在UCloud服务器上面,创建镜像仓库 step2: 登录UCloud镜像仓库 step3: ...
- 使用 IBM Bluemix 容器构建 Django 环境
使用 IBM Bluemix 容器构建 Django 环境 创建用户 首先需要在 IBM Bluemix 上创建一个用户 创建成功用户,就可以访问 IBM Bluemix 的仪表板了 https:// ...
- 中国人寿张青南:中国人寿如何基于容器构建PaaS平台
口述/作者: 张青南 中国人寿研发中心高级架构师 编辑: Rancher Labs 中国人寿研发中心高级架构师 张青南 从2017年起,中国人寿正式开始利用容器技术搭建PaaS平台"稻客云& ...
- 【ORACLE】从安装ORACLE LINUX 8开始构建一个ORACLE21C的docker镜像
前言 最近有不少ORACLE21C的特性想测试,但是它有些特性是基于ORACLE LINUX操作系统的,网上没搜到现成docker或者虚拟机镜像,而且oracle cloud免费的21c体验不对中国区 ...
- 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
一个用于构建和推送Docker镜像的Maven插件. 使用Maven插件构建Docker镜像,将Docker镜像push到DockerHub上,或者私有仓库,上一篇文章是手写Dockerfile,这篇 ...
- Vue项目构建后通过Nginx/SpringBoot/Express/Egg发布
Vue项目构建后通过Nginx/SpringBoot/Express/Egg发布 构建 当项目开发完毕,只需要运行一行命令就可以打包你的应用: $ yarn build or $ npm run bu ...
最新文章
- 结队-结队编程项目贪吃蛇-项目进度
- 一些大佬博客里的个签
- win10多合一原版系统_win10多合一系统下载_win10多合一系统下载地址-系统城
- python http服务器_超简单的Python HTTP服务
- JavaScript实现截留雨水问题的蛮力方法的算法(附完整源码)
- 【已解决】TypeError: ‘<‘ not supported between instances of ‘str‘ and ‘int‘_Python系列学习笔记
- picker封装 uniapp_uniapp自定义picker城市多级联动组件
- android字符串加删除线,android TextView 设置和取消删除线的两种方法
- Halcon 学习总结——错误处理方法
- 对比MySQL,一文看透HBase的能力及使用场景
- Cocoapods的安装及使用
- uniapp使用高德地图
- Java制作银行管理系统_java代码实现银行管理系统
- Java过滤字符串中的手机号+提取字符串中的手机号+验证是否存在手机号
- vue3.0 透传 Attribute
- 微信小程序进度条组件自定义数字_微信小程序之圆形进度条(自定义组件)
- 跟你聊聊员工的离职成本,细算下来超级恐怖!
- blob 在线解码_量子算命,在线掷筊:一个IBM量子云计算机的应用实践,代码都有了...
- Python异步 asyncio 异步文件下载
- 对于load方法的理解