Accueil Nos publications Blog ASP.NET Core sur un environnement Linux

ASP.NET Core sur un environnement Linux

ASP.NET logoDans ce billet, je souhaite aborder l’usage d’ASP.NET Core sur Linux, à la fois pour le développement d’un projet (configuration de l’environnement) que pour l’hébergement d’une application.

Ce billet est basé sur la version RC1 des outils d’ASP.NET Core. Il est probable que les APIs, notamment les utilitaires en lignes de commande, évoluent légèrement d’ici à la sortie de la version finale du produit.

Notez également que, dans ce billet, je me suis basé sur Ubuntu 14.04. A l’heure où j’écris ces lignes, c’est la seule distribution Linux réellement supportée par ASP.NET Core.

Configuration basique de l’environnement

Installation de DNVM

Pour commencer à configurer et faire fonctionner une première application ASP.NET Core sur Linux, la première étape consiste à installer le gestionnaire de runtimes, qui nous permettra par la suite d’installer une version spécifique du runtime et finalement d’exécuter nos applications.

Sous Windows, ce gestionnaire de runtimes se présente sous la simple forme d’un script powershell. Sous Linux, il s’agit d’un script dnvm.sh qu’il suffit de télécharger. Cette installation se fait au travers d’un autre script (dnvminstall.sh). Néanmoins, l’utilisation de ce dernier script nécessite des pré-requis : les utilitaires unzip (utilisé par le script dnvminstall.sh) et curl (utilisé dans la commande ci-dessous et par le script dnvminstall.sh).

Exécutez les deux commandes ci-dessous pour obtenir la commande dnvm fonctionnelle.

sudo apt-get install unzip curl

curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh

A présent, la commande DNVM est utilisable. Faîtes le test, tapez simplement dnvm dans l’invite de commande et le résultat suivant s’affiche. Néanmoins, notez qu’avec la commande précédente, le script dnvm.sh n’est installé que pour l’utilisateur courant.

    ___  _  ___   ____  ___
   / _ \/ |/ / | / /  |/  /
  / // /    /| |/ / /|_/ /
 /____/_/|_/ |___/_/  /_/

.NET Version Manager - Version 1.0.0-rc2-15546
By Microsoft Open Technologies, Inc.

DNVM can be used to download versions of the .NET Execution Environment and manage which version you are using.
You can control the URL of the stable and unstable channel by setting the DNX_FEED and DNX_UNSTABLE_FEED variables.

Current feed settings:
Default Stable: https://www.nuget.org/api/v2
Default Unstable: https://www.myget.org/F/aspnetvnext/api/v2
Current Stable Override: <none>
Current Unstable Override: <none>

Use dnvm [help|-h|-help|--help]  to display help text.

Installation de DNX

sudo apt-get install libunwind8 gettext libssl-dev libcurl4-openssl-dev zlib1g libicu-dev uuid-dev

Une fois ces dépendances installées, il est possible d’utiliser la commande DNVM pour installer une version du runtime. Par exemple, l’instruction dnvm upgrade -r coreclr va automatiquement récupérer la dernière version du runtime adaptée à .NET Core. Néanmoins, je vous conseille d’utiliser la variante ci-dessous qui vous permet de spécifier explicitement la version du runtime que vous souhaitez installer.

dnvm install 1.0.0-rc1-update1 -r coreclr

Attention, le switch -r coreclr est nécessaire pour préciser que le runtime .NET Core doit être installé. Sans ce switch, c’est le runtime Mono qui serait installé. Or, pour que ce dernier fonctionne, Mono doit également être installé sur le serveur. Dans le développement de vos projets, le support de .NET Core plutôt que Mono est plus intéressant, puisqu’il est développé et supporté directement par Microsoft. De plus, votre application qui cible .NET Core peut s’exécuter facilement et sans modification aussi bien sous Linux que sur Windows.

Notez également que le runtime CoreCLR pour Linux n’est actuellement disponible qu’en version 64 bits. L’utilisation du switch -a x86 se terminera donc automatiquement sur une erreur vous demandant de privilégier l’utilisation du 64 bits.

Installation de libuv

La libuv est utilisée par le serveur HTTP Kestrel. Ce dernier est actuellement l’unique serveur HTTP utilisable dans une application ASP.NET Core sous Linux.

La suite d’instruction suivante va télécharger les sources de la librairie, la compiler et enfin la placer dans le chargeur de bibliothèques dynamiques du système (dlopen).

sudo apt-get install make automake libtool curl
curl -sSL https://github.com/libuv/libuv/archive/v1.8.0.tar.gz | sudo tar zxfv - -C /usr/local/src
cd /usr/local/src/libuv-1.8.0
sudo sh autogen.sh
sudo ./configure
sudo make
sudo make install
sudo rm -rf /usr/local/src/libuv-1.8.0 && cd ~/
sudo ldconfig

Attention ! L’installation de libuv est une étape obligatoire pour faire fonctionner une application ASP.NET Core sous Linux. Sans ça, il sera impossible de démarrer l’application.

Démarrage d’un premier projet

Pour la suite du billet, vous devez disposer d’une application ASP.NET Core sur votre machine Linux. Vous pouvez utiliser au choix Yeoman (qui peut être installé au travers de NPM) pour générer un nouveau projet, ou alors transférer les sources d’une application existante et développée sur un autre environnement (ex. votre poste Windows avec Visual Studio).

