【问题标题】:nginx docker alpine envsubst doesn't work when there's a command in docker-compose当 docker-compose 中有命令时,nginx docker alpine envsubst 不起作用
【发布时间】:2021-08-22 22:42:23
【问题描述】:

我想将 envsubst 与 nginx docker alpine 一起使用。 Documentation:

在 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.

我有一个 nginx 容器服务,格式如下:

version: '3'

services:
  nginx:
    image: nginx:alpine
    restart: unless-stopped
    volumes:
      #- ./data/nginx:/etc/nginx/conf.d
      - ./templates:/etc/nginx/templates
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    ports:
      - "80:80"
      - "443:443"
    env_file: .env
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"

当我运行此服务时,envsubst 不起作用。但是,如果我在 docker-compose 中删除 command:,它确实有效。

我尝试将命令复制到 .sh 文件并将其移动到容器内 /docker-entrypoint.d/mycommand.sh。这里默认还有其他几个 .sh 文件在加载 nginx 之前运行:

ls -l docker-entrypoint.d
total 16
-rwxrwxr-x    1 root     root          1961 May 25 15:44 10-listen-on-ipv6-by-default.sh
-rwxrwxr-x    1 root     root          1037 May 25 15:44 20-envsubst-on-templates.sh
-rwxrwxr-x    1 root     root          4613 May 25 15:44 30-tune-worker-processes.sh

我也使用音量在其中添加了mycommand.sh。这是 mycommand.sh 的样子:

#! /bin/bash

# reload nginx config every 60 seconds in case certs get updated
while :; do
  sleep 60
  echo reloading
  nginx -s reload
done

但是,当我将此脚本添加到 /docker-entrypoint.d 目录时,nginx 似乎永远不会启动。

如何运行我的命令并根据文档使用 nginx alpine 来使用 envsubst?

我更喜欢能够走这条路,而不是例如。使用具有共享卷的新 nginx 容器来获得相同的结果。将 .sh 脚本添加到 docker-entrypoint.d '感觉' 像'正确' 的方式,并会导致更简约的 docker-compose。

【问题讨论】:

    标签: docker nginx docker-compose


    【解决方案1】:

    更改命令不起作用,因为/docker-entrypoint.sh 包含:

    if [ "$1" = "nginx" -o "$1" = "nginx-debug" ]; then
    ...
    

    当你更改命令时,$1 变为 /bin/sh

    /docker-entrypoint.d 中的脚本需要在docker-entrypoint.sh 到达运行命令的末尾之前运行并退出(默认情况下,启动 nginx)。您可以将该 while 循环放在后台来实现此目的,只需在完成后附加一个 &

    #! /bin/bash
    
    # reload nginx config every 60 seconds in case certs get updated
    while :; do
      sleep 60
      echo reloading
      nginx -s reload
    done &
    

    请注意,这在很大程度上是一种容器反模式,通常仅在开发环境中才有意义。在生产中,您将使用新配置重新部署一个新容器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-20
      • 2021-10-21
      • 2021-01-13
      • 2021-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多