首页 > 解决方案 > 将文件添加到`/docker-entrypoint.d/` 作为 app.conf.template 文件的一部分,以将全局变量交换到 nginx 设置中

问题描述

我想使用 docker 和 docker-compose 通过 app.conf.template 文件将全局变量传递给我的 nginx app.conf。

当使用我的变量中没有命令的 app.conf.template 文件时,docker-compose.yaml我的变量转换成功并且我通过 nginx 的重定向按预期工作。但是当我在 docker-compose 中使用命令时,我的 nginx 并重定向失败。

我的设置是按照文档中的说明,在“在 nginx 配置中使用环境变量(1.19 中的新功能)”部分下:

开箱即用的 nginx 不支持大多数配置块中的环境变量。但是这个镜像有个函数,会在nginx启动前提取环境变量。

这是使用 docker-compose.yml 的示例:

网络:图像:nginx 卷:

  • ./templates:/etc/nginx/templates 端口:
  • “8080:80”环境:
  • NGINX_HOST=foobar.com
  • NGINX_PORT=80

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

我的 docker-compose.yaml 如下所示:

version: "3.5"
networks:
  collabora:
  
services:
  nginx:
    image: nginx
    depends_on:
      - certbot   
      - collabora 
    volumes:
      - ./data/nginx/templates:/etc/nginx/templates
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    ports:
      - "80:80"
      - "443:443"
    env_file: .env
    networks:
      - collabora

在主机上,我有一个 conf 文件./data/nginx/templates/app.conf.template,其中包含一个带有全局变量的 conf 文件,格式为${variable_name}.

通过这个设置,我可以运行容器并且我的重定向按预期工作。当我exec进入容器时,我可以cat /etc/nginx/conf.d/app.conf看到从 .env 文件中换入的具有正确变量的文件。

但我需要在我的 docker-compose.yaml 中添加一个命令:

command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"

当我添加该命令时,设置失败并且全局变量不会交换到容器内的 app.conf 文件中。

在另一个论坛上,有人建议我将它移到command容器中它自己的文件中。然后我试了一下并创建了一个shell脚本test.sh

#/bin/sh 

while :; 
    do sleep 6h & wait $${!}; 
    nginx -s reload; 
done;

我的新码头工人撰写:

version: "3.5"
networks:
  collabora:
  
services:
  nginx:
    image: nginx
    depends_on:
      - certbot   
      - collabora 
    volumes:
      - ./data/nginx/templates:/etc/nginx/templates
      - ./test.sh:/docker-entrypoint.d/test.sh # new - added test.sh into the container here
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    ports:
      - "80:80"
      - "443:443"
    env_file: .env
    networks:
      - collabora

这失败了。尽管当我执行到容器中并且cat /etc/nginx/conf.d/app.conf确实看到了正确的配置时,它似乎并没有在我的重定向中起作用,否则当我没有在/docker-entrypoint.d/.

我昨天问了几乎同样的问题,并得到了一个可行的解决方案。/docker-entrypoint.d/然而,像我在这篇文章中尝试的那样,向容器中添加一个 shell 脚本并走这条路线“感觉更正确” 。

标签: dockernginxdocker-compose

解决方案


对于您正在尝试做的事情,我认为最好的解决方案是创建一个边车容器,如下所示:

version: "3.5"

networks:
  collabora:

volumes:
  shared_run:

services:
  nginx:
    image: nginx:1.19
    volumes:
      - "shared_run:/run"
      - ./data/nginx/templates:/etc/nginx/templates
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    ports:
      - "80:80"
      - "443:443"
    env_file: .env
    networks:
      - collabora

  nginx_reloader:
    image: nginx:1.19
    pid: service:nginx
    volumes:
      - "shared_run:/run"
    entrypoint:
      - /bin/bash
      - -c
    command:
      - |
        while :; do
          sleep 60
          echo reloading
          nginx -s reload
        done

这使您可以使用上游nginx图像,而无需纠结于其机制。这里的关键是(a)我们将容器运行nginx_reloader在与容器本身相同的 PID 命名空间中nginx,以及(b)我们安排两个容器共享一个/run目录,以便nginx -s reload命令可以nginx在预期中找到进程的 pid地点。


推荐阅读