在Docker Hub上的nginx镜像中,通过启动时的环境变量来进行proxy_set_header的控制

由于标题无法恰当地表达,我来解释一下,

         +-------------------------------------+
         |                                     |
         |    +-------+              +-----+   |
--(req)--|--> | nginx | --(proxy)--> | app |   |
         |    +-------+              +-----+   |
         |                                     |
         +-------------------------------------+

希望通过启动时的环境变量来控制nginx代理请求的标头。

$ OVERRIDE_UA=iPhone docker-compose up
$ docker-compose up

在应用程序中检查手机的用户代理(UA),并进行重定向等操作,本地开发时希望绕过这一功能,这是我的动机。

变更前的Docker文件和docker-compose.yml(仅限nginx部分)

FROM nginx:latest
ADD nginx.conf /etc/nginx/nginx.conf
services:
  nginx:
    build:
      context: .
      dockerfile: Dockerfiles/proxy
    ports:
     - "80:80"

使用可以使用perl模块的nginx: Perl图像

图书馆/nginx – Docker Hub

只有使用perl标签时,才包含ngx_http_perl_module。
然而,需要在启动nginx进程时启用perl模块。

请问在alpine Dockerfile中是否没有启用Perl模块?· 问题#124 · nginxinc/docker-nginx期

覆写CMD指令。

FROM nginx:perl
ADD nginx.conf /etc/nginx/nginx.conf
CMD ["nginx", "-g", "daemon off; load_module /etc/nginx/modules/ngx_http_perl_module-debug.so;"]

2. 将环境变量传递到容器中

Compose 中的环境变量 | Docker 文档

如果在docker-compose.yml中编写environment,可以传递环境变量。如果没有提供数值,则会继承docker-compose命令执行时的环境变量。

services:
  nginx:
    build:
      context: .
      dockerfile: Dockerfiles/proxy
    ports:
     - "80:80"
    environment:
     - OVERRIDE_UA

3. 使用nginx.conf文件加载环境变量。

使用nginx.conf读取环境变量- Qiita

正如上文所述,在nginx.conf文件中需要ngx_http_perl_module来控制环境变量。

--- a/nginx.conf
+++ b/nginx.conf
@@ -1,6 +1,8 @@
 user  nginx;
 worker_processes  1;

+env OVERRIDE_UA;
+
 error_log  /var/log/nginx/error.log warn;
 pid        /var/run/nginx.pid;

@@ -11,6 +13,8 @@ events {


 http {
+    perl_set $override_ua 'sub { return $ENV{"OVERRIDE_UA"}; }';
+
     include       /etc/nginx/mime.types;
     default_type  application/octet-stream;

@@ -29,6 +33,7 @@ http {

     proxy_set_header Host $host;
     proxy_set_header Client-Ip $remote_addr;
+    proxy_set_header User-Agent $override_ua;

     server {
       listen 80;

进行”写上”或”不写上”的控制。

代理 – nginx:为什么我不能将proxy_set_header放在if子句内? – Server Fault

根据以上,无法在nginx.conf的if语句内使用proxy_set_header。虽然尝试通过值的有无来进行控制,但似乎行不通。我认为这是一种不太正规的方法,但尝试在容器启动时修改nginx.conf文件。

perl -pi -e "s/# proxy_set_header User-Agent/proxy_set_header User-Agent/" /etc/nginx/nginx.conf
if [ -z "$OVERRIDE_UA" ]; then
  perl -pi -e "s/proxy_set_header User-Agent/# proxy_set_header User-Agent/" /etc/nginx/nginx.conf
fi

nginx -g "daemon off; load_module /etc/nginx/modules/ngx_http_perl_module-debug.so;"
FROM nginx:perl
ADD nginx.conf /etc/nginx/nginx.conf
ADD run_nginx.sh /
CMD ["sh", "/run_nginx.sh"]

执行

这样就能实现我们所期望的控制了。

$ OVERRIDE_UA=iPhone docker-compose up
$ docker-compose up
广告
将在 10 秒后关闭
bannerAds