@@ -310,11 +310,7 @@ export class DockerService {
310310 }
311311 } catch ( error ) {
312312 logger . warn ( `Error during container cleanup: ${ error . message } ` )
313- this . _broadcast (
314- serviceName ,
315- 'cleanup-warning' ,
316- `Warning during cleanup: ${ error . message } `
317- )
313+ this . _broadcast ( serviceName , 'cleanup-warning' , `Warning during cleanup: ${ error . message } ` )
318314 }
319315
320316 // Step 3: Clear volumes/data if needed
@@ -356,7 +352,7 @@ export class DockerService {
356352 // Step 5: Recreate the container
357353 this . _broadcast ( serviceName , 'recreating' , `Recreating container...` )
358354 const containerConfig = this . _parseContainerConfig ( service . container_config )
359-
355+
360356 // Execute installation asynchronously and handle cleanup
361357 this . _createContainer ( service , containerConfig ) . catch ( async ( error ) => {
362358 logger . error ( `Reinstallation failed for ${ serviceName } : ${ error . message } ` )
@@ -427,14 +423,23 @@ export class DockerService {
427423 }
428424 }
429425
430- // Start pulling the Docker image and wait for it to complete
431- const pullStream = await this . docker . pull ( service . container_image )
432- this . _broadcast (
433- service . service_name ,
434- 'pulling' ,
435- `Pulling Docker image ${ service . container_image } ...`
436- )
437- await new Promise ( ( res ) => this . docker . modem . followProgress ( pullStream , res ) )
426+ const imageExists = await this . _checkImageExists ( service . container_image )
427+ if ( imageExists ) {
428+ this . _broadcast (
429+ service . service_name ,
430+ 'image-exists' ,
431+ `Docker image ${ service . container_image } already exists locally. Skipping pull...`
432+ )
433+ } else {
434+ // Start pulling the Docker image and wait for it to complete
435+ const pullStream = await this . docker . pull ( service . container_image )
436+ this . _broadcast (
437+ service . service_name ,
438+ 'pulling' ,
439+ `Pulling Docker image ${ service . container_image } ...`
440+ )
441+ await new Promise ( ( res ) => this . docker . modem . followProgress ( pullStream , res ) )
442+ }
438443
439444 if ( service . service_name === DockerService . KIWIX_SERVICE_NAME ) {
440445 await this . _runPreinstallActions__KiwixServe ( )
@@ -466,7 +471,7 @@ export class DockerService {
466471 [ DockerService . NOMAD_NETWORK ] : { } ,
467472 } ,
468473 } ,
469- } )
474+ } ) ,
470475 } )
471476
472477 this . _broadcast (
@@ -632,4 +637,22 @@ export class DockerService {
632637 throw new Error ( `Invalid container configuration: ${ error . message } ` )
633638 }
634639 }
640+
641+ /**
642+ * Check if a Docker image exists locally.
643+ * @param imageName - The name and tag of the image (e.g., "nginx:latest")
644+ * @returns - True if the image exists locally, false otherwise
645+ */
646+ private async _checkImageExists ( imageName : string ) : Promise < boolean > {
647+ try {
648+ const images = await this . docker . listImages ( )
649+
650+ // Check if any image has a RepoTag that matches the requested image
651+ return images . some ( ( image ) => image . RepoTags && image . RepoTags . includes ( imageName ) )
652+ } catch ( error ) {
653+ logger . warn ( `Error checking if image exists: ${ error . message } ` )
654+ // If run into an error, assume the image does not exist
655+ return false
656+ }
657+ }
635658}
0 commit comments