• Overview
    • Django
    • Next.js
    • Drupal
    • WordPress
    • Symfony
    • Magento
    • See all frameworks
    • Observability
    • Auto-scaling
    • Marketing Teams
    • Retail
    • Higher Education
  • Pricing
  • Featured articles
    • Switching to Platform.sh can help IT/DevOps organizations drive 219% ROI
    • Organizations, the ultimate way to manage your users and projects
  • Support
  • Docs
  • Contact
  • Login
  • Free Trial
Perpetually polyglot: .NET on Platform.sh

Perpetually polyglot: .NET on Platform.sh

October 10, 2019
Chad Carlson
Chad Carlson
Manager, Developer Relations

At Platform.sh, we understand that modern web development isn’t restricted to just PHP or Node.js. It’s not a one language game out there; it’s a diverse ecosystem of languages and frameworks. We support eight different runtime languages out of the box, so that you have the tools you need to solve the problems those languages are best suited for.

This week, we're excited to announce yet another runtime added to that lineup of supported languages: C#/.NET.

How would you deploy a .NET application on Platform.sh?

.NET applications need only slight modifications to run on Platform.sh. As a simple example, you can deploy a common "Getting Started" tutorial for the popular ASP.NET web framework. In this post, we'll push the default ASP.NET MVC application built with the command dotnet new mvc -o PlatformAspNetCore described in that tutorial using the dotnet utility. You can find more detailed information about this process on the Platform.sh Community tutorial here.

Like any other application, .NET apps require at least three configuration files to run on Platform.sh. The first two files need to sit in a new .platform subdirectory of your project. You won't need any services for this example, so you can create an empty services.yaml file in that subdirectory (it can be empty, but it must exist in your repository in order to deploy).

Then create a simple routes.yaml file there, too:

# .platform/routes.yaml

    type: upstream
    upstream: "app:http"

    type: redirect
    to: "https://www.{default}/"

The routes.yaml file defines how requests will be directed to our application, which will be named app, including redirects.

Next, you’ll need a .platform.app.yaml file in the project root, which tells Platform.sh how to handle builds, deploys, and what version of .NET Core will be used on Platform.sh.

# .platform.app.yaml

name: app

type: dotnet:2.2

disk: 512

  build: |
    set -e
    dotnet publish --output "$PLATFORM_OUTPUT_DIR" -p:UseRazorBuildServer=false -p:UseSharedCompilation=false

    start: 'dotnet PlatformshAspNetCore.dll'

In this file, the application is named app, which matches the name in the routes.yaml file. It specifies the .NET Core version (2.2) and the amount of persistent disk given to the application (512 MB).

For simple applications like this, using the dotnet publish default framework-dependent deployment method in the build hook is sufficient to build in our .NET containers. Pass to that command the final output directory of the application (PLATFORM_OUTPUT_DIR, the environment variable for the general output directory for compiled languages at build time). Make sure to also pass the two additional flags that disable compilers which would normally start a collection of build servers, but are inadvisable in the Platform.sh build process.

The final start command (web.commands.start) launches the application using the dotnet utility directly, calling the built application PlatformshAspNetCore.

So this app is ready push to Platform.sh?

Almost. The entry point file Program.cs has to be modified slightly to receive a few environment variables defined in every Platform.sh project. Modify the Main method to pass the PORT and SOCKET environment variables as options to the Kestrel web server:

// Program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace PlatformshAspNetCore
    public class Program
        public static void Main(string[] args)
            var builder = CreateWebHostBuilder(args);

            builder.UseKestrel(options =>
                var port = Environment.GetEnvironmentVariable("PORT");
                if (port != null && Int16.TryParse(port, out var portNum))

                var socket = Environment.GetEnvironmentVariable("SOCKET");
                if (socket != null)


        private static IWebHostBuilder CreateWebHostBuilder(string[] args) =>

That's it! Now the application is complete. Commit, push, and deploy!

There's no reason to stop here, though. Any of our managed services can be configured for .NET applications. Want to use a MariaDB database? Create a DbContext, pass it credentials from the PLATFORM_RELATIONSHIPS environment variable, and add the database to your services.yaml file. There's a Platform.sh template ready to show you how. Using a different version of .NET? Check the documentation, and see our supported versions.

Another language, ready to go on your polyglot PaaS!

Relevant links

Platform.sh .NET documentation

ASP.NET Core template

ASP.NET MVC Tutorial on Platform.sh Community

Get the latest Platform.sh news and resources

Related Content

Infrastructure metrics expanded to longer time frames

Infrastructure metrics expanded to longer time frames

AboutSecurity and complianceTrust CenterBoard and investorsCareersPressContact us
Leader Winter 2023
System StatusPrivacyTerms of ServiceImpressumWCAG ComplianceManage your cookie preferencesReport a security issue
© 2023 Platform.sh. All rights reserved.
Supported by Horizon 2020's SME Instrument - European Commission 🇪🇺