Une fois libuv installée, placez-vous dans le répertoire de l’application. Un appel à dnu restore restaurera automatiquement et de manière récursive les différentes dépendances exprimées dans votre fichier project.json.

Puis l’instruction dnx web va démarrer votre application et Kestrel va écouter sur le port pour lequel il est configuré (5000) par défaut.

Déploiement et hébergement d’une solution

Pourquoi utiliser un reverse proxy ?

Votre application ASP.NET Core porte son propre serveur HTTP (Kestrel). Néanmoins, il est peu commun d’exposer un serveur HTTP seul au grand public. En terme d’architecture de production, on préfèrera plutôt placer un reverse proxy devant le serveur HTTP et exposer ce reverse proxy au grand public.

L’intérêt du reverse proxy est alors de prendre en charge tout ce qui n’est pas lié à l’exécution d’un bout de code dynamique. Par exemple, service des fichiers statiques, compresser les réponses HTTP, assurer la prise en charge de SSL, etc.

Installation de Nginx

L’installation de Nginx se fait de manière très classique, comme n’importe quelle autre application.

sudo apt-get install nginx

Une fois installé, Nginx est présent sous la forme d’un service. Vous avez alors la possibilité soit de redémarrer la machine, soit de démarrer manuellement le service.

sudo service nginx start

Configuration de Nginx

La configuration des sites exposés par Nginx se fait en éditant le fichier à l’emplacement /etc/nginx/sites-available/default. Dans mon exemple, j’ai fait le choix de rediriger le trafic du site sur le port 80 vers le port 5000. J’ajoute au passage différentes en-têtes à la requête HTTP afin de faire le forward a Kestrel. Notez que l’en-tête Connection doit absolument être présente, sans quoi les réponses ne seraient pas retournées par Kestrel.

 server {
     listen 80;
     location / {
         proxy_pass https://localhost:5000;
         proxy_http_version 1.1;
         proxy_set_header Upgrade $http_upgrade;
         proxy_set_header Connection keep-alive;
         proxy_set_header Host $host;
         proxy_cache_bypass $http_upgrade;
     }
 }

Une seconde approche, plus performante et plus proche des scénarios appliqués avec d’autres technologies web sur Linux, consiste à utiliser des sockets Unix pour faire communiquer le reverse proxy et le serveur HTTP.

Les sockets Unix sont une autre forme de communication inter-processus. Le fonctionnement est très simple, le serveur HTTP n’est plus configuré par rapport à un port TCP mais par rapport à un chemin vers un fichier. Au démarrage de l’application, le serveur HTTP va créer ce fichier puis le monitorer. Nginx de son côté va simplement écrire dans ce fichier à chaque fois qu’une requête entrante doit être transmise au serveur HTTP.

En termes de configuration, les changements à apporter sont très simples. Il suffit d’indiquer à Nginx le chemin du fichier à utiliser comme socket (via la propriété proxy_pass).

 server {
     listen 80;
     location / {
         proxy_pass https://unix:/var/aspnet/nerddinner/kestrel.sock;
         proxy_http_version 1.1;
         proxy_set_header Upgrade $http_upgrade;
         proxy_set_header Connection keep-alive;
         proxy_set_header Host $host;
         proxy_cache_bypass $http_upgrade;
     }
 }

Puis, il faut également modifier le nœud commands du fichier project.json de l’application ASP.NET Core. En effet, jusqu’à présent, je me reposais sur le port utilisé par défaut par Kestrel (5000). Cependant, je souhaite à présent que Kestrel utilise le même socket unix que celui configuré auprès de Nginx. L’option server.urls permet de surcharger facilement la configuration de Kestrel.

"commands": {
    "web": "Microsoft.AspNet.Server.Kestrel --server.urls https://unix:/var/aspnet/nerddinner/kestrel.sock",
}

Gestion de l’application

Il y a une différence de taille entre le fonctionnement d’une application ASP.NET Core avec IIS et celui d’une application ASP.NET Core avec Nginx.
En effet, dans le premier cas, IIS va encapsuler la création du processus DNX et donc de l’application. Avec Nginx, l’approche est différente, le reverse proxy va se contenter de transférer du trafic HTTP vers un socket TCP ou UNIX selon votre configuration. En aucun cas Nginx n’est responsable de l’instanciation du processus de l’application ASP.NET Core.

L’application supervisor permet de gérer l’instanciation, et éventuellement la réinstanciation automatique de notre application en cas de crash.

Elle s’installe au travers de la commande ci-dessous.

sudo apt-get install supervisor

Puis, le contenu suivant est à placer dans un fichier /etc/supervisor/conf.d/nerddinner.conf.

[program:nerddinner]
command=bash /var/aspnet/nerddinner/approot/web
autostart=true
autorestart=true
stderr_logfile=/var/log/nerddinner.err.log
stdout_logfile=/var/log/nerddinner.out.log
environment=ASPNET_ENV=Production
user=www-data
stopsignal=INT

Il ne vous reste plus qu’à redémarrer votre machine ou le service supervisor pour que votre application ASP.NET Core soit démarrée par le superviseur.