-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #106 from radiofrance/improve-dx
Improve user experience
- Loading branch information
Showing
24 changed files
with
649 additions
and
1,058 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,121 @@ | ||
DIB (Docker Image Builder) is a tool to build multiple Docker images hosted within the same repository. | ||
DIB: Docker Image Builder | ||
========================= | ||
|
||
![CI Status](https://img.shields.io/github/workflow/status/radiofrance/dib/CI?label=CI&logo=github%20actions&logoColor=fff) | ||
[![codecov](https://codecov.io/gh/radiofrance/dib/branch/main/graph/badge.svg)](https://codecov.io/gh/radiofrance/dib) | ||
![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/radiofrance/dib?sort=semver) | ||
|
||
# Concepts | ||
DIB is a tool designed to help build multiple Docker images defined within a directory, possibly having dependencies | ||
with one another. | ||
|
||
First, DIB creates a graph representation of all Dockerfiles in the repository with their dependencies. | ||
Imagine you have the following Dockerfiles in your repository (you can see this example in the `test/fixtures` directory). | ||
Each image in a subfolder depends on the image in its parent directory (e.g. `sub-image` has a `FROM bullseye` instruction) | ||
## Features | ||
|
||
- Build all your Docker images with a single command. | ||
- Only build images when something has changed since last build. | ||
- Supports dependencies between images, builds will be queued until all parent images are built. | ||
- Run test suites on images, and ensure the tests pass before promoting images. | ||
- Multiple build backends supported (Docker/BuildKit, Kaniko) | ||
- Multiple executors supported (Shell, Docker, Kubernetes) | ||
|
||
## How it works | ||
|
||
DIB recursively parses all Dockerfiles found within a directory, and builds a dependency graph. It computes a unique | ||
hash from each image build context and Dockerfile (plus the hashes from images dependencies if any). This hash is then | ||
converted to human-readable tag, which will make the final image tag. | ||
|
||
When an image build context, Dockerfile, or any parent image changes, the hash changes (as well as the human-readable | ||
tag) and DIB knows the image needs to be rebuilt. If the tag is already present on the registry, DIB considers there is | ||
nothing to do as the image has already been built and pushed. This mechanism allows to only build what is necessary. | ||
|
||
Example with a simple directory structure: | ||
|
||
``` | ||
debian | ||
├── Dockerfile # Image: debian-bullseye | ||
└── nginx | ||
└── Dockerfile # Image: nginx | ||
``` | ||
└── bullseye | ||
├── Dockerfile | ||
├── external-parent | ||
│ └── Dockerfile | ||
├── multistage | ||
│ └── Dockerfile | ||
├── skipbuild | ||
│ └── Dockerfile | ||
└── sub-image | ||
└── Dockerfile | ||
|
||
The parent `debian-bullseye` image depends on an external image, not managed by DIB : | ||
|
||
```dockerfile | ||
# debian/Dockerfile | ||
FROM debian:bullseye | ||
LABEL name="debian-bullseye" | ||
``` | ||
|
||
Then, DIB will check the git diff between the current version of your repository and the previous one. | ||
To figure out the name of the image to build, DIB uses the `name` label (`debian-bullseye` here). The image name is then | ||
appended to the configured registry URL (we'll use `gcr.io/project` in examples). The target image DIB will build here | ||
is `gcr.io/project/debian-bullseye`. | ||
|
||
For the `nginx` image, we need to extend the `gcr.io/project/debian-bullseye` image : | ||
|
||
To calculate this "previous" version, DIB use a file called `.docker-version` stored in the docker build directory. | ||
The content of this file is a unique hash of the docker directoy, generated by `dib hash`. | ||
```dockerfile | ||
# debian/nginx/Dockerfile | ||
FROM gcr.io/project/debian-bullseye:DIB_MANAGED_VERSION | ||
LABEL name="nginx" | ||
``` | ||
|
||
Then, for each dockerfile, if its was changed since the last update, it is taggued for rebuild. The tag of this newly | ||
built image is the result of `dib hash`. If the image is unchanged, a new tag is created from the previous tag. | ||
The `DIB_MANAGED_VERSION` placeholder tells DIB it should use the latest `debian-bullseye` image built by DIB itself. | ||
DIB will always use the latest built image, based on the current filesystem state. If the `debian-bullseye` | ||
image changed, it will be rebuilt first, then `nginx` will also be rebuilt because it depends on it. | ||
|
||
# Installation | ||
## Installation | ||
|
||
First, install the cli | ||
### With Go install: | ||
|
||
``` | ||
go install github.com/radiofrance/dib@latest | ||
``` | ||
|
||
Dib uses a "referential" image to store metadata about previous runs. This image needs to be present on the remote | ||
registry. A bootstrap dockerfile is present in the `init` directory with the instructions to build it. | ||
### Download binaries: | ||
|
||
Binaries are available to download from the [GitHub releases](https://github.com/radiofrance/dib/releases) page. | ||
|
||
## Usage | ||
|
||
# Initialisation | ||
Check `dib --help` for command usage. | ||
|
||
DIB requires a "meta" docker image to store metadata on previous dib builds. By default, dib expects an image named | ||
`dib-referential` to be present on the registry. If you choose to use another name than `dib-referential`, you will need | ||
to set it in your command-line, with `--referential-image`, or in the dib config file. | ||
## Configuration | ||
|
||
The `init` folder helps setup this image. It contains a simple minimalist Dockerfile. | ||
DIB can be configured either by command-line flags, environment variables or configuration file. | ||
|
||
```bash | ||
docker build -t <your_registry_url>/dib-referential init | ||
docker push <your_registry_url>/dib-referential | ||
The command-line flags have the highest priority, then environment variables, then config file. This means you can set | ||
default values in the configuration file, and then override with environment variables of command-line flags. | ||
|
||
### Command-line flags | ||
|
||
Example: | ||
|
||
```shell | ||
dib build --registry-url=gcr.io/project path/to/images/dir | ||
``` | ||
|
||
### Environment variables | ||
|
||
Environment variables must be prefixed by `DIB_` followed by the capitalized, snake_cased flag name. | ||
|
||
Example: | ||
|
||
```shell | ||
export DIB_REGISTRY_URL=gcr.io/project | ||
dib build path/to/images/dir | ||
``` | ||
|
||
# Usage | ||
### Configuration file | ||
|
||
A `.dib.yaml` config file is expected in the current working directory. You can change the file location with | ||
the `--config` (`-c`) flag. | ||
|
||
Check `dib --help` for command usage | ||
The YAML keys must be camelCased flag names. | ||
|
||
Example | ||
|
||
```yaml | ||
# .dib.yaml | ||
registryUrl: gcr.io/project | ||
``` | ||
# License | ||
## License | ||
dib is released under the [CeCILL V2.1 License](https://cecill.info/licences/Licence_CeCILL_V2.1-en.txt) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.