J'ai migré mon blog chez Clever Cloud

J'ai découvert il y a peu le service d'hébergement cloud français Clever Cloud, quelques jours après avoir lu l'article de Guillaume Champeau sur la souveraineté numérique.

J'ai eu l'occasion de déployer des projets professionnels sur Microsoft Azure, Amazon AWS, ainsi que sur du Windows Server. Mon blog était hébergé sur Azure car je voulais un service managé : je ne veux pas perdre de temps à gérer le serveur ; et ça limite les options.

Donc en voyant un service français qui promettait un déploiement facile de mes applis .NET, je me suis empressé de tester. Après une découverte un peu déroutante, et un changement de quelques habitudes, mon blog est maintenant hébergé à Paris.

Voici mes quelques petits retours, à l'usage des développeurs .NET

Le service

Le principe est simple : Clever Cloud nous fournit des machines virtuelles pour héberger nos applications. On pousse notre code, on configure nos nom de domaines, le type de VM et le nombre d'instances, et on les laisse gérer le reste.
La montée en charge est aussi gérée automatiquement, en définissant le nombre minimal est maximal d'instances, et la taille minimale et maximale de chaque VM.

Le moteur interne semble être du Kubernetes [Update] J'ai pu discuter avec un ingénieur de Clever Cloud qui m'a indiqué que l'orchestration est un outil maison, optimisé pour la sécurité et les performances.

Tout ça tourne sous Linux, comme vous vous en doutez sûrement, pas question donc de faire tourner des applications sous le vieux .NET Framework. Ici, uniquement du .NET Core ou .NET 5.

Ensuite, tout se configure à l'aide de variable d'environnement, autant les options de déploiement que les paramètres de notre application.

Déploiement d'une application

Le déploiement se fait directement depuis le dépôt Git de l'application. Pas question ici de pousser vos dll depuis Azure Devops Pipelines, c'est Clever Cloud qui fera le dotnet publish directement.

C'est assez déroutant pour quelqu'un comme moi qui aime bien customiser son déploiement, puisqu'il faut uniquement définir le dossier de l'application (avec la variable d'environnement' APP_FOLDER) et espérer que le dotnet publish fonctionnera bien.

Il est néanmoins possible de se brancher sur différents Hooks, pour exécuter des tâches avant ou après la compilation ; donc en théorie rien n'empêche de créer ses propres scripts pour faire tout ce dont on a besoin.

HTTPS

J'ai été surpris de ne pas trouver d'option pour activer HTTPS, mais en fait elle n'est pas nécessaire puisque tous les domaines ajoutés sont automatiquement protégés par Let's Encrypt.
Configurez le domaine dans la console Clever Cloud, faites pointer vos DNS, et attendez quelques minutes : c'est tout bon.

Il est aussi possible d'utiliser vos propres certificats si vous préférez, il faudra passer par l'API pour l'installer.

Les Addons

Étant donné qu'une application se limite rarement à du code qui s'exécute dans un container, nous avons ici ce qu'ils appellent des Addons : différent services managés à brancher à notre application : stockage de fichiers, bases de données, Redis ou Elastic Search.

Une fois lié à notre application, les informations de connexion sont automatiquement ajoutées en tant que variable d'environnement, pour pouvoir s'y connecter directement.

Stockage

Pour le stockage de fichier, le service proposé se nomme Cellar, et est compatible avec l'api de AWS S3. Il suffit donc d'utiliser le package Nuget AWSSDK.S3, pour s'y connecter de la manière suivante :

    private AmazonS3Client GetS3Client()
    {
        var host = "https://" + configuration["CELLAR_ADDON_HOST"];
        var s3config = new AmazonS3Config
        {
            ServiceURL = host
        };

        var accesskey = configuration["CELLAR_ADDON_KEY_ID"];
        var secretkey = configuration["CELLAR_ADDON_KEY_SECRET"];
        var credentials = new BasicAWSCredentials(accesskey, secretkey);

        var client = new AmazonS3Client(credentials, s3config);
        return client;
    }

Il est aussi possible de monter un dossier cloud en tant que dossier dans notre VM avec l'add-on File System Bucket. Mais à moins de vouloir déployer une application qui utilise déjà le file system, il est recommandé de préférer Cellar : moins cher, et mieux adapté à la montée en charge.

