• Stars
    star
    199
  • Rank 196,105 (Top 4 %)
  • Language
    Go
  • License
    MIT License
  • Created about 5 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

dazzle is a rather experimental Docker image builder which builds independent layers

Setup Automated Go Report Card Stability: Experimental

dazzle is a rather experimental Docker/OCI image builder. Its goal is to build independent layers where a change to one layer does not invalidate the ones sitting "above" it.

Beware Recently the format for dazzle builds was changed, moving from a single Dockerfile to one per "chunk"/layer. It is also about 5x faster, more reliable and less hacky.

How does it work?

dazzle has three main capabilities.

  1. build independent layer chunks: in a dazzle project there's a chunks/ folder which contains individual Dockerfiles (e.g. chunks/something/Dockerfile). These chunk images are built independently of each other. All of them share the same base image using a special build argument ${base}. Dazzle can build the base image (built from base/Dockerfile), as well as the chunk images. After each chunk image build dazzle will remove the base image layer from that image, leaving just the layers that were produced by the chunk Dockerfile.
  2. merge layers into one image: dazzle can merge multiple OCI images/chunks (not just those built using dazzle) by building a new manifest and image config that pulls the layers/DiffIDs from the individual chunks and the base image they were built from.
  3. run tests against images: to ensure that an image is capable of what we think it should be - especially after merging - dazzle supports simple tests and assertions that run against Docker images.

Would I want to use this?

Not ordinarily, no. For example, if you're packing your service/app/software/unicorn you're probably better of with a regular Docker image build and well established means for optimizing that one (think multi-stage builds, proper layer ordering).

If however you are building images which consist of a lot of independent "concerns", i.e. chunks that can be strictly separated, then this might for you. For example, if you're building an image that serves as a collection of tools, the layer hierarchy imposed by regular builds doesn't fit so well.

Limitations and caveats

  • build args are not supported at the moment
  • there are virtually no tests covering this so things might just break
  • consider this alpha-level software

Requirements

Install and run buildkit - currently 0.10.1 - in the background. Pull and run a docker registry.

NOTE: if you are running it in Gitpod this is done for you!

sudo su -c "cd /usr; curl -L https://github.com/moby/buildkit/releases/download/v0.10.1/buildkit-v0.10.1.linux-amd64.tar.gz | tar xvz"
docker run -p 5000:5000 --name registry --rm registry:2

Getting started

# start a new project
dazzle project init

# add our first chunk
dazzle project init helloworld
echo hello world > chunks/helloworld/hello.txt
echo "COPY hello.txt /" >> chunks/helloworld/Dockerfile

# add another chunk, just for fun
dazzle project init anotherchunk
echo some other chunk > chunks/anotherchunk/message.txt
echo "COPY message.txt /" >> chunks/anotherchunk/Dockerfile

# register a combination which takes in all the chunks
dazzle project add-combination full helloworld anotherchunk

# build the chunks
dazzle build eu.gcr.io/some-project/dazzle-test

# build all combinations
dazzle combine eu.gcr.io/some-project/dazzle-test --all

Usage

init

$ dazzle project init
Starts a new dazzle project

Usage:
  dazzle project init [chunk] [flags]

Flags:
  -h, --help   help for init

Global Flags:
      --addr string      address of buildkitd (default "unix:///run/buildkit/buildkitd.sock")
      --context string   context path (default "/workspace/workspace-images")
  -v, --verbose          enable verbose logging

Starts a new dazzle project. If you don't know where to start, this is the place.

build

$ dazzle build --help
Builds a Docker image with independent layers

Usage:
  dazzle build <target-ref> [flags]

Flags:
      --chunked-without-hash   disable hash qualification for chunked image
  -h, --help                   help for build
      --no-cache               disables the buildkit build cache
      --plain-output           produce plain output

Global Flags:
      --addr string      address of buildkitd (default "unix:///run/buildkit/buildkitd.sock")
      --context string   context path (default "/workspace/workspace-images")
  -v, --verbose          enable verbose logging

