├── .gitignore ├── Dockerfile ├── README.md ├── example.docker-compose.yml ├── main.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | docker-compose.yml 2 | .idea -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:2.7 2 | 3 | RUN mkdir /app 4 | 5 | COPY requirements.txt . 6 | RUN pip install -r requirements.txt 7 | 8 | COPY main.py . 9 | 10 | CMD [ "python", "-u","./main.py" ] 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Automatically creates CNAMES pointing to a specific domain when other containers are created 2 | 3 | ### Usage 4 | 5 | To run it: 6 | 7 | version: '2' 8 | services: 9 | dns_flare: 10 | build: . 11 | volumes: 12 | - /var/run/docker.sock:/var/run/docker.sock 13 | environment: 14 | - "EMAIL=" 15 | - "ZONE_ID=" 16 | - "TOKEN=" 17 | - "TARGET_DOMAIN=" 18 | 19 | Then start any containers you want registered with an env var `VIRTUAL_HOST=subdomain.youdomain.com` or `FLARE_DOMAIN=subdomain.youdomain.com` 20 | 21 | $ docker run -e VIRTUAL_HOST=foo.bar.com ... 22 | 23 | or 24 | 25 | $ docker run -e FLARE_DOMAIN=foo.bar.com ... 26 | 27 | Highly inspired and compatible with https://github.com/jwilder/nginx-proxy 28 | 29 | Pull requests are welcome and ideas for future development -------------------------------------------------------------------------------- /example.docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | dns_flare: 4 | build: . 5 | volumes: 6 | - /var/run/docker.sock:/var/run/docker.sock 7 | environment: 8 | - "EMAIL=" 9 | - "ZONE_ID=" 10 | - "TOKEN=" 11 | - "TARGET_DOMAIN=" -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import docker 3 | import CloudFlare 4 | from datetime import datetime 5 | 6 | 7 | def point_domain(name): 8 | try: 9 | r = cf.zones.dns_records.post(zone_id, 10 | data={u'type': u'CNAME', u'name': name, u'content': target_domain, u'ttl': ttl, 11 | u'proxied': proxied}) 12 | except CloudFlare.exceptions.CloudFlareAPIError as e: 13 | print '/zones.dns_records.post %s - %d %s' % (name, e, e) 14 | 15 | 16 | def check_container(c): 17 | for prop in c.attrs.get(u'Config').get(u'Env'): 18 | if u'VIRTUAL_HOST' in prop or u'FLARE_DOMAIN' in prop: 19 | value = prop.split("=")[1].strip() 20 | if ',' in value: 21 | for v in value.split(","): 22 | point_domain(v) 23 | else: 24 | point_domain(value) 25 | 26 | 27 | def init(): 28 | for c in client.containers.list(all=True): 29 | check_container(c) 30 | 31 | 32 | try: 33 | zone_id = os.environ['ZONE_ID'] 34 | except KeyError as e: 35 | exit('ZONE_ID not defined') 36 | 37 | try: 38 | email = os.environ['EMAIL'] 39 | except KeyError as e: 40 | exit('EMAIL not defined') 41 | 42 | try: 43 | token = os.environ['TOKEN'] 44 | except KeyError as e: 45 | exit('TOKEN not defined') 46 | 47 | try: 48 | target_domain = os.environ['TARGET_DOMAIN'] 49 | except KeyError as e: 50 | exit('TARGET_DOMAIN not defined') 51 | 52 | try: 53 | proxied = os.environ['PROXIED'] 54 | except KeyError as e: 55 | proxied = false 56 | 57 | try: 58 | ttl = os.environ['TTL'] 59 | except KeyError as e: 60 | ttl = 120 61 | 62 | cf = CloudFlare.CloudFlare(email=email, token=token) 63 | client = docker.DockerClient(base_url='unix://var/run/docker.sock') 64 | 65 | init() 66 | 67 | t = datetime.now().time().strftime("%s") 68 | 69 | for event in client.events(since=t, filters={'status': u'start'}, decode=True): 70 | if event.get(u'status') == u'start': 71 | try: 72 | print u'started %s' % event.get(u'id') 73 | check_container(client.containers.get(event.get(u'id'))) 74 | except docker.errors.NotFound as e: 75 | print 'Ignoring %s' % event.get(u'from') 76 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | docker 2 | cloudflare --------------------------------------------------------------------------------