PinguApps.Aspire.Hosting.Railway 1.1.1

dotnet add package PinguApps.Aspire.Hosting.Railway --version 1.1.1
                    
NuGet\Install-Package PinguApps.Aspire.Hosting.Railway -Version 1.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PinguApps.Aspire.Hosting.Railway" Version="1.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PinguApps.Aspire.Hosting.Railway" Version="1.1.1" />
                    
Directory.Packages.props
<PackageReference Include="PinguApps.Aspire.Hosting.Railway" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add PinguApps.Aspire.Hosting.Railway --version 1.1.1
                    
#r "nuget: PinguApps.Aspire.Hosting.Railway, 1.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package PinguApps.Aspire.Hosting.Railway@1.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=PinguApps.Aspire.Hosting.Railway&version=1.1.1
                    
Install as a Cake Addin
#tool nuget:?package=PinguApps.Aspire.Hosting.Railway&version=1.1.1
                    
Install as a Cake Tool

PinguApps.Aspire.Hosting.Railway

PinguApps.Aspire.Hosting.Railway version PinguApps.Aspire.Hosting.Railway downloads

Deploy normal Aspire projects and containers into a pre-created, site-owned Railway environment. Local development stays unchanged. Retained images deploy without building or pushing containers. Opt-in source uploads let Railway build and retain containers without an external private-registry pull credential.

Install

Requires .NET 10 and Aspire 13.6.0.

dotnet add package PinguApps.Aspire.Hosting.Railway --version 1.0.0

C# AppHost

using Aspire.Hosting.Railway;

var web = builder.AddProject<Projects.Web>("web");
if (builder.ExecutionContext.IsPublishMode)
{
    var target = builder.AddRailwayTarget("railway",
        builder.AddParameter("railway-project-id", Current("Parameters__railway_project_id")),
        builder.AddParameter("railway-environment-id", Current("Parameters__railway_environment_id")),
        builder.AddParameter("railway-api-token", Current("Parameters__railway_api_token"), secret: true),
        builder.AddParameter("site-key", Current("Parameters__site_key")));

    web.PublishToRailway(target, options =>
    {
        options.Image = release.WebImage; // ghcr.io/...@sha256:...
        options.Port = 8080;
        options.PublicDomain = true;
        options.HealthCheckPath = "/health";
        options.Region = "europe-west4-drams3a";
        options.MemoryGB = 1;
        options.VCpus = 1;
        options.SealedVariables.Add("ConnectionStrings__database");
    });
}

string Current(string name) => Environment.GetEnvironmentVariable(name)
    ?? throw new InvalidOperationException($"Missing deployment input: {name}");

Before deployment, set the environment's shared PINGUAPPS_SITE_KEY to its allocation record's site key. The package never creates projects, environments, or allocation records. Default authentication uses an environment-scoped project token and validates its exact scope and the live site marker before writes.

Supply current destination and credential parameters on every deployment. Aspire itself can retain parameter values in deployment state; do not rely on cached credentials after rotation. The C# guide shows explicit current inputs. Account/workspace Bearer mode additionally requires the recorded project name and workspace ID.

aspire deploy --non-interactive
aspire deploy --non-interactive --list-steps

The read-only target plan validates all declared services before provider mutations. Then each service waits for provider prerequisites and explicit release dependencies, resolves runtime bindings, applies changes, and verifies the exact deployment ID.

TypeScript AppHost

{
  "appHost": { "path": "apphost.mts", "language": "typescript/nodejs" },
  "sdk": { "version": "13.6.0" },
  "packages": { "PinguApps.Aspire.Hosting.Railway": "1.0.0" }
}
import { createBuilder, railwayOwnershipMode } from "./.aspire/modules/aspire.mjs";
const builder = await createBuilder();
let web = await builder.addContainer("web", "example/web");
if (await builder.executionContext().isPublishMode()) {
  const project = await builder.addParameter("railway-project-id", { value: current("Parameters__railway_project_id") });
  const environment = await builder.addParameter("railway-environment-id", { value: current("Parameters__railway_environment_id") });
  const token = await builder.addParameter("railway-api-token", { value: current("Parameters__railway_api_token"), secret: true });
  const site = await builder.addParameter("site-key", { value: current("Parameters__site_key") });
  const target = await builder.addRailwayTarget("railway", project, environment, token, site);
  web = await web.publishToRailway(target, {
    image: "ghcr.io/example/web@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    ownershipMode: railwayOwnershipMode.createOrAdopt,
    port: 8080, publicDomain: true, healthCheckPath: "/health"
  });
}
const app = await builder.build();
await app.run();

