Nginx容器如何通过环境变量设置配置文件
使用Nginx容器时,一定会有个需求,那就是通过环境变量来设置配置文件,因为在容器中,对于一些易变且常用的配置,用环境变量会比修改配置文件更容易,比如代理的地址,端口等等。
但是我们知道Nginx并不支持在配置文件中使用环境变量,所以我们需要通过一些方式来实现这个需求,且不需要改Nginx的源码。经过思考发现可以用工具去替换配置文件中的环境变量,这样就可以实现了,以下是一个有效方案:
-
nginx.conf.tempalte
:指的是配置文件模板,这个文件中会有一些环境变量,比如${SERVER_IP}
,${SERVER_PORT}
等等 -
转换工具
:用于将模板文件中的环境变量替换成真实值。能实现该功能的方式很多,我这里只展示其中2种。 -
nginx.conf
:Nginx的配置文件,由nginx.conf.tempalte
经Substitution Tool
处理后生成的。
转换工具: envsubst(推荐)¶
envsubst
是一个非常简单的工具,它可以将环境变量替换成真实值,比如:
上述命令会将 /path/to/nginx.conf.template
中的 ${SERVER_IP}
和 ${SERVER_PORT}
替换成真实值,然后输出到 /path/to/nginx.conf
中。
假设nginx.conf.template
的内容如下:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
proxy_set_header Client-Port $remote_port;
proxy_set_header Client-IP $remote_addr;
location / {
proxy_pass http://${SERVER_IP}:${SERVER_PORT};
}
}
}
我们设置环境变量为:export SERVER_IP=192.168.8.10
和export SERVER_PORT=8080
经过替换工具后,它将产生下面的结果:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
proxy_set_header Client-Port $remote_port;
proxy_set_header Client-IP $remote_addr;
location / {
proxy_pass http://192.168.8.10:8080;
}
}
}
大家应该注意到了,nginx.conf.template
中还有别的变量,但是并没有被替换,这是因为我在envsubst
种指定了要替代的变量名,这一点尤其重要:envsubst '${SERVER_IP} ${SERVER_PORT}'
但是只有上面还不够,我们需要跟容器结合,这里就分别给Dockerfile和docker-compose.yml给出示例。
docker-compose.yml示例如下:
version: '3.8'
services:
proxy:
image: homqyy/hengine
command: bash -c "envsubst '${SERVER_IP} ${SERVER_PORT}' < /usr/local/hengine/conf/nginx.conf.template > /usr/local/hengine/conf/nginx.conf && /usr/local/hengine/sbin/nginx -g 'daemon off;'"
environment:
SERVER_IP: 192.168.8.10
SERVER_PORT: 8080
volumes:
- ./conf/nginx.conf.template:/usr/local/hengine/conf/nginx.conf.template
Dockerfile示例如下:
-
编写
docker-entrypoint.sh
作为容器的启动文件: -
编写
Dockerfile
:
envsubst
的工具使用特别简单,因此强烈推荐。其安装方式可参考如下:
操作系统 | 安装方式 |
---|---|
OS X | brew install gettext |
Debian | apt-get install gettext-base |
Ubuntu | apt-get install gettext-base |
Alpine | apk add gettext |
Arch Linux | pacman -S gettext |
Kali Linux | apt-get install gettext-base |
CentOS | yum install gettext |
Fedora | dnf install gettext |
Raspbian | apt-get install gettext-base |
转换工具: sed¶
如果使用别人的镜像,可能没有envsubst
这个工具,那么我们可以使用sed
来实现替换,比如:
-
复制模板文件到正式文件:
-
修改IP:
-
修改端口:
可以看出这种方法如果修改较多变量的话命令组合起来会比较长,但是它的优点是不需要安装额外的工具。
如果采用这种方法,最佳实践是写个docker-entrypoint.sh
封装上述的替换命令,然后在Dockerfile
中调用。