docker - 基于环境变量的nginx条件代理传递
问题描述
我想根据环境变量有条件地将proxy_pass传递给相关服务。我的意思是,prox_pass地址应该根据NODE_ENV变量进行更改。
这样做的最佳方法是什么?我可以使用如下 if 语句作为 proxy_pass 吗?如果是,我应该怎么做?除此之外,我尝试如下创建一个 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;"]
解决方案
Docker Hubnginx
映像(截至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,则可以使用多个docker-compose.yml
文件来为特定环境提供设置。
# 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
推荐阅读
- node.js - mongodb中的类别和子类别使用猫鼬
- python - cv2.mouseCallback 没有在 cv2 窗口上注册鼠标点击
- jestjs - NestJS / GraphQL e2e 测试错误:“PickObjectType”的“id”字段的默认值不匹配导致的错误。确保这些 val
- flutter - CircularNotchedRectangle 类的解释
- node.js - 如何使用 Nginx 和 Node.js 映射原始 tcp 连接?
- php - php无法访问外部驱动器上的文件
- javascript - 将 xml 解析为表但按日期过滤
- google-cloud-platform - Asp.net Core 无法确定重定向的 https 端口
- reporting-services - SSRS 报表生成器:在报表中间、父组“内”显示详细数据
- javascript - UnhandledPromiseRejectionWarning: AggregateError: Issuer.discover() 失败。[auth0] [express] [openid-connect]