diff --git a/src/compose/app.ts b/src/compose/app.ts index f8a94b13..d3eaf2ce 100644 --- a/src/compose/app.ts +++ b/src/compose/app.ts @@ -921,19 +921,24 @@ class AppImpl implements App { volumePairs: Array>, servicePairs: Array>, ): boolean { - // Firstly we check if a dependency is not already running (this is + // Firstly we check if a dependency has already been started (this is // different to a dependency which is in the servicePairs below, as these // are services which are changing). We could have a dependency which is // starting up, but is not yet running. - const depInstallingButNotRunning = _.some(this.services, (svc) => { + const depCreatedButNotStarted = _.some(this.services, (svc) => { if (target.dependsOn?.includes(svc.serviceName)) { - if (!svc.config.running) { + if ( + svc.status === 'Installing' || + svc.startedAt == null || + svc.createdAt == null || + svc.startedAt < svc.createdAt + ) { return true; } } }); - if (depInstallingButNotRunning) { + if (depCreatedButNotStarted) { return false; } diff --git a/src/compose/service.ts b/src/compose/service.ts index a0bdde68..3c712ae7 100644 --- a/src/compose/service.ts +++ b/src/compose/service.ts @@ -61,6 +61,7 @@ class ServiceImpl implements Service { public dockerImageId: string | null; public status: ServiceStatus; public createdAt: Date | null; + public startedAt: Date | null; private static configArrayFields: ServiceConfigArrayField[] = [ 'volumes', @@ -476,6 +477,7 @@ class ServiceImpl implements Service { } svc.createdAt = new Date(container.Created); + svc.startedAt = new Date(container.State.StartedAt); svc.containerId = container.Id; svc.exitErrorMessage = container.State.Error; diff --git a/src/compose/types/service.ts b/src/compose/types/service.ts index 9add9488..073cd907 100644 --- a/src/compose/types/service.ts +++ b/src/compose/types/service.ts @@ -373,6 +373,7 @@ export interface Service { // from docker status: ServiceStatus; createdAt: Date | null; + startedAt: Date | null; hasNetwork(networkName: string): boolean; hasVolume(volumeName: string): boolean; diff --git a/test/integration/compose/application-manager.spec.ts b/test/integration/compose/application-manager.spec.ts index f06a8632..2b6b76a9 100644 --- a/test/integration/compose/application-manager.spec.ts +++ b/test/integration/compose/application-manager.spec.ts @@ -1128,11 +1128,20 @@ describe('compose/application-manager', () => { const { currentApps, availableImages, downloading, containerIdsByAppId } = createCurrentState({ services: [ - await createService({ - image: 'dep-image', - serviceName: 'dep', - commit: 'new-release', - }), + await createService( + { + image: 'dep-image', + serviceName: 'dep', + commit: 'new-release', + }, + { + state: { + createdAt: new Date(Date.now() - 5 * 1000), + // Container was started 5 after creation + startedAt: new Date(), + }, + }, + ), ], networks: [DEFAULT_NETWORK], images: [ diff --git a/test/unit/compose/app.spec.ts b/test/unit/compose/app.spec.ts index 8c559e7d..4109a073 100644 --- a/test/unit/compose/app.spec.ts +++ b/test/unit/compose/app.spec.ts @@ -1458,7 +1458,14 @@ describe('compose/app', () => { services: [ await createService( { appId: 1, serviceName: 'dep' }, - { state: { containerId: 'dep-id' } }, + { + state: { + containerId: 'dep-id', + createdAt: new Date(Date.now() - 5 * 1000), + // Container was started 5 after creation + startedAt: new Date(), + }, + }, ), ], networks: [DEFAULT_NETWORK], @@ -1475,7 +1482,7 @@ describe('compose/app', () => { .that.deep.includes({ serviceName: 'main' }); }); - it('should not start a container when it depends on a service that is not running', async () => { + it('should not start a container when it depends on a service that has not been started yet', async () => { const current = createApp({ services: [ await createService( @@ -1535,7 +1542,14 @@ describe('compose/app', () => { services: [ await createService( { appId: 1, serviceName: 'dep' }, - { state: { containerId: 'dep-id' } }, + { + state: { + containerId: 'dep-id', + createdAt: new Date(Date.now() - 5 * 1000), + // Container was started 5 after creation + startedAt: new Date(), + }, + }, ), ], networks: [DEFAULT_NETWORK],