diff --git a/src/platform.js b/src/platform.js index f3aaa4c12..0c49a7f05 100644 --- a/src/platform.js +++ b/src/platform.js @@ -97,7 +97,28 @@ async function onPlatformReady(infraChanged) { async function pruneInfraImages() { debug('pruneInfraImages: checking existing images'); - await shell.promises.exec('pruneInfraImages', 'docker image prune -a --force'); + + // cannot blindly remove all unused images since redis image may not be used + const images = infra.baseImages.concat(Object.keys(infra.images).map(function (addon) { return infra.images[addon]; })); + + for (const image of images) { + let output = safe.child_process.execSync(`docker images --digests ${image.repo} --format "{{.ID}} {{.Repository}}:{{.Tag}}@{{.Digest}}"`, { encoding: 'utf8' }); + if (output === null) { + debug(`Failed to list images of ${image}`, safe.error); + throw safe.error; + } + + let lines = output.trim().split('\n'); + for (let line of lines) { + if (!line) continue; + let parts = line.split(' '); // [ ID, Repo:Tag@Digest ] + if (image.tag === parts[1]) continue; // keep + debug(`pruneInfraImages: removing unused image of ${image.repo}: tag: ${parts[1]} id: ${parts[0]}`); + + let result = safe.child_process.execSync(`docker rmi ${parts[0]}`, { encoding: 'utf8' }); + if (result === null) debug(`Error removing image ${parts[0]}: ${safe.error.mesage}`); + } + } } async function createDockerNetwork() {