Dazzle can build regular Docker files much like docker build would. build will build all images found under chunks/.

Dazzle cannot reproducibly build layers but can only re-use previously built ones. To ensure reusable layers and maximize Docker cache hits, dazzle itself caches the layers it builds in a Docker registry.

combine

$ dazzle combine --help
Combines previously built chunks into a single image

Usage:
  dazzle combine <target-ref> [flags]

Flags:
      --all                  build all combinations
      --build-ref string     use a different build-ref than the target-ref
      --chunks string        combine a set of chunks - format is name=chk1,chk2,chkN
      --combination string   build a specific combination
  -h, --help                 help for combine
      --no-test              disables the tests

Global Flags:
      --addr string      address of buildkitd (default "unix:///run/buildkit/buildkitd.sock")
      --context string   context path (default "/workspace/workspace-images")
  -v, --verbose          enable verbose logging

Dazzle can combine previously built chunks into a single image. For example dazzle combine some.registry.com/dazzle --chunks foo=chunk1,chunk2 will combine base, chunk1 and chunk2 into an image called some.registry.com/dazzle:foo. One can pre-register such chunk combinations using dazzle project add-combination.

The dazzle.yaml file specifies the list of available combinations. Those combinations can also reference each other:

combiner:
  combinations:
  - name: minimal
    chunks:
    - golang
  - name: some-more
    ref:
    - minimal
    chunks:
    - node

Testing Chunks and Combinations

During a dazzle build one can test the individual chunks and the combination images. During the build dazzle will execute the layer tests for each individual layer, as well as the final image. This makes finding and debugging issues created by the layer merge process tractable.

Each chunk gets its own set of tests found under tests/chunk.yaml.

For example:

- desc: "it should demonstrate tests"
  command: ["echo", "hello world"]
  assert:
  - status == 0
  - stdout.indexOf("hello") != -1
  - stderr.length == 0
- desc: "it should handle exit codes"
  command: ["sh", "-c", "exit 1"]
  assert:
  - status == 1
- desc: "it should have environment variables"
  command: ["sh", "-c", "echo $MESSAGE"]
  env:
  - MESSAGE=foobar
  assert:
  - stdout.trim() == "foobar"
- desc: "it should have right binary version"
  entrypoint: [bash, -i, -c]
  command: [foo -version]
  assert:
  - stderr.indexOf("1.8.0_312") != -1

Following fields are available in the test spec.

assert

Field assert is used to add assertions on the test. It accepts an array input. All test assertions are written in ES5 Javascript. Three variables are available in an assertion:

  • stdout contains the standard output produced by the command
  • stderr contains the standard error output produced by the command
  • status contains the exit code of the command/container.

The assertion itself must evaluate to a boolean value, otherwise the test fails.

desc

Field desc is used to add description of the test. It accepts a string input.

command

Field command contains the test command. It accepts an array of string.

entrypoint

Field entrypoint defines the entrypoint in the image. This is especially handy when the default entrypoint of the image is not a shell. It accepts an array of string.

skip

Field skip is used to decide if the test should run. It accepts a boolean input.

user

Field user is used to define the user as whom the tests should run. It accepts a string input.

env

Field env is used to define the user as whom the tests should run. It accepts an array of string. Each string is a key value pair separated by =.

Testing approach

While the test runner is standalone, the linux+amd64 version is embedded into the dazzle binary using go.rice and go generate - see build.sh. TODO: use go:embed? Note that if you make changes to code in the test runner you will need to re-embed the runner into the binary in order to use it via dazzle.

go generate ./...

The test runner binary is extracted and copied to the generated image where it is run using an encoded JSON version of the test specification - see container.go. The exit code, stdout & stderr are captured and returned for evaluation against the assertions in the test specification.

While of limited practical use, it is possible to run the test runner standalone using a base64-encoded JSON blob as a parameter:

