Compare commits

...

25 Commits

Author SHA1 Message Date
CrazyMax
89154c7d33 Merge pull request #2261 from dvdksn/backport_docs-cli-reference-urlscheme
[v0.12 backport] docs: update external links
2024-02-20 09:48:49 +01:00
David Karlsson
1a03187338 docs: update external link paths
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
(cherry picked from commit cdfc35d0b6)
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
2024-02-20 09:39:21 +01:00
David Karlsson
b3e7827871 vendor: github.com/docker/cli-docs-tool v0.7.0
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
(cherry picked from commit ce66d8830d)
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
2024-02-20 09:35:51 +01:00
CrazyMax
d43cf8c2c6 Merge pull request #2214 from dvdksn/chp-cli-linkupdates
[v0.12 backport]: update doc links to canonical build command
2024-01-26 12:40:58 +01:00
David Karlsson
c954a45352 docs: update link to docker build reference
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
(cherry picked from commit 68c3ac4f66)
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
2024-01-26 12:32:25 +01:00
CrazyMax
ce521a3a85 Merge pull request #2213 from crazy-max/0.12_pin-docs-validate-worklofw
[v0.12] ci(docs-upstream): pin reusable workflow
2024-01-26 12:29:56 +01:00
CrazyMax
29f879990e ci(docs-upstream): pin reusable workflow
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2024-01-26 10:13:05 +01:00
CrazyMax
5e3bf8713a Merge pull request #2191 from thaJeztah/0.12_backport_bump_golang
[v0.12 backport] update to go1.21.6
2024-01-17 14:42:43 +01:00
Sebastiaan van Stijn
57f7f1becc update to go1.21.6
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 61dff684ad)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-01-12 23:30:18 +01:00
Tõnis Tiigi
091214d59d Merge pull request #2189 from crazy-max/0.12_backport_ci-dockerhub-creds
[v0.12 backport] ci: use public bot account to push bin image
2024-01-12 11:10:25 -08:00
CrazyMax
5f26f514a1 ci: use org-wide var as username
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
(cherry picked from commit 45deb29f09)
2024-01-12 09:16:07 +01:00
CrazyMax
454306a8ef ci: use public bot account to push bin image
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
(cherry picked from commit 54a1f0f0ea)
2024-01-12 09:15:57 +01:00
Tõnis Tiigi
30feaa1a91 Merge pull request #2178 from crazy-max/0.12_backport_fix-builder-creation
[v0.12 backport] driver(container): fix conditional statement for error handling
2024-01-05 12:47:15 -08:00
CrazyMax
8fb1163577 driver(container): fix conditional statement for error handling
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
(cherry picked from commit 57d737a13c)
2024-01-05 17:39:33 +01:00
CrazyMax
b68ee824c6 Merge pull request #2161 from crazy-max/0.12_backport_docs-annotations
[0.12 backport] docs: annotations
2023-12-14 10:15:05 +01:00
David Karlsson
2175f9ec7c docs: add levels to bake file target.annotations
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
(cherry picked from commit c6535e9675)
2023-12-14 10:08:43 +01:00
David Karlsson
ba1ee7af6e docs: build --annotation
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
(cherry picked from commit d762c76a68)
2023-12-14 10:08:42 +01:00
David Karlsson
565b0b8991 docs: add lang tag for plaintext code blocks
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
(cherry picked from commit 1091707bd5)
2023-12-14 10:08:42 +01:00
David Karlsson
a494e9ccc4 docs: imagetools create --annotation
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
(cherry picked from commit a4c392f4db)
2023-12-14 10:08:42 +01:00
Tõnis Tiigi
542e5d810e Merge pull request #2125 from tonistiigi/v0.12-revert-node-resolution
[v0.12] Revert "build: rework node resolution"
2023-11-16 14:04:54 -08:00
Tonis Tiigi
89fb005922 Revert "build: rework node resolution"
This reverts commit 616fb3e55c.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit 3c709640e1)
2023-11-16 13:29:13 -08:00
Tõnis Tiigi
d353f6c426 Merge pull request #2123 from tonistiigi/v0.12.0-cherry-picks-docs
[v0.12] cherry picks docs only
2023-11-16 12:02:04 -08:00
David Karlsson
2271096e46 chore: add docs reminder comments for driver opts
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
(cherry picked from commit 1326634c7d)
2023-11-16 11:47:10 -08:00
David Karlsson
95062ce8df docs: minor cli reference editorial updates
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
(cherry picked from commit 7a724ac445)
2023-11-16 11:47:07 -08:00
CrazyMax
255aff71fb docs: fix imagetools inspect json format
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
(cherry picked from commit 707ae87060)
2023-11-16 11:46:57 -08:00
42 changed files with 742 additions and 1012 deletions

View File

@@ -225,8 +225,8 @@ jobs:
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
username: ${{ vars.DOCKERPUBLICBOT_USERNAME }}
password: ${{ secrets.DOCKERPUBLICBOT_WRITE_PAT }}
-
name: Build and push image
uses: docker/bake-action@v4

View File

@@ -13,7 +13,7 @@ permissions:
security-events: write
env:
GO_VERSION: 1.21.3
GO_VERSION: 1.21.6
jobs:
codeql:

View File

@@ -52,7 +52,7 @@ jobs:
retention-days: 1
validate:
uses: docker/docs/.github/workflows/validate-upstream.yml@main
uses: docker/docs/.github/workflows/validate-upstream.yml@e864c797e391fa35aecf1ddcecdbdeb683546424 # pin for artifact v3 support
needs:
- docs-yaml
with:

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
ARG GO_VERSION=1.21.3
ARG GO_VERSION=1.21.6
ARG XX_VERSION=1.2.1
ARG DOCKER_VERSION=24.0.6

View File

