diff --git a/src/spec-node/ports.ts b/src/spec-node/ports.ts new file mode 100644 index 000000000..3cc0f2470 --- /dev/null +++ b/src/spec-node/ports.ts @@ -0,0 +1,11 @@ +import { DevContainerFromDockerfileConfig, DevContainerFromImageConfig } from '../spec-configuration/configuration'; + +function normalizePorts(ports: number | string | (number | string)[] | undefined): string[] { + ports = ports ?? []; + ports = typeof ports === 'number' || typeof ports === 'string' ? [ports] : ports; + return ports.map((port) => typeof port === 'number' ? `127.0.0.1:${port}:${port}`: port); +} + +export function getStaticPorts(config: DevContainerFromDockerfileConfig | DevContainerFromImageConfig): string[] { + return normalizePorts(config.forwardPorts).concat(normalizePorts(config.appPort)); +} diff --git a/src/spec-node/singleContainer.ts b/src/spec-node/singleContainer.ts index 6a8bfa3af..a63ba1237 100644 --- a/src/spec-node/singleContainer.ts +++ b/src/spec-node/singleContainer.ts @@ -13,6 +13,7 @@ import { LogLevel, Log, makeLog } from '../spec-utils/log'; import { extendImage, getExtendImageBuildInfo, updateRemoteUserUID } from './containerFeatures'; import { getDevcontainerMetadata, getImageBuildInfoFromDockerfile, getImageMetadataFromContainer, ImageMetadataEntry, lifecycleCommandOriginMapFromMetadata, mergeConfiguration, MergedDevContainerConfig } from './imageMetadata'; import { ensureDockerfileHasFinalStageName, generateMountCommand } from './dockerfileUtils'; +import { getStaticPorts } from './ports'; export const hostFolderLabel = 'devcontainer.local_folder'; // used to label containers created from a workspace/folder export const configFileLabel = 'devcontainer.config_file'; @@ -196,7 +197,7 @@ async function buildAndExtendImage(buildParams: DockerResolverParameters, config if (buildParams.buildxPush) { args.push('--push'); } else { - if (buildParams.buildxOutput) { + if (buildParams.buildxOutput) { args.push('--output', buildParams.buildxOutput); } else { args.push('--load'); // (short for --output=docker, i.e. load into normal 'docker images' collection) @@ -348,9 +349,8 @@ export async function spawnDevContainer(params: DockerResolverParameters, config const { common } = params; common.progress(ResolverProgress.StartingContainer); - const appPort = config.appPort; - const exposedPorts = typeof appPort === 'number' || typeof appPort === 'string' ? [appPort] : appPort || []; - const exposed = ([]).concat(...exposedPorts.map(port => ['-p', typeof port === 'number' ? `127.0.0.1:${port}:${port}` : port])); + const exposedPorts = getStaticPorts(config); + const exposed = exposedPorts.flatMap((port) => ['-p', port]); const cwdMount = workspaceMount ? ['--mount', workspaceMount] : [];