$ go run pkg/test/runner/main.go eyJEZXNjIjoiaXQgc2hvdWxkIGhhdmUgR28gaW4gdmVyc2lvbiAxLjEzIiwiU2tpcCI6ZmFsc2UsIlVzZXIiOiIiLCJDb21tYW5kIjpbImdvIiwidmVyc2lvbiJdLCJFbnRyeXBvaW50IjpudWxsLCJFbnYiOm51bGwsIkFzc2VydGlvbnMiOlsic3Rkb3V0LmluZGV4T2YoXCJnbzEuMTFcIikgIT0gLTEiXX0=
{"Stdout":"Z28gdmVyc2lvbiBnbzEuMTYuNCBsaW51eC9hbWQ2NAo=","Stderr":"","StatusCode":0}

The stdout/err are returned as base64-encoded values. They can be extracted using jq e.g.:

$ go run pkg/test/runner/main.go eyJEZXNjIjoiaXQgc2hvdWxkIGhhdmUgR28gaW4gdmVyc2lvbiAxLjEzIiwiU2tpcCI6ZmFsc2UsIlVzZXIiOiIiLCJDb21tYW5kIjpbImdvIiwidmVyc2lvbiJdLCJFbnRyeXBvaW50IjpudWxsLCJFbnYiOm51bGwsIkFzc2VydGlvbnMiOlsic3Rkb3V0LmluZGV4T2YoXCJnbzEuMTFcIikgIT0gLTEiXX0= | jq -r '.Stdout | @base64d'
go version go1.16.4 linux/amd64

Integration tests

There is an integration test for the build command in pkg/dazzle/build_test.go - TestProjectChunk_test_integration and a shell script to run it. The integration test does an end-to-end check along with editing a test and re-running to ensure only the test image is updated.

It requires a running Buildkitd instance at unix:///run/buildkit/buildkitd.sock and a docker registry on 127.0.0.1:5000 (i.e. as this workspace is setup on startup).

Override the env vars BUILDKIT_ADDR and TARGET_REF as required prior to running in a different environment.

$ ./integration_tests.sh

More Repositories

1

gitpod

The developer platform for on-demand cloud development environments to create software faster and more securely.
TypeScript
12,378
star
2

workspace-images

Ready to use docker images for Gitpod workspaces
Dockerfile
478
star
3

website

Gitpod website and documentation
Svelte
327
star
4

self-hosted

DEPRECATED since Gitpod 0.5.0; use https://github.com/gitpod-io/gitpod/tree/master/chart and https://github.com/gitpod-io/gitpod/tree/master/install/helm
Go
222
star
5

leeway

Leeway is a heavily caching build system for Go, Typescript and Docker projects.
Go
155
star
6

browser-extension

The browser extension for gitpod.io. Works with Chrome and Firefox.
TypeScript
135
star
7

definitely-gp

External `.gitpod.yml` files.
Dockerfile
94
star
8

openvscode-releases

This repo is only to produce releases for OpenVSCode Server.
JavaScript
92
star
9

contribute.dev

A list of cool open-source projects that you can contribute to with one click
JavaScript
80
star
10

retired-gatsby-website

Gitpod website and documentation
TypeScript
68
star
11

full-stack-web-development

The source code for the "Full Stack Web Development in the Cloud" course.
Svelte
66
star
12

gitpod-eks-guide

This repo is being deprecated in favor of the single cluster reference architecture and the corresponding Terraform config.
Shell
51
star
13

run-gp

Run a local workspace using the .gitpod.yml
Go
48
star
14

roadmap

๐Ÿ—บ๏ธ The public roadmap for Gitpod
46
star
15

template-k3s

The k3s template, configured for Gitpod (www.gitpod.io) to give you pre-built, ephemeral Kubernetes development environments in the cloud.
Shell
38
star
16

gitpod-gke-guide

