A simple little docker container that connects to the docker socket (either locally or remotely) and generates Nginx virtual host files based on a template when a container starts or dies.
Q: Why not Traefik?
A: Traefik v1 was great, but didn't meet some of my requirements when it came to having multiple ACME cert methods (eg combining DNS and TLS was a gigantic hassle), and I messed with v2 for about a week straight and at the time of writing it's so horrifically buggy and verbose that I can't deal with it. So, nginx it is.
The docker-compose.yaml file gives a couple of use cases, including remote docker hosts, different suffixes on configs and a couple of local subdomain examples.
You can configure the the conf generator with the followng environment variables:
docker_confIs a JSON strinigified object used by Docker Modem to connect to the docker endpoint.conf_dirIs the directory in the container that config will be generated in. Probably/confsince you can just add a volume.templateIs the default template we use for each vhostsuffixIs the suffix we add to each config file so we can have multiple config generators pointed to the same place and they won't interferedestinationIf the docker socket you're generating config for isn't in the same network as nginx (either it's remote or just in a different network) you can set the host here. Eg.http://<destination>:<port>. See notes below for more info.
You can configure containers with the following labels to change their settings:
proxy.notifyContainers with this label will receive a SIGHUP every time we generate config (basically to reload nginx) **Note: This currently doesn't work if the container is pointed to another host than your webserver, because it'll try to reload anything with theproxy.notifylabel on the target host. You can either reload nginx manually usingdocker kill web_web_1 -s HUPor use the inotify sidecar detailed below..proxy.hostsA comma delimited list of URL's for nginx's host listproxy.portThe container port.proxy.publicAddsallow 0.0.0.0/0;to the template if it has${is_public}in it somewhere.proxy.templateThe name of the template to use relative to the config generator.
If all of your containers are on the same host as the Nginx container, then the config generator will automatically hit nginx with a SIGHUP after generating config. However, I didn't feel like having to overcomplicate that script to look at local proxy.notify targets if their container watch targets are on a different host. Therefore, I also included a little inotify script in the inotify directory. This is a simple sidecar container that will SIGHUP all local proxy.notify containers in the event anything in the conf folder changes.
You can see an example of it working in docker-compose.yaml.
Notes:
- If
destinationis omitted, we assume that the nginx container will be able to resolve the container using its name (docker dns) and will useproxy.portas given. - If
destinationis present, we search forproxy.portin the open ports of the container and find the relevantPublicPort. If the container is on another host, you should expose the container port on a random host port eg.
ports:
- 9117
labels:
- proxy.port=9117These scripts are extremely specific to my use-cases and are therefore not super customisable. However, they are quite short and easy to understand, so feel free to modify them to your use cases.