Skip to content

Commit 3b1004c

Browse files
jotkaglours
authored andcommitted
fix: gate extra EndpointsConfig behind API >= 1.44
Before API 1.44 (Docker Engine 25.0), ContainerCreate only accepted a single EndpointsConfig entry. Passing multiple entries silently drops all but one network, leaving containers under-connected on older daemons such as Docker 20.10 or Synology DSM 7.1/7.2. Add apiVersion144 constant and wrap the secondary-networks loop in defaultNetworkSettings so that only the primary network is included in the ContainerCreate call when the negotiated API version is below 1.44. Signed-off-by: jarek <jkrochmalski@gmail.com>
1 parent 9cab439 commit 3b1004c

3 files changed

Lines changed: 44 additions & 6 deletions

File tree

pkg/compose/api_versions.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ package compose
1919
// Docker Engine API version constants.
2020
// These versions correspond to specific Docker Engine releases and their features.
2121
const (
22+
// apiVersion144 represents Docker Engine API version 1.44 (Engine v25.0).
23+
//
24+
// New features in this version:
25+
// - ContainerCreate API accepts multiple EndpointsConfig entries
26+
//
27+
// Before this version:
28+
// - Only a single EndpointsConfig entry was accepted in ContainerCreate
29+
// - Extra networks must be connected individually after container creation via NetworkConnect
30+
apiVersion144 = "1.44"
31+
2232
// apiVersion148 represents Docker Engine API version 1.48 (Engine v28.0).
2333
//
2434
// New features in this version:

pkg/compose/create.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -563,13 +563,17 @@ func defaultNetworkSettings(project *types.Project,
563563
// so we can pass all the extra networks we want the container to be connected to
564564
// in the network configuration instead of connecting the container to each extra
565565
// network individually after creation.
566-
for _, networkKey := range serviceNetworks {
567-
epSettings, err := createEndpointSettings(project, service, serviceIndex, networkKey, links, useNetworkAliases)
568-
if err != nil {
569-
return "", nil, err
566+
// For older API versions, extra networks are connected via NetworkConnect after
567+
// container creation (see createMobyContainer in convergence.go).
568+
if !versions.LessThan(version, apiVersion144) {
569+
for _, networkKey := range serviceNetworks {
570+
epSettings, err := createEndpointSettings(project, service, serviceIndex, networkKey, links, useNetworkAliases)
571+
if err != nil {
572+
return "", nil, err
573+
}
574+
mobyNetworkName := project.Networks[networkKey].Name
575+
endpointsConfig[mobyNetworkName] = epSettings
570576
}
571-
mobyNetworkName := project.Networks[networkKey].Name
572-
endpointsConfig[mobyNetworkName] = epSettings
573577
}
574578

575579
networkConfig := &network.NetworkingConfig{

pkg/compose/create_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,30 @@ func TestDefaultNetworkSettings(t *testing.T) {
273273
assert.Check(t, cmp.Nil(networkConfig))
274274
})
275275

276+
t.Run("returns only primary network in EndpointsConfig for API < 1.44", func(t *testing.T) {
277+
service := composetypes.ServiceConfig{
278+
Name: "myService",
279+
Networks: map[string]*composetypes.ServiceNetworkConfig{
280+
"myNetwork1": {Priority: 10},
281+
"myNetwork2": {Priority: 1000},
282+
},
283+
}
284+
project := composetypes.Project{
285+
Name: "myProject",
286+
Services: composetypes.Services{"myService": service},
287+
Networks: composetypes.Networks(map[string]composetypes.NetworkConfig{
288+
"myNetwork1": {Name: "myProject_myNetwork1"},
289+
"myNetwork2": {Name: "myProject_myNetwork2"},
290+
}),
291+
}
292+
293+
networkMode, networkConfig, err := defaultNetworkSettings(&project, service, 1, nil, true, "1.43")
294+
assert.NilError(t, err)
295+
assert.Equal(t, string(networkMode), "myProject_myNetwork2")
296+
assert.Check(t, cmp.Len(networkConfig.EndpointsConfig, 1))
297+
assert.Check(t, cmp.Contains(networkConfig.EndpointsConfig, "myProject_myNetwork2"))
298+
})
299+
276300
t.Run("returns defined network mode if explicitly set", func(t *testing.T) {
277301
service := composetypes.ServiceConfig{
278302
Name: "myService",

0 commit comments

Comments
 (0)