未加星标

为多个PHP-FPM容器量身打造单一Nginx镜像虚拟化

字体大小 | |
[大数据技术 所属分类 大数据技术 | 发布者 店小二04 | 时间 | 作者 红领巾 ] 0人收藏点击收藏

为多个PHP-FPM容器量身打造单一Nginx镜像虚拟化
tm
为多个PHP-FPM容器量身打造单一Nginx镜像虚拟化
基础
为多个PHP-FPM容器量身打造单一Nginx镜像虚拟化
Hadoop
为多个PHP-FPM容器量身打造单一Nginx镜像虚拟化
开源
为多个PHP-FPM容器量身打造单一Nginx镜像虚拟化
Docker
为多个PHP-FPM容器量身打造单一Nginx镜像虚拟化
Nginx
最近我一直在努力部署一套使用Docker容器php微服务。其中一个问题是我们的PHP应用程序被设置为与PHP-FPM和Nginx一起工作(而不是这里所说的简单的Apache/PHP[1]设置),因此每个PHP微服务需要两个容器(也就是相当于两个Docker镜像):

PHP-FPM容器

Nginx容器


假设一个应用运行超过六个PHP微服务,算上你的dev和prod环境,那么最终差不多会产生接近30个容器。我决定构建一个单独的Nginx Docker镜像,将PHP-FPM主机名作为环境变量映射到这个镜像里面独特的配置文件中,而不是为每个PHP-FPM微服务的镜像构建独特的Nginx镜像。



为多个PHP-FPM容器量身打造单一Nginx镜像虚拟化

在这篇博客文章中,我将概述我从上述方法1到方法2的过程,最后用介绍如何使用新定制Nginx Docker镜像的解决方案来结束这篇博客。


我已经将这个镜像开源GitHub[2],所以如果这刚好是您经常遇到的问题,请随时查看。

为什么是Nginx?

PHP-FPM和Nginx一起使用可以产生更好的PHP应用程序性能[3],但缺点是PHP-FPM Docker镜像默认没有像PHP Apache镜像那样与Nginx捆绑在一起。

如果您想将Nginx容器连接到PHP-FPM后端,则需要将该后端的DNS记录添加到您的Nginx配置中。


例如,如果PHP-FPM容器作为名为php-fpm-api的容器运行,那么您的Nginx配置文件应该这样写:


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;

}


如果你只服务一个PHP-FPM容器应用,在你的Nginx容器的配置文件中硬编码对应的名字是可以的。但是,如我上面提到的,每个PHP服务都需要一个对应的Nginx容器,我们就需要运行多个Nginx容器。创建一个新的Nginx镜像(我们后面必须维护和升级)将是一件痛苦的事情,因为即使管理一堆不同的卷,对于更改单个变量名称似乎也有很多工作要做。


第一个解决方案:使用Docker文档里提到的方法envsubst

起初,我认为这很容易。在Docker文档中关于如何使用envsubst有一个很好的小章节[4],但不幸的是,这不适用于我的Nginx配置文件:

vhost.conf

nginx

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;

}

}


我的vhost.conf文件用到了好几个Nginx内置的环境变量,结果当我运行Docker文档里提到的如下命令行时,提示错误:$uri和fastcgi_script_name未定义。


shell

/bin/bash -c "envsubst < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"


这些变量通常由Nginx本身传入[5],所以不容易搞清楚他们是什么和怎么进行参数传递的,而且这会影响容器的动态可配置性。

另一个差点成功的Docker镜像

接下来,我开始搜索不同的Nginx的基础镜像。找到了两个,但是这两个都是两年没有更新了。我从martin/nginx[6]开始,尝试看看能不能得到一个可以工作的原型。

Martin的镜像有点不太一样,因为它要求特定的文件目录结构。我先在Dockerfile中添加了:


FROM martin/nginx


接下来,我添加了app/空目录,只包含一个vhost.conf文件的conf/目录。


vhost.conf

nginx

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;。现在当我想要启动一个Nginx容器和一个叫php-fpm-api的PHP容器的时候,我可以先编译一个新的镜像,然后在它运行的时候传递给它对应的环境变量:


shell

docker build -t shiphp/nginx-env:test .

docker run -it --rm -e NGINX_HOST=php-fpm-api shiphp/nginx-env:test


成功了!但是,这个方法有两个问题困扰着我:


基础镜像版本陈旧,两年多没更新了。这可能会造成安全和性能风险。

要求一个app的空目录似乎没啥必要,再加上我的文件放在不同的目录。


最终解决方案

我觉得Martin的镜像是个不错的自定义方案选择。所以,我fork了他的仓库并构建了一个新的并解决了以上两个问题的Nginx基础镜像。现在,如果你想运行一个伴随着nginx容器的动态命名后端应用,你只需要简单地这么做:


shell

# Pull down the latest from Docker Hub

docker pull shiphp/nginx-env:latest

# Run a PHP container named "php-fpm-api"

docker run --name php-fpm-api -v $(pwd):/var/www php:fpm

# Start this NGinx container linked to the PHP-FPM container

docker run --link php-fpm-api -e NGINX_HOST=php-fpm-api shiphp/nginx-env


如果你想自定义这个镜像,添加你自己的文件或者Nginx配置文件,只需要像下面这样扩展你的Dockerfile:


FROM shiphp/nginx-env

ONBUILD ADD <PATH_TO_YOUR_CONFIGS> /etc/nginx/conf.d/


现在我所有的PHP-FPM容器都使用单个Nginx镜像的实例,当我需要升级Nginx、修改权限或者配置一些东西的时候,这让我的生活变得简单多了。


所有的代码都放在GitHub[2]上面了。如果您发现任何问题或想要提出改进建议,请随时创建issue。如果您对这个问题或Docker相关的任何问题,可以在Twitter[7]上找我一起讨论。

相关链接:

https://www.shiphp.com/blog/2017/php-web-app-in-docker

https://github.com/shiphp/nginx-env

https://blog.a2o.si/2009/06/24/apache-mod_php-compared-to-nginx-php-fpm/

https://docs.docker.com/samples/library/nginx/#using-environment-variables-in-nginx-configuration

http://nginx.org/en/docs/varindex.html

https://hub.docker.com/r/martin/nginx/

https://twitter.com/shiphpnow


原文链接:https://www.shiphp.com/blog/2018/nginx-php-fpm-with-env


欢迎加入本站公开兴趣群

软件开发技术群

兴趣范围包括:Java,C/C++,python,PHP,Ruby,shell等各种语言开发经验交流,各种框架使用,外包项目机会,学习、培训、跳槽等交流

QQ群:204132433


Hadoop源代码研究群

兴趣范围包括:Hadoop源代码解读,改进,优化,分布式系统场景定制,与Hadoop有关的各种开源项目,总之就是玩转Hadoop

QQ群:204050420

主题: NginxPHPDocker虚拟化Hadoop微服务开源GitHubGitJava
tags: #160,Nginx,php,fastcgi,PHP,nginx,镜像,index,FPM,Docker,容器,fpm,api,shiphp,conf
分页:12
转载请注明
本文标题:为多个PHP-FPM容器量身打造单一Nginx镜像虚拟化
本站链接:https://www.codesec.net/view/577319.html


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 大数据技术 | 评论(0) | 阅读(176)