Skip to content

Generated App Publishing

This guide is the published-output baseline for freshly generated Cephalon apps.

Use it when you want to prove that a generated host can move from scaffolded source to a deterministic publish folder and then run from the published output without relying on the SDK build loop or the Docker build stage.

Generated app roots from cephalon new and the app-focused dotnet new cephalon-* starters now include:

  • NuGet.config
  • .cephalon/packages/README.md
  • Properties/PublishProfiles/CephalonFolder.pubxml
  • deploy/container-image/README.md
  • deploy/container-image/publish-image.ps1
  • deploy/windows-service/README.md
  • deploy/windows-service/install-service.ps1
  • deploy/windows-service/remove-service.ps1
  • deploy/iis/README.md
  • deploy/iis/install-site.ps1
  • deploy/iis/remove-site.ps1
  • deploy/azure-app-service/README.md
  • deploy/azure-app-service/deploy-zip.ps1
  • deploy/azure-container-apps/README.md
  • deploy/azure-container-apps/deploy-up.ps1
  • deploy/kubernetes/README.md
  • deploy/kubernetes/apply.ps1
  • deploy/kubernetes/kustomization.yaml
  • deploy/kubernetes/namespace.yaml
  • deploy/kubernetes/deployment.yaml
  • deploy/kubernetes/service.yaml
  • deploy/linux/systemd/README.md
  • deploy/linux/systemd/<AppName>.service
  • deploy/linux/systemd/<AppName>.env
  • .dockerignore
  • Dockerfile
  • compose.yaml
  • otel-collector-config.yaml

That means the published-output path is now part of the generated app contract rather than an implicit dotnet publish guess. The Azure Container Apps and Kubernetes assets ship alongside that same generated host root, but they stay source/Dockerfile-based rather than depending on the published-output folder. cephalon doctor --app-root <path> now also checks that the generated Windows Service teardown script, IIS teardown script, and Linux systemd environment file (deploy/linux/systemd/Acme.Store.env in the scaffolded examples) still stay aligned with that published-output contract before teams replay those install or removal flows literally.

  • a generated app root from cephalon new or dotnet new cephalon-*
  • Cephalon* packages available either through ./.cephalon/packages or a shared package source that replaces the generated cephalon feed entry

If you are iterating from the Cephalon repository before packages land on a shared feed, seed the generated app root with:

Terminal window
$generatedRoot = (Resolve-Path ./Acme.Store).Path
pwsh ./scripts/publish-package-artifacts.ps1 -OutputPath (Join-Path $generatedRoot '.cephalon/packages')

That seeding flow now preserves the generated ./.cephalon/packages/README.md guidance so teams can refresh package artifacts into the local feed without losing the scaffolded bootstrap instructions that cephalon doctor --app-root <path> also validates.

For scaffolded multi-project apps from cephalon new:

Terminal window
dotnet publish ./Acme.Store/src/Acme.Store.Host/Acme.Store.Host.csproj -p:PublishProfile=CephalonFolder

For app-starter templates from dotnet new cephalon-*:

Terminal window
dotnet publish ./Acme.Store.TemplateStarter/Acme.Store.TemplateStarter.csproj -p:PublishProfile=CephalonFolder

CephalonFolder.pubxml keeps the publish output deterministic:

  • scaffolded multi-project apps publish to ./artifacts/publish/<HostProjectName>/
  • single-project template starters publish to ./artifacts/publish/<ProjectName>/
  • UseAppHost=false stays on so the published output is easy to replay across Windows, WSL, and Linux-class shells

Example for a scaffolded modular-monolith host:

Terminal window
dotnet ./Acme.Store/artifacts/publish/Acme.Store.Host/Acme.Store.Host.dll --urls http://127.0.0.1:18080

Once the published host is running, inspect:

  • /engine
  • /engine/snapshot
  • /engine/runtime-story
  • /health
  • /health/ready
  • /scalar

Those routes should behave the same way they do under dotnet run and under the generated Docker compose path. Before you replay the generated Windows Service, IIS, Azure App Service, or Linux systemd paths from this published-output baseline, rerun cephalon doctor --app-root ./Acme.Store so the same generated-app command path can confirm the generated self-hosted and hosted deployment assets still align with the current host identity, publish profile, and package-source bootstrap.

From this published-output baseline, teams can continue into the shipped Windows Service, IIS, Azure App Service, or Linux systemd install surfaces without changing the generated host shape. For the source/Dockerfile-based hosted container paths, continue with the generated deploy/container-image/* assets and Container image publishing, then into the generated deploy/azure-container-apps/* assets and Azure Container Apps deployment, or with the generated deploy/kubernetes/* assets and Kubernetes deployment.

If you want the broader external cold-start replay first, use:

Terminal window
pwsh ./scripts/validate-generated-app-adoption.ps1

That scenario-driven script installs Cephalon.Cli from a temporary package feed, runs cephalon doctor, scaffolds a fresh app outside the repository, seeds the generated local package feed, reruns cephalon doctor --app-root, restores, builds, runs the generated host, and validates the runtime routes before you decide whether you need the published-output-specific replay below.

To replay the full generated-app publish baseline from the Cephalon repository in one command, run:

Terminal window
pwsh ./scripts/validate-generated-app-publish.ps1

That script:

  • scaffolds a fresh app through Cephalon.Cli
  • seeds ./.cephalon/packages with repo-local package artifacts
  • publishes the generated host through CephalonFolder.pubxml
  • runs the published output on a local HTTP URL
  • validates /health/ready, /engine, /engine/snapshot, and /scalar
  • tears the temporary app back down afterward unless -KeepOutput is supplied