使用NGINX向静态网站注入环境变量(翻译)

原文地址:https://www.innoq.com/de/blog/nginx-ssi-env/

标题:Injecting environment variables into static websites using NGINX

静态站点生成非常适合发布文档在最近的一个项目中,我们选择使用 NGINX 作为 web 服务器来托管 HTML 和 CSS 文件。 但是,我们还希望使用 SSO 保护站点。  

这就是事情变得有点困难的地方。

当然,在使用 HTTP 基本身份验证之外的 SSO 机制时,我们需要向用户显示一个 “Sign Out” 按钮。但是当结合静态站点生成 (SSG) 时,我们还不知道sign out的URI ,因为它可能依赖于部署的特定配置。  

为了真正渲染按钮,我们面临两个选择:  

  1. 不是在 CI 中运行 SSG 工具,而是在 Docker 容器启动时运行。
  2. 在没有 URI 的情况下渲染链接,并让 web 服务器在运行时注入它。  

在我们的例子中,SSG 工具是 Jekyll,所以添加它的整个 Ruby 工具链会破坏使用 NGINX 的目的: 尽可能的轻量级。此外,这个巨大的镜像将创造更多的攻击表面(https://kubernetes.io/docs/concepts/workloads/pods/init-containers/可以在这里提供帮助,但我们希望避免将工作从 CI 转移到运行时)。所以,我们很快就排除了这个选项。

但是如何实施第二种选择呢?  幸运的是,SSI(server side includes) 可以在这里提供帮助。简而言之,生成的页面包含了几乎所有的内容,再加上一些小的指令给 web 服务器来插入更多的内容。SSI 可以用于从其他服务器获取内容,有条件地启用或禁用页面中的区域,或者仅仅打印某个变量的内容(比如当前日期和时间) 

NGINX 在启用配置选项后支持 SSI:  

location / {

root /var/www; 

ssi on; 

}

在 Jekyll 模板文件中,我们现在可以添加以下代码片段:  

<a href="<!--#echo var="ssisignouturl"-->">Sign out</a>

当使用 jekyll 服务在本地浏览页面时,这将产生无效的 HTML 标记(虽然它不会破坏页面,因为浏览器是容的)    所以我建议只在生产模式下渲染它(即在 CI 中):  

{% if jekyll.environment == "production" %}

<a href="<!--#echo var="ssisignouturl"-->">Sign out</a>

{% endif %}

其他 SSG 工具也有类似的方法来区分不同的环境。

现在唯一的开放问题是 NGINX 不传递为 SSI 引擎的进程而设的环境变量。更糟糕的是,NGINX 甚至不支持在配置文件中读取环境变量。

根据官方的 NGINX Docker 像,将这些变量传递到正在运行的容器的方法是使用模板。 像包含一个启动脚本,在标记为“模板”的配置文件上运行 envsubst。当启动容器时,将处理模板,并将环境变量复制到实际的 NGINX 配置中。

为了利用这个机制,将 NGINX 配置的相关部分移动到一个名为 default.conf.template 的模板文件中(或任何以.conf.template结尾的名称)。

Dockerfile也相应进行了调整:

FROM nginx:1.19.9

COPY default.conf.template /etc/nginx/templates/

ENV SIGN_OUT_URL="#"

这是必要的,这样启动脚本就可以获取文件并通过 envsubst 运行它。

现在,在 NGINX 配置中,你可以访问这些变量:  

location / {

      root /var/www;

      ssi on;

set $ssisignouturl "${SIGN_OUT_URL}";

}

当容器启动时,无需更多的 ado,脚本生成以下配置:  

location / {

      root /var/www;

      ssi on;

      set $ssisignouturl "#";

}

这是因为 Dockerfile 为 SIGN_OUT_URL 指定了一个默认值。

非常重要的是,在 NGINX 模板中,SSI 变量名 (sisignouturl) 与环境变量名 (SIGN_OUT_URL) 是不同的,否则 envsubst 将替换这两种情况。这些脚本保持未定义变量的出现不变。

最后,在如上所述更改配置后,SSI 引擎可以替换 URL。 如下所示构建并启动 Docker 

docker build -t docs .

docker run --rm -it -p 80:80 -e SIGN_OUT_URL="https://sso.bigcorp.com/signout" docs

这将呈现以下 HTML:

<a href="https://sso.bigcorp.com/signout">Sign out</a>

让我们惊讶的是,NGINX 没有内置的机制来传递环境变量,我们不得不依赖 Docker 像提供的启动脚本。在无法使用 Docker 官方像的情况下,我建议生成一个文本文件的sign out链接,并通过include 包含该文件,而不是使用 echo 打印变量。

更多的资料请访问:https://nginx.org/en/docs/http/ngx_http_ssi_module.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值