# Reusable layer for base update - Should be cached from builder
RUN apt-get update && apt-get -y dist-upgrade && apt-get clean
-# Ensure python3 is present (for startup script), and sqlite3 (for db schema), and tini (for signal management)
-RUN apt-get install -y python3 sqlite3 tini libcap2-bin && apt-get clean
+# Ensure python3 and jinja2 is present (for startup script), and sqlite3 (for db schema), and tini (for signal management)
+RUN apt-get install -y python3 python3-jinja2 sqlite3 tini libcap2-bin && apt-get clean
# Output from builder
COPY --from=builder /build /
# Config file(s) from builder
# Should not grab this from builder - since it isn't being built
COPY --from=builder /source/dockerdata/pdns.conf /etc/powerdns/
-RUN mkdir -p /etc/powerdns/pdns.d /var/run/pdns
-RUN touch /etc/powerdns-api.conf && chown 953 /etc/powerdns-api.conf
-RUN ln -s /etc/powerdns-api.conf /etc/powerdns/pdns.d/api.conf
-
-# Make database dir before we drop root
-RUN mkdir -p /var/lib/powerdns && chown 953 /var/lib/powerdns
+RUN mkdir -p /etc/powerdns/pdns.d /var/run/pdns /var/lib/powerdns /etc/powerdns/templates.d
# Work with pdns user - not root
RUN adduser --system --disabled-password --disabled-login --no-create-home --group pdns --uid 953
-RUN chown pdns:pdns /var/run/pdns
+RUN chown pdns:pdns /var/run/pdns /var/lib/powerdns /etc/powerdns/pdns.d /etc/powerdns/templates.d
USER pdns
# Set up database - this needs to be smarter
# Reusable layer for base update - Should be cached from builder
RUN apt-get update && apt-get -y dist-upgrade && apt-get clean
-# Ensure python3 is present (for startup script), and python3-atomicwrites (for backend management), and tini (for signal management)
-RUN apt-get install -y python3 python3-atomicwrites tini libcap2-bin && apt-get clean
+# Ensure python3 and jinja2 is present (for startup script), and python3-atomicwrites (for backend management), and tini (for signal management)
+RUN apt-get install -y python3 python3-jinja2 python3-atomicwrites tini libcap2-bin && apt-get clean
# Output from builder
COPY --from=builder /build /
RUN apt install -y /tmp/equivs-dummy_1.0_all.deb && apt clean
# Config
-RUN mkdir -p /etc/dnsdist/conf.d
-RUN touch /etc/dnsdist-api.conf && chown 953 /etc/dnsdist-api.conf
-RUN ln -s /etc/dnsdist-api.conf /etc/dnsdist/conf.d/api.conf
+RUN mkdir -p /etc/dnsdist/conf.d /etc/dnsdist/templates.d
COPY --from=builder /source/dockerdata/dnsdist.conf /etc/dnsdist/
# Start script
# Work with pdns user - not root
RUN adduser --system --disabled-password --disabled-login --no-create-home --group pdns --uid 953
+RUN chown pdns:pdns /etc/dnsdist/conf.d /etc/dnsdist/templates.d
USER pdns
# DNS ports
# Reusable layer for base update - Should be cached from builder
RUN apt-get update && apt-get -y dist-upgrade && apt-get clean
-# Ensure python3 is present (for startup script), and tini for signal management
-RUN apt-get install -y python3 tini libcap2-bin && apt-get clean
+# Ensure python3 and jinja2 is present (for startup script), and tini for signal management
+RUN apt-get install -y python3 python3-jinja2 tini libcap2-bin && apt-get clean
# Executables from builder
COPY --from=builder /build /
COPY --from=builder /source/dockerdata/recursor.conf /etc/powerdns/
# Is recursor.d necessary if we copy the config into recursor.conf? (see above)
-RUN mkdir -p /etc/powerdns/recursor.d /var/run/pdns-recursor
-RUN touch /etc/powerdns-api.conf && chown 953 /etc/powerdns-api.conf
-RUN ln -s /etc/powerdns-api.conf /etc/powerdns/recursor.d/api.conf
+RUN mkdir -p /etc/powerdns/recursor.d /var/run/pdns-recursor /etc/powerdns/templates.d
# Work with pdns user - not root
RUN adduser --system --disabled-password --disabled-login --no-create-home --group pdns --uid 953
-RUN chown pdns:pdns /var/run/pdns-recursor
+RUN chown pdns:pdns /var/run/pdns-recursor /etc/powerdns/recursor.d /etc/powerdns/templates.d
USER pdns
# DNS ports
#!/usr/bin/env python3
import os
import sys
+import jinja2
program = sys.argv[0].split('-')[0]
product = os.path.basename(program)
-apiconffile = None
apienvvar = None
apiconftemplate = None
+templateroot = '/etc/powerdns/templates.d'
+templatedestination = ''
args = []
if product == 'pdns_recursor':
args = ['--disable-syslog']
- apiconffile = '/etc/powerdns-api.conf'
apienvvar = 'PDNS_RECURSOR_API_KEY'
apiconftemplate = """webserver
-api-key={apikey}
+api-key={{ apikey }}
webserver-address=0.0.0.0
webserver-allow-from=0.0.0.0/0
-webserver-password={apikey}
+webserver-password={{ apikey }}
"""
+ templatedestination = '/etc/powerdns/recursor.d'
elif product == 'pdns_server':
args = ['--disable-syslog']
- apiconffile = '/etc/powerdns-api.conf'
apienvvar = 'PDNS_AUTH_API_KEY'
apiconftemplate = """webserver
api
-api-key={apikey}
+api-key={{ apikey }}
webserver-address=0.0.0.0
webserver-allow-from=0.0.0.0/0
-webserver-password={apikey}
+webserver-password={{ apikey }}
"""
+ templatedestination = '/etc/powerdns/pdns.d'
elif product == 'dnsdist':
args = ['--supervised', '--disable-syslog']
- apiconffile = '/etc/dnsdist-api.conf'
apienvvar = 'DNSDIST_API_KEY'
- apiconftemplate = """webserver("0.0.0.0:8083", '{apikey}', '{apikey}', {{}}, '0.0.0.0/0')
+ apiconftemplate = """webserver("0.0.0.0:8083", '{{ apikey }}', '{{ apikey }}', {}, '0.0.0.0/0')
controlSocket('0.0.0.0:5199')
-setKey('{apikey}')
+setKey('{{ apikey }}')
setConsoleACL('0.0.0.0/0')
"""
+ templateroot = '/etc/dnsdist/templates.d'
+ templatedestination = '/etc/dnsdist/conf.d'
apikey = os.getenv(apienvvar)
-print("apikey=", apikey)
if apikey is not None:
- with open(apiconffile, 'w') as conf:
- conf.write(apiconftemplate.format(apikey=apikey))
+ webserver_conf = jinja2.Template(apiconftemplate).render(apikey=apikey)
+ conffile = os.path.join(templatedestination, '_api.conf')
+ with open(conffile, 'w') as f:
+ f.write(webserver_conf)
+
+templates = os.getenv('TEMPLATE_FILES')
+if templates is not None:
+ for templateFile in templates.split(','):
+ template = None
+ with open(os.path.join(templateroot, templateFile + '.j2')) as f:
+ template = jinja2.Template(f.read())
+ rendered = template.render(os.environ)
+ with open(os.path.join(templatedestination, templateFile + '.conf'), 'w') as f:
+ f.write(rendered)
os.execv(program, [program]+args+sys.argv[1:])