function current(name: string): string {
  const value = process.env[name];
  if (!value) throw new Error(`Missing deployment input: ${name}`);
  return value;
}

The packed fixture validates actual NuGet-generated exports. Explicitly declare this package alongside companion packages so the shared target API is generated.

Ownership and repeatability

  • CreateOnly: create a missing service; later deployments reuse its recorded identity. Do not adopt unrelated pre-existing infrastructure.
  • ExistingOnly: require a proven existing service; never create one.
  • CreateOrAdopt: create a missing service or adopt a service marked for the same site/resource. Unmarked adoption additionally requires an explicit ExistingServiceId.
  • Cached IDs remain bound to site, project, environment, and name. Missing or replaced identities fail safely.
  • Volume identity, mount, region, and unexpected public-domain drift require operator reconciliation. Infrastructure is never deleted automatically.
  • Explicit region aliases configure Railway's provider region before volume creation. New volumes must prove their service, mount and region before deployment; incomplete creation metadata is polled within the shared deployment deadline, including in-flight reads, while known mismatches fail. A volume-confirmation timeout retains recorded identities and stops the remaining configuration and deployment stages. The completed deployment must retain the requested single region and replica count. Existing volume region drift still requires operator migration.
  • Pending application state allows retries without duplicate resources or skipping an unfinished deployment.

Runtime and release configuration

Use normal WithEnvironment, WithReference, and parameter expressions. Published endpoints resolve to Railway private hostnames and container ports. DeploymentDependsOn and WithRailwayDeploymentDependency gate dependent deployments, including finite jobs. Workers get no public domain unless requested.

Ordinary services must reach Railway SUCCESS. Finite execution additionally must stop with every instance EXITED; a running deployment is insufficient. Failure, removal, or a timeout prevents downstream deployment. Cron workloads use Never restart and must exit. The Jobs companion package supplies workload-specific APIs and cron validation.

Private GHCR images need Railway private-registry support (currently a Pro feature) and a narrowly scoped pull credential:

web.WithRailwayRegistryCredentials(
    builder.AddParameter("ghcr-user"),
    builder.AddParameter("ghcr-pull-token", secret: true));

Pull credentials go only to Railway's control plane. Variables listed in SealedVariables become write-only runtime secrets. State stores keyed desired-value fingerprints, never their values or registry passwords. Infrastructure credentials in workload configuration cause refusal.

For deployments without private-registry pull credentials, select options.Build = new RailwayBuildOptions { ContextPath = "../..", DockerfilePath = "src/Web/Dockerfile" }. Railway builds and retains that service's container; aspire deploy performs the upload internally. The deployment machine needs Railway CLI 5.63.1 or later. See source builds for C#/TypeScript examples, upload exclusions, job ordering, and retention limits. Existing image-based publishing remains the default.

Development and release

dotnet test Aspire.Hosting.Railway.slnx -c Release
pwsh ./eng/Test-AspireVersionPins.ps1
pwsh ./eng/Validate-TypeScriptAppHostPackage.ps1

Workflows follow the existing integration repositories: pinned actions, release drafting, NuGet OIDC publishing, symbols, and the packed TypeScript gate. Configure Blacksmith access and NUGET_USER; register the GitHub repository/workflow as a NuGet trusted publisher. No persistent NuGet API key is required.

See configuration, deployment behavior, security, and live validation.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on PinguApps.Aspire.Hosting.Railway:

Package Downloads
PinguApps.Aspire.Hosting.Railway.Jobs

Finite release jobs and scheduled container jobs for Aspire Railway deployments.

PinguApps.Aspire.Hosting.RabbitMQ.Railway

Deploy standard Aspire RabbitMQ resources to Railway with private AMQP and authenticated HTTPS management.

PinguApps.Aspire.Hosting.Dashboard.Railway

Authenticated standalone Aspire dashboard publishing for Railway.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.1 100 10/11/2026
1.1.0 88 10/10/2026
1.0.3 186 10/4/2026
1.0.2 196 10/2/2026
1.0.1 93 10/2/2026
1.0.0 172 10/2/2026