@@ -26,6 +26,7 @@ import (
2626 "os"
2727 "os/exec"
2828 "path/filepath"
29+ "slices"
2930 "strconv"
3031 "strings"
3132
@@ -35,6 +36,7 @@ import (
3536 "github.com/docker/cli/cli/command"
3637 "github.com/docker/compose/v2/pkg/api"
3738 "github.com/docker/compose/v2/pkg/progress"
39+ "github.com/docker/docker/api/types/versions"
3840 "github.com/docker/docker/builder/remotecontext/urlutil"
3941 "github.com/moby/buildkit/client"
4042 "github.com/moby/buildkit/util/progress/progressui"
@@ -93,19 +95,25 @@ type bakeGroup struct {
9395}
9496
9597type bakeTarget struct {
96- Context string `json:"context,omitempty"`
97- Dockerfile string `json:"dockerfile,omitempty"`
98- Args map [string ]string `json:"args,omitempty"`
99- Labels map [string ]string `json:"labels,omitempty"`
100- Tags []string `json:"tags,omitempty"`
101- CacheFrom []string `json:"cache-from,omitempty"`
102- CacheTo []string `json:"cache-to,omitempty"`
103- Secrets []string `json:"secret,omitempty"`
104- SSH []string `json:"ssh,omitempty"`
105- Platforms []string `json:"platforms,omitempty"`
106- Target string `json:"target,omitempty"`
107- Pull bool `json:"pull,omitempty"`
108- NoCache bool `json:"no-cache,omitempty"`
98+ Context string `json:"context,omitempty"`
99+ Contexts map [string ]string `json:"contexts,omitempty"`
100+ Dockerfile string `json:"dockerfile,omitempty"`
101+ DockerfileInline string `json:"dockerfile-inline,omitempty"`
102+ Args map [string ]string `json:"args,omitempty"`
103+ Labels map [string ]string `json:"labels,omitempty"`
104+ Tags []string `json:"tags,omitempty"`
105+ CacheFrom []string `json:"cache-from,omitempty"`
106+ CacheTo []string `json:"cache-to,omitempty"`
107+ Secrets []string `json:"secret,omitempty"`
108+ SSH []string `json:"ssh,omitempty"`
109+ Platforms []string `json:"platforms,omitempty"`
110+ Target string `json:"target,omitempty"`
111+ Pull bool `json:"pull,omitempty"`
112+ NoCache bool `json:"no-cache,omitempty"`
113+ ShmSize types.UnitBytes `json:"shm-size,omitempty"`
114+ Ulimits []string `json:"ulimits,omitempty"`
115+ Entitlements []string `json:"entitlements,omitempty"`
116+ Outputs []string `json:"output,omitempty"`
109117}
110118
111119type bakeMetadata map [string ]buildStatus
@@ -136,8 +144,9 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
136144 Targets : map [string ]bakeTarget {},
137145 }
138146 var group bakeGroup
147+ var privileged bool
139148
140- for _ , service := range serviceToBeBuild {
149+ for serviceName , service := range serviceToBeBuild {
141150 if service .Build == nil {
142151 continue
143152 }
@@ -153,23 +162,43 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
153162
154163 image := api .GetImageNameOrDefault (service , project .Name )
155164
156- cfg .Targets [image ] = bakeTarget {
157- Context : build .Context ,
158- Dockerfile : dockerFilePath (build .Context , build .Dockerfile ),
159- Args : args ,
160- Labels : build .Labels ,
161- Tags : append (build .Tags , image ),
165+ entitlements := build .Entitlements
166+ if slices .Contains (build .Entitlements , "security.insecure" ) {
167+ privileged = true
168+ }
169+ if build .Privileged {
170+ entitlements = append (entitlements , "security.insecure" )
171+ privileged = true
172+ }
173+
174+ outputs := []string {"type=docker" }
175+ if options .Push && service .Image != "" {
176+ outputs = append (outputs , "type=image,push=true" )
177+ }
178+
179+ cfg .Targets [serviceName ] = bakeTarget {
180+ Context : build .Context ,
181+ Contexts : additionalContexts (build .AdditionalContexts , service .DependsOn , options .Compatibility ),
182+ Dockerfile : dockerFilePath (build .Context , build .Dockerfile ),
183+ DockerfileInline : build .DockerfileInline ,
184+ Args : args ,
185+ Labels : build .Labels ,
186+ Tags : append (build .Tags , image ),
162187
163188 CacheFrom : build .CacheFrom ,
164189 // CacheTo: TODO
165- Platforms : build .Platforms ,
166- Target : build .Target ,
167- Secrets : toBakeSecrets (project , build .Secrets ),
168- SSH : toBakeSSH (build .SSH ),
169- Pull : options .Pull ,
170- NoCache : options .NoCache ,
190+ Platforms : build .Platforms ,
191+ Target : build .Target ,
192+ Secrets : toBakeSecrets (project , build .Secrets ),
193+ SSH : toBakeSSH (append (build .SSH , options .SSHs ... )),
194+ Pull : options .Pull ,
195+ NoCache : options .NoCache ,
196+ ShmSize : build .ShmSize ,
197+ Ulimits : toBakeUlimits (build .Ulimits ),
198+ Entitlements : entitlements ,
199+ Outputs : outputs ,
171200 }
172- group .Targets = append (group .Targets , image )
201+ group .Targets = append (group .Targets , serviceName )
173202 }
174203
175204 cfg .Groups ["default" ] = group
@@ -188,7 +217,14 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
188217 if err != nil {
189218 return nil , err
190219 }
191- cmd := exec .CommandContext (ctx , buildx .Path , "bake" , "--file" , "-" , "--progress" , "rawjson" , "--metadata-file" , metadata .Name ())
220+
221+ args := []string {"bake" , "--file" , "-" , "--progress" , "rawjson" , "--metadata-file" , metadata .Name ()}
222+ mustAllow := buildx .Version != "" && versions .GreaterThanOrEqualTo (buildx .Version [1 :], "0.17.0" )
223+ if privileged && mustAllow {
224+ args = append (args , "--allow" , "security.insecure" )
225+ }
226+
227+ cmd := exec .CommandContext (ctx , buildx .Path , args ... )
192228 // Remove DOCKER_CLI_PLUGIN... variable so buildx can detect it run standalone
193229 cmd .Env = filter (os .Environ (), manager .ReexecEnvvar )
194230
@@ -258,6 +294,31 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
258294 return results , nil
259295}
260296
297+ func additionalContexts (contexts types.Mapping , dependencies types.DependsOnConfig , compatibility bool ) map [string ]string {
298+ ac := map [string ]string {}
299+ if compatibility {
300+ for name := range dependencies {
301+ ac [name ] = "target:" + name
302+ }
303+ }
304+ for k , v := range contexts {
305+ ac [k ] = v
306+ }
307+ return ac
308+ }
309+
310+ func toBakeUlimits (ulimits map [string ]* types.UlimitsConfig ) []string {
311+ s := []string {}
312+ for u , l := range ulimits {
313+ if l .Single > 0 {
314+ s = append (s , fmt .Sprintf ("%s=%d" , u , l .Single ))
315+ } else {
316+ s = append (s , fmt .Sprintf ("%s=%d:%d" , u , l .Soft , l .Hard ))
317+ }
318+ }
319+ return s
320+ }
321+
261322func toBakeSSH (ssh types.SSHConfig ) []string {
262323 var s []string
263324 for _ , key := range ssh {
@@ -270,11 +331,15 @@ func toBakeSecrets(project *types.Project, secrets []types.ServiceSecretConfig)
270331 var s []string
271332 for _ , ref := range secrets {
272333 def := project .Secrets [ref .Source ]
334+ target := ref .Target
335+ if target == "" {
336+ target = ref .Source
337+ }
273338 switch {
274339 case def .Environment != "" :
275- s = append (s , fmt .Sprintf ("id=%s,type=env,env=%s" , ref . Source , def .Environment ))
340+ s = append (s , fmt .Sprintf ("id=%s,type=env,env=%s" , target , def .Environment ))
276341 case def .File != "" :
277- s = append (s , fmt .Sprintf ("id=%s,type=file,src=%s" , ref . Source , def .File ))
342+ s = append (s , fmt .Sprintf ("id=%s,type=file,src=%s" , target , def .File ))
278343 }
279344 }
280345 return s
0 commit comments