diff --git a/lib/utils/compose-types.d.ts b/lib/utils/compose-types.d.ts index 50816c1af9..ac9dc6757a 100644 --- a/lib/utils/compose-types.d.ts +++ b/lib/utils/compose-types.d.ts @@ -55,6 +55,7 @@ export interface ComposeOpts { noParentCheck: boolean; projectName: string; projectPath: string; + isLocal?: boolean; } export interface ComposeCliFlags { diff --git a/lib/utils/compose_ts.ts b/lib/utils/compose_ts.ts index 92a3331509..b94ace66fe 100644 --- a/lib/utils/compose_ts.ts +++ b/lib/utils/compose_ts.ts @@ -136,6 +136,7 @@ export async function loadProject( } else { logger.logDebug('Resolving project...'); [composeName, composeStr] = await resolveProject(logger, opts.projectPath); + if (composeName) { if (opts.dockerfilePath) { logger.logWarn( @@ -148,11 +149,52 @@ export async function loadProject( ); composeStr = compose.defaultComposition(undefined, opts.dockerfilePath); } + + // If local push, merge dev compose overlay + if (opts.isLocal) { + composeStr = await mergeDevComposeOverlay( + logger, + composeStr, + opts.projectPath, + ); + } } logger.logDebug('Creating project...'); return createProject(opts.projectPath, composeStr, opts.projectName); } +/** + * Check for existence of docker-compose dev overlay file + * and merge in services definitions. + */ +async function mergeDevComposeOverlay( + logger: Logger, + composeStr: string, + projectRoot: string, +) { + const devOverlayFilename = 'docker-compose.dev.yml'; + const devOverlayPath = path.join(projectRoot, devOverlayFilename); + + if (await exists(devOverlayPath)) { + logger.logInfo( + `Docker compose dev overlay detected (${devOverlayFilename}) - merging.`, + ); + try { + const yaml = await import('js-yaml'); + const compose = yaml.load(composeStr); + const devOverlay = yaml.load(await fs.readFile(devOverlayPath, 'utf8')); + // We only want to merge the services section + compose.services = { ...compose.services, ...devOverlay.services }; + composeStr = yaml.dump(compose); + } catch (err) { + err.message = `Error merging docker compose dev overlay file "${devOverlayPath}":\n${err.message}`; + throw err; + } + } + + return composeStr; +} + /** * Look into the given directory for valid compose files and return * the contents of the first one found. @@ -181,6 +223,7 @@ async function resolveProject( if (!quiet && !composeFileName) { logger.logInfo(`No "docker-compose.yml" file found at "${projectRoot}"`); } + return [composeFileName, composeFileContents]; } diff --git a/lib/utils/device/deploy.ts b/lib/utils/device/deploy.ts index ad7b7602fa..4b120364e2 100644 --- a/lib/utils/device/deploy.ts +++ b/lib/utils/device/deploy.ts @@ -186,6 +186,7 @@ export async function deployToDevice(opts: DeviceDeployOptions): Promise { noParentCheck: opts.noParentCheck, projectName: 'local', projectPath: opts.source, + isLocal: true, }); // Attempt to attach to the device's docker daemon