基于环境变量的nginx条件代理pass

时间:2021-07-09 10:22:23

标签: docker nginx

我想根据环境变量有条件地将proxy_pass传递给相关服务..我的意思是,应该根据NODE_ENV变量更改prox_pass地址..

这样做的最佳方法是什么?我可以对 proxy_pass 使用如下所示的 if 语句吗?如果是,我该怎么做?除此之外,我尝试创建一个如下所示的 bash 以将环境变量传递给 nginx,但无法以某种方式设置 $NGINX_BACKEND_ADDRESS 并将其传递给 nginx conf。任何帮助将不胜感激

   if ($NODE_ENV == "development) {
       proxy_pass http://myservice-dev;
   }

nginx.conf

server {
    listen  3000;
    location / {
        root /usr/src/app;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;
    }
    location /csrf/token {
        proxy_pass ${NGINX_BACKEND_ADDRESS}/csrf/token;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
    location /export/apis {
        proxy_pass ${NGINX_BACKEND_ADDRESS}/export/apis;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

入口点.sh

#!/usr/bin/env sh
set -eu
export NODE_ENV=development
if ["$NODE_ENV" == "development"]
then
    export NGINX_BACKEND_ADDRESS=http://backend-dev
elif ["$NODE_ENV" == "stage"]
then
    export NGINX_BACKEND_ADDRESS=http://backend-stage
elif ["$NODE_ENV" == "development"
then
    export NGINX_BACKEND_ADDRESS=http://backend-preprod
elif ["$NODE_ENV" == "development"]
then
    export NGINX_BACKEND_ADDRESS=http://backend
else 
    echo "Error in reading environment variable in nginx-conf.sh."
fi
echo "Will proxy requests for  to ${NGINX_BACKEND_ADDRESS}*"
exec /nginx-conf.sh "$@"

Dockerfile

FROM nginx:alpine AS production-build
WORKDIR /usr/src/app
ARG NODE_ENVIRONMENT=development
ENV NODE_ENV=$NODE_ENVIRONMENT
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/nginx.conf.template /etc/nginx/conf.d/default.conf.template
COPY nginx-conf.sh /
RUN chgrp -R root /var/cache/nginx /var/run /var/log/nginx /var/run/nginx.pid && \
    chmod -R 775 /var/cache/nginx /var/run /var/log/nginx /var/run/nginx.pid
USER nginx
COPY --from=builder /usr/src/app/dist .
ENTRYPOINT ["/nginx-conf.sh", $NODE_ENVIRONMENT]
EXPOSE 3000
CMD ["nginx", "-g", "daemon off;"]

3 个答案:

答案 0 :(得分:1)

Docker Hub nginx image(从 nginx:1.19 开始)具有在配置文件中进行环境变量替换的功能:

<块引用>

[...] 这个镜像有一个函数,它会在 nginx 启动之前提取环境变量。 [...] 该函数读取 /etc/nginx/templates/*.template 中的模板文件,并将执行 envsubst 的结果输出到 /etc/nginx/conf.d

因此,您的第一步是将您的配置文件(包括 proxy_pass ${NGINX_BACKEND_ADDRESS}/...)按原样重命名为类似 default.conf.template 的名称,并将其放入所需的目录中。

我会直接在您的部署时配置中传递该地址。我不会以任何方式将它包含在图像中。 (想象一下像“开发人员试图在他们的本地桌面系统上运行这个堆栈”这样的设置,其中入口点脚本中的所有 URL 都不正确。)这也可以让您摆脱这里的几乎所有代码;你只要

# Dockerfile
FROM ... AS builder
...
FROM nginx:1.21-alpine
COPY nginx/nginx.conf.template /etc/nginx/conf.d/default.conf.template
COPY --from=builder /usr/src/app/dist /usr/share/nginx/html
# Permissions, filesystem layout, _etc._ are fine in the base image
# Use the base image's ENTRYPOINT/CMD
# docker-compose.yml
version: '3.8'
services:
  proxy:
    build: .
    ports: ['8000:80']
    environment:
      - NGINX_BACKEND_ADDRESS=https://backend-prod.example.com

如果您确实在使用 Compose,则可以use multiple docker-compose.yml files 为特定环境提供设置。

# docker-compose.local.yml
# Run the backend service locally too in development mode
version: '3.8'
services:
  backend: # not in docker-compose.yml
    build: backend
    # and other settings as required
  nginx: # overrides docker-compose.yml settings
    environment:
      - NGINX_BACKEND_ADDRESS=http://backend
    # no other settings
docker-compose -f docker-compose.yml -f docker-compose.local.yml up

答案 1 :(得分:0)

如果你想在你的 dockerfile 中运行 if 语句,那么你可以在 dockerfile 中使用 RUN 命令,例如使用 bash, RUN if [[ -z "$arg" ]] ; then echo Argument not provided ; else echo Argument is $arg ; fi

答案 2 :(得分:0)

我通常这样做的方式是我有一个通用的 nginx 代理,然后我只将 url 和协议作为 env vars 传入

ubuntu@vps-f116ed9f:/opt/docker_projects/docker_examples/load_balancer$ cat proxy.conf
server {
  listen 80 default_server;

  resolver 127.0.0.11 valid=1s;

  set $protocol $PROXY_PROTOCOL;
  set $upstream $PROXY_UPSTREAM;

  location / {
    proxy_pass $protocol://$upstream$request_uri;

    proxy_pass_header Authorization;

    proxy_http_version 1.1;
    proxy_ssl_server_name on;
    proxy_set_header Host $upstream;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Connection "";

    proxy_buffering off;
    proxy_read_timeout 5s;
    proxy_redirect off;
    proxy_ssl_verify off;
    client_max_body_size 0;
  }
}
ubuntu@vps-f116ed9f:/opt/docker_projects/docker_examples/load_balancer$ cat Dockerfile
FROM nginx:1.13.8

ENV PROXY_PROTOCOL=http PROXY_UPSTREAM=example.com

COPY proxy.conf /etc/nginx/conf.d/default.template
COPY start.sh /

CMD ["/start.sh"]

然后我有一个启动脚本,它将把环境变量替换到我的 proxy_config 中。

ubuntu@vps-f116ed9f:/opt/docker_projects/docker_examples/load_balancer$ cat start.sh
#!/usr/bin/env bash
envsubst '$PROXY_PROTOCOL,$PROXY_UPSTREAM' < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf

exec nginx -g 'daemon off;'