C# is going through a somewhat of a renaissance at the moment, largely driven by the release of the open source, cross platform version .NET Core.

We do a lot of C# development, and we can now write code that will run on:

  • Windows
  • Linux
  • macOS
  • iOS, tvOS, watchOS
  • Android
  • Unity, Hololens
  • Aws, Azure and Google Cloud

All from the same codebase :-)

We run a lot of our internal services on a dedicated Linux server, which up until now has contained lots of bespoke Ruby (mostly Rails) code. With C# now working perfectly on Linux, I am migrating some of the code over to C# (or F# like our phone system).

Ruby is great for quick prototyping, and some of the open-source services like Gitlab are amazing, but I do find dynamic langauges harder to maintain over time, than I do with static languages like C#.

We also use Docker on out Linux box to keep all the services seperated and easy to migrate to other hosts, so it makes sense to do the same for the C# & F# code.

The first thing to do is set up a docker-compose.yml definition of the service. This tells docker what image to use (the microsoft/dotnet core image), which port to open (we use Apache2 as a reverse proxy to terminate SSL), and where the files are on the disk.

In this example we are exposing the docker container on port 9993 (which is what Apache will proxy to), and it will link this to port 5000 in the container.

  restart: always
  image: microsoft/dotnet:2-sdk
    - ""
  entrypoint: /asp_site/dockerRun
  - /home/david/Phones/files:/asp_site

The next key step is to tell docker how to run the container. The docker compose file above tells docker that the dockerRun file is what should be run (the entrypoint setting).

That file looks like this:

#!/usr/bin/env bash

cd /asp_site/phonesNet
export ASPNETCORE_URLS=http://+:5000
dotnet restore
dotnet run --no-launch-profile

The key things to be aware of are:

  • Use of ASPNETCORE_ environmental variables to choose the URL, and which environment to use (and hence which appsettings.json file to use)
  • dotnet restore to download all required nuget packages (which will be cached after the first run)
  • --no-launch-profile when running the site. If you don't do this, the launch settings file from Visual Studio will be used, and the enviromental variables above ignored.

I've had great success with running .NET like this, but it did take me a while to setup correctly (especially the launch profile bit), so hopefully this helps other people running dotnet on Linux.

Viva La Renaissance !