README ¶
kompoze
Render Docker Compose / Stack files with the power of go templates with dockerize and sprig useful template functions.
Docker Compose / Stack files are very static in nature as you only can use YAML to define them.
Yes, there are several nice tricks to make YAML feels more dynamic like anchors or block merging but in the end, you can't add conditionals, neither iterations, scoped blocks...
This is where kompoze
appears to the rescue!
Usage
kompoze
utilizes a definition.toml
file (read definition section for more information) that defines how to render the templates.
By default, if you don't pass anything to kompoze
, it will search for a definition.toml
file in current directory. So:
$ kompoze
And this, are equal:
$ kompoze definition.toml
You can specify multiple definition files by passing their paths directly:
$ kompoze definition.toml another-definition.toml /another/path/definition2.toml
You can tail multiple files to STDOUT
and STDERR
by passing the options multiple times:
$ kompoze -stdout definition.toml
If your file uses {{
and }}
as part of it's syntax, you can change the template escape characters using the -delims
option:
$ kompoze -delims "<%:%>"
By default, the base-path
for rendering will be the one on which you run kompoze
(so any relative paths that are specified inside the definition file can be resolved). You can change it with the following option:
$ kompoze --base-path /another/path
Definition File
The definition file uses TOML format and tries to be very minimal and concise. It's composed by two main sections:
- Global vars: Those common variables that will be applied to every template (if any).
- Templates: Where it defines which templates to render and which variables are overridden from the global scope.
Take a look on the example below:
# Example definition file
# defines global variables that will be applied to each template definition (can be null)
[vars]
# you can define the variables directly here (higher priority when merging same entries)
[vars.global]
network_enabled = true
network_name = "net"
network_subnet = "172.25.0.0/16"
# or you can include other global variables files (lower priority when merging same entries)
include = ["vars/global.toml"]
# defines a list of templates to render
[[templates]]
src = "templates/stack.yml.tpl"
dest = "out/stack-1.yml"
include_vars = ["vars/local.toml"]
[templates.local_vars]
mariadb_version = "10.2.21"
mariadb_volume_enabled = true
[[templates]]
src = "templates/stack.yml.tpl"
dest = "out/stack-2.yml"
[templates.local_vars]
mariadb_version = "11"
mariadb_volume_enabled = false
As you can see above the syntax is pretty straightforward. You can define relative paths for src
and dest
and they will be resolved to the defined base-path
option.
The format for including external variables are as follows:
[vars]
this_is_another_var = 'var'
The different sources of variables are merged together in the following order:
- global
vars
- global
include
- template
include_vars
- template
vars
Templates
Templates are rendered by using Golang's text/template package with the mix of two powerful additions:
You can access environment variables within a template with .Env
like dockerize
or those defined in the definition file with plain .
(like .some_global_var
).
{{ .Env.PATH }} is my path
The set of stolen built in functions stolen from dockerize are the following:
exists $path
- Determines if a file path exists or not.{{ exists "/etc/default/myapp" }}
parseUrl $url
- Parses a URL into it's protocol, scheme, host, etc. parts. Alias forurl.Parse
isTrue $value
- Parses a string $value to a boolean value.{{ if isTrue .Env.ENABLED }}
isFalse $value
- Parses a string $value to a boolean value.{{ if isFalse .Env.ENABLED }}
loop
- Create for loops.
On the sprig side, everything is included by default, so you have access to all defined functions.
Contributions
Contributions to this project are very welcome and will be fully credited.
Feel free to send a PR to correct any possible bug or improvement you may want to add.
Just make sure you follow these rules:
- Create feature branches: It's important to be concise with your commits, so don't ask us to pull from your master branch.
- Document any change in behaviour: Make sure the
README.md
is kept up-to-date. - One pull request per feature: If you want to do more than one thing, send multiple pull requests.
- Send coherent history: Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please squash them before submitting.
Acknowledgements
Many thanks to:
Both of them for creating dockerize and python-docker-compose-templer respectively, from which this project draws 99% inspiration!
License
kompoze is released under the MIT License. See LICENSE.md for more information.