2026-04-04·5 min read·sota.io team

Deploy .NET & ASP.NET Core to Europe — EU Hosting for C# Apps in 2026

.NET is the enterprise stack of choice across Germany, Austria, and Switzerland. SAP integrations, banking backends, healthcare platforms, industrial IoT — an enormous share of DACH enterprise software runs on C# and ASP.NET Core. And virtually all of it has strict data residency requirements.

Yet the obvious hosting choice — Azure — runs on Microsoft infrastructure, making it a US-owned processor under GDPR Article 28. The Azure Germany North region (previously operated by T-Systems as a "German cloud") was retired. Azure today routes German enterprise data through standard US-owned Microsoft Azure regions with EU region designation, but the processor remains a US entity.

For EU .NET teams that need true data residency — where the infrastructure operator is EU-owned — sota.io is built for this exact gap.

The EU Data Residency Problem for .NET Teams

.NET 8 (and .NET 9) made Linux containers a first-class deployment target. dotnet publish can produce a Docker image directly. Modern ASP.NET Core apps run on Linux without Windows Server.

This opens the door to EU-native PaaS hosting — but most platforms were built for Node.js and Python. Railway supports .NET containers, but it's a US company with EU as an opt-in region. Render is US-first. Fly.io is US-incorporated.

sota.io is incorporated and operated in the EU, running on Hetzner Cloud in Germany. Your ASP.NET Core app, its data, and its logs never leave EU jurisdiction.

Deploy ASP.NET Core to sota.io in 3 Steps

Modern .NET apps ship as Docker containers. sota.io detects your .csproj and builds automatically:

Step 1: Install the CLI and deploy

curl -fsSL https://sota.io/install.sh | sh
cd MyWebApi
sota deploy

Step 2: Set environment variables

sota env set ASPNETCORE_ENVIRONMENT=Production
sota env set ASPNETCORE_URLS=http://+:8080

Step 3: Live

$ sota deploy

Packaging...           done
Detecting framework... .NET / ASP.NET Core
Building image...      done
Deploying...           done

> Live at https://my-web-api.sota.io

sota.io builds from your Dockerfile if present. For production .NET workloads, use a multi-stage build to keep the image lean:

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY *.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish

FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build /app/publish .
EXPOSE 8080
ENV ASPNETCORE_URLS=http://+:8080
ENTRYPOINT ["dotnet", "MyWebApi.dll"]

The SDK image handles dotnet restore and dotnet publish. The final image uses only the ASP.NET runtime — roughly 200 MB vs the 800 MB SDK image.

PostgreSQL with Entity Framework Core

sota.io provides managed PostgreSQL 17. Connection string injection is automatic:

# Only needed if you use a custom env var name
sota env set ConnectionStrings__DefaultConnection "$DATABASE_URL"

In Program.cs:

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection")
    ?? Environment.GetEnvironmentVariable("DATABASE_URL");

builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseNpgsql(connectionString));

Or use Npgsql directly without Entity Framework:

using Npgsql;

var dataSource = NpgsqlDataSource.Create(
    Environment.GetEnvironmentVariable("DATABASE_URL")!);

builder.Services.AddSingleton(dataSource);

Running Migrations on Startup

For EF Core migrations, run them at application startup inside your container:

// In Program.cs, after var app = builder.Build()
using (var scope = app.Services.CreateScope())
{
    var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
    db.Database.Migrate(); // Applies pending migrations
}

This is the recommended pattern for containerized deployments — migrations run automatically each time a new version is deployed.

GDPR & the EU .NET Stack

For .NET applications that handle EU personal data, the legal chain matters:

Layersota.ioAzure
Infrastructure operatorHetzner Cloud (German GmbH)Microsoft Corporation (US)
Data centerGermanyEU region designation (US processor)
GDPR Article 28 DPA✅ Available✅ Available (but US entity)
Schrems II risk✅ None (EU operator)⚠️ US entity, SCCs required
Azure German Cloud (T-Systems)N/A❌ Retired

The 2020 Schrems II ruling made clear that standard contractual clauses are insufficient when data is processed by US companies subject to FISA Section 702 and Executive Order 12333. For healthcare, financial, and public-sector .NET applications in the EU, this is a material legal risk.

Comparison: sota.io vs Azure App Service vs Railway

Featuresota.ioAzure App ServiceRailway
EU data residency✅ Germany (Hetzner)⚠️ EU region, US processor⚠️ EU opt-in, US company
Managed PostgreSQL✅ IncludedAzure Database for PostgreSQL (extra cost)Plugin (extra cost)
.NET support✅ Container-based✅ Native✅ Container-based
Windows Server❌ Linux only✅ Supported❌ Linux only
PricingFlat from €9/moVariable, compute + storage + egressVariable usage-based
DevOps requiredZeroMediumLow

Where Azure wins: Windows Server workloads, tight Azure Active Directory integration, .NET Framework (not Core) legacy apps, and full Azure ecosystem lock-in.

Where sota.io wins: EU data sovereignty, flat pricing, zero DevOps, GDPR-clear data residency for modern .NET Core applications.

Example: Minimal ASP.NET Core Web API

// Program.cs — minimal ASP.NET Core 8 API
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// PostgreSQL via Npgsql
var dataSource = NpgsqlDataSource.Create(
    builder.Configuration["DATABASE_URL"]!);
builder.Services.AddSingleton(dataSource);

var app = builder.Build();

app.MapGet("/health", () => Results.Ok(new { status = "ok" }));

app.MapGet("/users", async (NpgsqlDataSource db) =>
{
    await using var conn = await db.OpenConnectionAsync();
    await using var cmd = conn.CreateCommand();
    cmd.CommandText = "SELECT id, email FROM users LIMIT 20";
    await using var reader = await cmd.ExecuteReaderAsync();

    var users = new List<object>();
    while (await reader.ReadAsync())
        users.Add(new { id = reader.GetInt32(0), email = reader.GetString(1) });

    return Results.Ok(users);
});

app.Run();

Deploy this as-is — sota.io detects Program.cs, injects DATABASE_URL, and your API is live in under 60 seconds.

Who Is This For?

DACH enterprise teams building internal tools, APIs, or microservices in C# that must comply with German, Austrian, or Swiss data protection laws.

Healthcare and financial SaaS built on .NET that requires EU-only data processing for compliance.

Modernizing teams migrating from Windows Server + IIS to containerized ASP.NET Core, looking for a managed PaaS that doesn't lock them into Azure.

Indie .NET developers who want a simple, affordable EU host for their side projects and APIs.


sota.io is free to try — no credit card required.

curl -fsSL https://sota.io/install.sh | sh
sota deploy

See also: Deploy Node.js to Europe · Deploy Python to Europe · Railway Alternative