@@ -26,6 +26,7 @@ import (
26
26
"os"
27
27
"os/exec"
28
28
"path/filepath"
29
+ "slices"
29
30
"strconv"
30
31
"strings"
31
32
@@ -35,6 +36,7 @@ import (
35
36
"github.com/docker/cli/cli/command"
36
37
"github.com/docker/compose/v2/pkg/api"
37
38
"github.com/docker/compose/v2/pkg/progress"
39
+ "github.com/docker/docker/api/types/versions"
38
40
"github.com/docker/docker/builder/remotecontext/urlutil"
39
41
"github.com/moby/buildkit/client"
40
42
"github.com/moby/buildkit/util/progress/progressui"
@@ -93,19 +95,25 @@ type bakeGroup struct {
93
95
}
94
96
95
97
type 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"`
109
117
}
110
118
111
119
type bakeMetadata map [string ]buildStatus
@@ -136,8 +144,9 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
136
144
Targets : map [string ]bakeTarget {},
137
145
}
138
146
var group bakeGroup
147
+ var privileged bool
139
148
140
- for _ , service := range serviceToBeBuild {
149
+ for serviceName , service := range serviceToBeBuild {
141
150
if service .Build == nil {
142
151
continue
143
152
}
@@ -153,23 +162,43 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
153
162
154
163
image := api .GetImageNameOrDefault (service , project .Name )
155
164
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 ),
162
187
163
188
CacheFrom : build .CacheFrom ,
164
189
// 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 ,
171
200
}
172
- group .Targets = append (group .Targets , image )
201
+ group .Targets = append (group .Targets , serviceName )
173
202
}
174
203
175
204
cfg .Groups ["default" ] = group
@@ -188,7 +217,14 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
188
217
if err != nil {
189
218
return nil , err
190
219
}
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 ... )
192
228
// Remove DOCKER_CLI_PLUGIN... variable so buildx can detect it run standalone
193
229
cmd .Env = filter (os .Environ (), manager .ReexecEnvvar )
194
230
@@ -258,6 +294,31 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
258
294
return results , nil
259
295
}
260
296
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
+
261
322
func toBakeSSH (ssh types.SSHConfig ) []string {
262
323
var s []string
263
324
for _ , key := range ssh {
@@ -270,11 +331,15 @@ func toBakeSecrets(project *types.Project, secrets []types.ServiceSecretConfig)
270
331
var s []string
271
332
for _ , ref := range secrets {
272
333
def := project .Secrets [ref .Source ]
334
+ target := ref .Target
335
+ if target == "" {
336
+ target = ref .Source
337
+ }
273
338
switch {
274
339
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 ))
276
341
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 ))
278
343
}
279
344
}
280
345
return s
0 commit comments