Bases de données

Concernant l'utilisation des bases de données, rien de compliqué : on ajoute l'addon, et on s'y connecte depuis notre application avec les identifiants générés.

Pour une base relationnelle, on a le choix entre MySQL et PostgreSQL. Pas de MS SQL Server ici, et ça sera certainement le plus gros frein à la migration d'applications .NET existantes, étant donné la popularité du serveur dans le monde du développement Microsoft.

Entity Framework Core est cependant parfaitement compatible avec ces deux SGBD, rien de bloquant donc si on démarre de nouveaux développements.

Nous avons aussi d'autres addons tels que MongoDB pour les amateurs de noSQL, ou Redis, qui sera vite indispensable si vous souhaitez par exemple utiliser SignalR dans vos applications cloud.

Conclusion

Après quelques jours d'utilisation sur mes projets personnels, j'adore le service. C'est moins poussé que d'autres services de cloud beaucoup plus connus, mais l'essentiel est là, et je pense qu'il ne manque pas grand chose pour déployer dessus de gros projets.
Si la migration de projets existant sera probablement compliquée dans de nombreux cas, les services de base et la possibilité de déployer des images Docker devrait permettre de faire à peu près tout ce dont on a besoin si on démarre un projet avec tout ça en tête.

Héberger son serveur de cartes OpenStreetMap

Cet article est la seconde partie de ma série sur OpenStreetMap :

Dans mon précédent article, j'ai montré comment on pouvait afficher des cartes grâce aux données d'OpenStreetMap. Mais même si ça a l'avantage indéniable de permettre de se passer de Google, on doit toujours passer par un service externe.
Nous allons voir maintenant comment nous pouvons héberger nous-même nos cartes, afin de supprimer cette dépendance.

Installation du serveur de cartes

Il existe plusieurs de serveurs. Étant donné que je souhaite utiliser mes cartes en mode vectoriel, j'ai décidé d'utiliser un serveur OpenMapTiles PHP.

Il existe aussi une version du serveur en NodeJS (déployable avec Docker), ou si vous préférez rester sur la version la plus classique d'OpenStreetMap, vous pouvez aussi suivre cet article de Switch2OSM.

Pour déployer mon serveur, j'ai créé un App Service sur Azure, au niveau gratuit (il vous faudra certainement une machine plus puissante en prod), avec la stack PHP.

Ensuite, il faut installer le serveur PHP. Il suffit de récupérer la dernière version de tileserver-php sur Github, et de copier les 2 fichiers tileserver.php ainsi que le .htaccess dans l'App Service.

Mettez à jour le .htaccess pour configurer les en-têtes CORS - décommentez les lignes ci-dessous, et mettez à jour avec vos domaines autorisés :

# Option: CORS header for cross-domain origin access to all data
<ifModule mod_headers.c>
  Header set Access-Control-Allow-Origin *
</ifModule>

Vous pouvez maintenant copier les 2 fichiers tileserver.php et .htaccess dans l'App Service.
C'est bon votre serveur fonctionne, même s'il est encore un peu vide.

Téléchargement des données

En effet, maintenant que votre serveur tourne, il faut ajouter les données des cartes. Vous pouvez les télécharger sur le site d'OpenMapTiles.

Il s'agit d'un service payant qui fournit les données avec des mises à jour hebdomadaires, mais vous pouvez récupérer des données gratuitement pour des projets non-commerciaux/open-source, ou pour vos tests. Si vous ne souhaitez pas vous inscrire, vous pouvez télécharger directement la carte de Toulouse.

Mettez ce fichier .mbtiles dans le même dossier que tileserver.php, et cette fois le serveur est prêt à être utilisé.

Sélection d'un style

Jusque là, nous avons réussi à mettre en place le serveur, mais il va nous fournir uniquement les objects vectoriels pour afficher la carte, il va nous manquer le style, c'est à dire un fichier json qui va définir de quelle manière doivent s'afficher chaque type d'objet. Si vous vous souvenez de l'article précédent, c'est ce fichier là qui est référencé lors de l'initialisation de la carte avec la librairie Mapbox GL.

