diff --git a/src/compose/network-manager.ts b/src/compose/network-manager.ts index 54603c8d..f329988d 100644 --- a/src/compose/network-manager.ts +++ b/src/compose/network-manager.ts @@ -11,10 +11,10 @@ import * as logger from '../logger'; import { Network } from './network'; import { ResourceRecreationAttemptError } from './errors'; -export function getAll(): Bluebird { - return getWithBothLabels().map((network: { Name: string }) => { +export async function getAll(): Promise { + return getWithBothLabels().map(async (network: { Id: string }) => { return docker - .getNetwork(network.Name) + .getNetwork(network.Id) .inspect() .then((net) => { return Network.fromDockerNetwork(net); diff --git a/src/compose/network.ts b/src/compose/network.ts index aa34a128..b7dde844 100644 --- a/src/compose/network.ts +++ b/src/compose/network.ts @@ -205,8 +205,12 @@ export class Network { network: { name: this.name, appUuid: this.appUuid }, }); - // Find the network - const [networkName] = (await docker.listNetworks()) + // Find the networks with the same name. While theoretically + // the network name is unique, because moby is not great with concurrency + // it's possible to have multiple networks with the same name + // https://github.com/moby/moby/issues/20648 + // For this reason we need to delete them all + const networkIds = (await docker.listNetworks()) .filter((network) => { try { const { appId, appUuid, name } = Network.deconstructDockerName( @@ -220,14 +224,16 @@ export class Network { return false; } }) - .map((network) => network.Name); + .map((network) => network.Id); - if (!networkName) { + if (networkIds.length === 0) { return; } try { - await docker.getNetwork(networkName).remove(); + await Promise.all( + networkIds.map((networkId) => docker.getNetwork(networkId).remove()), + ); } catch (error) { logger.logSystemEvent(logTypes.removeNetworkError, { network: { name: this.name, appUuid: this.appUuid },