Tedi is a tool for building Docker images for your project. It adds a templating layer to your Dockerfile and any other files you choose. It then renders those templates to a build context and arranges for Docker to build it.
Tedi is a CLI tool written in Python 3.6. It can be installed with Pip or run as a Docker container.
If you are interested in using Tedi but not in developing it, Docker is the recommended approach.
# Pull the image
docker pull docker.elastic.co/tedi/tedi:0.13
# Give it a nice, short name for local use.
docker tag docker.elastic.co/tedi/tedi:0.13 tedi
# Run a build (from your project directory).
docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock -v $PWD:/mnt tedi build
- Because Tedi is itself a Docker client, we mount the Docker socket inside the container.
- We also mount the directory of whatever project we want to build on
/mnt
, where Tedi expects to find it. In particular, it expects to a find atedi.yml
there (see below).
Verbose output, including the output from the Docker build, can be requested by
setting the TEDI_DEBUG
environment variable to true
:
docker run -e TEDI_DEBUG=true [...] tedi build
You can explore other commands via the built-in help:
docker run --rm tedi --help
To build a Docker image for your project, create a file within your project at
.tedi/tedi.yml
.
Like this:
# Tedi can produce multiple images for a single project.
# Declare them under the "images" key.
images:
elasticsearch-full:
# Aliases will cause the image to have several names. Having both a short
# local name and a fully qualified name in a registry is particularly handy.
aliases:
- elasticsearch
- docker.elastic.co/elasticsearch/elasticsearch
# Differences between images can be expressed with "facts". Facts are used
# for variable expansion in template files, notably the Dockerfile template.
facts:
image_flavor: full
elasticsearch-oss:
facts:
image_flavor: oss
aliases:
- docker.elastic.co/elasticsearch/elasticsearch-oss
# Global facts apply to all images.
facts:
elastic_version: 6.3.1
# The "image_tag" fact has explicit support inside Tedi. Specify it to have
# your images tagged something other than "latest".
image_tag: 6.3.1-SNAPSHOT
# Asset sets declare files that need be acquired (downloaded) before building
# the image. Declaring different asset sets is a good way to build different
# variants of your project without having to have a bunch of conditionals in
# your templates.
asset_sets:
# The "default" asset set is special and will be used unless you specify
# otherwise.
default:
# Global facts can be used in asset declarations.
- filename: elasticsearch-{{ elastic_version }}.tar.gz
source: https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-{{ elastic_version }}.tar.gz
# Alternative asset sets can be used with the "--asset-set" CLI flag.
remote_snapshot:
- filename: elasticsearch-{{ elastic_version }}.tar.gz
source: https://snapshots.elastic.co/downloads/elasticsearch/elasticsearch-{{ elastic_version }}-SNAPSHOT.tar.gz
Add any other files that are needed to complete your image to the .tedi/template/
directory. They will be included in the Docker build context. Each declared image
will create a build context directory under .tedi/build/
.
Both plain files and Jinja2 templates are supported.
The contents of .tedi/build/
are temporary and can be regenerated. You'll likely
want to add it to your .gitignore
file.
Any plain files, including arbitrarily deep directory structures will be copied into the Docker build context.
Any files with a .j2
extension will be rendered through the Jinja2 template
engine before being added to the Docker build context. Generally, you will want
to create (at least) a Dockerfile template at tedi/template/Dockerfile.j2
.
The template engine will expand variables from the facts defined in tedi.yml
and elsewhere (see below).
Facts can be defined in tedi.yml
, either at the project (top) level, or the image
level.
They can also be set on the command line with this colon delimited syntax:
tedi build --fact=elastic_version:7.0.0
...and via environment variables:
TEDI_FACT_image_tag=7.0.0-SNAPSHOT tedi build
All standard environment variables are also mapped as facts, with a prefix of
ENV_
. So, for example, you can find the current working directory as the fact
ENV_PWD
and the current username as ENV_USER
.
If the Docker build fails, it can be handy to try running the build with pure Docker. That way, you don't have to think through as many layers of abstraction. One of the design principles of Tedi is that the rendered build context sent to Docker is very much "normal" and can be fed straight to Docker. Like this:
tedi render
docker build .tedi/build/elasticsearch-full
This also provides a mechanism for building the results of tedi render
with
alternative build tools.
Tedi is written in Python 3.6 with tests in pytest. Some type annotations can be found sprinkled around, for consumption by mypy.
There's a separate README covering some of the design and implementation details.
git clone git@github.com:elastic/tedi.git
cd tedi
virtualenv --python=python3.6 venv
. venv/bin/activate
pip install -e .
python setup.py test
A small wrapper is provided to run a fast suite of tests continuously while doing Test Driven Development. It uses pytest-watch with some options to skip slow things like coverage reporting and mypy type checking.
./bin/test-watcher