Commit 51074a57 authored by Ozoux's avatar Ozoux

Clean repo, closes #57

parent 8b801bcb
[submodule "services/revealjs"]
path = services/revealjs
url = https://github.com/indiehosters/revealjs
# Dockerfiles
This repo is a placeholder for all the applications that need to be developped.
This repo contains the Dockerfiles for images used by indiehosters. Some are per-user, others (like the load-balancer and email service) are server-wide.
In this repo, we have three ways of building Docker images:
* from source - In this repo, there will be a git submodule to a software project that includes a Dockerfile in its source repo.
we will build images from that as indiehosters/project:tag, where project is the name of the submodule here, and tag is a git
tag inside that repo. If what we need for the IndieHosters infrastructure is not available out of the box then we will fork the
project, and submodule our fork, while at the same time submiting a pull request upstream. As soon as this pull request gets merged
we will submodule the upstream project directly again.
* from package - In this repo, there will be a folder with a Dockerfile which refers to the actual software via a package system, probably
apt-get.
* by reference - Same as from package, but instead of doing a package install like `apt-get`, it would do a source install, so `git clone` or
`wget`. This might be useful for instance when an image combines code from several open source projects. In most cases though, it will be preferable to add the Dockerfile into the upstream source repo of the user-facing application.
# Build
To build, run `sh ./init.sh; sh ./build.sh`
You can see as the issue tracker for all modularized IndieHosters applications.
module.exports.getDockerOptions = function(host, application, envVars, MbOfRAM, localDataPath) {
var envVarArr = [];
for (var i in envVars) {
envVarArr.push(i + '=' + envVars[i]);
}
return {
createOptions: {
Image: 'indiehosters/' + application,
name: host,
Hostname: host,
Memory: MbOfRAM * 1024 * 1024,
MemorySwap: -1,
Env: envVarArr
},
startOptions: {
Binds: [ localDataPath + '/' + application + ':/data' ]
}
};
};
{
"name": "indiehosters-applications",
"repository": "https://github.com/indiehosters/applications",
"version": "0.0.1",
"dependencies": {
},
"main": "index.js"
}
FROM debian:jessie
ENV DEBIAN_FRONTEND noninteractive
RUN \
export VERSION=0.7.01 && \
apt-get update && \
apt-get install -y wget python python-dev python-pip librsync-dev ncftp lftp rsync && \
rm -rf /var/lib/apt/lists/* && \
pip install --upgrade lockfile paramiko pycrypto && \
cd /tmp/ && \
wget https://launchpad.net/duplicity/0.7-series/$VERSION/+download/duplicity-$VERSION.tar.gz && \
cd /opt/ && \
tar xzvf /tmp/duplicity-$VERSION.tar.gz && \
rm /tmp/duplicity-$VERSION.tar.gz && \
cd duplicity-$VERSION && \
./setup.py install
ENTRYPOINT [ "/usr/local/bin/duplicity" ]
#!/bin/sh
git pull --rebase
git submodule update
cd per-user/idno
git checkout add-Dockerfile
cd ../..
cd per-user/anchorcms
git checkout add-Dockerfile
cd ../..
for image in $(ls per-user/* | cut -d "/" -f 2); do
echo sudo docker build -t indiehosters/$image per-user/$image/;
done
for image in $(ls server-wide/* | cut -d "/" -f 2); do
echo sudo docker build -t indiehosters/$image server-wide/$image/;
done
FROM debian:jessie
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && \
apt-get install -q -y \
python3 \
mysql-client \
wget curl && \
rm -rf /var/lib/apt/lists/*
COPY editconf.py /opt/editconf.py
COPY mysql-check.sh /opt/mysql-check.sh
RUN chmod u+x /opt/editconf.py && \
chmod u+x /opt/mysql-check.sh
#!/usr/bin/python3
#
# This is a helper tool for editing configuration files during the setup
# process. The tool is given new values for settings as command-line
# arguments. It comments-out existing setting values in the configuration
# file and adds new values either after their former location or at the
# end.
#
# The configuration file has settings that look like:
#
# NAME=VALUE
#
# If the -s option is given, then space becomes the delimiter, i.e.:
#
# NAME VALUE
#
# If the -w option is given, then setting lines continue onto following
# lines while the lines start with whitespace, e.g.:
#
# NAME VAL
# UE
import sys, re
# sanity check
if len(sys.argv) < 3:
print("usage: python3 editconf.py /etc/file.conf [-s] [-w] [-t] NAME=VAL [NAME=VAL ...]")
sys.exit(1)
# parse command line arguments
filename = sys.argv[1]
settings = sys.argv[2:]
delimiter = "="
delimiter_re = r"\s*=\s*"
comment_char = "#"
folded_lines = False
testing = False
while settings[0][0] == "-" and settings[0] != "--":
opt = settings.pop(0)
if opt == "-s":
# Space is the delimiter
delimiter = " "
delimiter_re = r"\s+"
elif opt == "-w":
# Line folding is possible in this file.
folded_lines = True
elif opt == "-c":
# Specifies a different comment character.
comment_char = settings.pop(0)
elif opt == "-t":
testing = True
else:
print("Invalid option.")
sys.exit(1)
# create the new config file in memory
found = set()
buf = ""
input_lines = list(open(filename))
while len(input_lines) > 0:
line = input_lines.pop(0)
# If this configuration file uses folded lines, append any folded lines
# into our input buffer.
if folded_lines and line[0] not in (comment_char, " ", ""):
while len(input_lines) > 0 and input_lines[0][0] in " \t":
line += input_lines.pop(0)
# See if this line is for any settings passed on the command line.
for i in range(len(settings)):
# Check that this line contain this setting from the command-line arguments.
name, val = settings[i].split("=", 1)
m = re.match(
"(\s*)"
+ "(" + re.escape(comment_char) + "\s*)?"
+ re.escape(name) + delimiter_re + "(.*?)\s*$",
line, re.S)
if not m: continue
indent, is_comment, existing_val = m.groups()
# If this is already the setting, do nothing.
if is_comment is None and existing_val == val:
# It may be that we've already inserted this setting higher
# in the file so check for that first.
if i in found: break
buf += line
found.add(i)
break
# comment-out the existing line (also comment any folded lines)
if is_comment is None:
buf += comment_char + line.rstrip().replace("\n", "\n" + comment_char) + "\n"
else:
# the line is already commented, pass it through
buf += line
# if this option oddly appears more than once, don't add the setting again
if i in found:
break
# add the new setting
buf += indent + name + delimiter + val + "\n"
# note that we've applied this option
found.add(i)
break
else:
# If did not match any setting names, pass this line through.
buf += line
# Put any settings we didn't see at the end of the file.
for i in range(len(settings)):
if i not in found:
name, val = settings[i].split("=", 1)
buf += name + delimiter + val + "\n"
if not testing:
# Write out the new file.
with open(filename, "w") as f:
f.write(buf)
else:
# Just print the new file to stdout.
print(buf)
#!/bin/bash -eux
source /etc/environment
echo "=> Trying to connect to MySQL/MariaDB using:"
echo "========================================================================"
echo " Database Host Address: $DB_HOST"
echo " Database Port number: $DB_PORT"
echo " Database Username: $DB_USER"
echo " Database Password: $DB_PASS"
echo "========================================================================"
for ((i=0;i<10;i++))
do
DB_CONNECTABLE=$(mysql -u$DB_USER -p$DB_PASS -h$DB_HOST -P$DB_PORT -e 'status' >/dev/null 2>&1; echo "$?")
if [[ DB_CONNECTABLE -eq 0 ]]; then
exit 0
fi
sleep 5
done
exit 1
service auth {
unix_listener /var/spool/postfix/dovecot/auth {
mode = 0666
user = postfix
group = postfix
}
}
service lmtp {
unix_listener /var/spool/postfix/dovecot/lmtp {
mode = 0600
user = postfix
group = postfix
}
}
FROM indiepaas/base-email
RUN apt-get update && \
apt-get install -q -y \
dovecot-core \
dovecot-imapd \
dovecot-lmtpd \
dovecot-mysql && \
rm -rf /var/lib/apt/lists/*
COPY 99-local-lmtp.conf /etc/dovecot/conf.d/99-local-lmtp.conf
COPY auth-sql.conf.ext /etc/dovecot/conf.d/auth-sql.conf.ext
COPY dovecot-sql.conf.ext /etc/dovecot/dovecot-sql.conf.ext
COPY 99-local-auth.conf /etc/dovecot/conf.d/99-local-auth.conf
COPY init.sql /init.sql
COPY startup.sh /startup.sh
RUN \
groupadd -r postfix && \
useradd -r -g postfix postfix && \
chmod u+x /startup.sh && \
/opt/editconf.py /etc/dovecot/conf.d/10-master.conf \
default_process_limit=250 && \
/opt/editconf.py /etc/sysctl.conf \
fs.inotify.max_user_instances=1024 && \
/opt/editconf.py /etc/dovecot/conf.d/10-mail.conf \
mail_location=maildir:/mail/mailboxes/%d/%n \
mail_privileged_group=mail \
first_valid_uid=0 && \
/opt/editconf.py /etc/dovecot/conf.d/10-auth.conf \
disable_plaintext_auth=yes \
'auth_mechanisms=plain login' && \
/opt/editconf.py /etc/dovecot/conf.d/10-ssl.conf \
ssl=required \
'ssl_cert=</ssl/ssl_certificate.pem' \
'ssl_key=</ssl/ssl_private_key.pem' \
'ssl_protocols=!SSLv3 !SSLv2' \
'ssl_cipher_list=TLSv1+HIGH !SSLv2 !RC4 !aNULL !eNULL !3DES @STRENGTH' && \
/opt/editconf.py /etc/dovecot/conf.d/20-imap.conf \
imap_idle_notify_interval="4 mins" && \
sed -i "s/#port = 143/port = 0/" /etc/dovecot/conf.d/10-master.conf && \
sed -i "s/#port = 110/port = 0/" /etc/dovecot/conf.d/10-master.conf && \
sed -i "s/#*\(\!include auth-system.conf.ext\)/#\1/" /etc/dovecot/conf.d/10-auth.conf && \
sed -i "s/#\(\!include auth-sql.conf.ext\)/\1/" /etc/dovecot/conf.d/10-auth.conf && \
mkdir -p /mail/mailboxes && \
chown -R mail:dovecot /etc/dovecot && \
chown -R mail.mail /mail/mailboxes && \
chmod -R o-rwx /etc/dovecot && \
chmod 0600 /etc/dovecot/dovecot-sql.conf.ext
ENTRYPOINT ["/startup.sh"]
VOLUME ["/var/spool/postfix/dovecot"]
EXPOSE 993
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = static
args = uid=mail gid=mail home=/mail/mailboxes/%d/%n
}
driver = mysql
connect = host=##DB_HOST## dbname=servermail user=##DB_USER## password=##DB_PASS##
default_pass_scheme = SHA512-CRYPT
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';
USE servermail;
CREATE TABLE `virtual_domains` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `virtual_users` (
`id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT NOT NULL,
`password` VARCHAR(106) NOT NULL,
`email` VARCHAR(120) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `virtual_aliases` (
`id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT NOT NULL,
`source` varchar(100) NOT NULL,
`destination` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#!/bin/bash -eux
export DB_PORT=3306
export DB_HOST=db
export DB_USER=admin
echo $HOSTNAME
sed -i "s/##DB_HOST##/$DB_HOST/" /etc/dovecot/dovecot-sql.conf.ext
sed -i "s/##DB_USER##/$DB_USER/" /etc/dovecot/dovecot-sql.conf.ext
sed -i "s/##DB_PASS##/$DB_PASS/" /etc/dovecot/dovecot-sql.conf.ext
/opt/editconf.py /etc/dovecot/conf.d/15-lda.conf postmaster_address=postmaster@$HOSTNAME
/opt/mysql-check.sh
DB_EXISTS=$(mysql -u$DB_USER -p$DB_PASS -h$DB_HOST -P$DB_PORT -e "SHOW DATABASES LIKE 'servermail';" 2>&1 |grep servermail > /dev/null ; echo "$?")
if [[ DB_EXISTS -eq 1 ]]; then
echo "=> Creating database servermail"
RET=$(mysql -u$DB_USER -p$DB_PASS -h$DB_HOST -P$DB_PORT -e "CREATE DATABASE servermail")
if [[ RET -ne 0 ]]; then
echo "Cannot create database for emails"
exit RET
fi
echo "=> Loading initial database data to servermail"
RET=$(mysql -u$DB_USER -p$DB_PASS -h$DB_HOST -P$DB_PORT servermail < /init.sql)
if [[ RET -ne 0 ]]; then
echo "Cannot load initial database data for emails"
exit RET
fi
echo "=> Done!"
else
echo "=> Skipped creation of database servermail it already exists."
fi
dovecot -F
INSERT INTO `servermail`.`virtual_domains`
(`id` ,`name`)
VALUES
('1', 'example.com'),
('2', 'hostname.example.com');
INSERT INTO `servermail`.`virtual_users`
(`id`, `domain_id`, `password` , `email`)
VALUES
('1', '1', ENCRYPT('firstpassword', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'email1@example.com'),
('2', '1', ENCRYPT('secondpassword', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'email2@example.com');
INSERT INTO `servermail`.`virtual_aliases`
(`id`, `domain_id`, `source`, `destination`)
VALUES
('1', '1', 'alias@example.com', 'email1@example.com');
FROM indiepaas/base-email
RUN apt-get update && \
apt-get install -q -y \
postfix \
postfix-pcre \
postfix-mysql \
supervisor \
ca-certificates \
opendkim \
opendkim-tools \
opendmarc && \
rm -rf /var/lib/apt/lists/*
COPY install.sh /install.sh
COPY postfix_outgoing_mail_header_filters /etc/postfix/outgoing_mail_header_filters
COPY virtual-mailbox-domains.cf /etc/postfix/virtual-mailbox-domains.cf
COPY virtual-mailbox-maps.cf /etc/postfix/virtual-mailbox-maps.cf
COPY virtual-alias-maps.cf /etc/postfix/virtual-alias-maps.cf
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
RUN \
chmod u+x /install.sh && \
/opt/editconf.py /etc/postfix/main.cf \
inet_interfaces=all \
myhostname=##HOSTNAME##\
smtpd_banner="\$myhostname ESMTP Hi, I'm a hosted by an IndieHoster (Debian/Postfix; see https://indiehosters.net/)" \
mydestination=localhost && \
/opt/editconf.py /etc/postfix/master.cf -s -w \
"submission=inet n - - - - smtpd -o syslog_name=postfix/submission -o smtpd_milters=inet:127.0.0.1:8891 -o smtpd_tls_ciphers=high -o smtpd_tls_protocols=!SSLv2,!SSLv3 -o cleanup_service_name=authclean" && \
/opt/editconf.py /etc/postfix/master.cf -s -w \
"authclean=unix n - - - 0 cleanup -o header_checks=pcre:/etc/postfix/outgoing_mail_header_filters" && \
/opt/editconf.py /etc/postfix/main.cf \
smtpd_tls_security_level=may\
smtpd_tls_auth_only=yes \
smtpd_tls_cert_file=/ssl/ssl_certificate.pem \
smtpd_tls_key_file=/ssl/ssl_private_key.pem \
smtpd_tls_dh1024_param_file=/ssl/dh2048.pem \
smtpd_tls_received_header=yes && \
/opt/editconf.py /etc/postfix/main.cf \
smtpd_relay_restrictions=permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination && \
/opt/editconf.py /etc/postfix/main.cf \
smtp_tls_CAfile=/etc/ssl/certs/ca-certificates.crt \
smtp_tls_loglevel=2 && \
/opt/editconf.py /etc/postfix/main.cf virtual_transport=lmtp:[127.0.0.1]:10025 && \
/opt/editconf.py /etc/postfix/main.cf virtual_transport=lmtp:unix:dovecot/lmtp && \
/opt/editconf.py /etc/postfix/main.cf \
smtpd_sender_restrictions="reject_non_fqdn_sender,reject_unknown_sender_domain,reject_rhsbl_sender dbl.spamhaus.org" \
smtpd_recipient_restrictions=permit_sasl_authenticated,permit_mynetworks,"reject_rbl_client zen.spamhaus.org",reject_unlisted_recipient && \
/opt/editconf.py /etc/postfix/main.cf \
message_size_limit=134217728 && \
/opt/editconf.py /etc/postfix/main.cf \
smtpd_sasl_type=dovecot \
smtpd_sasl_path=dovecot/auth \
smtpd_sasl_auth_enable=yes && \
/opt/editconf.py /etc/postfix/main.cf \
virtual_mailbox_domains=mysql:/etc/postfix/virtual-mailbox-domains.cf \
virtual_mailbox_maps=mysql:/etc/postfix/virtual-mailbox-maps.cf \
virtual_alias_maps=mysql:/etc/postfix/virtual-alias-maps.cf \
local_recipient_maps=\$virtual_mailbox_maps && \
/opt/editconf.py /etc/postfix/main.cf \
mynetworks="127.0.0.0/8 172.17.42.0/24" && \
/opt/editconf.py /etc/opendmarc.conf -s \
"Syslog=true" \
"Socket=inet:8893@[127.0.0.1]" && \
/opt/editconf.py /etc/postfix/main.cf \
"smtpd_milters=inet:127.0.0.1:8891 inet:127.0.0.1:8893"\
non_smtpd_milters=\$smtpd_milters \
milter_default_action=accept && \
echo "MinimumKeyBits 1024" >> /etc/opendkim.conf && \
echo "ExternalIgnoreList refile:/etc/opendkim/TrustedHosts" >> /etc/opendkim.conf && \
echo "InternalHosts refile:/etc/opendkim/TrustedHosts" >> /etc/opendkim.conf && \
echo "KeyTable refile:/etc/opendkim/KeyTable" >> /etc/opendkim.conf && \
echo "SigningTable refile:/etc/opendkim/SigningTable" >> /etc/opendkim.conf && \
echo "Socket inet:8891@localhost" >> /etc/opendkim.conf && \
echo "RequireSafeKeys false" >> /etc/opendkim.conf
#RUN /opt/editconf.py /etc/postfix/main.cf \
#smtp_tls_security_level=dane \
#smtp_dns_support_level=dnssec
VOLUME ["/var/spool/postfix/"]
CMD /install.sh;/usr/bin/supervisord -c /etc/supervisor/supervisord.conf
#!/bin/bash -eux
export DB_PORT=3306
export DB_HOST=db
export DB_USER=admin
echo $HOSTNAME
sed -i "s/##DB_USER##/$DB_USER/" /etc/postfix/virtual-mailbox-domains.cf
sed -i "s/##DB_PASS##/$DB_PASS/" /etc/postfix/virtual-mailbox-domains.cf
sed -i "s/##DB_USER##/$DB_USER/" /etc/postfix/virtual-mailbox-maps.cf
sed -i "s/##DB_PASS##/$DB_PASS/" /etc/postfix/virtual-mailbox-maps.cf
sed -i "s/##DB_USER##/$DB_USER/" /etc/postfix/virtual-alias-maps.cf
sed -i "s/##DB_PASS##/$DB_PASS/" /etc/postfix/virtual-alias-maps.cf
sed -i "s/##HOSTNAME##/$HOSTNAME/" /etc/postfix/virtual-alias-maps.cf
sed -i "s/##HOSTNAME##/$HOSTNAME/" /etc/postfix/main.cf
/opt/mysql-check.sh
if [ ! -f /etc/opendkim/TrustedHosts ]; then
mkdir -p /etc/opendkim
echo "127.0.0.1" > /etc/opendkim/TrustedHosts
fi
chown -R postfix:postfix /var/spool/postfix/dovecot
# Remove the first line of the Received: header. Note that we cannot fully remove the Received: header
# because OpenDKIM requires that a header be present when signing outbound mail. The first line is
# where the user's home IP address would be.
/^\s*Received:[^\n]*(.*)/ REPLACE Received: from authenticated-user (unknown [127.0.0.1])$1
# Remove other typically private information.
/^\s*User-Agent:/ IGNORE
/^\s*X-Enigmail:/ IGNORE
/^\s*X-Mailer:/ IGNORE
/^\s*X-Originating-IP:/ IGNORE
[supervisord]
nodaemon=true
[program:postfix]
process_name = postfix
command = /etc/init.d/postfix start
startsecs = 0
autorestart = false
[program:opendkim]
process_name = opendkim
command = /etc/init.d/opendkim start
startsecs = 0
autorestart = false
[program:opendmarc]
process_name = opendmarc
command = /etc/init.d/opendmarc start
startsecs = 0
autorestart = false
user = ##DB_USER##
password = ##DB_PASS##
hosts = db
dbname = servermail
query = SELECT destination FROM virtual_aliases WHERE source='%s'
user = ##DB_USER##
password = ##DB_PASS##
hosts = db
dbname = servermail
query = SELECT 1 FROM virtual_domains WHERE name='%s'
user = ##DB_USER##
password = ##DB_PASS##
hosts = db
dbname = servermail
query = SELECT 1 FROM virtual_users WHERE email='%s'
#!/bin/sh
git pull --rebase
git submodule init
git submodule update
cd server-wide/yunohost
git submodule init
git submodule update
git remote add me git@github.com:michielbdejong/YunoHost-install_script
git fetch me
git checkout me/add-Dockerfile -b add-Dockerfile
cd ../..
cd per-user/idno
git submodule init
git submodule update
git remote add me git@github.com:michielbdejong/idno
git fetch me
git checkout me/add-Dockerfile -b add-Dockerfile
cd ../..
FROM debian:jessie
ENV DEBIAN_FRONTEND noninteractive
RUN \
apt-get update &&\
apt-get install -y \
wget \
ca-certificates &&\
rm -rf /var/lib/apt/lists/*
ADD confd /etc/confd
RUN \
wget https://github.com/kelseyhightower/confd/releases/download/v0.7.1/confd-0.7.1-linux-amd64 -O confd && \
chmod +x confd
RUN \
wget https://get.docker.com/builds/Linux/x86_64/docker-1.2.0 -O docker && \
chmod +x docker
VOLUME ["/etc/confd/", "/etc/haproxy"]
ENTRYPOINT ["/confd"]
CMD ["-interval=60", "-node=172.17.42.1:4001", "-watch=true", "-verbose=true"]
# Confd
The smallest confd docker image in town ;)
## Run
This image will log everything to stdout/stderr.
It was designed to work with HAproxy, but you can use it for anything! There is no configuration, you'll have to mount the config folder. There is a nice example in [indiehosters/confd git repo](https://github.com/indiehosters/dockerfiles/tree/master/server-wide/confd).
```bash
docker run\
-v /haproxy-config:/etc/haproxy/\
-v ./confd/:/etc/confd/\
-v /var/run/docker.sock:/var/run/docker.sock\
indiehosters/confd
```
It works really well with [indiehosters/haproxy](https://registry.hub.docker.com/u/indiehosters/haproxy/) to have automatic configuration of HAproxy backed by `etcd` or `consul`.
[template]
src = "crt-list.tmpl"
dest = "/etc/haproxy/crt-list"
keys = [
"/services"
]
reload_cmd = "/docker kill --signal=\"SIGUSR1\" haproxy"
[template]
src = "haproxy.cfg.tmpl"
dest = "/etc/haproxy/haproxy.cfg"
keys = [
"/services"
]
reload_cmd = "/docker kill --signal=\"SIGUSR1\" haproxy"
{{range $app := lsdir "/services"}}
{{$hostnames := printf "/services/%s/*" $app}}
{{range gets $hostnames}}
{{$hostname := .Key}}
/etc/haproxy/approved-certs/{{base $hostname}}.pem {{base $hostname}}
/etc/haproxy/approved-certs/{{base $hostname}}.pem www.{{base $hostname}}
{{end}}
{{end}}