6

使用 NGINX 将环境变量注入静态网站

 2 years ago
source link: https://blog.p2hp.com/archives/8187
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
使用 NGINX 将环境变量注入静态网站

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

当然,当使用 HTTP 基本身份验证以外的 SSO 机制时,我们需要向用户显示“退出”按钮。但是当与静态站点生成 (SSG) 结合使用时,我们还不知道注销 URI,因为它可能取决于部署的特定配置。

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

  1. 不在 CI 中运行 SSG 工具,而是在 Docker 容器启动时运行。
  2. 呈现没有 URI 的链接,并让 Web 服务器在运行时注入它。

在我们的例子中,SSG 工具是 Jekyll,所以添加它的整个 Ruby 工具链会违背使用 NGINX 的目的:尽可能轻量级。此外,这个巨大的图像会创造更多的攻击面。[1] 所以,我们很快就取消了这个选项。

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

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

location / {
  root /var/www;
  ssi on;
}

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

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

当使用 本地浏览页面时jekyll serve,这会产生无效的 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}";
}

当容器启动时,脚本会生成以下配置:

location / {
  root /var/www;
  ssi on;
  set $ssisignouturl "#";

}

这是因为我们为Dockerfile指定了默认值SIGN_OUT_URL

非常重要的是,在 NGINX 模板中,SSI 变量名 ( ssisignouturl) 与环境变量名 ( 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 映像的情况下,我建议将注销链接生成为文本文件并通过 包含该文件include,而不是使用echo. 更多文档可以在 NGINX 站点上找到

  1. Kubernetes Init Containers可以在这里提供帮助,但我们希望避免将工作从 CI 转移到运行时。 ↩

via https://www.innoq.com/de/blog/nginx-ssi-env/


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK