PinguApps.Aspire.Hosting.PostgreSQL.Railway 1.1.9

dotnet add package PinguApps.Aspire.Hosting.PostgreSQL.Railway --version 1.1.9
                    
NuGet\Install-Package PinguApps.Aspire.Hosting.PostgreSQL.Railway -Version 1.1.9
                    
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.PostgreSQL.Railway" Version="1.1.9" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PinguApps.Aspire.Hosting.PostgreSQL.Railway" Version="1.1.9" />
                    
Directory.Packages.props
<PackageReference Include="PinguApps.Aspire.Hosting.PostgreSQL.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.PostgreSQL.Railway --version 1.1.9
                    
#r "nuget: PinguApps.Aspire.Hosting.PostgreSQL.Railway, 1.1.9"
                    
#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.PostgreSQL.Railway@1.1.9
                    
#: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.PostgreSQL.Railway&version=1.1.9
                    
Install as a Cake Addin
#tool nuget:?package=PinguApps.Aspire.Hosting.PostgreSQL.Railway&version=1.1.9
                    
Install as a Cake Tool

PinguApps.Aspire.Hosting.PostgreSQL.Railway

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

PinguApps.Aspire.Hosting.PostgreSQL.Railway lets an Aspire AppHost keep using Aspire's normal PostgreSQL resource model locally, then create or adopt a Railway PostgreSQL service during aspire deploy.

  • Local behaviour: standard Aspire PostgreSQL
  • Deploy behaviour: opt-in Railway PostgreSQL create/adopt flow
  • Resource of record: PostgresServerResource
  • Child databases: postgres.AddDatabase(...) resources are created inside the Railway PostgreSQL service during deploy
  • Required Railway inputs: service name, project id, environment id/name, management token
  • Connection output: public Railway PostgreSQL URL/TCP proxy when available, otherwise Railway's PostgreSQL host variables

Install

dotnet add package PinguApps.Aspire.Hosting.PostgreSQL.Railway

TypeScript AppHosts consume the same NuGet package through Aspire's generated module flow:

{
  "packages": {
    "Aspire.Hosting.PostgreSQL": "13.5.1",
    "PinguApps.Aspire.Hosting.PostgreSQL.Railway": "<package version>"
  }
}

Then run:

aspire restore --non-interactive

C# Example

using Aspire.Hosting;
using Aspire.Hosting.ApplicationModel;
using Aspire.Hosting.PostgreSQL.Railway;

var builder = DistributedApplication.CreateBuilder(args);

IResourceBuilder<ParameterResource> serviceName = builder.AddParameter("railway-postgres-service-name");
IResourceBuilder<ParameterResource> projectId = builder.AddParameter("railway-project-id");
IResourceBuilder<ParameterResource> environmentId = builder.AddParameter("railway-environment-id");
IResourceBuilder<ParameterResource> apiToken = builder.AddParameter("railway-api-token", secret: true);

IResourceBuilder<PostgresServerResource> postgres = builder.AddPostgres("postgres");

IResourceBuilder<PostgresDatabaseResource> orders = postgres.AddDatabase("orders");

postgres.PublishToRailway(
    serviceName,
    projectId,
    environmentId,
    apiToken,
    RailwayPostgresOwnershipMode.CreateOrAdopt,
    options =>
    {
        options.Region = RailwayPostgresRegions.EuWestMetal;
        options.RestartPolicy = RailwayPostgresRestartPolicy.OnFailure;
        options.RestartPolicyMaxRetries = 10;
        options.MemoryGB = 2;
        options.VCpus = 1;
        options.SharedMemoryBytes = 524288000;
        options.Template = RailwayPostgresTemplate.PointInTimeRecovery;
        options.AuthenticationMode = RailwayPostgresAuthenticationMode.ProjectToken;
        options.EnablePublicProvisioningEndpoint = true;
    });

builder.AddProject<Projects.Api>("api")
    .WithReference(orders)
    .WaitFor(postgres);

builder.Build().Run();

TypeScript Example

import {
  createBuilder,
  RailwayPostgresRegions,
  RailwayPostgresRestartPolicy,
  RailwayPostgresTemplate,
  RailwayPostgresAuthenticationMode,
  railwayPostgresOwnershipMode,
} from "./.aspire/modules/aspire.mjs";

const builder = await createBuilder();

const serviceName = await builder.addParameter("railway-postgres-service-name");
const projectId = await builder.addParameter("railway-project-id");
const environmentId = await builder.addParameter("railway-environment-id");
const apiToken = await builder.addParameter("railway-api-token", { secret: true });

let postgres = await builder.addPostgres("postgres");
postgres = await postgres.publishToRailway(serviceName, projectId, environmentId, apiToken, {
  ownershipMode: railwayPostgresOwnershipMode.createOrAdopt,
  region: RailwayPostgresRegions.EuWestMetal,
  restartPolicy: RailwayPostgresRestartPolicy.OnFailure,
  restartPolicyMaxRetries: 10,
  memoryGB: 2,
  vCpus: 1,
  sharedMemoryBytes: 524288000,
  template: RailwayPostgresTemplate.PointInTimeRecovery,
  authenticationMode: RailwayPostgresAuthenticationMode.ProjectToken,
  enablePublicProvisioningEndpoint: true,
});

const orders = await postgres.addDatabase("orders");

let worker = await builder.addContainer("worker", "mcr.microsoft.com/dotnet/runtime-deps:10.0");
worker = await worker.withReference(orders);

const app = await builder.build();
await app.run();

Deploy Inputs

Aspire parameter Secret Purpose
railway-postgres-service-name No Railway service name and stable remote identity.
railway-project-id No Existing Railway project id.
railway-environment-id No Existing Railway environment id or exact environment name, for example production.
railway-api-token Yes Railway project token for the selected environment, or an account/workspace token in legacy Bearer mode. Used only by deployment infrastructure.

Create a project token in Railway project Settings → Tokens, selecting the target environment. Use a separate token for each environment. Set AuthenticationMode = RailwayPostgresAuthenticationMode.ProjectToken in C#, or authenticationMode: RailwayPostgresAuthenticationMode.ProjectToken in TypeScript. The default Bearer mode preserves existing account/workspace token deployments. Token type is never inferred or retried with another header. Railway API token documentation.

For non-interactive deploys:

Set-Item Env:Parameters__railway-postgres-service-name $env:RAILWAY_POSTGRES_SERVICE_NAME
Set-Item Env:Parameters__railway-project-id $env:RAILWAY_PROJECT_ID
Set-Item Env:Parameters__railway-environment-id $env:RAILWAY_ENVIRONMENT_ID
Set-Item Env:Parameters__railway-api-token $env:RAILWAY_API_TOKEN
aspire deploy --non-interactive

If railway-environment-id is not a UUID, the deployment step resolves it by listing environments in the configured Railway project before creating or adopting the PostgreSQL service. With project-token mode, deployment first checks projectToken { projectId environmentId } and rejects a token whose project or environment differs from the configured values before any service mutation.

Deployment Options

PublishToRailway can also reconcile selected Railway service settings during deploy:

Option Purpose
Region Railway region enum: UsWestMetal, UsEastMetal, EuWestMetal, or SoutheastAsiaMetal.
RestartPolicy Railway restart policy: Always, OnFailure, or Never.
RestartPolicyMaxRetries Maximum Railway restart attempts.
MemoryGB Railway memory limit in GB.
VCpus Railway vCPU limit.
SharedMemoryBytes Sets Railway service variable RAILWAY_SHM_SIZE_BYTES for container shared memory. This is not volume storage.
Template Railway template for new services: Standard, PointInTimeRecovery, PostGis, PgVector, or TimescaleDb. Default is Standard.
AuthenticationMode Bearer (default) for account/workspace tokens; ProjectToken for environment-scoped project tokens.
EnablePublicProvisioningEndpoint Creates or reuses a public TCP proxy targeting PostgreSQL port 5432 before child-database provisioning. Default is false.

Railway templates used by Template:

Value Railway template
Standard PostgreSQL
PointInTimeRecovery Postgres PITR
PostGis PostGIS
PgVector pgvector
TimescaleDb TimescaleDB

When Region is set for a new PostgreSQL service, the deploy step applies it before waiting for Railway readiness. For existing volume-backed PostgreSQL services, region changes are rejected because Railway must migrate the attached volume; migrate manually in Railway or create a new service instead.

The existing-volume check recognises Railway's equivalent region IDs and names: sfo / us-west2, iad / us-east4-eqdc4a, ams / europe-west4-drams3a, and sin / asia-southeast1-eqsg3a. Either form in deployment metadata identifies the same region and does not require a volume migration or region-change redeploy. The matching retained region map is left unchanged, including its identifier spelling. Rewriting an alias can disrupt Railway's live routing even without requesting a redeploy. Other requested settings still apply without including region fields; different regions remain rejected.

Template is create-time only. If ownership adopts an existing Railway service, the package keeps using that service and does not convert it to another template. Services created by this package remember their original template in Aspire deployment state so later deploys keep matching connection-string behavior.

Standard and PITR template connection strings use Ssl Mode=Require. PostGIS, pgvector, and TimescaleDB template connection strings use Ssl Mode=Disable, matching the upstream Railway template endpoints this package targets.

Healthcheck path and replica count are intentionally not exposed for this PostgreSQL package. Railway healthchecks are HTTP based, while the PostgreSQL template exposes a database socket. Horizontal replicas of the default PostgreSQL template are not PostgreSQL HA/read replicas.

Behaviour

Enable EnablePublicProvisioningEndpoint when deploying from a workstation or CI runner that cannot reach Railway's private network. The package creates or reuses the selected service's TCP proxy, waits for an active route, then creates AddDatabase(...) databases through its authoritative public address. A newly created or inactive proxy requires a service redeployment. Activation is bounded to two minutes, and repeated deploys reuse the existing active proxy. The public endpoint remains enabled after deployment; manage its removal in Railway when it is no longer needed. Application-facing connection outputs retain their existing selection rules.

Local runs do not call Railway and keep normal Aspire PostgreSQL behaviour. During aspire deploy, this package creates or adopts the configured Railway PostgreSQL service, reads Railway's PostgreSQL variables, applies the server connection output, and applies child database connection strings for AddDatabase(...) resources. It prefers DATABASE_PUBLIC_URL, a public DATABASE_URL, or Railway TCP proxy variables when Railway exposes them, and otherwise falls back to PostgreSQL host variables. For PostGIS, pgvector, and TimescaleDB services created by this package, child databases are initialized with the matching extension.

For C# AppHosts, importing Aspire.Hosting.PostgreSQL.Railway also makes .WithReference(postgres) and .WithReference(database) Railway-aware for resources marked with .PublishToRailway(...). Consumers keep normal Aspire reference code while Azure App Service receives output-backed Railway PostgreSQL connection strings during deploy.

Docs

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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.9 92 11/8/2026
1.1.8 217 11/1/2026
1.1.7 211 10/25/2026
1.1.6 288 10/18/2026
1.1.5 241 10/11/2026
1.1.4 89 10/11/2026
1.1.3 99 10/11/2026
1.1.2 165 10/11/2026
1.1.1 215 10/4/2026
1.1.0 262 10/1/2026
1.0.1 111 9/28/2026
1.0.0 963 6/21/2026