[英]Add a file to `/docker-entrypoint.d/` as part of a app.conf.template file to swap global variables into nginx set up
I would like to pass global variables to my nginx app.conf via a app.conf.template file using docker and docker-compose.我想使用 docker 和 docker-compose 通过 app.conf.template 文件将全局变量传递给我的 nginx app.conf。
When using an app.conf.template file with no commands in docker-compose.yaml
my variables translate successfully and my redirects via nginx work as expected.当在
docker-compose.yaml
中使用没有命令的 app.conf.template 文件时,我的变量转换成功,我通过 nginx 的重定向按预期工作。 But when I use a command in docker-compose my nginx and redirects fail.但是当我在 docker-compose 中使用命令时,我的 nginx 和重定向失败。
My set up is per the instructions on the documentation , under section 'Using environment variables in nginx configuration (new in 1.19)':我的设置是按照文档上的说明进行的,在“在 nginx 配置中使用环境变量(1.19 中的新功能)”部分下:
Out-of-the-box, nginx doesn't support environment variables inside most configuration blocks.
开箱即用的 nginx 不支持大多数配置块中的环境变量。 But this image has a function, which will extract environment variables before nginx starts.
但是这个镜像有一个function,它会在nginx启动之前提取环境变量。
Here is an example using docker-compose.yml:
这是使用 docker-compose.yml 的示例:
web: image: nginx volumes:
web:图像:nginx 卷:
- ./templates:/etc/nginx/templates ports:
./templates:/etc/nginx/templates 端口:
- "8080:80" environment:
“8080:80”环境:
- NGINX_HOST=foobar.com
NGINX_HOST=foobar.com
- NGINX_PORT=80
NGINX_PORT=80
By default, this function reads template files in /etc/nginx/templates/*.template and outputs the result of executing envsubst to /etc/nginx/conf.d... more...
默认情况下,这个 function 读取 /etc/nginx/templates/*.template 中的模板文件,并将执行 envsubst 的结果输出到 /etc/nginx/conf.d... 更多...
My docker-compose.yaml works when it looks like this:我的 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
On host I have a conf file ./data/nginx/templates/app.conf.template
which contains a conf file with global variables throughout in the form ${variable_name}
.在主机上,我有一个 conf 文件
./data/nginx/templates/app.conf.template
,其中包含一个带有全局变量的 conf 文件,格式${variable_name}
。
With this set up I'm able to run the container and my redirects work as expected.通过这个设置,我可以运行容器并且我的重定向按预期工作。 When I
exec
into the container I can cat /etc/nginx/conf.d/app.conf
and see the file with the correct variables swapped in from the.env file.当我
exec
到容器中时,我可以cat /etc/nginx/conf.d/app.conf
并查看带有从 .env 文件中交换的正确变量的文件。
But I need to add a command to my docker-compose.yaml:但我需要向我的 docker-compose.yaml 添加一个命令:
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
When I add that command the set up fails and the global variables are not swapped into the app.conf file within the container.当我添加该命令时,设置失败并且全局变量不会交换到容器内的 app.conf 文件中。
On another forum it was suggested I move the command
into it's own file in the container.在另一个论坛上,有人建议我将
command
移到容器中它自己的文件中。 I then gave this a try and created a shell script test.sh
:然后我尝试了一下并创建了一个 shell 脚本
test.sh
:
#/bin/sh
while :;
do sleep 6h & wait $${!};
nginx -s reload;
done;
My new docker-compose:我的新 docker-compose:
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
This fails.这失败了。 Although when I exec into the container and
cat /etc/nginx/conf.d/app.conf
I DO see the correct config, it just does not seem to be working in that my redirects, which otherwise do work when I don't include this test.sh script within /docker-entrypoint.d/
.虽然当我执行到容器中并
cat /etc/nginx/conf.d/app.conf
我确实看到了正确的配置,但它似乎在我的重定向中不起作用,否则当我不这样做时它会起作用将此 test.sh 脚本包含在/docker-entrypoint.d/
中。
I asked nearly same question yesterday and was given a working solution.我昨天问了几乎同样的问题,并得到了一个可行的解决方案。 However, it 'feels more correct' to add a shell script to the container at
/docker-entrypoint.d/
and go that route instead like I've attempted in this post.但是,将 shell 脚本添加到
/docker-entrypoint.d/
和 go 的容器中,而不是像我在这篇文章中尝试的那样,“感觉更正确”。
For what you're trying to do, I think the best solution is to create a sidecar container, like this:对于您正在尝试做的事情,我认为最好的解决方案是创建一个边车容器,如下所示:
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
This lets you use the upstream nginx
image without needing to muck about with its mechanics.这使您可以使用上游
nginx
图像,而无需对其机制进行处理。 The key here is that (a) we run the nginx_reloader
container in the same PID namespace as the nginx
container itself, and (b) we arrange for the two containers to share a /run
directory so that the nginx -s reload
command can find the pid of the nginx
process in the expected location.这里的关键是(a)我们在与
nginx
容器本身相同的 PID 命名空间中运行nginx_reloader
容器,以及(b)我们安排两个容器共享一个/run
目录,以便nginx -s reload
命令可以找到nginx
进程在预期位置的 pid。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.