docker容器-nginx conf文件使用环境变量值

注意: 这篇文章仅作为记录用, 因为第一次搞也折腾了很久, 所以不要仔细看我的文章, 因为肯定会有更优雅更专业的解决方案

背景

使用docker 创建 nginx容器时, 如果需要设置conf文件, 并且conf文件中使用到宿主机的ip时, 我们更希望这个 ip 是可以动态替换的, 比如使用环境变量.

方法

https://hub.docker.com/_/nginx
 - 在 nginx 配置中使用环境变量(1.19 中的新功能)

1. 创建环境变量
2. 创建 xxx.conf.template 文件
3. .template 文件中使用环境变量值
4. nginx容器会自动将 xxx.conf.template 转换为 xxx.conf 文件, 其中的变量也会正常替换.

docker-compose 使用

docker-compose.yaml

version: "3.6"

services:
  test-server:
    container_name: test_server_nginx
    image: nginx:1.20.0
    ports:
      - "8155:80"
    environment:
      - NGINX_HOST=127.1.1.1
      - NGINX_PORT=80
    volumes:
      - ${PWD}/templates:/etc/nginx/templates
      - ${PWD}/conf:/etc/nginx/conf.d

default.conf.template

编写 .template 文件

server {
  listen       ${NGINX_PORT};
 
  location / {
    root   /opt/web_dist;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
  }

  location /api/ {
    proxy_pass  ${NGINX_HOST}/;    
  } 
}

启动容器

docker-compose up -d

可以看到, 挂载的conf目录中的 conf文件已经是正常的了(虽然不能用)

server {
  listen       80;
 
  location / {
    root   /opt/web_dist;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
  }

  location /v2api/ {
    proxy_pass  127.1.1.1/;    
  }
}

command使用

与上面的compose使用是一样的, 不过更多的是使用 command 命令行自定义

  • 目的
我们使用port为10086 进行端口的替换来测试

可以看到, 我们将conf.d文件挂载至 ./conf 文件中, 下一步需要创建中间文件

command指令:
    bin/bash -c  "envsubst '$$PORT' < /etc/nginx/conf.d/source.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;' "
    
	通过 envsubst 将容器内的环境变量替换并读出至中间文件 source.template, 然后再全部输出到我们的 conf 配置文件中
	
  • 步骤

docker-compose.yaml

version: "3.6"

services:
  test-server:
    container_name: test-server_nginx
    image: nginx:1.20.0
    ports:
      - "8155:80"
    environment:
      - PORT=10086
    volumes:
      - ${PWD}/conf:/etc/nginx/conf.d
    command:
      - bin/bash
      - -c
      - "envsubst '$$PORT' < /etc/nginx/conf.d/source.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;' "

source.template

upstream index {
    server 192.168.0.85:${PORT};
}
server {
    listen 80;
    charset utf-8;
    server_name 127.0.0.1;
    
     location / {
       proxy_pass http://index/test;
     }
}

启动

docker-compose up -d

查看 defalut.conf 文件

upstream index {
    server 192.168.0.85:10086;
}
server {
    listen 80;
    charset utf-8;
    server_name 127.0.0.1;
     
     location / {
       proxy_pass http://index/test;
     }
}

可以看到已经被替换成功了

docker使用

与上面的一样, 创建template文件
注意创建的目录, 需要挂载出来 /etc/nginx/templates/

然后启动容器

docker run -d --name nginx -e NGINX_PORT=80 -v $(PWD)/template:/etc/nginx/templates/ nginx:1.20.0

注意点:

默认情况下,该函数读取模板文件/etc/nginx/templates/*.template并将执行结果输出envsubst到/etc/nginx/conf.d.

可以通过以下环境变量更改此行为:

    - NGINX_ENVSUBST_TEMPLATE_DIR
    	它包含模板文件的目录(默认值:/etc/nginx/templates)
    	当这个目录不存在时,这个函数不会做任何模板处理。
    
    - NGINX_ENVSUBST_TEMPLATE_SUFFIX
    	模板文件的后缀(默认值:.template)
    	该函数只处理名称以该后缀结尾的文件。
    
    - NGINX_ENVSUBST_OUTPUT_DIR
    	一个目录,执行envsubst的结果被输出(默认值:/etc/nginx/conf.d)
    	输出文件名是去掉后缀的模板文件名。
   			ex.)/etc/nginx/templates/default.conf.template将与文件名一起输出/etc/nginx/conf.d/default.conf。
    	此目录必须可由运行容器的用户写入。
    	

shell 脚本使用

直接在shell脚本文件中定义, 替换宿主机中的文件, 宿主机的文件同时又是nginx docker容器挂载出来的conf配置文件.

流程 .sh 文件内根据 .env 里的环境变量, 修改template文件, 将template文件中的变量参数替换, 重定向输出到 conf 文件. 此conf文件同时是 nginx容器挂载的默认配置.

由此达成配置

  • .env 文件
VMP_SERVER_IP=127.0.0.1
APP_PORT=8111
  • .sh文件实例
source ./.env

NGINX_CONF_FILE="${PWD}/service/nginx"

export NGINX_VMP_SERVER="http://${VMP_SERVER_IP}:${APP_PORT}/"

	envsubst '${NGINX_VMP_SERVER}' < ${NGINX_CONF_FILE}/default.conf.template > ${NGINX_CONF_FILE}/default.conf

unset NGINX_VMP_SERVER

  • default.conf.template 文件
server {
  listen       80;
  root   /opt/web_dist;
  index index.html;

  location / {
    try_files $uri /index.html;
    index  index.html;
  }

  location /v2api/ {
    proxy_pass ${NGINX_VMP_SERVER}; 
    proxy_set_header Host $proxy_host; 
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
  
}
  • default.conf 文件
server {
  listen       80;
  root   /opt/web_dist;
  index index.html;

  location / {
    try_files $uri /index.html;
    index  index.html;
  }

  location /v2api/ {
    proxy_pass http://127.0.0.1:8111/; 
    proxy_set_header Host $proxy_host; 
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