Required Domains extracted at startup

The required domains are now extracted at startup of the
container via the docker socket. A certificate that contains all
domains as common or alternative name is generated and used.
This commit is contained in:
Joachim Lusiardi 2016-04-08 06:46:00 +02:00
parent 63994b2103
commit 973abaeb23
2 changed files with 40 additions and 16 deletions

View File

@ -34,11 +34,11 @@ def analyse_env_vars(inspect_data):
env_data[t[0]] = t[1] env_data[t[0]] = t[1]
return env_data return env_data
def handle_container(id): def handle_container(docker_client, id):
"""This function take a container's id and collects all data required """This function take a container's id and collects all data required
to create a proper proxy configuration. The configuration is then to create a proper proxy configuration. The configuration is then
written to the directory of temporary nginx files""" written to the directory of temporary nginx files"""
inspect_data = client.inspect_container(id) inspect_data = docker_client.inspect_container(id)
env_vars = analyse_env_vars(inspect_data) env_vars = analyse_env_vars(inspect_data)
if 'PROXY_DATA' in env_vars: if 'PROXY_DATA' in env_vars:
proxy_data = analyse_proxy_data(env_vars) proxy_data = analyse_proxy_data(env_vars)
@ -47,10 +47,10 @@ def handle_container(id):
return [] return []
def get_resolving_domains_from_containers(docker_client): def get_resolving_domains_from_containers(docker_client):
container_ids = client.containers(quiet=True) container_ids = docker_client.containers(quiet=True)
domains = [] domains = []
for container_id in container_ids: for container_id in container_ids:
domains.extend(handle_container(container_id['Id'])) domains.extend(handle_container(docker_client, container_id['Id']))
resolved_domains = [] resolved_domains = []
for domain in domains: for domain in domains:

View File

@ -1,11 +1,15 @@
#!/usr/bin/python3.4 #!/usr/bin/python3.4
import os import os
import sys
import signal import signal
import logging import logging
import time import time
import hashlib import hashlib
import list_domains
from docker import Client
cert_path='/data/haproxy' cert_path='/data/haproxy'
cert_file='/data/haproxy/cert.pem' cert_file='/data/haproxy/cert.pem'
pid_file='/haproxy.pid' pid_file='/haproxy.pid'
@ -45,10 +49,12 @@ def kill_haproxy():
def start_haproxy_ssl(): def start_haproxy_ssl():
logging.info('starting haproxy SSL') logging.info('starting haproxy SSL')
os.system('/usr/sbin/haproxy -f /haproxy_ssl.conf -p /haproxy.pid') os.system('/usr/sbin/haproxy -f /haproxy_ssl.conf -p /haproxy.pid')
return is_haproxy_running()
def start_haproxy(): def start_haproxy():
logging.info('starting haproxy NON SSL') logging.info('starting haproxy NON SSL')
os.system('/usr/sbin/haproxy -f /haproxy.conf -p /haproxy.pid') os.system('/usr/sbin/haproxy -f /haproxy.conf -p /haproxy.pid')
return False
def is_haproxy_running(): def is_haproxy_running():
try: try:
@ -68,25 +74,43 @@ def ssl_possible():
else: else:
return True return True
def create_haproxy_cert():
"""Combines the freshly created fullchain.pem and privkey.pem into /data/haproxy/cert.pem"""
os.system('DIR=`ls -td /data/config/live/*/ | head -1`; cat ${DIR}/fullchain.pem ${DIR}/privkey.pem > /data/haproxy/cert.pem')
def create_cert_data_standalone(domains):
domains = " -d ".join(domains)
os.system('/letsencrypt/letsencrypt-auto --config letencrypt.conf certonly -d ' + domains)
if __name__ == '__main__': if __name__ == '__main__':
setup_logging() setup_logging()
logging.info('starting') logging.info('starting')
cert_file_hash = ''
if ssl_possible():
logging.info('try in SSL mode')
start_haproxy_ssl()
cert_file_hash = hash_cert_file() cert_file_hash = hash_cert_file()
if is_haproxy_running():
SSL_RUNNING=True # try to start in SSL mode, no problem if that fails
else: logging.info('try in SSL mode')
SSL_RUNNING = start_haproxy_ssl()
if not SSL_RUNNING:
logging.info('SSL mode failed') logging.info('SSL mode failed')
if not is_haproxy_running() or not ssl_possible():
if not is_haproxy_running():
# tried to start haproxy and this failed, so we need to create a certificate and try again:
# - start non ssl haproxy to be able to get a valid cert
logging.info('try in NON SSL mode') logging.info('try in NON SSL mode')
start_haproxy() SSL_RUNNING = start_haproxy()
SSL_RUNNING=False # - get all domains
client = Client(base_url='unix://var/run/docker.sock', version='1.15')
resolved_domains = list_domains.get_resolving_domains_from_containers(client)
# - create cert
create_cert_data_standalone(resolved_domains)
create_haproxy_cert()
# now we should have it up and running or something weird happened.
if not is_haproxy_running():
logging.error('could not start after generating cert. See output above.')
sys.exit(1)
while True: while True:
time.sleep(10) time.sleep(10)