diff --git a/src/spec-node/devContainersSpecCLI.ts b/src/spec-node/devContainersSpecCLI.ts index 2c3902241..b108b2574 100644 --- a/src/spec-node/devContainersSpecCLI.ts +++ b/src/spec-node/devContainersSpecCLI.ts @@ -16,7 +16,7 @@ import { probeRemoteEnv, runPostCreateCommands, runRemoteCommand, UserEnvProbe } import { bailOut, buildNamedImageAndExtend, findDevContainer, hostFolderLabel } from './singleContainer'; import { extendImage } from './containerFeatures'; import { DockerCLIParameters, dockerPtyCLI, inspectContainer } from '../spec-shutdown/dockerUtils'; -import { buildAndExtendDockerCompose, getProjectName, readDockerComposeConfig } from './dockerCompose'; +import { buildAndExtendDockerCompose, getDefaultImageName, getProjectName, readDockerComposeConfig } from './dockerCompose'; import { getDockerComposeFilePaths } from '../spec-configuration/configuration'; import { workspaceFromPath } from '../spec-utils/workspaces'; import { readDevContainerConfigFile } from './configContainer'; @@ -384,7 +384,7 @@ async function doBuild({ await buildAndExtendDockerCompose(config, projectName, infoParams, composeFiles, envFile, composeGlobalArgs, [config.service], params.buildNoCache || false, params.common.persistedFolder, 'docker-compose.devcontainer.build', addCacheFroms); const service = composeConfig.services[config.service]; - const originalImageName = service.image || `${projectName}_${config.service}`; + const originalImageName = service.image || getDefaultImageName(await buildParams.dockerComposeCLI(), projectName, config.service); if (imageNames) { await Promise.all(imageNames.map(imageName => dockerPtyCLI(params, 'tag', originalImageName, imageName))); diff --git a/src/spec-node/dockerCompose.ts b/src/spec-node/dockerCompose.ts index 3dbead455..c4e68e8f1 100644 --- a/src/spec-node/dockerCompose.ts +++ b/src/spec-node/dockerCompose.ts @@ -319,7 +319,7 @@ async function startContainer(params: DockerResolverParameters, buildParams: Doc const { started } = await startEventSeen(params, { [projectLabel]: projectName, [serviceLabel]: config.service }, canceled, common.output, common.getLogLevel() === LogLevel.Trace); // await getEvents, but only assign started. const service = composeConfig.services[config.service]; - const originalImageName = service.image || `${projectName}_${config.service}`; + const originalImageName = service.image || getDefaultImageName(await buildParams.dockerComposeCLI(), projectName, config.service); // Try to restore the 'third' docker-compose file and featuresConfig from persisted storage. // This file may have been generated upon a Codespace creation. @@ -400,6 +400,12 @@ async function startContainer(params: DockerResolverParameters, buildParams: Doc }; } +export function getDefaultImageName(dockerComposeCLI: DockerComposeCLI, projectName: string, serviceName: string) { + const version = parseVersion(dockerComposeCLI.version); + const separator = version && isEarlierVersion(version, [2, 8, 0]) ? '_' : '-'; + return `${projectName}${separator}${serviceName}`; +} + async function writeFeaturesComposeOverrideFile( updatedImageName: string, originalImageName: string,