Skip to content

Add container runtime health check as orphan pipeline step#16196

Merged
davidfowl merged 1 commit intomainfrom
davidfowl/deploy-delight
Apr 18, 2026
Merged

Add container runtime health check as orphan pipeline step#16196
davidfowl merged 1 commit intomainfrom
davidfowl/deploy-delight

Conversation

@davidfowl
Copy link
Copy Markdown
Contributor

Description

Add a container runtime health check as an orphan pipeline step that prevents cascading failures when Docker/Podman isn't running during deployment.

Problem: When Docker isn't running and a user runs aspire deploy, the container build step fails and cancels sibling pipeline steps (like Azure provisioning) via the shared CancellationTokenSource. The cancelled provisioning step surfaces misleading DefaultAzureCredential errors, burying the actual root cause.

Solution: Add a check-container-runtime step to the pipeline that:

  • Is an orphan by default — no dependencies, nothing depends on it. It only participates when a resource's build step explicitly depends on it (ProjectResource, ContainerResource).
  • Uses IContainerRuntimeResolver to detect and verify the runtime.
  • In interactive mode, prompts the user to start the runtime and retry instead of failing immediately.
  • In non-interactive mode (CI), fails fast with a clear error message.
  • Adds WellKnownPipelineSteps.CheckContainerRuntime so third-party resources can depend on it too.

Fixes #12348

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No
  • Does the change require an update in our Aspire docs?

Copilot AI review requested due to automatic review settings April 15, 2026 06:29
@davidfowl davidfowl force-pushed the davidfowl/deploy-delight branch from 6879cbc to 95ea21b Compare April 15, 2026 06:33
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a dedicated pipeline step to validate the container runtime (Docker/Podman) health so deployments fail with a clearer root cause when the runtime is stopped, and allows interactive retry.

Changes:

  • Introduce a new well-known pipeline step check-container-runtime.
  • Register the step in DistributedApplicationPipeline with interactive prompting and non-interactive fail-fast behavior.
  • Make container/project build steps depend on the new health-check step; update pipeline tests accordingly.
Show a summary per file
File Description
tests/Aspire.Hosting.Tests/Pipelines/DistributedApplicationPipelineTests.cs Updates expectations/targeting to account for the new default step.
src/Aspire.Hosting/Pipelines/WellKnownPipelineSteps.cs Adds CheckContainerRuntime constant for cross-resource dependencies.
src/Aspire.Hosting/Pipelines/DistributedApplicationPipeline.cs Registers the container runtime health-check step and its behavior.
src/Aspire.Hosting/ContainerResourceBuilderExtensions.cs Adds dependency from container build step to the runtime check.
src/Aspire.Hosting/ApplicationModel/ProjectResource.cs Adds dependency from project image build step to the runtime check.

Copilot's findings

  • Files reviewed: 5/5 changed files
  • Comments generated: 4

Comment thread src/Aspire.Hosting/Pipelines/DistributedApplicationPipeline.cs Outdated
Comment thread src/Aspire.Hosting/Pipelines/DistributedApplicationPipeline.cs Outdated
Comment thread src/Aspire.Hosting/Pipelines/DistributedApplicationPipeline.cs
Copy link
Copy Markdown
Member

@JamesNK JamesNK left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good — clean design with the orphan step pattern. One minor test gap noted.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 15, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 16196

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 16196"

@davidfowl davidfowl force-pushed the davidfowl/deploy-delight branch from 8261d11 to 5cd3ac2 Compare April 15, 2026 07:29
Comment thread src/Aspire.Hosting/Pipelines/DistributedApplicationPipeline.cs Outdated
Comment thread src/Aspire.Hosting/ContainerResourceBuilderExtensions.cs
@davidfowl davidfowl force-pushed the davidfowl/deploy-delight branch from 937c19e to c46bd5f Compare April 16, 2026 04:40
Comment thread src/Aspire.Hosting/Publishing/DockerContainerRuntime.cs
Add a check-container-runtime pipeline step that verifies the Docker/Podman
daemon is running before container build steps execute. This prevents
cascading failures where Docker-not-running errors cancel unrelated steps
(like Azure provisioning), producing misleading credential errors.

Changes:
- Add WellKnownPipelineSteps.CheckContainerRuntime
- Register the step in DistributedApplicationPipeline with interactive
  retry support (prompts user to start Docker in interactive mode)
- ProjectResource and ContainerResourceBuilderExtensions wire build steps
  to depend on it
- Fix CheckIfRunningAsync to check daemon only (remove buildx check)
- Update tests and snapshots

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@davidfowl davidfowl force-pushed the davidfowl/deploy-delight branch from 94aeef8 to ec99d35 Compare April 18, 2026 05:04
@github-actions
Copy link
Copy Markdown
Contributor

🎬 CLI E2E Test Recordings — 72 recordings uploaded (commit ec99d35)

