Maybe you can try dcinja, it's my open-source project
dcinja use inja powerful library (like jinja) as template engine for run-time render template. It's support condition & include feature, that envsubst can't provided. Need to install dcinja in your docker image, and the binary is small.
here is the simple example
alpine:
$ apk --no-cache add wget libstdc++
$ wget https://github.com/Falldog/dcinja/releases/download/v1.3/dcinja-1.3.alpine.tar.gz \
&& tar xvzf dcinja-1.3.alpine.tar.gz
$ ./dcinja -j '{"SERVER_NAME": "www.test.com"}' -s /etc/nginx/nginx.conf.template -d /etc/nginx/nginx.conf
debian:
$ apt-get update && apt-get install -y wget
$ wget https://github.com/Falldog/dcinja/releases/download/v1.3/dcinja-1.3.linux-amd64.tar.gz \
&& tar xvzf dcinja-1.3.linux-amd64.tar.gz
$ ./dcinja -j '{"SERVER_NAME": "www.test.com"}' -s /etc/nginx/nginx.conf.template -d /etc/nginx/nginx.conf
Example
An example of dynamically embedding the environment variable SERVER_NAME in nginx.conf is as follows:
nginx.conf.template
server {
listen 80;
server_name {{ SERVER_NAME }};
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name {{ SERVER_NAME }};
ssl_certificate /etc/ssl/private/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
ssl on;
access_log /var/log/nginx/ghost.access.log;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://xxx:2368;
proxy_read_timeout 90;
proxy_redirect http://xxx:2368 https://{{ SERVER_NAME }}:443;
}
}
Dockerfile
need to build the image with dcinja library
FROM nginx:1.21-alpine
RUN apk add --no-cache wget libstdc++
RUN mkdir -p /app \
&& cd /app \
&& wget https://github.com/Falldog/dcinja/releases/download/v1.3/dcinja-1.3.alpine.tar.gz \
&& tar xvzf dcinja-1.3.alpine.tar.gz \
&& cp /app/dcinja /bin/
docker-compose.yml
You can assign the the env SERVER_NAME at docker-compose to control the runtime result of nginx.conf
version: '2'
services:
nginx:
build: .
image: my-nginx:latest
container_name: my-nginx
command: >
/bin/sh -c "
dcinja --force-system-envs -e SERVER_NAME \
-s /etc/nginx/nginx.conf.template \
-d /etc/nginx/nginx.conf \
&& nginx -g 'daemon off;'
"
volumes:
- ./nginx.conf.template:/etc/nginx/nginx.conf.template
ports:
- 8080:80
environment:
SERVER_NAME: "test.example.com"
Complex template example
You can maintain 3 template files, 1) nginx.conf.template 2) https.conf.template 3) http.conf.template. Determine the flag (enable_ssl) to include the right template at runtime.
{% if enable_ssl %}
{% include "https.conf.template" %}
{% else %}
{% include "http.conf.template" %}
{% endif %}
Other dcinja examples
input template from STDIN, output template to STDOUT
$ echo "TEST Name: {{ name }}" | dcinja -j '{"name": "Foo"}'
>>> TEST Name: Foo
input template from file, output template to file
$ dcinja -j '{"name": "Foo"}' -s input.template -d output.template
input json from file
$ dcinja -f param.json -s input.template -d output.template