点赞
评论
收藏
分享
举报
使用 NGINX Unit 构建应用堆栈
发表于2021-03-04 16:07

浏览 5.1k


作者:Artem Konev Timo Stark
原始 URLhttps://f5-my.sharepoint.com/:w:/p/a_konev/EQokQGFnDKpIoiMGE99tfBoBKYuI6BoS0KBYH3Ds9i2rkw?e=Rp1Zvn

客户经常询问如何在已建好的某种技术堆栈中使用 NGINX Unit。单就其本身而言,NGINX Unit 很容易配置,但要将其整合到各种工具和服务中就没那么容易了;此外,如何让最终客户享受到潜在的好处也面临着同样的问题。本文旨在通过一个相当常见的使用场景来探讨这一问题。

问题:复杂的应用部署工作流

有个问题可能我们的许多读者都遇到过,那就是需要实现生产环境部署流程的自动化,这涉及使用定制的语言运行时版本以及[TM1] 特定的库、模块和扩展,以满足特定的业务需求。一般来说,通过临时采取合理的措施就可以实现这一目标,但是将自定义的半手动工作流转换成适合较大规模的一系列可调整的自动化步骤是一项极其繁琐的工作,不胜其烦的用户最终会选择彻底放弃该项目。下面就让我们看看 NGINX Unit如何帮您解决这一问题。

上述场景通常会因需求重叠而复杂化,例如:

·      实现 Web 应用本身设置步骤的自动化

·      构建定制的语言运行库以满足应用的需求

·      将部署特定的设置注入到生成的通用镜像中

·      部署和管理实例化镜像

单就每项要求而言,不难满足,但如果需要反复重复所有步骤,则就会带来巨大的压力。在这里,我们推荐了一种可缓解这一压力的方法,支持您将更多的时间用于提升业务价值,而非铺设管道。您可以直接使用该方法,也可以根据具体场景进行调整 [TM2] .

解决方案:Docker NGINX Unit

质上我们要介绍的是一款面向您所选应用的 NGINX Unit 插件,该插件由我们的同事 Timo Stark 设计并在 GitHub (https://github.com/tippexs/unitwp) 上提供。该构建堆栈以 WordPress 为目标应用,被形象地称为 unitwp。但是,也可以根据其他需求对其进行改编。举例来说,现在它就可以为基于 CakePHP (https://cakephp.org) 的网站https://kaufdaheim.org提供强大支持,该网站正在帮助德国本地企业在新冠疫情封锁期间生存下去。

在此描述的设置几乎可以毫不费力地创建带有内置 PHP 支持的基于 NGINX Unit 的自定义容器镜像,准备 WordPress 安装镜像,在 NGINX Unit 中使 Web 应用做好启动准备,最后运行 Web 应用并将其暴露在预先配置的端口上。出于在开发环境环境变量中所讨论的原因,该设置会刻意避免包含数据库。[TM3] [AK4] 

该解决方案依赖于官方 NGINX Unit 镜像,该镜像已预先配置了 PHP 7.3 运行时以及适用于 NGINX Unit 的语言模块,与自行准备自定义镜像相比,这可节省大量时间和精力。如果您希望使用简单的 Docker 镜像,则可以使用NGINX/unit:1.16.0-minimal[TM5] [AK6] [TM7] [AK8] 镜像,该镜像仅包含核心 NGINX Unit 可执行文件。有关结合使用 NGINX Unit Docker的建议,请参见我们的官方指南

注意:以下步骤假定您拥有面向 PHP Composer 依赖管理器;如有必要,请按照下载说明进行下载。如果没有,则可以继续使用任何其他可用的安装方法。

我们首先使用基础 Composer 配置为我们的 WordPress 应用创建文件的本地副本,该基础 Composer 配置使用了 GitHub 上支持 Composer WordPress 分支:

{

"require": {

"johnpbloch/wordpress[TM9] ": "*"

}

}

如欲下载并安装 Composer,请将此代码段另存为 composer.json,然后在同一目录中运行 composer install 命令。

现在,让我们使用以下 Dockerfile 将文件加载到 Docker 镜像中:

FROM NGINX/unit:1.16.0-php7.3

RUN mkdir /var/apphome/ && groupadd -r wpgroup && useradd --no-log-init -r -g wpgroup wpuser && \

chown -R wpuser:wpgroup /var/apphome/ && \

apt-get update && apt-get install --no-install-recommends --no-install-suggests -y php7.3-mysql php7.3-gd

COPY wordpress /var/apphome

RUN chown -R wordpress:wordpress /var/apphome/

COPY .unit.conf.json /docker-entrypoint.d/.unit.conf.json

CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"]

该文件首先使用 WordPress 所需的几个程序包对基础镜像的 PHP 环境进行了定制。如果您的项目还需要额外的程序包或定制,那么这将是第一个潜在的扩展点。如果您希望自己构建整个工具链,则可以使用 -minimal 基础镜像进行构建,而非上文提到的镜像。

随后,该文件会将 WordPress 文件从 Composer 创建的目录复制到镜像中,并设置适当的所有权。最后,它会复制 JSON 代码段,当容器启动时,该代码段就会被上传到 NGINX Unit 配置中。启动脚本会自动运行,但是您也可以使用自定义证书和 shell 脚本,正如在 NGINX Unit 文档中所述。

以下是 NGINX Unit 配置:

{

"listeners": {

"*:8080": {

"pass": "routes/wordpress"

}

},

"routes": {

"wordpress": [

{

"match": {

"uri": [

"*.php",

"*.php/*",

"/wp-admin/"

]

},

"action": {

"pass": "applications/wp_direct"

}

},

{

"action": {

"share": "/var/apphome",

"fallback": {

"pass": "applications/wp_index"

}

}

}

]

},

"applications": {

"wp_direct": {

"type": "php",

"options": {

"file": "/etc/php.ini",

"admin": {

"upload_max_filesize": "20M"

}

},

"user": "wordpress",

"group": "wordpress",

"root": "/var/apphome"

},

"wp_index": {

"type": "php",

"options": {

"file": "/etc/php.ini",

"admin": {

"upload_max_filesize": "20M"

}

},

"user": "wpuser",

"group": "wpgroup",

"root": "/var/apphome",

"script": "index.php"

}

},

"settings": {

"http": {

"header_read_timeout": 10,

"body_read_timeout": 10,

"send_timeout": 10,

"idle_timeout": 120,

"max_body_size": 6291456,

"static": {

"mime_types": {

"text/plain": [

".log",

"README",

"CHANGES"

]

}

}

}

}

}

WordPress 特定[TM10] [AK11] 路由方案(选自我们的指南)利用了NGINX Unit 1.16.0 中引入的 fallback 路由选项,该选项类似于NGINX try_files 指令。还要注意,我们在“应用”部分的不同 wp_direct wp_index 对象中就不同的网站部分应用了不同的设置;如果您愿意,还可以使用不同的 php.ini 文件。

最后,我们将所有内容都打包到一个小巧的 build.sh 脚本中:

#!/usr/bin/env bash

set -ex

build_container() {

docker build -t YOURIMAGETAG --no-cache .

}

containerize() {

echo "Building Container Image"

build_container

docker tag YOURIMAGETAG:latest REMOTEIMAGETAG:latest

echo "Pushing... "

docker push REMOTEIMAGETAG:latest

}

case $1 in

"push")