Nous n'allons pas rentrer dans les détails de la définition du style, nous allons nous pour le moment prendre l'un des styles existant proposés par OpenMapTiles. Histoire de changer un peu de ce dont on a l'habitude, j'ai choisi le style Positron, et je suis allé télécharger sa branche gh-pages sur Github.

Une fois téléchargé, il va falloir le modifier un peu avant qu'il ne soit utilisable.

Première chose, prenez le fichier style-cdn.json, que vous pouvez renommer en style.json, et cherchez les lignes suivantes :

"sources": {
  "openmaptiles": {
    "type": "vector",
    "url": "https://maps.tilehosting.com/data/v3.json?key=SymbVzXrAD6Jmqe6yBOS"
  }
},

Ici l'url correspond au serveur de tuiles. Il faut la remplacer par un lien vers l'API de notre serveur : https://maps-lacasa.azurewebsites.net/tileserver.php?/2017-07-03_france_toulouse.json (il s'agit du lien vers le fichier php, dont la requête prend en paramètre le nom du fichier de données, et avec l'extension json)

Ensuite, plus bas se trouve le lien vers les sprites (les 2 fichiers sprite.png et sprite.json qui sont fournis avec le thème) - remplacez le par le lien vers vos fichiers sprite, sans extension : https://maps-lacasa.azurewebsites.net/positron/sprite (ici j'ai déployé le style sur le même serveur pour des raisons pratiques, mais les styles peuvent être déployés ailleurs).

Dernier point à mettre à jour : les fonts utilisées pour l'écriture du texte. Cherchez toutes les occurences de "text-font" dans le style.json :

"text-font": [
  "Metropolis Medium Italic",
  "Noto Sans Italic"
],

