#!/usr/bin/python3.4 import os import sys import http.client import json import signal from string import Template target_path="/tmp/nginx" pid_file="/run/nginx.pid" non_location_template = """server { listen $listen; server_name $name; location / { proxy_set_header X-Real-IP $$remote_addr; proxy_set_header X-Forwarded-For $$remote_addr; proxy_set_header Host $$host; proxy_pass http://$ip:$port/; } } """ location_template="""server { listen $listen; server_name $name; location / { return 301 $$scheme://$name/$location; } location /$location { proxy_set_header X-Real-IP $$remote_addr; proxy_set_header X-Forwarded-For $$remote_addr; proxy_set_header Host $$host; proxy_pass http://$ip:$port/; } } """ def get_pid(): with open(pid_file, 'r') as file: return int(file.read()) def get_container_data(): conn = http.client.HTTPConnection("localhost:2375") conn.request("GET", "/containers/json") response = conn.getresponse() data = response.read().decode("UTF-8") data = json.loads(data) # print(json.dumps(data, sort_keys=True, indent=4)) conn.close() return data def inspect_container(container_id): conn = http.client.HTTPConnection("localhost:2375") conn.request("GET", "/containers/"+str(container_id)+"/json") response = conn.getresponse() data = response.read().decode("UTF-8") data = json.loads(data) # print(json.dumps(data, sort_keys=True, indent=4)) conn.close() return data def analyse_env_vars(data): env_data = {} for env_var in data: t = env_var.split("=") env_data[t[0]] = t[1] return env_data def analyse_proxy_data(data): proxy_data = {} for proxy_var in data.split(','): t = proxy_var.split(":") proxy_data[t[0]] = t[1] return proxy_data def handle_event(event): files = os.listdir(target_path) print('deleting files') for file in files: if file.startswith('proxy_'): os.remove(target_path+'/'+file) event_data = json.loads(event) containers_data = get_container_data() for container_data in containers_data: inspect_data = inspect_container(container_data['Id']) env_data = analyse_env_vars(inspect_data['Config']['Env']) if 'PROXY_DATA' in env_data: container_id = container_data['Id'] ip = inspect_data['NetworkSettings']['IPAddress'] proxy_data = analyse_proxy_data(env_data['PROXY_DATA']) server_name = '' if 'server_name' in proxy_data: server_name = proxy_data['server_name'] port = 0 if 'port' in proxy_data: port = proxy_data['port'] location = '' if 'location' in proxy_data: location = proxy_data['location'] listen ='*:80' if 'ip' in proxy_data: listen = proxy_data['ip']+':80' print('writing /tmp/nginx/proxy_'+container_id) with open('/tmp/nginx/proxy_'+container_id, 'w') as file: if location == '': s = Template(non_location_template) file.write(s.substitute(name=server_name,ip=ip,port=port,listen=listen)) else: s = Template(location_template) file.write(s.substitute(name=server_name,ip=ip,port=port,listen=listen,location=location)) print('HUPing nginx') os.kill(pid, signal.SIGHUP) if not os.path.exists(target_path): os.mkdir(target_path) pid = get_pid() conn = http.client.HTTPConnection("localhost:2375") try: conn.request("GET", "/events") except ConnectionRefusedError: print('Docker does not expose events on its REST-API. Perhaps it is not running?') sys.exit(-1) response = conn.getresponse() events = "" while not response.closed: data = response.read(80) if len(data) != 0: events += data.decode("UTF-8") if events.find("{") != -1: open_pos = events.index("{") if events.find("}", open_pos) != -1: close_pos = events.index("}", open_pos)+1 handle_event(events[open_pos:close_pos]) events = events[close_pos:]