echo "Building and Pushing to Registry ..."

containerize

;;

esac

对于 YOURIMAGETAG,替换本地标签;对于 REMOTEIMAGETAG,最终标签包含目标 Docker 注册表的名称。[TM12] [AK13] 为简洁起见,该脚本省略了错误处理和报告。

当我们运行 build.sh push 命令时,该脚本会从头构建一个新映像并对其进行标记,然后将其推送到我们选择的注册表中。您还可以增强 shell 脚本,比如引入可调整的标签和版本控制,或删除同一镜像的旧版本以减少混乱。

设置开发环境

NGINX Unit 的功能还能为其他同样相关的场景带来更多益处,即简单快速地扩展和关闭本地开发或测试环境。得益于动态配置特性,NGINX Unit 支持在语言运行时版本、环境变量或处理应用的几乎所有设置之间无缝切换。下面就让我们基于上述内容进一步展开。

我们 unitwp WordPress 应用的开发版本位于 GitHub 存储库的 dev子目录 (https://github.com/tippexs/unitwp)。它使用的设置与解决方案:Docker NGINX Unit中所描述的基本相同,只有几处不同。

第一个区别在于 Dockerfile,它具有以下命令,而没有将 WordPress 文件复制到镜像中的命令。此更改支持您在每次构建镜像时添加特定的 php.ini 设置。


COPY php.ini /etc/php/7.3/cli/conf.d/php-unit.ini

另一个显著差异是使用 docker-compose 添加 MariaDB 数据库容器。以下是 docker-compose.yaml 文件:

version: "3.7"

services:

mariadb:

image: mariadb:latest

ports:

- 3306:3306

restart: always

volumes:

- ./db-volume:/var/lib/mysql

environment:

MYSQL_USER: wordpressdev

MYSQL_PASSWORD: wordpressdev

MYSQL_DATABASE: wordpress

MYSQL_ROOT_PASSWORD: devpassword

wordpress:

image: YOURIMAGETAG:latest

environment:

DB_USER: wordpressdev

volumes:

- ../wordpress:/var/apphome/wordpress

- ../vendor:/var/apphome/vendor

ports:

- 8044:8080

一个容器维护一个服务是 Docker 的最佳工作方式,这也是我们没有在 解决方案:Docker NGINX Unit 中添加数据库的原因。在生产环境中,数据库连接可以有多种形式,因此我们使容器通用化,可在任何情况下使用,而无需选择特定的数据库。相反,开发环境通常需要保持独立,因此这部分的动态配置会在运行时创建完全可操作的堆栈。这涉及对环境变量的大量使用,下一部分将对此进行详细讨论。

如要运行此设置,我们需要一个升级的 shell 脚本,在这里我们称作 run-local.sh,其中一个选项用于构建镜像并运行容器,另一个选项用于停止服务并清理:

#!/usr/bin/env bash

set -ex

case $1 in

"dev")