Running Gitpod in Google Kubernetes Engine
Shell
37
star
17

template-nixos

The NixOS template, configured for Gitpod (www.gitpod.io) to give you pre-built, nix based ephemeral operating system environments in the cloud.
Nix
35
star
18

optimus

An ordinary discord bot that empowers the @gitpod-io and @supremegamers Discord servers
Rust
27
star
19

gitpod-vscode-desktop

Gitpod Support for VS Code
TypeScript
25
star
20

gitpod-microsoft-aks-guide

Running Gitpod in Azure AKS
Shell
20
star
21

devxconf.org

TypeScript
19
star
22

NextSimpleStarter

Fork from https://github.com/ooade/NextSimpleStarter
JavaScript
18
star
23

gitpod-bot

A GitHub App built with Probot that opens issues and pull requests in Gitpod.
TypeScript
18
star
24

flutter_stock_example

The Flutter stock example configured for Gitpod
Dart
18
star
25

gitpod-mobile-ios

Something unofficial @ghuntley is hacking on out of hours and on weekends from time to time. Wanna help out?
Ruby
18
star
26

go-gin-app

Fork from https://github.com/demo-apps/go-gin-app.git
Go
17
star
27

apache-example

Dockerfile
13
star
28

devx-community

A dedicated space for developer experience
Svelte
13
star
29

community

Home for the Gitpod community ๐Ÿชด
13
star
30

gitbot

GitHub bot for gitpod
Go
13
star
31

dockerfreeze

Freeze your development environment as a Dockerfile
Rust
12
star
32

template-hugo

This is a Hugo template configured for ephemeral development environments on Gitpod.
HTML
10
star
33

.github

Defaults for Community Health
10
star
34

beans

Beans, beans, beans!
10
star
35

template-jetbrains-pycharm

A template, configured for Gitpod (www.gitpod.io) to give you pre-built, ephemeral development environments in the cloud via JetBrains PyCharm.
10
star
36

gitpod-status

This archived repository contains information about service incidents that occurred prior to the 30th of April 2021.
Dockerfile
10
star
37

gh-gp

A gh extension to work with GitHub repositories with Gitpod.
Shell
10
star
38

flutter-example

A Flutter Web Example
Dart
9
star
39

CDE-Universe

Repository for CDE Universe '23 Website
Svelte
9
star
40

devx-community-legacy

To hold devx community content
8
star
41

template-terraform-aws

This is a Terraform-AWS template configured for ephemeral development environments on Gitpod.
HCL
8
star
42

template-jetbrains-intellij-idea

A template, configured for Gitpod (www.gitpod.io) to give you pre-built, ephemeral development environments in the cloud via JetBrains IntelliJ IDEA.
8
star
43

browser-bookmarklet

The browser bookmarklet for gitpod.io. Works with Chrome, Firefox and Safari.
TypeScript
8
star
44

gitpod-vscode-theme

Gitpod Theme for VS Code
8
star
45

demo-multi-repo-frontend

8
star
46

observability

Go
7
star
47

create-react-app

Basic React App
JavaScript
7
star
48

template-gitpod-sxs-codespaces

A template that demonstrates how to have isomorphic developer environments between Gitpod and GitHub Codespaces
Rust
7
star
49

template-jetbrains-phpstorm

A template, configured for Gitpod (www.gitpod.io) to give you pre-built, ephemeral development environments in the cloud via JetBrains PhpStorm.
6
star
50

template-meteor

6
star
51

xterm-web-ide

The xterm.js web IDE aka The Browser Terminal
TypeScript
6
star
52

firebase-on-gitpod

Example repository and proof of concept for firebase on gitpod
Dockerfile
6
star
53

gitpod-code

Home of the VS Code Browser Gitpod built-in extensions
TypeScript
6
star
54

rm-rf

Deletes everything, but, hey, itโ€™s okay because Gitpod is an ephemeral sandbox. Run as many times as you want!
6
star
55

nginx-example

