Generate files from docker container meta-data
docker-gen is a file generator that renders templates using docker container meta-data.
It can be used to generate various kinds of files for:
There are three common ways to run docker-gen:
Download the version you need, untar, and install to your PATH.
wget https://github.com/nginx-proxy/docker-gen/releases/download/0.16.0/docker-gen-linux-amd64-0.16.0.tar.gz
tar xvzf docker-gen-linux-amd64-0.16.0.tar.gz
./docker-gen
Docker-gen can be bundled inside of a container along-side applications.
nginx-proxy/nginx-proxy trusted build is an example of running docker-gen within a container along-side nginx. jwilder/docker-register is an example of running docker-gen within a container to do service registration with etcd.
It can also be run as two separate containers using the nginx-proxy/docker-gen image, together with virtually any other image.
This is how you could run the official nginx image and
have docker-gen generate a reverse proxy config in the same way that nginx-proxy works. You may want to do
this to prevent having the docker socket bound to a publicly exposed container service.
Start nginx with a shared volume:
docker run -d -p 80:80 --name nginx -v /tmp/nginx:/etc/nginx/conf.d -t nginx
Fetch the template and start the docker-gen container with the shared volume:
mkdir -p /tmp/templates && cd /tmp/templates
curl -o nginx.tmpl https://raw.githubusercontent.com/nginx-proxy/docker-gen/main/templates/nginx.tmpl
docker run -d --name nginx-gen --volumes-from nginx \
-v /var/run/docker.sock:/tmp/docker.sock:rw \
-v /tmp/templates:/etc/docker-gen/templates \
-t nginxproxy/docker-gen -notify-sighup nginx -watch -only-exposed /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
Start a container, taking note of any Environment variables a container expects. See the top of a template for details.
docker run --env VIRTUAL_HOST='example.com' --env VIRTUAL_PORT=80 ...
…
If no <dest> file is specified, the output is sent to stdout. Mainly useful for debugging.
Using the -config flag from above you can tell docker-gen to use the specified config file instead of command-line options. Multiple templates can be defined and they will be executed in the order that they appear in the config file.
An example configuration file, docker-gen.cfg can be found in the examples folder.
…
Putting it all together here is an example configuration file.
[[config]]
template = "/etc/nginx/nginx.conf.tmpl"
dest = "/etc/nginx/sites-available/default"
onlyexposed = true
notifycmd = "/etc/init.d/nginx reload"
[[config]]
template = "/etc/logrotate.conf.tmpl"
dest = "/etc/logrotate.d/docker"
watch = true
[[config]]
template = "/etc/docker-gen/templates/nginx.tmpl"
dest = "/etc/nginx/conf.d/default.conf"
watch = true
wait = "500ms:2s"
[config.NotifyContainers]
nginx = 1 # 1 is a signal number to be sent; here SIGHUP
e75a60548dc9 = 1 # a key can be either container name (nginx) or ID
The templates used by docker-gen are written using the Go text/template language. In addition to the built-in functions supplied by Go, docker-gen uses sprig and some additional functions to make it simpler (or possible) to generate your desired output. Some templates rely on environment variables within the container to make decisions on what to generate from the template.
Several templates may be parsed at once by using a semicolon (;) to delimit the template value. This can be used as a proxy for Golang's nested template functionality. In all cases, the main rendered template should go first.
[[config]]
template = "/etc/docker-gen/templates/nginx.tmpl;/etc/docker-gen/templates/header.tmpl"
dest = "/etc/nginx/conf.d/default.conf"
watch = true
wait = "500ms:2s"
Within the templates, the object emitted by docker-gen will be a structure consisting of following Go structs:
…
The root also exposes .CurrentContainer, the RuntimeContainer of the docker-gen container itself (or nil if it cannot be determined). Like .Docker, it is resolved independently from the container list, so it remains available even when -only-exposed/-only-published would filter the docker-gen container out; depending on filters, it may also be present in the containers the templates iterate over.
For example, this is a JSON version of an emitted RuntimeContainer struct:
…
Addresses and NetworksThe Addresses and Networks slices are emitted in a deterministic order, so generated output is stable across regenerations and does not trigger spurious reloads/restarts when nothing meaningful changed:
Addresses are sorted by port (compared numerically), then by protocol, host port, host IP and IP.Networks are sorted alphabetically by Name.As a consequence, index .Networks 0 returns the alphabetically-first network (for example bridge) rather than an arbitrary one. To select a specific network by name, filter with where:
{{ $net := index (where $value.Networks "Name" "my-network") 0 }}
server {{ $net.IP }}:{{ (index $value.Addresses 0).Port }};
closest $array $value: Returns the longest matching substring in $array that matches $valuecoalesce ...: Returns the first non-nil argument.comment $delimiter $string: Returns $string with each line prefixed by $delimiter (helpful for debugging combined with Sprig toPrettyJson: {{ toPrettyJson $ | comment "#" }}).contains $map $key: Returns true if $map contains $key. Takes maps from string to any type.dir $path: Returns an array of filenames in the specified $path.exists $path: Returns true if $path refers to an existing file or directory. Takes a string.eval $templateName [$data]: Evaluates the named template like Go's built-in template action, but instead of writing out the result it returns the result as a string so that it can be post-processed. The $data argument may be omitted, which is equivalent to passing nil.groupBy $containers $fieldPath: Groups an array of RuntimeContainer instances based on the values of a field path expression $fieldPath. A field path expression is a dot-delimited list of map keys or struct member names specifying the path from container to a nested value, which must be a string. Returns a map from the value of the field path expression to an array of containers having that value. Containers that do not have a value for the field path in question are omitted.groupByWithDefault $containers $fieldPath $defaultValue: Returns the same as groupBy, but containers that do not have a value for the field path are instead included in the map under the $defaultValue key.groupByKeys $containers $fieldPath: Returns the same as groupBy but only returns the keys of the map.groupByMulti $containers $fieldPath $sep: Like groupBy, but the string value specified by $fieldPath is first split by $sep into a list of strings. A container whose $fieldPath value contains a list of strings will show up in the map output under each of those strings.groupByLabel $containers $label: Returns the same as groupBy but grouping by the given label's value. Containers that do not have the $label set are omitted.groupByLabelWithDefault $containers $label $defaultValue: Returns the same as groupBy but grouping by the given label's value. Containers that do not have the $label set are included in the map under the $defaultValue key.include $file: Returns content of $file, and empty string if file reading error.intersect $slice1 $slice2: Returns the strings that exist in both string slices.mustBeOneOf $slice $value: Validates that $value is one of the allowed string values in $slice, returns $value on success and an error otherwise.mustBeInt $value: Validates that $value is a base-10 integer string, returns $value on success and an error otherwise.mustBeIntInRange $min $max $value: Validates that $value is a base-10 integer string in the inclusive range $min..$max, returns $value on success and an error otherwise.fromYaml $string / mustFromYaml $string: Similar to Sprig's fromJson / mustFromJson, but for YAML.toYaml $dict / mustToYaml $dict: Similar to Sprig's toJson / mustToJson, but for YAML.keys $map: Returns the keys from $map. If $map is nil, a nil is returned. If $map is not a map, an error will be thrown.sortStringsAsc $strings: Returns a slice of strings $strings sorted in ascending order.sortStringsDesc $strings: Returns a slice of strings $strings sorted in descending (reverse) order.sortObjectsByKeysAsc $objects $fieldPath: Returns the array $objects, sorted in ascending order based on the values of a field path expression $fieldPath.sortObjectsByKeysDesc $objects $fieldPath: Returns the array $objects, sorted in descending (reverse) order based on the values of a field path expression $fieldPath.when $condition $trueValue $falseValue: Returns the $trueValue when the $condition is true and the $falseValue otherwisewhere $items $fieldPath $value: Filters an array or slice based on the values of a field path expression $fieldPath. A field path expression is a dot-delimited list of map keys or struct member names specifying the path from container to a nested value. Returns an array of items having that value.whereNot $items $fieldPath $value: Filters an array or slice based on the values of a field path expression $fieldPath. A field path expression is a dot-delimited list of map keysNo open issues yet, or sync has not completed.