View recordings
Test Recording
AddPackageInteractiveWhileAppHostRunningDetached ▶️ View Recording
AddPackageWhileAppHostRunningDetached ▶️ View Recording
AgentCommands_AllHelpOutputs_AreCorrect ▶️ View Recording
AgentInitCommand_DefaultSelection_InstallsSkillOnly ▶️ View Recording
AgentInitCommand_MigratesDeprecatedConfig ▶️ View Recording
AspireAddPackageVersionToDirectoryPackagesProps ▶️ View Recording
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps ▶️ View Recording
Banner_DisplayedOnFirstRun ▶️ View Recording
Banner_DisplayedWithExplicitFlag ▶️ View Recording
Banner_NotDisplayedWithNoLogoFlag ▶️ View Recording
CertificatesClean_RemovesCertificates ▶️ View Recording
CertificatesTrust_WithNoCert_CreatesAndTrustsCertificate ▶️ View Recording
CertificatesTrust_WithUntrustedCert_TrustsCertificate ▶️ View Recording
ConfigSetGet_CreatesNestedJsonFormat ▶️ View Recording
CreateAndRunAspireStarterProject ▶️ View Recording
CreateAndRunAspireStarterProjectWithBundle ▶️ View Recording
CreateAndRunEmptyAppHostProject ▶️ View Recording
CreateAndRunJavaEmptyAppHostProject ▶️ View Recording
CreateAndRunJsReactProject ▶️ View Recording
CreateAndRunPythonReactProject ▶️ View Recording
CreateAndRunTypeScriptEmptyAppHostProject ▶️ View Recording
CreateAndRunTypeScriptStarterProject ▶️ View Recording
CreateJavaAppHostWithViteApp ▶️ View Recording
CreateTypeScriptAppHostWithViteApp ▶️ View Recording
DashboardRunWithOtelTracesReturnsNoTraces ▶️ View Recording
DeployK8sBasicApiService ▶️ View Recording
DeployK8sWithGarnet ▶️ View Recording
DeployK8sWithMongoDB ▶️ View Recording
DeployK8sWithMySql ▶️ View Recording
DeployK8sWithPostgres ▶️ View Recording
DeployK8sWithRabbitMQ ▶️ View Recording
DeployK8sWithRedis ▶️ View Recording
DeployK8sWithSqlServer ▶️ View Recording
DeployK8sWithValkey ▶️ View Recording
DeployTypeScriptAppToKubernetes ▶️ View Recording
DescribeCommandResolvesReplicaNames ▶️ View Recording
DescribeCommandShowsRunningResources ▶️ View Recording
DetachFormatJsonProducesValidJson ▶️ View Recording
DetachFormatJsonProducesValidJsonWhenRestartingExistingInstance ▶️ View Recording
DoListStepsShowsPipelineSteps ▶️ View Recording
DoctorCommand_DetectsDeprecatedAgentConfig ▶️ View Recording
DoctorCommand_WithSslCertDir_ShowsTrusted ▶️ View Recording
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted ▶️ View Recording
GlobalMigration_HandlesCommentsAndTrailingCommas ▶️ View Recording
GlobalMigration_HandlesMalformedLegacyJson ▶️ View Recording
GlobalMigration_PreservesAllValueTypes ▶️ View Recording
GlobalMigration_SkipsWhenNewConfigExists ▶️ View Recording
GlobalSettings_MigratedFromLegacyFormat ▶️ View Recording
InitTypeScriptAppHost_AugmentsExistingViteRepoAtRoot ▶️ View Recording
InvalidAppHostPathWithComments_IsHealedOnRun ▶️ View Recording
LegacySettingsMigration_AdjustsRelativeAppHostPath ▶️ View Recording
LogsCommandShowsResourceLogs ▶️ View Recording
OtelLogsReturnsStructuredLogsFromStarterApp ▶️ View Recording
PsCommandListsRunningAppHost ▶️ View Recording
PsFormatJsonOutputsOnlyJsonToStdout ▶️ View Recording
PublishWithConfigureEnvFileUpdatesEnvOutput ▶️ View Recording
PublishWithDockerComposeServiceCallbackSucceeds ▶️ View Recording
PublishWithoutOutputPathUsesAppHostDirectoryDefault ▶️ View Recording
RestoreGeneratesSdkFiles ▶️ View Recording
RestoreRefreshesGeneratedSdkAfterAddingIntegration ▶️ View Recording
RestoreSupportsConfigOnlyHelperPackageAndCrossPackageTypes ▶️ View Recording
RunFromParentDirectory_UsesExistingConfigNearAppHost ▶️ View Recording
SecretCrudOnDotNetAppHost ▶️ View Recording
SecretCrudOnTypeScriptAppHost ▶️ View Recording
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels ▶️ View Recording
StartAndWaitForTypeScriptSqlServerAppHostWithNativeAssets ▶️ View Recording
StopAllAppHostsFromAppHostDirectory ▶️ View Recording
StopAllAppHostsFromUnrelatedDirectory ▶️ View Recording
StopNonInteractiveMultipleAppHostsShowsError ▶️ View Recording
StopNonInteractiveSingleAppHost ▶️ View Recording
StopWithNoRunningAppHostExitsSuccessfully ▶️ View Recording
UnAwaitedChainsCompileWithAutoResolvePromises ▶️ View Recording

📹 Recordings uploaded automatically from CI run #24597482751

@davidfowl davidfowl merged commit 9c750e1 into main Apr 18, 2026
284 checks passed
@github-actions github-actions Bot added this to the 13.3 milestone Apr 18, 2026
@davidfowl
Copy link
Copy Markdown
Contributor Author

Had to make a few more changes but this works well now

radical pushed a commit to radical/aspire that referenced this pull request Apr 18, 2026
…icrosoft#16196)

Add a check-container-runtime pipeline step that verifies the Docker/Podman
daemon is running before container build steps execute. This prevents
cascading failures where Docker-not-running errors cancel unrelated steps
(like Azure provisioning), producing misleading credential errors.

Changes:
- Add WellKnownPipelineSteps.CheckContainerRuntime
- Register the step in DistributedApplicationPipeline with interactive
  retry support (prompts user to start Docker in interactive mode)
- ProjectResource and ContainerResourceBuilderExtensions wire build steps
  to depend on it
- Fix CheckIfRunningAsync to check daemon only (remove buildx check)
- Update tests and snapshots

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Apr 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Spooky failure mode when container runtime is not running

5 participants