如何为多个PHP-FPM容器构建单一的Nginx Docker镜像教程-linux运维教程

  • 为什么用 Nginx?
  • 第一种方案: 使用 Docker 文档中的方法
  • 使用另一个 Docker 镜像,差点成功
  • 最终解决方案

在使用 Docker 容器来开发 PHP 微服务套件的过程中,作者遇到了容器数量过多的问题。

最近,我一直在使用 Docker 容器来开发 PHP 微服务套件。一个问题是 PHP 应用已经搭建,可以与 PHP-FPM 还有 Nginx(取代了简单的 Apche/PHP 环境)一起工作,因此每个 PHP 微服务需要两个容器(以及两个 Docker 镜像):一个 PHP-FPM 容器和一个 Nginx 容器。
这个应用运行了 6 个以上的服务,做个乘法就知道,在开发和生产之间会有约 30 个容器。于是我决定构建一个单独的 Nginx Docker 镜像,它可以使用 PHP-FPM 的主机名作为环境变量并运行单独的配置文件,而不用为每个容器构建单独的 Nginx 镜像。

如何为多个PHP-FPM容器构建单一的Nginx Docker镜像教程-linux运维教程

在本文中,我介绍了自己从上图中的方法 1 到方法 2 的转换,最后采用的方案中采用了一种新的定制 Docker 镜像。该镜像的代码是开源的,如果读者碰到类似问题,可以提供给大家参考。

为什么用 Nginx?

Nginx 和 PHP-FPM 配合使用能使 PHP 应用的性能更好,但不好的地方在于,和 PHP Apache 镜像不同,PHP-FPM Docker 镜像默认不是和和 Nginx 绑定在一起的。如果需要通过 Nginx 容器和 PHP-FPM 连接,需要在 Nginx 配置里为该后端增加 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 < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g ‘daemon off;’”) 时,得到错误提示$uri和$fastcgi_script_name没有定义。这些变量通常通过 Nginx 传入,因此不能简单的识别出他们是什么并传给自身,而且这样会影响容器的动态配置。

使用另一个 Docker 镜像,差点成功

接下来,我开始研究不同的 Nginx 镜像。找到的有两个,但它们都在随后的几年中都没有任何更新。我开始使用 martin/nginx,试图找到可以工作的原型。

Martin 的镜像和其它镜像有点不一样,因为它要求特定的文件夹结构。在 root 下增加Dockerfile:

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

它可以正常工作了。但是,这种方法有两个困扰的地方:
正在使用的基础镜像已经有两年了。这会引入安全和性能风险。
有个空的/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 <PATH_TO_YOUR_CONFIGS> /etc/nginx/conf.d/
...

现在所有的 PHP-FPM 容器都能使用单个Docker镜像中自己的实例,这样在升级 Nginx,改变权限或做某些调整时,就变得非常轻松了。

所有的代码都在 Github 上,如果你看到任何问题或有改进建议,可以直接创建 issue。

GitHub 项目链接:https://github.com/shiphp/nginx-env

主题测试文章,只做测试使用。发布者:云大使,转转请注明出处:https://www.xp8.net/server/1003.html

(0)
打赏 微信扫一扫 微信扫一扫
云大使的头像云大使
上一篇 2018年10月16日 下午9:19
下一篇 2018年10月16日 下午9:19

相关推荐

  • 关于Win2008R2服务器配置VPN服务器的图文教程方法-windows教程-学派吧

    这篇文章主要介绍了Win2008 r2服务器配置VPN服务器教程(图文详解),需要的朋友可以参考下 系统环境:WindowsServer2008R2Enterprise(完全安装) 1、配置准备工作1.1、点击“开始”右边的“服务器管理器”1.2、在“服务器管理器”里点击“角色”1.3、在“角色”上点击右键选译“添加角色”,点击“下一步”1.4、在“角色”里…

    服务器运维 2018年12月2日
    3.6K00
  • Win2008 64Bit下IIS环境安装memcache和memcached服务端的方法教程-学派吧

    这篇文章主要介绍了Win2008 R2 64Bit下IIS环境安装memcache和memcached服务端的方法,需要的朋友可以参考下 如果IIS+PHP的环境下需要memcache的缓存支持。需要安装服务端和客户端呢! 一、安装memcached服务端 1、首先下载memcached的服务端,下面的下载地址包含了32位和64位的,大家可以参考自己的系统来…

    服务器运维 2018年12月10日
    2.7K00
  • SaltStack设置配置教程 | Linux运维教程

    SaltStack简介 SaltStack是基于Python开发的一套C/S架构配置管理工具(功能不仅仅是配置管理,如使用salt-cloud配置AWS EC2实例),它的底层使用ZeroMQ消息队列pub/sub方式通信,使用SSL证书签发的方式进行认证管理。 号称世界上最快的消息队列ZeroMQ使得SaltStack能快速在成千上万台机器上进行各种操作,…

    服务器运维 2018年11月21日
    2.5K00
  • Linux系统怎么查看版本信息实例分享教程-学派吧

    如果您有服务器咨询问题、购买问题、可以联系我们客服 7271895 690624商祺云-阿里代理、景安代理、西部代理 1、输入”uname -a “,可显示电脑以及操作系统的相关信息。 $ uname -aLinux hadoop02.zjl.com 2.6.32-696.el6.x86_64 #1 SMP Tue Mar 21 19…

    服务器运维 2019年1月15日
    2.5K00
  • 如何准确的对于安全组使用新的限制-linux运维-学派吧

    本篇文章给大家带来的内容是关于如何准确的对于安全组使用新的限制 ,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 安全组新使用限制 可以调整安全组规则的数量上限吗? 不可以,每个安全组最多可以包含 100 条安全组规则。如果当前数量上限无法满足您的使用需求,建议您按照以下步骤操作: 检查是否存在冗余规则。您也可以提交工单,阿里云技术支持将提供…

    服务器运维 2018年11月21日
    2.6K00

发表回复

登录后才能评论
联系我们

联系我们

18838889666

在线咨询: QQ交谈

邮件:xinyun@88.com

工作时间:周一至周五,9:30-18:30,节假日休息

添加微信
添加微信
分享本页
返回顶部
---------官方优惠叠加渠道折扣:通过我们购买腾讯云/阿里云,价格更低,服务更优。更有专业配置指导与服务。微信同步:18838889666----