Et modifiez les pour n'en garder qu'une à chaque fois (car selon la documentation, ce système d'hébergement statique ne gère pas les font alternatives). Vous pouvez choisir celle que vous préférez, ou en choisir une tout autre.

"text-font": [ "Metropolis Medium Italic" ],

Vous pouvez récupérer les fonts sur Github, dans un repo dédié, et les copier sur votre hébergement web.

Maintenant vous pouvez faire un lien vers ces fichiers dans le style.json, dans la propriété glyphs :

"glyphs": "https://maps.tilehosting.com/fonts/{fontstack}/{range}.pbf?key=SymbVzXrAD6Jmqe6yBOS",

Que vous pouvez remplacer par le chemin vers votre dossier de fonts, dans mon cas https://maps-lacasa.azurewebsites.net/fonts/{fontstack}/{range}.pbf. fontstack et range seront appelés dynamiquement selon le nom de la font défini dans le style, et le niveau de zoom affiché.

Et cette fois on est bon, tout est en place pour afficher notre carte sans aucun appel externe ; il suffit de remplacer dans notre javascript le lien vers le style par notre nouveau style modifié.

Afficher une carte grâce aux données OpenStreetMap

Cet article est la première partie de ma série sur OpenStreetMap :

Cette semaine est sorti le jeu Flight Simulator 2020, et certains joueurs se sont amusés de la présence d'un immense monolithe au nord de Melbourne.
Ce bug a pour origine une erreur dans le service cartographique OpenStreetMap (qui a entre-temps été corrigé), et cette anecdote m'a rappelé que ça faisait un moment que je voulais vous en parler.

OpenStreetMap, pour ceux qui ne connaissent pas, est ce qu'on pourrait appeler le « Wikipedia de la cartographie ». Il s'agit d'un service de cartographie libre, utlisable gratuitement, et pouvant être mis à jour par n'importe qui.
Vous pouvez donc tout à fait corriger la carte si vous voyez des erreurs dans votre voisinage, ou la compléter avec les noms de vos magasins préférés.

Je tiens un blog de développement web, donc je ne vais pas approfondir le sujet de la cartographie, bien que le sujet soit passionnant, mais nous allons plutôt voir comment nous pouvons utiliser les données d'OpenStreetMap pour afficher une carte sur nos applications web, à la place de Google Maps qui est un peu trop souvent utilisé sans se poser la question des alternatives.

Licence

Avant de commencer, on va voir rapidement la partie légale.

Les données brutes sont distribuées sous la licence libre Open Data Commons Open Database License (ODbL). Comme indiqué sur la page copyright d'OpenStreetMap, vous pouvez utiliser les données dans vos applications, à condition de créditer les contributeurs d'OpenStreetMap, et de redistribuer les données sous la même licence.
Lorsqu'on veut afficher la carte, on va utiliser les tuiles (les images des cartes, générées à partir des données brutes). Ces images sont sous licence Creative Commons CC-BY-SA 2.0 - les conditions d'utilisation sont globalement les mêmes que pour les données brutes : n'oubliez pas de mettre le copyright.

Affichage d'une carte avec Leaflet

Pour afficher une carte dynamique dans une page web, il va tout d'abord falloir choisir un serveur de tuile, le serveur qui nous fournira les fonds de carte.
La fondation OpenStreetMap n'a pas les moyens de financer des serveurs de tuiles utilisables librement par tout le monde, mais les données étant libres, de nombreux services proposent d'utiliser leurs serveurs - certains gratuitement pour des usages modérés, d'autres fournissant des services professionnels contre rémunération. Notez que vous pouvez aussi installer votre propre serveur de tuiles, si vous souhaitez être autonome.

Mon choix pour cet article s'est porté sur celui de l'association OpenStreetMap France.

On va maintenant utiliser une librairie JavaScript pour l'affichage. De nombreuses solutions existent, les plus utilisées sont OpenLayers et Leaflet ; j'utilise ce dernier dans cet exemple.

Pour afficher la carte, créer un div qui la contiendra, en lui précisant obligatoirement une taille.
Ensuite, vous pouvez initlialiser la carte, avec cet exemple de code :

<div id="mapDiv" style="width:800px; height: 400px;"></div>

<script>
    // Initialisation de la carte
    var map = L.map('mapDiv'); 

    // Initialisation des tuiles 
    var tileUrl = "https://a.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png";
    var copyright = '&copy; Contributeurs de <a href="https://www.openstreetmap.org/">OpenStreetMap</a>';
    L.tileLayer(tileUrl, {
        attribution: copyright,
        maxZoom: 18,
        tileSize: 512,
        zoomOffset: -1,
    }).addTo(map);
    
    // On zoome sur Toulouse
    map.setView([43.60, 1.44], 10); 
</script>

Ce qui nous donne le résultat suivant :


Vous pouvez ensuite afficher toutes sorte d'informations sur la carte ou intéragir avec l'utilisateur ; je vous laisse jete un œil à la documentation pour ça.

Affichage vectoriel avec OpenMapTiles

Les données brutes étant libres, il est possible d'afficher les cartes autrement qu'en chargeant des images d'un serveur de tuiles. C'est ce que fait le projet OpenMapTiles, en proposant un système de tuiles vectorielles.
Au lieu d'afficher des images, c'est le navigateur qui dessine les objets de la carte ; permettant ainsi un affichage plus fluide et des plus d'interactions possibles (essayer de bouger avec le clic droit dans l'exemple plus bas). C'est le choix qu'a fait Qwant pour son service de cartographie Qwant Maps.

Ceci a malheureusement un coût, puisque le navigateur de l'utilisateur est plus fortement mis à contribution, et peut poser des problèmes de performances sur des ordinateurs peu puissants ou certains mobiles.

Pour afficher une carte vectorielle, j'utilise cette fois les serveurs de MapTiler, et la librairie Mapbox GL JS. OpenLayers et Leaflet ne gèrent pas l'affichage vectoriel nativement, mais peuvent fonctionner avec des plugins.

Pour afficher la carte, l'API est un peu différente, mais le système reste le même, je vous laisse regarder le code :

<div id="mapDiv" style="width:800px; height: 400px;"></div>

<script>
    var map = new mapboxgl.Map({
        container: 'mapDiv',
        style: 'https://api.maptiler.com/maps/bright/style.json?key=apikey',
        center: [1.44, 43.60],
        zoom: 10
    });
</script>

Vous pouvez ainsi voir le résultat - et voir la différence avec la carte précédente :

Vous noterez que même si l'affichage est différent, les cartes sont les mêmes. Les rues, les bâtiments ne changent pas de l'un à l'autre, car la source des données est la même.

J'espère que je vous ai donné envie d'essayer ça, et que la prochaine fois que vous devrez afficher une carte dans l'un de vos projets vous étudierez l'option OpenStreetMap.