echo "Building local image and mounting code base..."

docker build -t YOURIMAGETAG:latest .

docker-compose up

;;

"stop")

echo "Stopping services..."

docker-compose down

docker rm --force dev_wordpress_1

;;

esac

如要启动或停止本地开发环境,请分别运行 ./run-local.sh dev ./run-local.sh stop 命令。

使用环境变量


尽管在开发环境中存储一次性凭证是合理的,但将硬编码的数据库密码或 API 访问令牌推送到生产存储库却不是个好主意,虽然总是有人这么做 (https://searchsecurity.techtarget.com/news/252477280/AWS-leak-exposes-passwords-private-keys-on-GitHub)避免此类事件的方法有很多,但环境变量是硬编码证书最基本的替代方案。

您可以通过多种方式设置环境变量,包括:

·      启动时将它们作为 docker run --env docker run --env-file 命令参数提供

·      docker-compose.yaml 文件中将它们列出,正如在“设置开发环境”中

·      最后一点也是很重要的一点是,使用 NGINX Unit 配置 API,特别是其环境选项 (https://unit.nginx.org/configuration/#applications)

NGINX Unit 配置的开发版本中,我们针对两款应用使用了“环境”选项,如本示例所示:

"applications": {

"wp_direct": {

"type": "php",

"environment": {

"DB_HOST": "mariadb"

}

}

}

如您所见,“环境”部分中的 JSON 非常简单:您只需为应用提供变量名称的键值清单及其设置即可。这样做的好处是这些值仅对单个应用可见,而不会与同一环境中的其他应用共享。

当然,具体方法取决于您个人的选择。但是,我们建议选择一个位置来配置环境变量并且不再更改。

结语

正如文中所述,NGINX Unit 包含许多特性和选项,可将涉及诸多工具和技术的多层方案简化为几个 shell 命令:

·      动态配置支持您随时更新应用或其特定部分。

·      配置精细,支持您在不影响整体设置的情况下微调个别设置。

·      Docker 镜像提供了几乎无需调整的现成解决方案,支持您快速封装任何应用以供独立使用或与其他服务一起部署。

综上所述,NGINX Unit 是各量级应用交付堆栈的理想之选。我们也在推进几项重要更新 (https://github.com/orgs/nginx/projects/1),以增强请求路由和应用隔离,从而提供更多选择,敬请期待!



已修改于2023-03-08 02:21
创作不易,留下一份鼓励
NGINX官方账号

暂无个人介绍

关注



写下您的评论
发表评论
全部评论(0)

按点赞数排序

按时间排序

关于作者
NGINX官方账号
这家伙很懒还未留下介绍~
228
文章
21
问答
198
粉丝
相关文章
配置Nginx官方yum源[nginx]name=nginxrepobaseurl=http://nginx.org/packages/centos/7/$basearch/gpgcheck=0enabled=1
点赞 1
浏览 745
原文作者:LiamCrillyofF5原文链接:将NGINX部署为API网关,第2部分:保护后端服务转载来源:NGINX官方网站  本文是将NGINX开源版和NGINXPlus部署为API网关系列博文的第二篇。第1部分提供了几个用例的详细配置说明。本文对这些用例进行了扩展,探讨了一系列可用于保护生产环境中后端API服务的安全措施:限流限定请求方法应用细粒度的访问控制控制请求大小验证请求正文本文最初发布于2018年,现进行了更新,以反映API配置的当前最佳实践——即使用嵌套的 location 块路由请求,而不是重写规则。第3部分解释了如何将NGINX开源版和NGINXPlus部署为gRPC服务的API网关。注:除非另有说明,否则本文中的所有信息都适用于NGINX开源版和NGINXPlus。为了便于阅读,下文将NGINX开源版和NGINXPlus统称为“NGINX”。限流与基于浏览器的客户端不同,单个API客户端就能够给您的API造成巨大的负载,甚至
点赞 0
浏览 991
要勇敢 要自信 要爱自己!
点赞 2
浏览 447