Dockerfile
6
star
56

gitpod-qa

TypeScript
6
star
57

gitpod-docs

DEPRECATED. Gitpod's documentation is here: https://github.com/gitpod-io/website/tree/master/src/docs
JavaScript
5
star
58

template-ibm-i

5
star
59

gce-github-runner

Shell
5
star
60

theia-app

The Theia running in Gitpod
TypeScript
5
star
61

template-microsoft-mssql-server

This is a Microsoft SQL Server via Docker Compose template configured for ephemeral development environments on Gitpod.
4
star
62

support-bundle

Tooling that generates a support bundle that contains logs and system information that can be used to diagnose and resolve problems with Gitpod Self-Hosted installations.
4
star
63

template-typescript-node-tabnine

SCSS
4
star
64

gitpod-yml-inferrer

Gitpod .gitpod.yml inference logic
TypeScript
4
star
65

template-all

A Gitpod multi-repo workspace for all template-* repositories.
4
star
66

template-jetbrains-webstorm

A template, configured for Gitpod (www.gitpod.io) to give you pre-built, ephemeral development environments in the cloud via JetBrains WebStorm.
4
star
67

demo-multi-repo-backend

3
star
68

spring-boot-demo

A simple spring boot demo
3
star
69

template-custom-org-repo

Use custom organization repository without installing Gitpod app
3
star
70

template-dynamic-workspace-location-and-tasks

3
star
71

template-java-spring-boot

Java
3
star
72

gh-app-auth

JavaScript
3
star
73

template-jetbrains-rider

A template, configured for Gitpod (www.gitpod.io) to give you pre-built, ephemeral development environments in the cloud via JetBrains Rider.
3
star
74

emoji-search

JavaScript
3
star
75

template-jetbrains-goland

A template, configured for Gitpod (www.gitpod.io) to give you pre-built, ephemeral development environments in the cloud via JetBrains GoLand.
3
star
76

template-amazonlinux

This templates demonstrates the use amazonlinux with Gitpod
2
star
77

gitpod-test-repo

This repo is being used by automated tests from gitpod-io/gitpod
JavaScript
2
star
78

gitpodify

A simple site to generate useful resources for Gitpodification, including "open in gitpod" buttons and sample configuration scripts
Svelte
2
star
79

template-selective-services

Start selective services via Gitpod tasks (example)
2
star
80

template-golang-cli-tabnine

Go
2
star
81

template-keystonejs

2
star
82

test

2
star
83

template-java-spring-boot-gradle

Java
2
star
84

non-gitpodified-repo

Repo that does not have .gitpod.yml yet, used for testing only.
Go
2
star
85

rickroll

does exactly what you think it does.
2
star
86

videos

Making neat videos about coding without friction
2
star
87

template-hy

The Hy template, configured for Gitpod (www.gitpod.io) to give you pre-built ephemeral development environments in the cloud.
Hy
2
star
88

empty

This repository intentionally left blank
2
star
89

gitpod-yml-schema

[MOVED] `.gitpod.yml` configuration file schema
2
star
90

example-rust-rocket

A starter project for building a web backend with Rocket in Rust
Dockerfile
2
star
91

template-python-flask-tabnine

Python
2
star
92

demo-xterm-ide

A simple IDE for the browser
1
star
93

template-fedora

Example repo using Fedora as workspace image
1
star
94

glu

Python
1
star
95

monitoring-cell

Go
1
star
96

exheredpod

(WIP) Custom downstream management designed for paludis package manager in gitpod
1
star
97

template-template

A <FRAMEWORK> template[, written in <LANGUAGE>], configured for Gitpod (www.gitpod.io) to give you pre-built, ephemeral development environments in the cloud.
1
star
98

oracle-devtools-demo

A repo for testing the Oracle DevTools VS Code Extension
1
star
99

search.gitpod-dev.com

HTML
1
star
100

template-python-django-tabnine

Python
1
star