@@ -135,6 +135,218 @@ func filterAvailableNodes(nodes []builder.Node) ([]builder.Node, error) {
return nil, err
}
type driverPair struct {
driverIndex int
platforms []specs.Platform
so *client.SolveOpt
bopts gateway.BuildOpts
}
func driverIndexes(m map[string][]driverPair) []int {
out := make([]int, 0, len(m))
visited := map[int]struct{}{}
for _, dp := range m {
for _, d := range dp {
if _, ok := visited[d.driverIndex]; ok {
continue
}
visited[d.driverIndex] = struct{}{}
out = append(out, d.driverIndex)
}
}
return out
}
func allIndexes(l int) []int {
out := make([]int, 0, l)
for i := 0; i < l; i++ {
out = append(out, i)
}
return out
}
func ensureBooted(ctx context.Context, nodes []builder.Node, idxs []int, pw progress.Writer) ([]*client.Client, error) {
clients := make([]*client.Client, len(nodes))
baseCtx := ctx
eg, ctx := errgroup.WithContext(ctx)
for _, i := range idxs {
func(i int) {
eg.Go(func() error {
c, err := driver.Boot(ctx, baseCtx, nodes[i].Driver, pw)
if err != nil {
return err
}
clients[i] = c
return nil
})
}(i)
}
if err := eg.Wait(); err != nil {
return nil, err
}
return clients, nil
}
func splitToDriverPairs(availablePlatforms map[string]int, opt map[string]Options) map[string][]driverPair {
m := map[string][]driverPair{}
for k, opt := range opt {
mm := map[int][]specs.Platform{}
for _, p := range opt.Platforms {
k := platforms.Format(p)
idx := availablePlatforms[k] // default 0
pp := mm[idx]
pp = append(pp, p)
mm[idx] = pp
}
// if no platform is specified, use first driver
if len(mm) == 0 {
mm[0] = nil
}
dps := make([]driverPair, 0, 2)
for idx, pp := range mm {
dps = append(dps, driverPair{driverIndex: idx, platforms: pp})
}
m[k] = dps
}
return m
}
func resolveDrivers(ctx context.Context, nodes []builder.Node, opt map[string]Options, pw progress.Writer) (map[string][]driverPair, []*client.Client, error) {
dps, clients, err := resolveDriversBase(ctx, nodes, opt, pw)
if err != nil {
return nil, nil, err
}
bopts := make([]gateway.BuildOpts, len(clients))
span, ctx := tracing.StartSpan(ctx, "load buildkit capabilities", trace.WithSpanKind(trace.SpanKindInternal))
eg, ctx := errgroup.WithContext(ctx)
for i, c := range clients {
if c == nil {
continue
}
func(i int, c *client.Client) {
eg.Go(func() error {
clients[i].Build(ctx, client.SolveOpt{
Internal: true,
}, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
bopts[i] = c.BuildOpts()
return nil, nil
}, nil)
return nil
})
}(i, c)
}
err = eg.Wait()
tracing.FinishWithError(span, err)
if err != nil {
return nil, nil, err
}
for key := range dps {
for i, dp := range dps[key] {
dps[key][i].bopts = bopts[dp.driverIndex]
}
}
return dps, clients, nil
}
func resolveDriversBase(ctx context.Context, nodes []builder.Node, opt map[string]Options, pw progress.Writer) (map[string][]driverPair, []*client.Client, error) {
availablePlatforms := map[string]int{}
for i, node := range nodes {
for _, p := range node.Platforms {
availablePlatforms[platforms.Format(p)] = i
}
}
undetectedPlatform := false
allPlatforms := map[string]struct{}{}
for _, opt := range opt {
for _, p := range opt.Platforms {
k := platforms.Format(p)
allPlatforms[k] = struct{}{}
if _, ok := availablePlatforms[k]; !ok {
undetectedPlatform = true
}
}
}
// fast path
if len(nodes) == 1 || len(allPlatforms) == 0 {
m := map[string][]driverPair{}
for k, opt := range opt {
m[k] = []driverPair{{driverIndex: 0, platforms: opt.Platforms}}
}
clients, err := ensureBooted(ctx, nodes, driverIndexes(m), pw)
if err != nil {
return nil, nil, err
}
return m, clients, nil
}
// map based on existing platforms
if !undetectedPlatform {
m := splitToDriverPairs(availablePlatforms, opt)
clients, err := ensureBooted(ctx, nodes, driverIndexes(m), pw)
if err != nil {
return nil, nil, err
}
return m, clients, nil
}
// boot all drivers in k
clients, err := ensureBooted(ctx, nodes, allIndexes(len(nodes)), pw)
if err != nil {
return nil, nil, err
}
eg, ctx := errgroup.WithContext(ctx)
workers := make([][]*client.WorkerInfo, len(clients))
for i, c := range clients {
if c == nil {
continue
}
func(i int) {
eg.Go(func() error {
ww, err := clients[i].ListWorkers(ctx)
if err != nil {
return errors.Wrap(err, "listing workers")
}
workers[i] = ww
return nil
})
}(i)
}
if err := eg.Wait(); err != nil {
return nil, nil, err
}
for i, ww := range workers {
for _, w := range ww {
for _, p := range w.Platforms {
p = platforms.Normalize(p)
ps := platforms.Format(p)
if _, ok := availablePlatforms[ps]; !ok {
availablePlatforms[ps] = i
}
}
}
}
return splitToDriverPairs(availablePlatforms, opt), clients, nil
}
func toRepoOnly(in string) (string, error) {
m := map[string]struct{}{}
p := strings.Split(in, ",")
@@ -505,14 +717,10 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
}
}
drivers, err := resolveDrivers(ctx, nodes, opt, w)
m, clients, err := resolveDrivers(ctx, nodes, opt, w)
if err != nil {
return nil, err
}
driversSolveOpts := make(map[string][]*client.SolveOpt, len(drivers))
for k, dps := range drivers {
driversSolveOpts[k] = make([]*client.SolveOpt, len(dps))
}
defers := make([]func(), 0, 2)
defer func() {
@@ -526,33 +734,30 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
eg, ctx := errgroup.WithContext(ctx)
for k, opt := range opt {
multiDriver := len(drivers[k]) > 1
multiDriver := len(m[k]) > 1
hasMobyDriver := false
gitattrs, err := getGitAttributes(ctx, opt.Inputs.ContextPath, opt.Inputs.DockerfilePath)
if err != nil {
logrus.WithError(err).Warn("current commit information was not captured by the build")
}
for i, np := range drivers[k] {
if np.Node().Driver.IsMobyDriver() {
for i, np := range m[k] {
node := nodes[np.driverIndex]
if node.Driver.IsMobyDriver() {
hasMobyDriver = true
}
opt.Platforms = np.platforms
gatewayOpts, err := np.BuildOpts(ctx)
so, release, err := toSolveOpt(ctx, node, multiDriver, opt, np.bopts, configDir, w, docker)
if err != nil {
return nil, err
}
so, release, err := toSolveOpt(ctx, np.Node(), multiDriver, opt, gatewayOpts, configDir, w, docker)
if err != nil {
return nil, err
}
if err := saveLocalState(so, k, opt, np.Node(), configDir); err != nil {
if err := saveLocalState(so, k, opt, node, configDir); err != nil {
return nil, err
}
for k, v := range gitattrs {
so.FrontendAttrs[k] = v
}
defers = append(defers, release)
driversSolveOpts[k][i] = so
m[k][i].so = so
}
for _, at := range opt.Session {
if s, ok := at.(interface {
@@ -566,8 +771,8 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
// validate for multi-node push
if hasMobyDriver && multiDriver {
for _, so := range driversSolveOpts[k] {
for _, e := range so.Exports {
for _, dp := range m[k] {
for _, e := range dp.so.Exports {
if e.Type == "moby" {
if ok, _ := strconv.ParseBool(e.Attrs["push"]); ok {
return nil, errors.Errorf("multi-node push can't currently be performed with the docker driver, please switch to a different driver")
@@ -580,13 +785,12 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
// validate that all links between targets use same drivers
for name := range opt {
dps := drivers[name]
for i, dp := range dps {
so := driversSolveOpts[name][i]
for k, v := range so.FrontendAttrs {
dps := m[name]
for _, dp := range dps {
for k, v := range dp.so.FrontendAttrs {
if strings.HasPrefix(k, "context:") && strings.HasPrefix(v, "target:") {
k2 := strings.TrimPrefix(v, "target:")
dps2, ok := drivers[k2]
dps2, ok := m[k2]
if !ok {
return nil, errors.Errorf("failed to find target %s for context %s", k2, strings.TrimPrefix(k, "context:")) // should be validated before already
}
@@ -610,13 +814,13 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
results := waitmap.New()
multiTarget := len(opt) > 1
childTargets := calculateChildTargets(drivers, driversSolveOpts, opt)
childTargets := calculateChildTargets(m, opt)
for k, opt := range opt {
err := func(k string) error {
opt := opt
dps := drivers[k]
multiDriver := len(drivers[k]) > 1
dps := m[k]
multiDriver := len(m[k]) > 1
var span trace.Span
ctx := ctx
@@ -632,9 +836,8 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
var insecurePush bool
for i, dp := range dps {
i, dp := i, dp
node := dp.Node()
so := driversSolveOpts[k][i]
i, dp, so := i, dp, *dp.so
node := nodes[dp.driverIndex]
if multiDriver {
for i, e := range so.Exports {
switch e.Type {
@@ -665,14 +868,11 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
pw := progress.WithPrefix(w, k, multiTarget)
c, err := dp.Client(ctx)
if err != nil {
return err
}
c := clients[dp.driverIndex]
eg2.Go(func() error {
pw = progress.ResetTime(pw)
if err := waitContextDeps(ctx, dp.driverIndex, results, so); err != nil {
if err := waitContextDeps(ctx, dp.driverIndex, results, &so); err != nil {
return err
}
@@ -770,10 +970,10 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
var rr *client.SolveResponse
if resultHandleFunc != nil {
var resultHandle *ResultHandle
resultHandle, rr, err = NewResultHandle(ctx, cc, *so, "buildx", buildFunc, ch)
resultHandle, rr, err = NewResultHandle(ctx, cc, so, "buildx", buildFunc, ch)
resultHandleFunc(dp.driverIndex, resultHandle)
} else {
rr, err = c.Build(ctx, *so, "buildx", buildFunc, ch)
rr, err = c.Build(ctx, so, "buildx", buildFunc, ch)
}
if desktop.BuildBackendEnabled() && node.Driver.HistoryAPISupported(ctx) {
buildRef := fmt.Sprintf("%s/%s/%s", node.Builder, node.Name, so.Ref)
@@ -797,7 +997,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
rr.ExporterResponse[k] = string(v)
}
node := dp.Node().Driver
node := nodes[dp.driverIndex].Driver
if node.IsMobyDriver() {
for _, e := range so.Exports {
if e.Type == "moby" && e.Attrs["push"] != "" {
@@ -889,7 +1089,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
if len(descs) > 0 {
var imageopt imagetools.Opt
for _, dp := range dps {
imageopt = dp.Node().ImageOpt
imageopt = nodes[dp.driverIndex].ImageOpt
break
}
names := strings.Split(pushNames, ",")
@@ -1303,16 +1503,16 @@ func resultKey(index int, name string) string {
}
// calculateChildTargets returns all the targets that depend on current target for reverse index
func calculateChildTargets(drivers map[string][]*resolvedNode, driversSolveOpts map[string][]*client.SolveOpt, opt map[string]Options) map[string][]string {
func calculateChildTargets(drivers map[string][]driverPair, opt map[string]Options) map[string][]string {
out := make(map[string][]string)
for name := range opt {
dps := drivers[name]
for i, dp := range dps {
so := driversSolveOpts[name][i]
for src := range opt {
dps := drivers[src]
for _, dp := range dps {
so := *dp.so
for k, v := range so.FrontendAttrs {
if strings.HasPrefix(k, "context:") && strings.HasPrefix(v, "target:") {
target := resultKey(dp.driverIndex, strings.TrimPrefix(v, "target:"))
out[target] = append(out[target], resultKey(dp.driverIndex, name))
out[target] = append(out[target], resultKey(dp.driverIndex, src))
}
}
}

View File

@@ -1,305 +0,0 @@
package build
import (
"context"
"fmt"
"github.com/containerd/containerd/platforms"
"github.com/docker/buildx/builder"
"github.com/docker/buildx/driver"
"github.com/docker/buildx/util/progress"
"github.com/moby/buildkit/client"
gateway "github.com/moby/buildkit/frontend/gateway/client"
"github.com/moby/buildkit/util/flightcontrol"
"github.com/moby/buildkit/util/tracing"
specs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"go.opentelemetry.io/otel/trace"
"golang.org/x/sync/errgroup"
)
type resolvedNode struct {
resolver *nodeResolver
driverIndex int
platforms []specs.Platform
}
func (dp resolvedNode) Node() builder.Node {
return dp.resolver.nodes[dp.driverIndex]
}
func (dp resolvedNode) Client(ctx context.Context) (*client.Client, error) {
clients, err := dp.resolver.boot(ctx, []int{dp.driverIndex}, nil)
if err != nil {
return nil, err
}
return clients[0], nil
}
func (dp resolvedNode) BuildOpts(ctx context.Context) (gateway.BuildOpts, error) {
opts, err := dp.resolver.opts(ctx, []int{dp.driverIndex}, nil)
if err != nil {
return gateway.BuildOpts{}, err
}
return opts[0], nil
}
type matchMaker func(specs.Platform) platforms.MatchComparer
type nodeResolver struct {
nodes []builder.Node
clients flightcontrol.Group[*client.Client]
opt flightcontrol.Group[gateway.BuildOpts]
}
func resolveDrivers(ctx context.Context, nodes []builder.Node, opt map[string]Options, pw progress.Writer) (map[string][]*resolvedNode, error) {
driverRes := newDriverResolver(nodes)
drivers, err := driverRes.Resolve(ctx, opt, pw)
if err != nil {
return nil, err
}
return drivers, err
}
func newDriverResolver(nodes []builder.Node) *nodeResolver {
r := &nodeResolver{
nodes: nodes,
}
return r
}
func (r *nodeResolver) Resolve(ctx context.Context, opt map[string]Options, pw progress.Writer) (map[string][]*resolvedNode, error) {
if len(r.nodes) == 0 {
return nil, nil
}
nodes := map[string][]*resolvedNode{}
for k, opt := range opt {
node, perfect, err := r.resolve(ctx, opt.Platforms, pw, platforms.OnlyStrict, nil)
if err != nil {
return nil, err
}
if !perfect {
break
}
nodes[k] = node
}
if len(nodes) != len(opt) {
// if we didn't get a perfect match, we need to boot all drivers
allIndexes := make([]int, len(r.nodes))
for i := range allIndexes {
allIndexes[i] = i
}
clients, err := r.boot(ctx, allIndexes, pw)
if err != nil {
return nil, err
}
eg, egCtx := errgroup.WithContext(ctx)
workers := make([][]specs.Platform, len(clients))
for i, c := range clients {
i, c := i, c
if c == nil {
continue
}
eg.Go(func() error {
ww, err := c.ListWorkers(egCtx)
if err != nil {
return errors.Wrap(err, "listing workers")
}
ps := make(map[string]specs.Platform, len(ww))
for _, w := range ww {
for _, p := range w.Platforms {
pk := platforms.Format(platforms.Normalize(p))
ps[pk] = p
}
}
for _, p := range ps {
workers[i] = append(workers[i], p)
}
return nil
})
}
if err := eg.Wait(); err != nil {
return nil, err
}
// then we can attempt to match against all the available platforms
// (this time we don't care about imperfect matches)
nodes = map[string][]*resolvedNode{}
for k, opt := range opt {
node, _, err := r.resolve(ctx, opt.Platforms, pw, platforms.Only, func(idx int, n builder.Node) []specs.Platform {
return workers[idx]
})
if err != nil {
return nil, err
}
nodes[k] = node
}
}
idxs := make([]int, 0, len(r.nodes))
for _, nodes := range nodes {
for _, node := range nodes {
idxs = append(idxs, node.driverIndex)
}
}
// preload capabilities
span, ctx := tracing.StartSpan(ctx, "load buildkit capabilities", trace.WithSpanKind(trace.SpanKindInternal))
_, err := r.opts(ctx, idxs, pw)
tracing.FinishWithError(span, err)
if err != nil {
return nil, err
}
return nodes, nil
}
func (r *nodeResolver) resolve(ctx context.Context, ps []specs.Platform, pw progress.Writer, matcher matchMaker, additional func(idx int, n builder.Node) []specs.Platform) ([]*resolvedNode, bool, error) {
if len(r.nodes) == 0 {
return nil, true, nil
}
if len(ps) == 0 {
ps = []specs.Platform{platforms.DefaultSpec()}
}
perfect := true
nodeIdxs := make([]int, 0)
for _, p := range ps {
idx := r.get(p, matcher, additional)
if idx == -1 {
idx = 0
perfect = false
}
nodeIdxs = append(nodeIdxs, idx)
}
var nodes []*resolvedNode
for i, idx := range nodeIdxs {
nodes = append(nodes, &resolvedNode{
resolver: r,
driverIndex: idx,
platforms: []specs.Platform{ps[i]},
})
}
nodes = recombineNodes(nodes)
if _, err := r.boot(ctx, nodeIdxs, pw); err != nil {
return nil, false, err
}
return nodes, perfect, nil
}
func (r *nodeResolver) get(p specs.Platform, matcher matchMaker, additionalPlatforms func(int, builder.Node) []specs.Platform) int {
best := -1
bestPlatform := specs.Platform{}
for i, node := range r.nodes {
platforms := node.Platforms
if additionalPlatforms != nil {
platforms = append([]specs.Platform{}, platforms...)
platforms = append(platforms, additionalPlatforms(i, node)...)
}
for _, p2 := range platforms {
m := matcher(p2)
if !m.Match(p) {
continue
}
if best == -1 {
best = i
bestPlatform = p2
continue
}
if matcher(p2).Less(p, bestPlatform) {
best = i
bestPlatform = p2
}
}
}
return best
}
func (r *nodeResolver) boot(ctx context.Context, idxs []int, pw progress.Writer) ([]*client.Client, error) {
clients := make([]*client.Client, len(idxs))
baseCtx := ctx
eg, ctx := errgroup.WithContext(ctx)
for i, idx := range idxs {
i, idx := i, idx
eg.Go(func() error {
c, err := r.clients.Do(ctx, fmt.Sprint(idx), func(ctx context.Context) (*client.Client, error) {
if r.nodes[idx].Driver == nil {
return nil, nil
}
return driver.Boot(ctx, baseCtx, r.nodes[idx].Driver, pw)
})
if err != nil {
return err
}
clients[i] = c
return nil
})
}
if err := eg.Wait(); err != nil {
return nil, err
}
return clients, nil
}
func (r *nodeResolver) opts(ctx context.Context, idxs []int, pw progress.Writer) ([]gateway.BuildOpts, error) {
clients, err := r.boot(ctx, idxs, pw)
if err != nil {
return nil, err
}
bopts := make([]gateway.BuildOpts, len(clients))
eg, ctx := errgroup.WithContext(ctx)
for i, idxs := range idxs {
i, idx := i, idxs
c := clients[i]
if c == nil {
continue
}
eg.Go(func() error {
opt, err := r.opt.Do(ctx, fmt.Sprint(idx), func(ctx context.Context) (gateway.BuildOpts, error) {
opt := gateway.BuildOpts{}
_, err := c.Build(ctx, client.SolveOpt{
Internal: true,
}, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
opt = c.BuildOpts()
return nil, nil
}, nil)
return opt, err
})
if err != nil {
return err
}
bopts[i] = opt
return nil
})
}
if err := eg.Wait(); err != nil {
return nil, err
}
return bopts, nil
}
// recombineDriverPairs recombines resolved nodes that are on the same driver
// back together into a single node.
func recombineNodes(nodes []*resolvedNode) []*resolvedNode {
result := make([]*resolvedNode, 0, len(nodes))
lookup := map[int]int{}
for _, node := range nodes {
if idx, ok := lookup[node.driverIndex]; ok {
result[idx].platforms = append(result[idx].platforms, node.platforms...)
} else {
lookup[node.driverIndex] = len(result)
result = append(result, node)
}
}
return result
}

View File

@@ -1,313 +0,0 @@
package build
import (
"context"
"sort"
"testing"
"github.com/containerd/containerd/platforms"
"github.com/docker/buildx/builder"
specs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/stretchr/testify/require"
)
func TestFindDriverSanity(t *testing.T) {
r := makeTestResolver(map[string][]specs.Platform{
"aaa": {platforms.DefaultSpec()},
})
res, perfect, err := r.resolve(context.TODO(), []specs.Platform{platforms.DefaultSpec()}, nil, platforms.OnlyStrict, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, 0, res[0].driverIndex)
require.Equal(t, "aaa", res[0].Node().Builder)
}
func TestFindDriverEmpty(t *testing.T) {
r := makeTestResolver(nil)
res, perfect, err := r.resolve(context.TODO(), []specs.Platform{platforms.DefaultSpec()}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Nil(t, res)
}
func TestFindDriverWeirdName(t *testing.T) {
r := makeTestResolver(map[string][]specs.Platform{
"aaa": {platforms.MustParse("linux/amd64")},
"bbb": {platforms.MustParse("linux/foobar")},
})
// find first platform
res, perfect, err := r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/foobar")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, 1, res[0].driverIndex)
require.Equal(t, "bbb", res[0].Node().Builder)
}
func TestFindDriverUnknown(t *testing.T) {
r := makeTestResolver(map[string][]specs.Platform{
"aaa": {platforms.MustParse("linux/amd64")},
})
res, perfect, err := r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/riscv64")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.False(t, perfect)
require.Len(t, res, 1)
require.Equal(t, 0, res[0].driverIndex)
require.Equal(t, "aaa", res[0].Node().Builder)
}
func TestSelectNodeSinglePlatform(t *testing.T) {
r := makeTestResolver(map[string][]specs.Platform{
"aaa": {platforms.MustParse("linux/amd64")},
"bbb": {platforms.MustParse("linux/riscv64")},
})
// find first platform
res, perfect, err := r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/amd64")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, 0, res[0].driverIndex)
require.Equal(t, "aaa", res[0].Node().Builder)
// find second platform
res, perfect, err = r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/riscv64")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, 1, res[0].driverIndex)
require.Equal(t, "bbb", res[0].Node().Builder)
// find an unknown platform, should match the first driver
res, perfect, err = r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/s390x")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.False(t, perfect)
require.Len(t, res, 1)
require.Equal(t, 0, res[0].driverIndex)
require.Equal(t, "aaa", res[0].Node().Builder)
}
func TestSelectNodeMultiPlatform(t *testing.T) {
r := makeTestResolver(map[string][]specs.Platform{
"aaa": {platforms.MustParse("linux/amd64"), platforms.MustParse("linux/arm64")},
"bbb": {platforms.MustParse("linux/riscv64")},
})
res, perfect, err := r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/amd64")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, 0, res[0].driverIndex)
require.Equal(t, "aaa", res[0].Node().Builder)
res, perfect, err = r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/arm64")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, 0, res[0].driverIndex)
require.Equal(t, "aaa", res[0].Node().Builder)
res, perfect, err = r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/riscv64")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, 1, res[0].driverIndex)
require.Equal(t, "bbb", res[0].Node().Builder)
}
func TestSelectNodeNonStrict(t *testing.T) {
r := makeTestResolver(map[string][]specs.Platform{
"aaa": {platforms.MustParse("linux/amd64")},
"bbb": {platforms.MustParse("linux/arm64")},
})
// arm64 should match itself
res, perfect, err := r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/arm64")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, "bbb", res[0].Node().Builder)
// arm64 may support arm/v8
res, perfect, err = r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/arm/v8")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, "bbb", res[0].Node().Builder)
// arm64 may support arm/v7
res, perfect, err = r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/arm/v7")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, "bbb", res[0].Node().Builder)
}
func TestSelectNodeNonStrictARM(t *testing.T) {
r := makeTestResolver(map[string][]specs.Platform{
"aaa": {platforms.MustParse("linux/amd64")},
"bbb": {platforms.MustParse("linux/arm64")},
"ccc": {platforms.MustParse("linux/arm/v8")},
})
res, perfect, err := r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/arm/v8")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, "ccc", res[0].Node().Builder)
res, perfect, err = r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/arm/v7")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, "ccc", res[0].Node().Builder)
}
func TestSelectNodeNonStrictLower(t *testing.T) {
r := makeTestResolver(map[string][]specs.Platform{
"aaa": {platforms.MustParse("linux/amd64")},
"bbb": {platforms.MustParse("linux/arm/v7")},
})
// v8 can't be built on v7 (so we should select the default)...
res, perfect, err := r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/arm/v8")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.False(t, perfect)
require.Len(t, res, 1)
require.Equal(t, "aaa", res[0].Node().Builder)
// ...but v6 can be built on v8
res, perfect, err = r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/arm/v6")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, "bbb", res[0].Node().Builder)
}
func TestSelectNodePreferStart(t *testing.T) {
r := makeTestResolver(map[string][]specs.Platform{
"aaa": {platforms.MustParse("linux/amd64")},
"bbb": {platforms.MustParse("linux/riscv64")},
"ccc": {platforms.MustParse("linux/riscv64")},
})
res, perfect, err := r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/riscv64")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, "bbb", res[0].Node().Builder)
}
func TestSelectNodePreferExact(t *testing.T) {
r := makeTestResolver(map[string][]specs.Platform{
"aaa": {platforms.MustParse("linux/arm/v8")},
"bbb": {platforms.MustParse("linux/arm/v7")},
})
res, perfect, err := r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/arm/v7")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, "bbb", res[0].Node().Builder)
}
func TestSelectNodeCurrentPlatform(t *testing.T) {
r := makeTestResolver(map[string][]specs.Platform{
"aaa": {platforms.MustParse("linux/foobar")},
"bbb": {platforms.DefaultSpec()},
})
res, perfect, err := r.resolve(context.TODO(), []specs.Platform{}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, "bbb", res[0].Node().Builder)
}
func TestSelectNodeAdditionalPlatforms(t *testing.T) {
r := makeTestResolver(map[string][]specs.Platform{
"aaa": {platforms.MustParse("linux/amd64")},
"bbb": {platforms.MustParse("linux/arm/v8")},
})
res, perfect, err := r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/arm/v7")}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, "bbb", res[0].Node().Builder)
res, perfect, err = r.resolve(context.TODO(), []specs.Platform{platforms.MustParse("linux/arm/v7")}, nil, platforms.Only, func(idx int, n builder.Node) []specs.Platform {
if n.Builder == "aaa" {
return []specs.Platform{platforms.MustParse("linux/arm/v7")}
}
return nil
})
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, "aaa", res[0].Node().Builder)
}
func TestSplitNodeMultiPlatform(t *testing.T) {
r := makeTestResolver(map[string][]specs.Platform{
"aaa": {platforms.MustParse("linux/amd64"), platforms.MustParse("linux/arm64")},
"bbb": {platforms.MustParse("linux/riscv64")},
})
res, perfect, err := r.resolve(context.TODO(), []specs.Platform{
platforms.MustParse("linux/amd64"),
platforms.MustParse("linux/arm64"),
}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 1)
require.Equal(t, "aaa", res[0].Node().Builder)
res, perfect, err = r.resolve(context.TODO(), []specs.Platform{
platforms.MustParse("linux/amd64"),
platforms.MustParse("linux/riscv64"),
}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 2)
require.Equal(t, "aaa", res[0].Node().Builder)
require.Equal(t, "bbb", res[1].Node().Builder)
}
func TestSplitNodeMultiPlatformNoUnify(t *testing.T) {
r := makeTestResolver(map[string][]specs.Platform{
"aaa": {platforms.MustParse("linux/amd64")},
"bbb": {platforms.MustParse("linux/amd64"), platforms.MustParse("linux/riscv64")},
})
// the "best" choice would be the node with both platforms, but we're using
// a naive algorithm that doesn't try to unify the platforms
res, perfect, err := r.resolve(context.TODO(), []specs.Platform{
platforms.MustParse("linux/amd64"),
platforms.MustParse("linux/riscv64"),
}, nil, platforms.Only, nil)
require.NoError(t, err)
require.True(t, perfect)
require.Len(t, res, 2)
require.Equal(t, "aaa", res[0].Node().Builder)
require.Equal(t, "bbb", res[1].Node().Builder)
}
func makeTestResolver(nodes map[string][]specs.Platform) *nodeResolver {
var ns []builder.Node
for name, platforms := range nodes {
ns = append(ns, builder.Node{
Builder: name,
Platforms: platforms,
})
}
sort.Slice(ns, func(i, j int) bool {
return ns[i].Builder < ns[j].Builder
})
return newDriverResolver(ns)
}

View File

@@ -487,7 +487,7 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions, debugConfig *debug.D
flags := cmd.Flags()
flags.StringSliceVar(&options.extraHosts, "add-host", []string{}, `Add a custom host-to-IP mapping (format: "host:ip")`)
flags.SetAnnotation("add-host", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#add-host"})
flags.SetAnnotation("add-host", annotation.ExternalURL, []string{"https://docs.docker.com/reference/cli/docker/image/build/#add-host"})
flags.StringSliceVar(&options.allow, "allow", []string{}, `Allow extra privileged entitlement (e.g., "network.host", "security.insecure")`)
@@ -500,12 +500,12 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions, debugConfig *debug.D
flags.StringArrayVar(&options.cacheTo, "cache-to", []string{}, `Cache export destinations (e.g., "user/app:cache", "type=local,dest=path/to/dir")`)
flags.StringVar(&options.cgroupParent, "cgroup-parent", "", `Set the parent cgroup for the "RUN" instructions during build`)
flags.SetAnnotation("cgroup-parent", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#cgroup-parent"})
flags.SetAnnotation("cgroup-parent", annotation.ExternalURL, []string{"https://docs.docker.com/reference/cli/docker/image/build/#cgroup-parent"})
flags.StringArrayVar(&options.contexts, "build-context", []string{}, "Additional build contexts (e.g., name=path)")
flags.StringVarP(&options.dockerfileName, "file", "f", "", `Name of the Dockerfile (default: "PATH/Dockerfile")`)
flags.SetAnnotation("file", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#file"})
flags.SetAnnotation("file", annotation.ExternalURL, []string{"https://docs.docker.com/reference/cli/docker/image/build/#file"})
flags.StringVar(&options.imageIDFile, "iidfile", "", "Write the image ID to the file")
@@ -537,10 +537,10 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions, debugConfig *debug.D
flags.StringArrayVar(&options.ssh, "ssh", []string{}, `SSH agent socket or keys to expose to the build (format: "default|<id>[=<socket>|<key>[,<key>]]")`)
flags.StringArrayVarP(&options.tags, "tag", "t", []string{}, `Name and optionally a tag (format: "name:tag")`)
flags.SetAnnotation("tag", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#tag"})
flags.SetAnnotation("tag", annotation.ExternalURL, []string{"https://docs.docker.com/reference/cli/docker/image/build/#tag"})
flags.StringVar(&options.target, "target", "", "Set the target build stage to build")
flags.SetAnnotation("target", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#target"})
flags.SetAnnotation("target", annotation.ExternalURL, []string{"https://docs.docker.com/reference/cli/docker/image/build/#target"})
options.ulimits = dockeropts.NewUlimitOpt(nil)
flags.Var(options.ulimits, "ulimit", "Ulimit options")

View File

@@ -274,13 +274,13 @@ target "db" {
### `target.annotations`
The `annotations` attribute is a shortcut to allow you to easily set a list of
annotations on the target.
The `annotations` attribute lets you add annotations to images built with bake.
The key takes a list of annotations, in the format of `KEY=VALUE`.
```hcl
target "default" {
output = ["type=image,name=foo"]
annotations = ["key=value"]
annotations = ["org.opencontainers.image.authors=dvdksn"]
}
```
@@ -288,10 +288,25 @@ is the same as
```hcl
target "default" {
output = ["type=image,name=foo,annotation.key=value"]
output = ["type=image,name=foo,annotation.org.opencontainers.image.authors=dvdksn"]
}
```
By default, the annotation is added to image manifests. You can configure the
level of the annotations by adding a prefix to the annotation, containing a
comma-separated list of all the levels that you want to annotate. The following
example adds annotations to both the image index and manifests.
```hcl
target "default" {
output = ["type=image,name=foo"]
annotations = ["index,manifest:org.opencontainers.image.authors=dvdksn"]
}
```
Read about the supported levels in
[Specifying annotation levels](https://docs.docker.com/build/building/annotations/#specifying-annotation-levels).
### `target.attest`
The `attest` attribute lets you apply [build attestations][attestations] to the target.
@@ -1054,20 +1069,20 @@ target "webapp-dev" {
[attestations]: https://docs.docker.com/build/attestations/
[bake_stdlib]: https://github.com/docker/buildx/blob/master/bake/hclparser/stdlib.go
[build-arg]: https://docs.docker.com/engine/reference/commandline/build/#build-arg
[build-context]: https://docs.docker.com/engine/reference/commandline/buildx_build/#build-context
[build-arg]: https://docs.docker.com/reference/cli/docker/image/build/#build-arg
[build-context]: https://docs.docker.com/reference/cli/docker/buildx/build/#build-context
[cache-backends]: https://docs.docker.com/build/cache/backends/
[cache-from]: https://docs.docker.com/engine/reference/commandline/buildx_build/#cache-from
[cache-to]: https://docs.docker.com/engine/reference/commandline/buildx_build/#cache-to
[context]: https://docs.docker.com/engine/reference/commandline/buildx_build/#build-context
[file]: https://docs.docker.com/engine/reference/commandline/build/#file
[cache-from]: https://docs.docker.com/reference/cli/docker/buildx/build/#cache-from
[cache-to]: https://docs.docker.com/reference/cli/docker/buildx/build/#cache-to
[context]: https://docs.docker.com/reference/cli/docker/buildx/build/#build-context
[file]: https://docs.docker.com/reference/cli/docker/image/build/#file
[go-cty]: https://github.com/zclconf/go-cty/tree/main/cty/function/stdlib
[hcl-funcs]: https://docs.docker.com/build/bake/hcl-funcs/
[output]: https://docs.docker.com/engine/reference/commandline/buildx_build/#output
[platform]: https://docs.docker.com/engine/reference/commandline/buildx_build/#platform
[run_mount_secret]: https://docs.docker.com/engine/reference/builder/#run---mounttypesecret
[secret]: https://docs.docker.com/engine/reference/commandline/buildx_build/#secret
[ssh]: https://docs.docker.com/engine/reference/commandline/buildx_build/#ssh
[tag]: https://docs.docker.com/engine/reference/commandline/build/#tag
[target]: https://docs.docker.com/engine/reference/commandline/build/#target
[output]: https://docs.docker.com/reference/cli/docker/buildx/build/#output
[platform]: https://docs.docker.com/reference/cli/docker/buildx/build/#platform
[run_mount_secret]: https://docs.docker.com/reference/dockerfile/#run---mounttypesecret
[secret]: https://docs.docker.com/reference/cli/docker/buildx/build/#secret
[ssh]: https://docs.docker.com/reference/cli/docker/buildx/build/#ssh
[tag]: https://docs.docker.com/reference/cli/docker/image/build/#tag
[target]: https://docs.docker.com/reference/cli/docker/image/build/#target
[userfunc]: https://github.com/hashicorp/hcl/tree/main/ext/userfunc

View File

@@ -1,6 +1,6 @@
# buildx
```
```text
docker buildx [OPTIONS] COMMAND
```

View File

@@ -1,6 +1,6 @@
# buildx bake
```
```text
docker buildx bake [OPTIONS] [TARGET...]
```
@@ -33,7 +33,7 @@ Build from a file
## Description
Bake is a high-level build command. Each specified target will run in parallel
Bake is a high-level build command. Each specified target runs in parallel
as part of the build.
Read [High-level build options with Bake](https://docs.docker.com/build/bake/)
@@ -54,8 +54,8 @@ Same as [`buildx --builder`](buildx.md#builder).
### <a name="file"></a> Specify a build definition file (-f, --file)
Use the `-f` / `--file` option to specify the build definition file to use.
The file can be an HCL, JSON or Compose file. If multiple files are specified
they are all read and configurations are combined.
The file can be an HCL, JSON or Compose file. If multiple files are specified,
all are read and the build configurations are combined.
You can pass the names of the targets to build, to build only specific target(s).
The following example builds the `db` and `webapp-release` targets that are
@@ -90,9 +90,9 @@ $ docker buildx bake -f docker-bake.dev.hcl db webapp-release
See the [Bake file reference](https://docs.docker.com/build/bake/reference/)
for more details.
### <a name="no-cache"></a> Do not use cache when building the image (--no-cache)
### <a name="no-cache"></a> Don't use cache when building the image (--no-cache)
Same as `build --no-cache`. Do not use cache when building the image.
Same as `build --no-cache`. Don't use cache when building the image.
### <a name="print"></a> Print the options without building (--print)
@@ -154,7 +154,7 @@ $ docker buildx bake --set *.platform=linux/arm64 # overrides platform for a
$ docker buildx bake --set foo*.no-cache # bypass caching only for targets starting with 'foo'
```
Complete list of overridable fields:
You can override the following fields:
* `args`
* `cache-from`

View File

@@ -1,6 +1,6 @@
# buildx build
```
```text
docker buildx build [OPTIONS] PATH | URL | -
```
@@ -13,44 +13,44 @@ Start a build
### Options
| Name | Type | Default | Description |
|:-------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------|:----------|:----------------------------------------------------------------------------------------------------|
| [`--add-host`](https://docs.docker.com/engine/reference/commandline/build/#add-host) | `stringSlice` | | Add a custom host-to-IP mapping (format: `host:ip`) |
| [`--allow`](#allow) | `stringSlice` | | Allow extra privileged entitlement (e.g., `network.host`, `security.insecure`) |
| `--annotation` | `stringArray` | | Add annotation to the image |
| [`--attest`](#attest) | `stringArray` | | Attestation parameters (format: `type=sbom,generator=image`) |
| [`--build-arg`](#build-arg) | `stringArray` | | Set build-time variables |
| [`--build-context`](#build-context) | `stringArray` | | Additional build contexts (e.g., name=path) |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| [`--cache-from`](#cache-from) | `stringArray` | | External cache sources (e.g., `user/app:cache`, `type=local,src=path/to/dir`) |
| [`--cache-to`](#cache-to) | `stringArray` | | Cache export destinations (e.g., `user/app:cache`, `type=local,dest=path/to/dir`) |
| [`--cgroup-parent`](https://docs.docker.com/engine/reference/commandline/build/#cgroup-parent) | `string` | | Set the parent cgroup for the `RUN` instructions during build |
| `--detach` | | | Detach buildx server (supported only on linux) |
| [`-f`](https://docs.docker.com/engine/reference/commandline/build/#file), [`--file`](https://docs.docker.com/engine/reference/commandline/build/#file) | `string` | | Name of the Dockerfile (default: `PATH/Dockerfile`) |
| `--iidfile` | `string` | | Write the image ID to the file |
| `--label` | `stringArray` | | Set metadata for an image |
| [`--load`](#load) | | | Shorthand for `--output=type=docker` |
| [`--metadata-file`](#metadata-file) | `string` | | Write build result metadata to the file |
| `--network` | `string` | `default` | Set the networking mode for the `RUN` instructions during build |
| `--no-cache` | | | Do not use cache when building the image |
| `--no-cache-filter` | `stringArray` | | Do not cache specified stages |
| [`-o`](#output), [`--output`](#output) | `stringArray` | | Output destination (format: `type=local,dest=path`) |
| [`--platform`](#platform) | `stringArray` | | Set target platform for build |
| `--print` | `string` | | Print result of information request (e.g., outline, targets) |
| [`--progress`](#progress) | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output |
| [`--provenance`](#provenance) | `string` | | Shorthand for `--attest=type=provenance` |
| `--pull` | | | Always attempt to pull all referenced images |
| [`--push`](#push) | | | Shorthand for `--output=type=registry` |
| `-q`, `--quiet` | | | Suppress the build output and print image ID on success |
| `--root` | `string` | | Specify root directory of server to connect |
| [`--sbom`](#sbom) | `string` | | Shorthand for `--attest=type=sbom` |
| [`--secret`](#secret) | `stringArray` | | Secret to expose to the build (format: `id=mysecret[,src=/local/secret]`) |
| `--server-config` | `string` | | Specify buildx server config file (used only when launching new server) |
| [`--shm-size`](#shm-size) | `bytes` | `0` | Size of `/dev/shm` |
| [`--ssh`](#ssh) | `stringArray` | | SSH agent socket or keys to expose to the build (format: `default\|<id>[=<socket>\|<key>[,<key>]]`) |
| [`-t`](https://docs.docker.com/engine/reference/commandline/build/#tag), [`--tag`](https://docs.docker.com/engine/reference/commandline/build/#tag) | `stringArray` | | Name and optionally a tag (format: `name:tag`) |
| [`--target`](https://docs.docker.com/engine/reference/commandline/build/#target) | `string` | | Set the target build stage to build |
| [`--ulimit`](#ulimit) | `ulimit` | | Ulimit options |
| Name | Type | Default | Description |
|:---------------------------------------------------------------------------------------------------------------------------------------------------|:--------------|:----------|:----------------------------------------------------------------------------------------------------|
| [`--add-host`](https://docs.docker.com/reference/cli/docker/image/build/#add-host) | `stringSlice` | | Add a custom host-to-IP mapping (format: `host:ip`) |
| [`--allow`](#allow) | `stringSlice` | | Allow extra privileged entitlement (e.g., `network.host`, `security.insecure`) |
| [`--annotation`](#annotation) | `stringArray` | | Add annotation to the image |
| [`--attest`](#attest) | `stringArray` | | Attestation parameters (format: `type=sbom,generator=image`) |
| [`--build-arg`](#build-arg) | `stringArray` | | Set build-time variables |
| [`--build-context`](#build-context) | `stringArray` | | Additional build contexts (e.g., name=path) |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| [`--cache-from`](#cache-from) | `stringArray` | | External cache sources (e.g., `user/app:cache`, `type=local,src=path/to/dir`) |
| [`--cache-to`](#cache-to) | `stringArray` | | Cache export destinations (e.g., `user/app:cache`, `type=local,dest=path/to/dir`) |
| [`--cgroup-parent`](https://docs.docker.com/reference/cli/docker/image/build/#cgroup-parent) | `string` | | Set the parent cgroup for the `RUN` instructions during build |
| `--detach` | | | Detach buildx server (supported only on linux) |
| [`-f`](https://docs.docker.com/reference/cli/docker/image/build/#file), [`--file`](https://docs.docker.com/reference/cli/docker/image/build/#file) | `string` | | Name of the Dockerfile (default: `PATH/Dockerfile`) |
| `--iidfile` | `string` | | Write the image ID to the file |
| `--label` | `stringArray` | | Set metadata for an image |
| [`--load`](#load) | | | Shorthand for `--output=type=docker` |
| [`--metadata-file`](#metadata-file) | `string` | | Write build result metadata to the file |
| `--network` | `string` | `default` | Set the networking mode for the `RUN` instructions during build |
| `--no-cache` | | | Do not use cache when building the image |
| `--no-cache-filter` | `stringArray` | | Do not cache specified stages |
| [`-o`](#output), [`--output`](#output) | `stringArray` | | Output destination (format: `type=local,dest=path`) |
| [`--platform`](#platform) | `stringArray` | | Set target platform for build |
| `--print` | `string` | | Print result of information request (e.g., outline, targets) |
| [`--progress`](#progress) | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output |
| [`--provenance`](#provenance) | `string` | | Shorthand for `--attest=type=provenance` |
| `--pull` | | | Always attempt to pull all referenced images |
| [`--push`](#push) | | | Shorthand for `--output=type=registry` |
| `-q`, `--quiet` | | | Suppress the build output and print image ID on success |
| `--root` | `string` | | Specify root directory of server to connect |
| [`--sbom`](#sbom) | `string` | | Shorthand for `--attest=type=sbom` |
| [`--secret`](#secret) | `stringArray` | | Secret to expose to the build (format: `id=mysecret[,src=/local/secret]`) |
| `--server-config` | `string` | | Specify buildx server config file (used only when launching new server) |
| [`--shm-size`](#shm-size) | `bytes` | `0` | Size of `/dev/shm` |
| [`--ssh`](#ssh) | `stringArray` | | SSH agent socket or keys to expose to the build (format: `default\|<id>[=<socket>\|<key>[,<key>]]`) |
| [`-t`](https://docs.docker.com/reference/cli/docker/image/build/#tag), [`--tag`](https://docs.docker.com/reference/cli/docker/image/build/#tag) | `stringArray` | | Name and optionally a tag (format: `name:tag`) |
| [`--target`](https://docs.docker.com/reference/cli/docker/image/build/#target) | `string` | | Set the target build stage to build |
| [`--ulimit`](#ulimit) | `ulimit` | | Ulimit options |
<!---MARKER_GEN_END-->
@@ -64,14 +64,60 @@ The `buildx build` command starts a build using BuildKit. This command is simila
to the UI of `docker build` command and takes the same flags and arguments.
For documentation on most of these flags, refer to the [`docker build`
documentation](https://docs.docker.com/engine/reference/commandline/build/). In
here we'll document a subset of the new flags.
documentation](https://docs.docker.com/reference/cli/docker/image/build/).
This page describes a subset of the new flags.
## Examples
### <a name="annotation"></a> Create annotations (--annotation)
```text
--annotation="key=value"
--annotation="[type:]key=value"
```
Add OCI annotations to the image index, manifest, or descriptor.
The following example adds the `foo=bar` annotation to the image manifests:
```console
$ docker buildx build -t TAG --annotation "foo=bar" --push .
```
You can optionally add a type prefix to specify the level of the annotation. By
default, the image manifest is annotated. The following example adds the
`foo=bar` annotation the image index instead of the manifests:
```console
$ docker buildx build -t TAG --annotation "index:foo=bar" --push .
```
You can specify multiple types, separated by a comma (,) to add the annotation
to multiple image components. The following example adds the `foo=bar`
annotation to image index, descriptors, manifests:
```console
$ docker buildx build -t TAG --annotation "index,manifest,manifest-descriptor:foo=bar" --push .
```
You can also specify a platform qualifier in square brackets (`[os/arch]`) in
the type prefix, to apply the annotation to a subset of manifests with the
matching platform. The following example adds the `foo=bar` annotation only to
the manifest with the `linux/amd64` platform:
```console
$ docker buildx build -t TAG --annotation "manifest[linux/amd64]:foo=bar" --push .
```
Wildcards are not supported in the platform qualifier; you can't specify a type
prefix like `manifest[linux/*]` to add annotations only to manifests which has
`linux` as the OS platform.
For more information about annotations, see
[Annotations](https://docs.docker.com/build/building/annotations/).
### <a name="attest"></a> Create attestations (--attest)
```
```text
--attest=type=sbom,...
--attest=type=provenance,...
```
@@ -98,7 +144,7 @@ BuildKit currently supports:
### <a name="allow"></a> Allow extra privileged entitlement (--allow)
```
```text
--allow=ENTITLEMENT
```
@@ -106,12 +152,10 @@ Allow extra privileged entitlement. List of entitlements:
- `network.host` - Allows executions with host networking.
- `security.insecure` - Allows executions without sandbox. See
[related Dockerfile extensions](https://docs.docker.com/engine/reference/builder/#run---securitysandbox).
[related Dockerfile extensions](https://docs.docker.com/reference/dockerfile/#run---securitysandbox).
For entitlements to be enabled, the `buildkitd` daemon also needs to allow them
with `--allow-insecure-entitlement` (see [`create --buildkitd-flags`](buildx_create.md#buildkitd-flags))
**Examples**
with `--allow-insecure-entitlement` (see [`create --buildkitd-flags`](buildx_create.md#buildkitd-flags)).
```console
$ docker buildx create --use --name insecure-builder --buildkitd-flags '--allow-insecure-entitlement security.insecure'
@@ -120,25 +164,23 @@ $ docker buildx build --allow security.insecure .
### <a name="build-arg"></a> Set build-time variables (--build-arg)
Same as [`docker build` command](https://docs.docker.com/engine/reference/commandline/build/#build-arg).
Same as [`docker build` command](https://docs.docker.com/reference/cli/docker/image/build/#build-arg).
There are also useful built-in build args like:
There are also useful built-in build arguments, such as:
* `BUILDKIT_CONTEXT_KEEP_GIT_DIR=<bool>` trigger git context to keep the `.git` directory
* `BUILDKIT_INLINE_CACHE=<bool>` inline cache metadata to image config or not
* `BUILDKIT_MULTI_PLATFORM=<bool>` opt into deterministic output regardless of multi-platform output or not
* `BUILDKIT_CONTEXT_KEEP_GIT_DIR=<bool>`: trigger git context to keep the `.git` directory
* `BUILDKIT_INLINE_CACHE=<bool>`: inline cache metadata to image config or not
* `BUILDKIT_MULTI_PLATFORM=<bool>`: opt into deterministic output regardless of multi-platform output or not
```console
$ docker buildx build --build-arg BUILDKIT_MULTI_PLATFORM=1 .
```
> **Note**
>
> More built-in build args can be found in [Dockerfile reference docs](https://docs.docker.com/engine/reference/builder/#buildkit-built-in-build-args).
Learn more about the built-in build arguments in the [Dockerfile reference docs](https://docs.docker.com/reference/dockerfile/#buildkit-built-in-build-args).
### <a name="build-context"></a> Additional build contexts (--build-context)
```
```text
--build-context=name=VALUE
```
@@ -166,7 +208,7 @@ FROM alpine
COPY --from=project myfile /
```
#### <a name="source-oci-layout"></a> Source image from OCI layout directory
#### <a name="source-oci-layout"></a> Use an OCI layout directory as build context
Source an image from a local [OCI layout compliant directory](https://github.com/opencontainers/image-spec/blob/main/image-layout.md),
either by tag, or by digest:
@@ -194,7 +236,7 @@ Same as [`buildx --builder`](buildx.md#builder).
### <a name="cache-from"></a> Use an external cache source for a build (--cache-from)
```
```text
--cache-from=[NAME|type=TYPE[,KEY=VALUE]]
```
@@ -230,7 +272,7 @@ More info about cache exporters and available attributes: https://github.com/mob
### <a name="cache-to"></a> Export build cache to an external cache destination (--cache-to)
```
```text
--cache-to=[NAME|type=TYPE[,KEY=VALUE]]
```
@@ -247,9 +289,8 @@ Export build cache to an external cache destination. Supported types are
- [`s3` type](https://github.com/moby/buildkit#s3-cache-experimental) exports
cache to a S3 bucket.
`docker` driver currently only supports exporting inline cache metadata to image
configuration. Alternatively, `--build-arg BUILDKIT_INLINE_CACHE=1` can be used
to trigger inline cache exporter.
The `docker` driver only supports cache exports using the `inline` and `local`
cache backends.
Attribute key:
@@ -283,6 +324,7 @@ directory of the specified file must already exist and be writable.
$ docker buildx build --load --metadata-file metadata.json .
$ cat metadata.json
```
```json
{
"containerimage.config.digest": "sha256:2937f66a9722f7f4a2df583de2f8cb97fc9196059a410e7f00072fc918930e66",
@@ -301,14 +343,14 @@ $ cat metadata.json
### <a name="output"></a> Set the export action for the build result (-o, --output)
```
```text
-o, --output=[PATH,-,type=TYPE[,KEY=VALUE]
```
Sets the export action for the build result. In `docker build` all builds finish
by creating a container image and exporting it to `docker images`. `buildx` makes
this step configurable allowing results to be exported directly to the client,
oci image tarballs, registry etc.
OCI image tarballs, registry etc.
Buildx with `docker` driver currently only supports local, tarball exporter and
image exporter. `docker-container` driver supports all the exporters.
@@ -363,15 +405,15 @@ The `docker` export type writes the single-platform result image as a [Docker im
specification](https://github.com/docker/docker/blob/v20.10.2/image/spec/v1.2.md)
tarball on the client. Tarballs created by this exporter are also OCI compatible.
Currently, multi-platform images cannot be exported with the `docker` export type.
The most common usecase for multi-platform images is to directly push to a registry
(see [`registry`](#registry)).
The default image store in Docker Engine doesn't support loading multi-platform
images. You can enable the containerd image store, or push multi-platform images
is to directly push to a registry, see [`registry`](#registry).
Attribute keys:
- `dest` - destination path where tarball will be written. If not specified the
tar will be loaded automatically to the current docker instance.
- `context` - name for the docker context where to import the result
- `dest` - destination path where tarball will be written. If not specified,
the tar will be loaded automatically to the local image store.
- `context` - name for the Docker context where to import the result
#### `image`
@@ -382,7 +424,7 @@ can be automatically pushed to a registry by specifying attributes.
Attribute keys:
- `name` - name (references) for the new image.
- `push` - boolean to automatically push the image.
- `push` - Boolean to automatically push the image.
#### `registry`
@@ -390,7 +432,7 @@ The `registry` exporter is a shortcut for `type=image,push=true`.
### <a name="platform"></a> Set the target platforms for the build (--platform)
```
```text
--platform=value[,value]
```
@@ -419,12 +461,12 @@ and `arm` architectures. You can see what runtime platforms your current builder
instance supports by running `docker buildx inspect --bootstrap`.
Inside a `Dockerfile`, you can access the current platform value through
`TARGETPLATFORM` build argument. Please refer to the [`docker build`
documentation](https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope)
`TARGETPLATFORM` build argument. Refer to the [`docker build`
documentation](https://docs.docker.com/reference/dockerfile/#automatic-platform-args-in-the-global-scope)
for the full description of automatic platform argument variants .
The formatting for the platform specifier is defined in the [containerd source
code](https://github.com/containerd/containerd/blob/v1.4.3/platforms/platforms.go#L63).
You can find the formatting definition for the platform specifier in the
[containerd source code](https://github.com/containerd/containerd/blob/v1.4.3/platforms/platforms.go#L63).
```console
$ docker buildx build --platform=linux/arm64 .
@@ -434,11 +476,11 @@ $ docker buildx build --platform=darwin .
### <a name="progress"></a> Set type of progress output (--progress)
```
```text
--progress=VALUE
```
Set type of progress output (auto, plain, tty). Use plain to show container
Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container
output (default "auto").
> **Note**
@@ -472,15 +514,18 @@ provenance attestations for the build result. For example,
`--provenance=mode=max` can be used as an abbreviation for
`--attest=type=provenance,mode=max`.
Additionally, `--provenance` can be used with boolean values to broadly enable
or disable provenance attestations. For example, `--provenance=false` can be
used to disable all provenance attestations, while `--provenance=true` can be
used to enable all provenance attestations.
Additionally, `--provenance` can be used with Boolean values to enable or disable
provenance attestations. For example, `--provenance=false` disables all provenance attestations,
while `--provenance=true` enables all provenance attestations.
By default, a minimal provenance attestation will be created for the build
result, which will only be attached for images pushed to registries.
result. Note that the default image store in Docker Engine doesn't support
attestations. Provenance attestations only persist for images pushed directly
to a registry if you use the default image store. Alternatively, you can switch
to using the containerd image store.
For more information, see [here](https://docs.docker.com/build/attestations/slsa-provenance/).
For more information about provenance attestations, see
[here](https://docs.docker.com/build/attestations/slsa-provenance/).
### <a name="push"></a> Push the build result to a registry (--push)
@@ -494,20 +539,24 @@ attestations for the build result. For example,
`--sbom=generator=<user>/<generator-image>` can be used as an abbreviation for
`--attest=type=sbom,generator=<user>/<generator-image>`.
Additionally, `--sbom` can be used with boolean values to broadly enable or
disable SBOM attestations. For example, `--sbom=false` can be used to disable
all SBOM attestations.
Additionally, `--sbom` can be used with Boolean values to enable or disable
SBOM attestations. For example, `--sbom=false` disables all SBOM attestations.
Note that the default image store in Docker Engine doesn't support
attestations. Provenance attestations only persist for images pushed directly
to a registry if you use the default image store. Alternatively, you can switch
to using the containerd image store.
For more information, see [here](https://docs.docker.com/build/attestations/sbom/).
### <a name="secret"></a> Secret to expose to the build (--secret)
```
```text
--secret=[type=TYPE[,KEY=VALUE]
```
Exposes secret to the build. The secret can be used by the build using
[`RUN --mount=type=secret` mount](https://docs.docker.com/engine/reference/builder/#run---mounttypesecret).
[`RUN --mount=type=secret` mount](https://docs.docker.com/reference/dockerfile/#run---mounttypesecret).
If `type` is unset it will be detected. Supported types are:
@@ -515,7 +564,7 @@ If `type` is unset it will be detected. Supported types are:
Attribute keys:
- `id` - ID of the secret. Defaults to basename of the `src` path.
- `id` - ID of the secret. Defaults to base name of the `src` path.
- `src`, `source` - Secret filename. `id` used if unset.
```dockerfile
@@ -557,7 +606,7 @@ optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes), or `g`
### <a name="ssh"></a> SSH agent socket or keys to expose to the build (--ssh)
```
```text
--ssh=default|<id>[=<socket>|<key>[,<key>]]
```
@@ -565,7 +614,7 @@ This can be useful when some commands in your Dockerfile need specific SSH
authentication (e.g., cloning a private repository).
`--ssh` exposes SSH agent socket or keys to the build and can be used with the
[`RUN --mount=type=ssh` mount](https://docs.docker.com/engine/reference/builder/#run---mounttypessh).
[`RUN --mount=type=ssh` mount](https://docs.docker.com/reference/dockerfile/#run---mounttypessh).
Example to access Gitlab using an SSH agent socket:
@@ -597,6 +646,6 @@ $ docker buildx build --ulimit nofile=1024:1024 .
> **Note**
>
> If you do not provide a `hard limit`, the `soft limit` is used
> for both values. If no `ulimits` are set, they are inherited from
> If you don't provide a `hard limit`, the `soft limit` is used
> for both values. If no `ulimits` are set, they're inherited from
> the default `ulimits` set on the daemon.

View File

@@ -1,6 +1,6 @@
# buildx create
```
```text
docker buildx create [OPTIONS] [CONTEXT|ENDPOINT]
```
@@ -29,9 +29,9 @@ Create a new builder instance
## Description
Create makes a new builder instance pointing to a docker context or endpoint,
Create makes a new builder instance pointing to a Docker context or endpoint,
where context is the name of a context from `docker context ls` and endpoint is
the address for docker socket (eg. `DOCKER_HOST` value).
the address for Docker socket (eg. `DOCKER_HOST` value).
By default, the current Docker configuration is used for determining the
context/endpoint value.
@@ -57,7 +57,7 @@ eager_beaver
### <a name="buildkitd-flags"></a> Specify options for the buildkitd daemon (--buildkitd-flags)
```
```text
--buildkitd-flags FLAGS
```
@@ -65,13 +65,13 @@ Adds flags when starting the buildkitd daemon. They take precedence over the
configuration file specified by [`--config`](#config). See `buildkitd --help`
for the available flags.
```
```text
--buildkitd-flags '--debug --debugaddr 0.0.0.0:6666'
```
### <a name="config"></a> Specify a configuration file for the buildkitd daemon (--config)
```
```text
--config FILE
```
@@ -79,7 +79,8 @@ Specifies the configuration file for the buildkitd daemon to use. The configurat
can be overridden by [`--buildkitd-flags`](#buildkitd-flags).
See an [example buildkitd configuration file](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md).
If the configuration file is not specified, will look for one by default in:
If you don't specify a configuration file, Buildx looks for one by default in:
* `$BUILDX_CONFIG/buildkitd.default.toml`
* `$DOCKER_CONFIG/buildx/buildkitd.default.toml`
* `~/.docker/buildx/buildkitd.default.toml`
@@ -91,23 +92,30 @@ will be updated to reflect that.
### <a name="driver"></a> Set the builder driver to use (--driver)
```
```text
--driver DRIVER
```
Sets the builder driver to be used. There are two available drivers, each have
their own specificities.
Sets the builder driver to be used. A driver is a configuration of a BuildKit
backend. Buildx supports the following drivers:
* `docker` (default)
* `docker-container`
* `kubernetes`
* `remote`
For more information about build drivers, see [here](https://docs.docker.com/build/drivers/).
#### `docker` driver
Uses the builder that is built into the docker daemon. With this driver,
Uses the builder that is built into the Docker daemon. With this driver,
the [`--load`](buildx_build.md#load) flag is implied by default on
`buildx build`. However, building multi-platform images or exporting cache is
not currently supported.
#### `docker-container` driver
Uses a BuildKit container that will be spawned via docker. With this driver,
Uses a BuildKit container that will be spawned via Docker. With this driver,
both building multi-platform images and exporting cache are supported.
Unlike `docker` driver, built images will not automatically appear in
@@ -116,7 +124,7 @@ to achieve that.
#### `kubernetes` driver
Uses a kubernetes pods. With this driver, you can spin up pods with defined
Uses Kubernetes pods. With this driver, you can spin up pods with defined
BuildKit container image to build your images.
Unlike `docker` driver, built images will not automatically appear in
@@ -135,59 +143,18 @@ to achieve that.
### <a name="driver-opt"></a> Set additional driver-specific options (--driver-opt)
```
```text
--driver-opt OPTIONS
```
Passes additional driver-specific options.
For information about available driver options, refer to the detailed
documentation for the specific driver:
Note: When using quoted values for the `nodeselector`, `annotations`, `labels` or
`tolerations` options, ensure that quotes are escaped correctly for your shell.
#### `docker` driver
No driver options.
#### `docker-container` driver
- `image=IMAGE` - Sets the BuildKit image to use for the container.
- `memory=MEMORY` - Sets the amount of memory the container can use.
- `memory-swap=MEMORY_SWAP` - Sets the memory swap limit for the container.
- `cpu-quota=CPU_QUOTA` - Imposes a CPU CFS quota on the container.
- `cpu-period=CPU_PERIOD` - Sets the CPU CFS scheduler period for the container.
- `cpu-shares=CPU_SHARES` - Configures CPU shares (relative weight) of the container.
- `cpuset-cpus=CPUSET_CPUS` - Limits the set of CPU cores the container can use.
- `cpuset-mems=CPUSET_MEMS` - Limits the set of CPU memory nodes the container can use.
- `network=NETMODE` - Sets the network mode for the container.
- `cgroup-parent=CGROUP` - Sets the cgroup parent of the container if docker is using the "cgroupfs" driver. Defaults to `/docker/buildx`.
Before you configure the resource limits for the container, read about [configuring runtime resource constraints for containers](https://docs.docker.com/config/containers/resource_constraints/).
#### `kubernetes` driver
- `image=IMAGE` - Sets the container image to be used for running buildkit.
- `namespace=NS` - Sets the Kubernetes namespace. Defaults to the current namespace.
- `replicas=N` - Sets the number of `Pod` replicas. Defaults to 1.
- `requests.cpu` - Sets the request CPU value specified in units of Kubernetes CPU. Example `requests.cpu=100m`, `requests.cpu=2`
- `requests.memory` - Sets the request memory value specified in bytes or with a valid suffix. Example `requests.memory=500Mi`, `requests.memory=4G`
- `limits.cpu` - Sets the limit CPU value specified in units of Kubernetes CPU. Example `limits.cpu=100m`, `limits.cpu=2`
- `limits.memory` - Sets the limit memory value specified in bytes or with a valid suffix. Example `limits.memory=500Mi`, `limits.memory=4G`
- `serviceaccount` - Sets the created pod's service account. Example `serviceaccount=example-sa`
- `"nodeselector=label1=value1,label2=value2"` - Sets the kv of `Pod` nodeSelector. No Defaults. Example `nodeselector=kubernetes.io/arch=arm64`
- `"annotations=domain/thing1=value1,domain/thing2=value2"` - Sets additional annotations on the deployments and pods. No Defaults. Example `annotations=example.com/owner=sarah`
- `"labels=domain/thing1=value1,domain/thing2=value2"` - Sets additional labels on the deployments and pods. No Defaults. Example `labels=example.com/team=rd`
- `"tolerations=key=foo,value=bar;key=foo2,operator=exists;key=foo3,effect=NoSchedule"` - Sets the `Pod` tolerations. Accepts the same values as the kube manifest tolera>tions. Key-value pairs are separated by `,`, tolerations are separated by `;`. No Defaults. Example `tolerations=operator=exists`
- `rootless=(true|false)` - Run the container as a non-root user without `securityContext.privileged`. Needs Kubernetes 1.19 or later. [Using Ubuntu host kernel is recommended](https://github.com/moby/buildkit/blob/master/docs/rootless.md). Defaults to false.
- `loadbalance=(sticky|random)` - Load-balancing strategy. If set to "sticky", the pod is chosen using the hash of the context path. Defaults to "sticky"
- `qemu.install=(true|false)` - Install QEMU emulation for multi platforms support.
- `qemu.image=IMAGE` - Sets the QEMU emulation image. Defaults to `tonistiigi/binfmt:latest`
#### `remote` driver
- `key=KEY` - Sets the TLS client key.
- `cert=CERT` - Sets the TLS client certificate to present to buildkitd.
- `cacert=CACERT` - Sets the TLS certificate authority used for validation.
- `servername=SERVER` - Sets the TLS server name to be used in requests (defaults to the endpoint hostname).
* [`docker` driver](https://docs.docker.com/build/drivers/docker/)
* [`docker-container` driver](https://docs.docker.com/build/drivers/docker-container/)
* [`kubernetes` driver](https://docs.docker.com/build/drivers/kubernetes/)
* [`remote` driver](https://docs.docker.com/build/drivers/remote/)
### <a name="leave"></a> Remove a node from a builder (--leave)
@@ -201,7 +168,7 @@ $ docker buildx create --name mybuilder --node mybuilder0 --leave
### <a name="name"></a> Specify the name of the builder (--name)
```
```text
--name NAME
```
@@ -210,17 +177,17 @@ If none is specified, one will be automatically generated.
### <a name="node"></a> Specify the name of the node (--node)
```
```text
--node NODE
```
The `--node` flag specifies the name of the node to be created or modified. If
none is specified, it is the name of the builder it belongs to, with an index
number suffix.
you don't specify a name, the node name defaults to the name of the builder it
belongs to, with an index number suffix.
### <a name="platform"></a> Set the platforms supported by the node (--platform)
```
```text
--platform PLATFORMS
```

View File

@@ -15,7 +15,7 @@ Start debugger
| Name | Type | Default | Description |
|:------------------|:---------|:--------|:---------------------------------------------------------------------------------------------------------|
| `--builder` | `string` | | Override the configured builder instance |
| `--detach` | | | Detach buildx server for the monitor (supported only on linux) |
| `--detach` | `bool` | `true` | Detach buildx server for the monitor (supported only on linux) |
| `--invoke` | `string` | | Launch a monitor with executing specified command |
| `--on` | `string` | `error` | When to launch the monitor ([always, error]) |
| `--progress` | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`) for the monitor. Use plain to show container output |

View File

@@ -9,44 +9,44 @@ Start a build
### Options
| Name | Type | Default | Description |
|:-------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------|:----------|:----------------------------------------------------------------------------------------------------|
| [`--add-host`](https://docs.docker.com/engine/reference/commandline/build/#add-host) | `stringSlice` | | Add a custom host-to-IP mapping (format: `host:ip`) |
| `--allow` | `stringSlice` | | Allow extra privileged entitlement (e.g., `network.host`, `security.insecure`) |
| `--annotation` | `stringArray` | | Add annotation to the image |
| `--attest` | `stringArray` | | Attestation parameters (format: `type=sbom,generator=image`) |
| `--build-arg` | `stringArray` | | Set build-time variables |
| `--build-context` | `stringArray` | | Additional build contexts (e.g., name=path) |
| `--builder` | `string` | | Override the configured builder instance |
| `--cache-from` | `stringArray` | | External cache sources (e.g., `user/app:cache`, `type=local,src=path/to/dir`) |
| `--cache-to` | `stringArray` | | Cache export destinations (e.g., `user/app:cache`, `type=local,dest=path/to/dir`) |
| [`--cgroup-parent`](https://docs.docker.com/engine/reference/commandline/build/#cgroup-parent) | `string` | | Set the parent cgroup for the `RUN` instructions during build |
| `--detach` | | | Detach buildx server (supported only on linux) |
| [`-f`](https://docs.docker.com/engine/reference/commandline/build/#file), [`--file`](https://docs.docker.com/engine/reference/commandline/build/#file) | `string` | | Name of the Dockerfile (default: `PATH/Dockerfile`) |
| `--iidfile` | `string` | | Write the image ID to the file |
| `--label` | `stringArray` | | Set metadata for an image |
| `--load` | | | Shorthand for `--output=type=docker` |
| `--metadata-file` | `string` | | Write build result metadata to the file |
| `--network` | `string` | `default` | Set the networking mode for the `RUN` instructions during build |
| `--no-cache` | | | Do not use cache when building the image |
| `--no-cache-filter` | `stringArray` | | Do not cache specified stages |
| `-o`, `--output` | `stringArray` | | Output destination (format: `type=local,dest=path`) |
| `--platform` | `stringArray` | | Set target platform for build |
| `--print` | `string` | | Print result of information request (e.g., outline, targets) |
| `--progress` | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output |
| `--provenance` | `string` | | Shorthand for `--attest=type=provenance` |
| `--pull` | | | Always attempt to pull all referenced images |
| `--push` | | | Shorthand for `--output=type=registry` |
| `-q`, `--quiet` | | | Suppress the build output and print image ID on success |
| `--root` | `string` | | Specify root directory of server to connect |
| `--sbom` | `string` | | Shorthand for `--attest=type=sbom` |
| `--secret` | `stringArray` | | Secret to expose to the build (format: `id=mysecret[,src=/local/secret]`) |
| `--server-config` | `string` | | Specify buildx server config file (used only when launching new server) |
| `--shm-size` | `bytes` | `0` | Size of `/dev/shm` |
| `--ssh` | `stringArray` | | SSH agent socket or keys to expose to the build (format: `default\|<id>[=<socket>\|<key>[,<key>]]`) |
| [`-t`](https://docs.docker.com/engine/reference/commandline/build/#tag), [`--tag`](https://docs.docker.com/engine/reference/commandline/build/#tag) | `stringArray` | | Name and optionally a tag (format: `name:tag`) |
| [`--target`](https://docs.docker.com/engine/reference/commandline/build/#target) | `string` | | Set the target build stage to build |
| `--ulimit` | `ulimit` | | Ulimit options |
| Name | Type | Default | Description |
|:---------------------------------------------------------------------------------------------------------------------------------------------------|:--------------|:----------|:----------------------------------------------------------------------------------------------------|
| [`--add-host`](https://docs.docker.com/reference/cli/docker/image/build/#add-host) | `stringSlice` | | Add a custom host-to-IP mapping (format: `host:ip`) |
| `--allow` | `stringSlice` | | Allow extra privileged entitlement (e.g., `network.host`, `security.insecure`) |
| `--annotation` | `stringArray` | | Add annotation to the image |
| `--attest` | `stringArray` | | Attestation parameters (format: `type=sbom,generator=image`) |
| `--build-arg` | `stringArray` | | Set build-time variables |
| `--build-context` | `stringArray` | | Additional build contexts (e.g., name=path) |
| `--builder` | `string` | | Override the configured builder instance |
| `--cache-from` | `stringArray` | | External cache sources (e.g., `user/app:cache`, `type=local,src=path/to/dir`) |
| `--cache-to` | `stringArray` | | Cache export destinations (e.g., `user/app:cache`, `type=local,dest=path/to/dir`) |
| [`--cgroup-parent`](https://docs.docker.com/reference/cli/docker/image/build/#cgroup-parent) | `string` | | Set the parent cgroup for the `RUN` instructions during build |
| `--detach` | | | Detach buildx server (supported only on linux) |
| [`-f`](https://docs.docker.com/reference/cli/docker/image/build/#file), [`--file`](https://docs.docker.com/reference/cli/docker/image/build/#file) | `string` | | Name of the Dockerfile (default: `PATH/Dockerfile`) |
| `--iidfile` | `string` | | Write the image ID to the file |
| `--label` | `stringArray` | | Set metadata for an image |
| `--load` | | | Shorthand for `--output=type=docker` |
| `--metadata-file` | `string` | | Write build result metadata to the file |
| `--network` | `string` | `default` | Set the networking mode for the `RUN` instructions during build |
| `--no-cache` | | | Do not use cache when building the image |
| `--no-cache-filter` | `stringArray` | | Do not cache specified stages |
| `-o`, `--output` | `stringArray` | | Output destination (format: `type=local,dest=path`) |
| `--platform` | `stringArray` | | Set target platform for build |
| `--print` | `string` | | Print result of information request (e.g., outline, targets) |
| `--progress` | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output |
| `--provenance` | `string` | | Shorthand for `--attest=type=provenance` |
| `--pull` | | | Always attempt to pull all referenced images |
| `--push` | | | Shorthand for `--output=type=registry` |
| `-q`, `--quiet` | | | Suppress the build output and print image ID on success |
| `--root` | `string` | | Specify root directory of server to connect |
| `--sbom` | `string` | | Shorthand for `--attest=type=sbom` |
| `--secret` | `stringArray` | | Secret to expose to the build (format: `id=mysecret[,src=/local/secret]`) |
| `--server-config` | `string` | | Specify buildx server config file (used only when launching new server) |
| `--shm-size` | `bytes` | `0` | Size of `/dev/shm` |
| `--ssh` | `stringArray` | | SSH agent socket or keys to expose to the build (format: `default\|<id>[=<socket>\|<key>[,<key>]]`) |
| [`-t`](https://docs.docker.com/reference/cli/docker/image/build/#tag), [`--tag`](https://docs.docker.com/reference/cli/docker/image/build/#tag) | `stringArray` | | Name and optionally a tag (format: `name:tag`) |
| [`--target`](https://docs.docker.com/reference/cli/docker/image/build/#target) | `string` | | Set the target build stage to build |
| `--ulimit` | `ulimit` | | Ulimit options |
<!---MARKER_GEN_END-->

View File

@@ -1,6 +1,6 @@
# buildx du
```
```text
docker buildx du
```

View File

@@ -1,6 +1,6 @@
# buildx imagetools
```
```text
docker buildx imagetools [OPTIONS] COMMAND
```
@@ -26,8 +26,9 @@ Commands to work on images in registry
## Description
Imagetools contains commands for working with manifest lists in the registry.
These commands are useful for inspecting multi-platform build results.
The `imagetools` commands contains subcommands for working with manifest lists
in container registries. These commands are useful for inspecting manifests
to check multi-platform configuration and attestations.
## Examples

View File

@@ -1,6 +1,6 @@
# buildx imagetools create
```
```text
docker buildx imagetools create [OPTIONS] [SOURCE] [SOURCE...]
```
@@ -11,7 +11,7 @@ Create a new image based on source images
| Name | Type | Default | Description |
|:---------------------------------|:--------------|:--------|:-----------------------------------------------------------------------------------------|
| `--annotation` | `stringArray` | | Add annotation to the image |
| [`--annotation`](#annotation) | `stringArray` | | Add annotation to the image |
| [`--append`](#append) | | | Append to existing manifest |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| [`--dry-run`](#dry-run) | | | Show final image instead of pushing |
@@ -31,6 +31,34 @@ specified, create performs a carbon copy.
## Examples
### <a name="annotation"></a> Add annotations to an image (--annotation)
The `--annotation` flag lets you add annotations the image index, manifest,
and descriptors when creating a new image.
The following command creates a `foo/bar:latest` image with the
`org.opencontainers.image.authors` annotation on the image index.
```console
$ docker buildx imagetools create \
--annotation "index:org.opencontainers.image.authors=dvdksn" \
--tag foo/bar:latest \
foo/bar:alpha foo/bar:beta foo/bar:gamma
```
> **Note**
>
> The `imagetools create` command supports adding annotations to the image
> index and descriptor, using the following type prefixes:
>
> - `index:`
> - `manifest-descriptor:`
>
> It doesn't support annotating manifests or OCI layouts.
For more information about annotations, see
[Annotations](https://docs.docker.com/build/building/annotations/).
### <a name="append"></a> Append new sources to an existing manifest list (--append)
Use the `--append` flag to append the new sources to an existing manifest list
@@ -46,7 +74,7 @@ Use the `--dry-run` flag to not push the image, just show it.
### <a name="file"></a> Read source descriptor from a file (-f, --file)
```
```text
-f FILE or --file FILE
```
@@ -67,7 +95,7 @@ The supported fields for the descriptor are defined in [OCI spec](https://github
### <a name="tag"></a> Set reference for new image (-t, --tag)
```
```text
-t IMAGE or --tag IMAGE
```

View File

@@ -1,6 +1,6 @@
# buildx imagetools inspect
```
```text
docker buildx imagetools inspect [OPTIONS] NAME
```
@@ -123,23 +123,93 @@ Manifests:
#### JSON output
A `json` go template func is also available if you want to render fields as
JSON bytes:
A `json` template function is also available if you want to render fields in
JSON format:
```console
$ docker buildx imagetools inspect crazymax/loop --format "{{json .Manifest}}"
$ docker buildx imagetools inspect crazymax/buildkit:attest --format "{{json .Manifest}}"
```
```json
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:a9ca35b798e0b198f9be7f3b8b53982e9a6cf96814cb10d78083f40ad8c127f1",
"size": 949
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.index.v1+json",
"digest": "sha256:7007b387ccd52bd42a050f2e8020e56e64622c9269bf7bbe257b326fe99daf19",
"size": 855,
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:fbd10fe50b4b174bb9ea273e2eb9827fa8bf5c88edd8635a93dc83e0d1aecb55",
"size": 673,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:a9de632c16998489fd63fbca42a03431df00639cfb2ecb8982bf9984b83c5b2b",
"size": 839,
"annotations": {
"vnd.docker.reference.digest": "sha256:fbd10fe50b4b174bb9ea273e2eb9827fa8bf5c88edd8635a93dc83e0d1aecb55",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
}
]
}
```
```console
$ docker buildx imagetools inspect crazymax/buildkit:attest --format "{{json .Image}}"
```
```json
{
"created": "2022-12-01T11:46:47.713777178Z",
"architecture": "amd64",
"os": "linux",
"config": {
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh"
]
},
"rootfs": {
"type": "layers",
"diff_ids": [
"sha256:ded7a220bb058e28ee3254fbba04ca90b679070424424761a53a043b93b612bf",
"sha256:d85d09ab4b4e921666ccc2db8532e857bf3476b7588e52c9c17741d7af14204f"
]
},
"history": [
{
"created": "2022-11-22T22:19:28.870801855Z",
"created_by": "/bin/sh -c #(nop) ADD file:587cae71969871d3c6456d844a8795df9b64b12c710c275295a1182b46f630e7 in / "
},
{
"created": "2022-11-22T22:19:29.008562326Z",
"created_by": "/bin/sh -c #(nop) CMD [\"/bin/sh\"]",
"empty_layer": true
},
{
"created": "2022-12-01T11:46:47.713777178Z",
"created_by": "RUN /bin/sh -c apk add curl # buildkit",
"comment": "buildkit.dockerfile.v0"
}
]
}
```
```console
$ docker buildx imagetools inspect moby/buildkit:master --format "{{json .Manifest}}"
```
```json
{
"schemaVersion": 2,
@@ -284,11 +354,13 @@ $ docker buildx imagetools inspect moby/buildkit:master --format "{{json .Manife
}
```
Following command provides [SLSA](https://github.com/moby/buildkit/blob/master/docs/attestations/slsa-provenance.md) JSON output:
The following command provides [SLSA](https://github.com/moby/buildkit/blob/master/docs/attestations/slsa-provenance.md)
JSON output:
```console
$ docker buildx imagetools inspect crazymax/buildkit:attest --format "{{json .Provenance}}"
```
```json
{
"SLSA": {
@@ -343,11 +415,13 @@ $ docker buildx imagetools inspect crazymax/buildkit:attest --format "{{json .Pr
}
```
Following command provides [SBOM](https://github.com/moby/buildkit/blob/master/docs/attestations/sbom.md) JSON output:
The following command provides [SBOM](https://github.com/moby/buildkit/blob/master/docs/attestations/sbom.md)
JSON output:
```console
$ docker buildx imagetools inspect crazymax/buildkit:attest --format "{{json .SBOM}}"
```
```json
{
"SPDX": {
@@ -372,6 +446,7 @@ $ docker buildx imagetools inspect crazymax/buildkit:attest --format "{{json .SB
```console
$ docker buildx imagetools inspect crazymax/buildkit:attest --format "{{json .}}"
```
```json
{
"name": "crazymax/buildkit:attest",
@@ -440,75 +515,6 @@ $ docker buildx imagetools inspect crazymax/buildkit:attest --format "{{json .}}
"comment": "buildkit.dockerfile.v0"
}
]
},
"Provenance": {
"SLSA": {
"builder": {
"id": ""
},
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/docker/buildkit-syft-scanner@stable-1",
"digest": {
"sha256": "b45f1d207e16c3a3a5a10b254ad8ad358d01f7ea090d382b95c6b2ee2b3ef765"
}
},
{
"uri": "pkg:docker/alpine@latest?platform=linux%2Famd64",
"digest": {
"sha256": "8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4"
}
}
],
"invocation": {
"configSource": {},
"parameters": {
"frontend": "dockerfile.v0",
"locals": [
{
"name": "context"
},
{
"name": "dockerfile"
}
]
},
"environment": {
"platform": "linux/amd64"
}
},
"metadata": {
"buildInvocationID": "02tdha2xkbxvin87mz9drhag4",
"buildStartedOn": "2022-12-01T11:50:07.264704131Z",
"buildFinishedOn": "2022-12-01T11:50:08.243788739Z",
"reproducible": false,
"completeness": {
"parameters": true,
"environment": true,
"materials": false
},
"https://mobyproject.org/buildkit@v1#metadata": {}
}
}
},
"SBOM": {
"SPDX": {
"SPDXID": "SPDXRef-DOCUMENT",
"creationInfo": {
"created": "2022-12-01T11:46:48.063400162Z",
"creators": [
"Tool: syft-v0.60.3",
"Tool: buildkit-1ace2bb",
"Organization: Anchore, Inc"
],
"licenseListVersion": "3.18"
},
"dataLicense": "CC0-1.0",
"documentNamespace": "https://anchore.com/syft/dir/run/src/core-0a4ccc6d-1a72-4c3a-a40e-3df1a2ffca94",
"files": [...],
"spdxVersion": "SPDX-2.2"
}
}
}
```
@@ -522,6 +528,7 @@ go template function:
```console
$ docker buildx imagetools inspect --format '{{json (index .Image "linux/s390x")}}' moby/buildkit:master
```
```json
{
"created": "2022-11-30T17:42:26.414957336Z",
@@ -588,15 +595,14 @@ $ docker buildx imagetools inspect --format '{{json (index .Image "linux/s390x")
}
```
### <a name="raw"></a> Show original, unformatted JSON manifest (--raw)
### <a name="raw"></a> Show original JSON manifest (--raw)
Use the `--raw` option to print the unformatted JSON manifest bytes.
> `jq` is used here to get a better rendering of the output result.
Use the `--raw` option to print the raw JSON manifest.
```console
$ docker buildx imagetools inspect --raw crazymax/loop | jq
$ docker buildx imagetools inspect --raw crazymax/loop
```
```json
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
@@ -629,6 +635,7 @@ $ docker buildx imagetools inspect --raw crazymax/loop | jq
```console
$ docker buildx imagetools inspect --raw moby/buildkit:master | jq
```
```json
{
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",

View File

@@ -1,6 +1,6 @@
# buildx inspect
```
```text
docker buildx inspect [NAME]
```
@@ -27,7 +27,7 @@ Shows information about the current or specified builder.
Use the `--bootstrap` option to ensure that the builder is running before
inspecting it. If the driver is `docker-container`, then `--bootstrap` starts
the buildkit container and waits until it is operational. Bootstrapping is
the BuildKit container and waits until it's operational. Bootstrapping is
automatically done during build, and therefore not necessary. The same BuildKit
container is used during the lifetime of the associated builder node (as
displayed in `buildx ls`).
@@ -45,7 +45,9 @@ The following example shows information about a builder instance named
> **Note**
>
> Asterisk `*` next to node build platform(s) indicate they had been set manually during `buildx create`. Otherwise, it had been autodetected.
> The asterisk (`*`) next to node build platform(s) indicate they have been
> manually set during `buildx create`. Otherwise the platforms were
> automatically detected.
```console
$ docker buildx inspect elated_tesla

View File

@@ -1,6 +1,6 @@
# buildx ls
```
```text
docker buildx ls
```

View File

@@ -1,6 +1,6 @@
# buildx prune
```
```text
docker buildx prune
```

View File

@@ -1,6 +1,6 @@
# buildx rm
```
```text
docker buildx rm [NAME]
```
@@ -50,10 +50,13 @@ $ docker buildx rm --all-inactive --force
### <a name="keep-daemon"></a> Keep the buildkitd daemon running (--keep-daemon)
Keep the buildkitd daemon running after the buildx context is removed. This is useful when you manage buildkitd daemons and buildx contexts independently.
Currently, only supported by the [`docker-container` and `kubernetes` drivers](buildx_create.md#driver).
Keep the BuildKit daemon running after the buildx context is removed. This is
useful when you manage buildkitd daemons and buildx contexts independently.
Only supported by the
[`docker-container`](https://docs.docker.com/build/drivers/docker-container/)
and [`kubernetes`](https://docs.docker.com/build/drivers/kubernetes/) drivers.
### <a name="keep-state"></a> Keep BuildKit state (--keep-state)
Keep BuildKit state, so it can be reused by a new builder with the same name.
Currently, only supported by the [`docker-container` driver](buildx_create.md#driver).
Currently, only supported by the [`docker-container` driver](https://docs.docker.com/build/drivers/docker-container/).

View File

@@ -18,7 +18,7 @@ Stop builder instance
## Description
Stops the specified or current builder. This will not prevent buildx build to
Stops the specified or current builder. This does not prevent buildx build to
restart the builder. The implementation of stop depends on the driver.
## Examples

View File

@@ -1,6 +1,6 @@
# buildx version
```
```text
docker buildx version
```
@@ -16,5 +16,5 @@ View version information
```console
$ docker buildx version
github.com/docker/buildx v0.5.1-docker 11057da37336192bfc57d81e02359ba7ba848e4a
github.com/docker/buildx v0.11.2 9872040b6626fb7d87ef7296fd5b832e8cc2ad17
```

View File

@@ -39,7 +39,10 @@ const (
type Driver struct {
driver.InitConfig
factory driver.Factory
factory driver.Factory
// if you add fields, remember to update docs:
// https://github.com/docker/docs/blob/main/content/build/drivers/docker-container.md
netMode string
image string
memory opts.MemBytes

View File

@@ -51,11 +51,11 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver
case k == "image":
d.image = v
case k == "memory":
if err := d.memory.Set(v); err == nil {
if err := d.memory.Set(v); err != nil {
return nil, err
}
case k == "memory-swap":
if err := d.memorySwap.Set(v); err == nil {
if err := d.memorySwap.Set(v); err != nil {
return nil, err
}
case k == "cpu-period":

View File

@@ -17,6 +17,8 @@ type Driver struct {
factory driver.Factory
driver.InitConfig
// if you add fields, remember to update docs:
// https://github.com/docker/docs/blob/main/content/build/drivers/docker.md
features features
hostGateway hostGateway
}

View File

@@ -38,7 +38,10 @@ const (
type Driver struct {
driver.InitConfig
factory driver.Factory
factory driver.Factory
// if you add fields, remember to update docs:
// https://github.com/docker/docs/blob/main/content/build/drivers/kubernetes.md
minReplicas int
deployment *appsv1.Deployment
configMaps []*corev1.ConfigMap

View File

@@ -14,6 +14,9 @@ import (
type Driver struct {
factory driver.Factory
driver.InitConfig
// if you add fields, remember to update docs:
// https://github.com/docker/docs/blob/main/content/build/drivers/remote.md
*tlsOpts
}

2
go.mod
View File

@@ -14,7 +14,7 @@ require (
github.com/creack/pty v1.1.18
github.com/distribution/reference v0.5.0
github.com/docker/cli v24.0.5+incompatible
github.com/docker/cli-docs-tool v0.6.0
github.com/docker/cli-docs-tool v0.7.0
github.com/docker/docker v24.0.5+incompatible
github.com/docker/go-units v0.5.0
github.com/gofrs/flock v0.8.1

4
go.sum
View File

@@ -155,8 +155,8 @@ github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/cli v24.0.5+incompatible h1:WeBimjvS0eKdH4Ygx+ihVq1Q++xg36M/rMi4aXAvodc=
github.com/docker/cli v24.0.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli-docs-tool v0.6.0 h1:Z9x10SaZgFaB6jHgz3OWooynhSa40CsWkpe5hEnG/qA=
github.com/docker/cli-docs-tool v0.6.0/go.mod h1:zMjqTFCU361PRh8apiXzeAZ1Q/xupbIwTusYpzCXS/o=
github.com/docker/cli-docs-tool v0.7.0 h1:M2Da98Unz2kz3A5d4yeSGbhyOge2mfYSNjAFt01Rw0M=
github.com/docker/cli-docs-tool v0.7.0/go.mod h1:zMjqTFCU361PRh8apiXzeAZ1Q/xupbIwTusYpzCXS/o=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
ARG GO_VERSION=1.21.3
ARG GO_VERSION=1.21.6
ARG FORMATS=md,yaml
FROM golang:${GO_VERSION}-alpine AS docsgen

View File

@@ -5,7 +5,7 @@
# Copyright The Buildx Authors.
# Licensed under the Apache License, Version 2.0
ARG GO_VERSION="1.21.3"
ARG GO_VERSION="1.21.6"
ARG PROTOC_VERSION="3.11.4"
# protoc is dynamically linked to glibc so can't use alpine base

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
ARG GO_VERSION=1.21.3
ARG GO_VERSION=1.21.6
ARG GOLANGCI_LINT_VERSION=1.54.2
FROM golang:${GO_VERSION}-alpine

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
ARG GO_VERSION=1.21.3
ARG GO_VERSION=1.21.6
ARG MODOUTDATED_VERSION=v0.8.0
FROM golang:${GO_VERSION}-alpine AS base

39
tests/create.go Normal file
View File

@@ -0,0 +1,39 @@
package tests
import (
"strings"
"testing"
"github.com/moby/buildkit/util/testutil/integration"
"github.com/stretchr/testify/require"
)
func createCmd(sb integration.Sandbox, opts ...cmdOpt) (string, error) {
opts = append([]cmdOpt{withArgs("create")}, opts...)
cmd := buildxCmd(sb, opts...)
out, err := cmd.CombinedOutput()
return string(out), err
}
var createTests = []func(t *testing.T, sb integration.Sandbox){
testCreateMemoryLimit,
}
func testCreateMemoryLimit(t *testing.T, sb integration.Sandbox) {
if sb.Name() != "docker-container" {
t.Skip("only testing for docker-container driver")
}
var builderName string
t.Cleanup(func() {
if builderName == "" {
return
}
out, err := rmCmd(sb, withArgs(builderName))
require.NoError(t, err, out)
})
out, err := createCmd(sb, withArgs("--driver", "docker-container", "--driver-opt", "network=host", "--driver-opt", "memory=1g"))
require.NoError(t, err, out)
builderName = strings.TrimSpace(out)
}

View File

@@ -27,6 +27,7 @@ func TestIntegration(t *testing.T) {
tests = append(tests, lsTests...)
tests = append(tests, imagetoolsTests...)
tests = append(tests, versionTests...)
tests = append(tests, createTests...)
testIntegration(t, tests...)
}

12
tests/rm.go Normal file
View File

@@ -0,0 +1,12 @@
package tests
import (
"github.com/moby/buildkit/util/testutil/integration"
)
func rmCmd(sb integration.Sandbox, opts ...cmdOpt) (string, error) {
opts = append([]cmdOpt{withArgs("rm")}, opts...)
cmd := buildxCmd(sb, opts...)
out, err := cmd.CombinedOutput()
return string(out), err
}

View File

@@ -241,7 +241,7 @@ func mdCmdOutput(cmd *cobra.Command, old string) (string, error) {
name += mdMakeLink("`--"+f.Name+"`", f.Name, f, isLink)
var ftype string
if f.Value.Type() != "bool" {
if f.Value.Type() != "bool" || (f.Value.Type() == "bool" && f.DefValue == "true") {
ftype = "`" + f.Value.Type() + "`"
}
@@ -253,7 +253,7 @@ func mdCmdOutput(cmd *cobra.Command, old string) (string, error) {
} else if cd, ok := cmd.Annotations[annotation.CodeDelimiter]; ok {
defval = strings.ReplaceAll(defval, cd, "`")
}
} else if f.DefValue != "" && (f.Value.Type() != "bool" && f.DefValue != "true") && f.DefValue != "[]" {
} else if f.DefValue != "" && ((f.Value.Type() != "bool" && f.DefValue != "true") || (f.Value.Type() == "bool" && f.DefValue == "true")) && f.DefValue != "[]" {
defval = "`" + f.DefValue + "`"
}

View File

@@ -29,6 +29,9 @@ var (
// for our use-case; DO NOT consider using this as a generic regex, or at least
// not before reading https://stackoverflow.com/a/1732454/1811501.
htmlAnchor = regexp.MustCompile(`<a\s+(?:name|id)="?([^"]+)"?\s*></a>\s*`)
// relativeLink matches parts of internal links between .md documents
// e.g. "](buildx_build.md)"
relativeLink = regexp.MustCompile(`\]\((\.\/)?[a-z-_]+\.md(#.*)?\)`)
)
// getSections returns all H2 sections by title (lowercase)
@@ -58,6 +61,16 @@ func cleanupMarkDown(mdString string) (md string, anchors []string) {
mdString = strings.ReplaceAll(mdString, "\t", " ")
mdString = strings.ReplaceAll(mdString, "https://docs.docker.com", "")
// Rewrite internal links, replacing relative paths with absolute path
// e.g. from [docker buildx build](buildx_build.md#build-arg)
// to [docker buildx build](/reference/cli/docker/buildx/build/#build-arg)
mdString = relativeLink.ReplaceAllStringFunc(mdString, func(link string) string {
link = strings.TrimLeft(link, "](./")
link = strings.ReplaceAll(link, "_", "/")
link = strings.ReplaceAll(link, ".md", "/")
return "](/reference/cli/docker/" + link
})
var id string
// replace trailing whitespace per line, and handle custom anchors
lines := strings.Split(mdString, "\n")

2
vendor/modules.txt vendored
View File

@@ -224,7 +224,7 @@ github.com/docker/cli/cli/streams
github.com/docker/cli/cli/trust
github.com/docker/cli/cli/version
github.com/docker/cli/opts
# github.com/docker/cli-docs-tool v0.6.0
# github.com/docker/cli-docs-tool v0.7.0
## explicit; go 1.18
github.com/docker/cli-docs-tool
github.com/docker/cli-docs-tool/annotation