Automatically generate docker nginx reverse proxy configuration using python

#### Since multiple applications are deployed with docker in the test environment, and some of their ports are the same, some are different, and the number is relatively large, when using jenkins to release the version, it is not easy to configure, so I thought To write a script that can automatically generate nginx reverse proxy when the docker container is created and stopped, and then reload nginx

. My principle is to be as simple as possible, light weight, and low memory usage. The

goal is very clear, as long as the docker container can be monitored to start /Stop the event, you can check the

Internet and use docker events to monitor docker events, try it, and find that it is basically satisfactory, so I wrote a program in python to monitor docker events

python
```
#!/usr/ bin/python
# coding: utf8
import os
import json
import re
import subprocess


def override(path, text):
    if not os.path.exists(path) and os.path.exists(path+"_temp"):
        os.rename( path+"_temp",path)
    fw = open(path+"_temp", 'wb')
    fw.write(text)
    fw.close()
    if os.path.exists(path):
        os.remove(path)
    os.rename(path+"_temp", path)


def read(path):
    try:
        fr = open(path, "rb")
    except IOError:
        print "The file don't exist, Please double check!"
        return
    lines = fr.readlines()
    ret = ''
    for line in lines:
        ret += line
    return ret


def read_jsonfile(path):
    return json.loads(read(path))


def cmd(command):
    return os.popen(command).read()


def get_name(container):
    return cmd("docker inspect -f '{{.Name}}' " + container).replace("/", "").replace('\n', '')


def get_ip(container):
    return cmd("docker inspect -f '{{.NetworkSettings.IPAddress}}' " + container).replace('\n', '')


def get_port(container):
    return cmd("docker inspect -f '{{.Config.ExposedPorts}}' " + container).replace('/tcp:{}]', '').replace('map[', '').replace('\n', '')


def get_info(container):
    filename = "/var/lib/docker/containers/" + container + "/config.v2.json"
    config = read_jsonfile(filename)

    name = config['Name'].replace("/", "")
    port = config['Config']['ExposedPorts'].keys()[0].replace('/tcp', '')
    ip = cmd("docker inspect -f '{{.NetworkSettings.IPAddress}}' " + name)
    # ip = config['NetworkSettings']['Networks']['bridge']['IPAddress']

    ret = {'name': name, 'port': port, 'ip': ip}
    return ret


tpl = """
    server {
        listen 80;
        server_name $name.test.com;
        location / {
    proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $http_host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://$ip:$port;
        }
    }
"""


def generate_conf():
    print "generate_conf"
    out = cmd("docker ps | grep -v CONTAINER | awk '{print $1}'")
    containers = out.split("\n")
    servers = ''
    hosts = ''
    for con in containers:
        if con != '':
            name = get_name(con)
            ip = get_ip(con)
            port = get_port(con)
            print ip, port
            if len(port) >= 2:
                servers += tpl.replace("$name", name).replace("$ip", ip).replace("$port", port)
                hosts += "11.12.13.14 " + name + ".test.com\n"
    override('/usr/local/openresty/nginx/conf/vhost.conf', servers)
    override('/usr/local/openresty/nginx/html/vhost.html', "<pre>" + hosts + "</pre>")


def reload_nginx():
    print "reload nginx"
    cmd('nginx -s reload')


def auto_reload():
    generate_conf()
    reload_nginx()

print " ==================== docker events ==================== "

# auto_reload()

proc = subprocess.Popen(["docker", "events"],
                        # shell=True,   # windows: true, linux: false
                        stdout=subprocess.PIPE)

while 1:
    out = proc.stdout.readline()
    event = re.sub('\(|\)', "", out).split(" ")
    if out.find('container stop') != -1:
        auto_reload()
        print ' container stop '
    elif out.find('container start') != -1:
        auto_reload()
        print ' start container '
    if out == '':
        print "out "
        break

````

Startup command:

````
nohup ./docker.py > /dev/null 2>&1 &
````

The program will run in the background, and disconnecting ssh will not end. The

main thing is to generate a conf file, which needs to be Introduce it in nginx.conf, and then generate this file every time a container starts/stops, and then restarts nginx. I also add a domain name to the container name, combine it into a subdomain name, and then generate the corresponding mapping relationship An html file is created, which can be accessed through a browser, and then the corresponding code is copied into the hosts file of the local machine, so that the application can be accessed through the domain name. Of course, this is only done during development and testing, but it is enough.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327014838&siteId=291194637