CérénIT

Le blog tech de Nicolas Steinmetz (Time Series, IoT, Web, Ops, Data)

Web, Ops, IoT et Time Series - Mars 2022

pythonasgigitgrepdockerzipclidjangonumériquergpdprivacy shielddocker composedockerfilegoogle analyticsmatomofugueduckdbpandassql

Conteneur et Orchestration

  • Docker Engine 20.10.13 : Docker compose v2 arrive dans docker : ce qui permet de faire docker compose (au lieu de l’original docker-compose coté en python)
  • COPY --chmod reduced the size of my container image by 35% : pour réduire la taille de vos images, plutôt que de faire un ADD ... puis un RUN chmod ..., faites directement un ADD/COPY --chmod. Marche aussi avec --chown.
  • Docker Compose > depends > condition: ready : depends_on a une syntaxe longue qui permet de définir une condition sur l'état du service dépendant : démarré (valeur par défaut de la version courte), "sain" (en fonction du résultat d'un healthcheck) ou "terminé avec succès" (si votre service dépend du résultat d'un job ou d'une tâche).

Numérique

Open Data

  • adresse.data.gouv.fr : le site national des adresses dont l'objectif est de référencer l’intégralité des adresses du territoire et les rendre utilisables par tous.

Outils

  • GitUI : si vous trouvez tig pas très intuitif/pratique, GitUI pourrait vous plaire. Prévu pour le terminal, il permet de se ballader facilement dans votre historique git & co. L' outil en codé en Rust.
  • igrep : un grep interactif qui permet d'ouvrir le fichier dans un éditeur et d'aller directement à la ligne contenant le motif recherché. Basé sur l'excellent ripgrep.

Python

RGPD & Privacy Shield

Web, Ops, Data et Time Series - Avril 2021

falcosysdigsécuritégrafanadashboardraspberrypipicodockerdocker-composegrafanahashicorpvaultvectorcontainerdgitgit-filter-repokubernetespspgitlab-cipodmanwarp10sqliteterraformtimescalevelerodockerdocker-composegrafanalokitempokubernetesminioinfluxdatanotebookgeospatialagplbme680co2

Code

Conteneur et orchestration

  • Electro Monkeys - Docker Compose avec Nicolas de Loof : Retour sur la Developper Experience autour de Docker, l'historique et le futur de docker-compose, la création de la spécification Compose, les intégrations AWS/ECS et Azure/ACI, l'intégration Kubernetes, etc.
  • nerdctl: Docker-compatible CLI for contaiNERD : une CLI qui imite la CLI Docker mais en interagissant directement avec containerd. Elle permet aussi de bénéficier de certaines fonctionnalités de containerd qui ne sont pas prévues pour tout de suite dans Docker apparemment.
  • Blog: Kubernetes 1.21: Power to the Community : au programme de cette nouvelle version : Cronjobs GA, Immutable Secrets and ConfigMaps GA, IPv4/IPv6 dual-stack support, Graceful Node Shutdown, PersistentVolume Health Monitor mais aussi PodSecurityPolicy Deprecation et TopologyKeys Deprecation
  • PodSecurityPolicy Deprecation: Past, Present, and Future: article plus détaillé sur la dépréciation des PSP.
  • Podman v3.1.0 Released : ajout de la gestion des secrets, améliorations des commandes kube avec notamment la génération des PersistentVolumeClaim ou encore la gestion des propriétaires des volumes.
  • Velero 1.6.0 : améliorations diverses comme le support des identifiants par buckets (et non globaux uniquement), mise à jour de restic vers 0.12.0, etc.
  • Compose CLI Tech Preview : compose devrait devenir une sous-commande officiel de la CLI Docker ; on pourra alors faire docker compose up -d
  • Docker 20.10.6 : version de maintenance avec le support des puces Apple Silicon M1.
  • Kubernetes : vers 3 releases par an au lieu de 4 : de quoi courrir un peu moins derrière les versions et à relier avec le support de chaque version étendue à 1 an depuis la 1.19.

Data

  • sq: swiss-army knife for data : le jq pour les données relationelles. Du SQL ou des fichiers Excel/CSV/JOSN/XML en entrée et les mêmes formats en sortie (et un peu plus).
  • SQLite is not a toy database : On a souvent une fausse image de sqlite - l’article permet de se mettre à jour...

IaC

IoT

  • Pico 2 Pi Adapter Board : un petit adapteur sympathique pour Raspeberry Pi Pico et vous permettre de brancher facilement vos composants sans soudure et mener ainsi vos expériences.
  • Piper Make : Pour programmer facilement votre Raspberry Pi Pico en MicroPython mais avec une logique de blocs à la Scratch.
  • Utilisation des BME680 et RV3028 avec Raspberry Pi Pico : le composant BME680 permet d'évaluer la qualité de l'air - le projet permet donc de capturer et d'afficher cette information avec un Raspberry Pi. Son successeur, le BME688 dispose d'une pincée d'IA.
  • Projet CO2 et Makers CO2 : pour mieux comprendre les enjeux autour de l'aération des pièces et comment faire vos capteurs.

Observabilité & Monitoring

Réseau

  • The Mystery of AS8003 : Une entité inconnue jusque là mais liée à l'administration américaine a annoncé la gestion d'une très grande plage réseau. Les implications et les motivations sont encore à éclaircir. Le billet émet différents hypothèses. Le thread twitter associé est intéressant aussi.

Sécurité

Time Series

Web, Ops, Data et Time Series - Avril 2021

falcosysdigsécuritégrafanadashboardraspberrypipicodockerdocker-composegrafanahashicorpvaultvectorcontainerdgitgit-filter-repokubernetespspgitlab-cipodmanwarp10sqliteterraformtimescalevelerodockerdocker-composegrafanalokitempokubernetesminioinfluxdatanotebookgeospatialagplbme680co2

Code

Conteneur et orchestration

  • Electro Monkeys - Docker Compose avec Nicolas de Loof : Retour sur la Developper Experience autour de Docker, l'historique et le futur de docker-compose, la création de la spécification Compose, les intégrations AWS/ECS et Azure/ACI, l'intégration Kubernetes, etc.
  • nerdctl: Docker-compatible CLI for contaiNERD : une CLI qui imite la CLI Docker mais en interagissant directement avec containerd. Elle permet aussi de bénéficier de certaines fonctionnalités de containerd qui ne sont pas prévues pour tout de suite dans Docker apparemment.
  • Blog: Kubernetes 1.21: Power to the Community : au programme de cette nouvelle version : Cronjobs GA, Immutable Secrets and ConfigMaps GA, IPv4/IPv6 dual-stack support, Graceful Node Shutdown, PersistentVolume Health Monitor mais aussi PodSecurityPolicy Deprecation et TopologyKeys Deprecation
  • PodSecurityPolicy Deprecation: Past, Present, and Future: article plus détaillé sur la dépréciation des PSP.
  • Podman v3.1.0 Released : ajout de la gestion des secrets, améliorations des commandes kube avec notamment la génération des PersistentVolumeClaim ou encore la gestion des propriétaires des volumes.
  • Velero 1.6.0 : améliorations diverses comme le support des identifiants par buckets (et non globaux uniquement), mise à jour de restic vers 0.12.0, etc.
  • Compose CLI Tech Preview : compose devrait devenir une sous-commande officiel de la CLI Docker ; on pourra alors faire docker compose up -d
  • Docker 20.10.6 : version de maintenance avec le support des puces Apple Silicon M1.
  • Kubernetes : vers 3 releases par an au lieu de 4 : de quoi courrir un peu moins derrière les versions et à relier avec le support de chaque version étendue à 1 an depuis la 1.19.

Data

  • sq: swiss-army knife for data : le jq pour les données relationelles. Du SQL ou des fichiers Excel/CSV/JOSN/XML en entrée et les mêmes formats en sortie (et un peu plus).
  • SQLite is not a toy database : On a souvent une fausse image de sqlite - l’article permet de se mettre à jour...

IaC

IoT

  • Pico 2 Pi Adapter Board : un petit adapteur sympathique pour Raspeberry Pi Pico et vous permettre de brancher facilement vos composants sans soudure et mener ainsi vos expériences.
  • Piper Make : Pour programmer facilement votre Raspberry Pi Pico en MicroPython mais avec une logique de blocs à la Scratch.
  • Utilisation des BME680 et RV3028 avec Raspberry Pi Pico : le composant BME680 permet d'évaluer la qualité de l'air - le projet permet donc de capturer et d'afficher cette information avec un Raspberry Pi. Son successeur, le BME688 dispose d'une pincée d'IA.
  • Projet CO2 et Makers CO2 : pour mieux comprendre les enjeux autour de l'aération des pièces et comment faire vos capteurs.

Observabilité & Monitoring

Réseau

  • The Mystery of AS8003 : Une entité inconnue jusque là mais liée à l'administration américaine a annoncé la gestion d'une très grande plage réseau. Les implications et les motivations sont encore à éclaircir. Le billet émet différents hypothèses. Le thread twitter associé est intéressant aussi.

Sécurité

Time Series

Web, Ops & Data - Février 2021

javarepositoryartefacttimescalepostgreskapacitorgrafananomadhashicorppodmandocker-composeregistrydockergolangvscodewarp10dataviztransformationvectorlinter

Container et orchrestration

  • Running Nomad for home server : pour avoir mené une expérience très similaire sur le mois de janvier, je me retrouve complètement dans ce retour d'expérience sur nomad (vs kubernetes dans une certaine mesure). Le trio nomad/consul/vault permet de faire des choses assez proches de ce que l'on peut faire avec kubernetes et parfois même de façon plus simple. Et ce, avec moins de couches intermédiaires (CSI, CNI, etc) mais aussi quelques fonctionnalités en moins. Un compromis assez réussi je trouve entre un docker nu et/ou avec docker-compose et un kubernetes.
  • Podman 3.0 has been released! : support de docker-compose, support des noms courts d'image, amélioration sur le réseau, apport de la dernière version de buildah, correction d'une CVE, etc.
  • Donating Docker Distribution to the CNCF : Docker Inc donne sa registry à la fondation CNCF pour fédérer les initiatives autour d'un même standard et élargir le champ des contributeurs/mainteneurs.
  • Panorama des outils de sécurité autour des conteneurs : comparaison des outils de bonnes pratiques et d'analyses de vulnérabilités des containers docker pour améliorer la sécurité de vos conteneurs.

Code

Monitoring & observabilité

Time Series

Si vous êtes en manque de news, vous pouvez aller consulter (et vous abonner) aux brèves du BigData Hebdo

Web, Ops & Data - Janvier 2021

timeseriesprometheuspromqlovhcloudiotopenhabvectortimescaledbptsmanomalielabelmachine-learningiacansiblelibsshvectorlogwarp10influxdbopensshgpgpodmandocker-composesudo

Cloud

Code

  • GitLab release feature report : le code qui permet de générer le rapport ce qui a changé entre les versions de Gitlab.
  • SSH is the new GPG : les dernières versions d'OpenSSH permettent de signer un fichier. Une solution intermédiaire entre de la signature de fichiers à base de MD5 & co qui donnent des informations de conformité mais sans indiquer qui a signé le fichier et une solution GPG plus complexe à mettre en oeuvre ?

Container et orchestration

  • Using Podman and Docker Compose : podman, le "daemonless container engine" va permettre d'être utilisé avec docker-compose dans le cadre de la version 3.0. De quoi favoriser l'adoption de podman ?

Infra as code

  • New LibSSH Connection Plugin for Ansible Network Replaces Paramiko, Adds FIPS Mode Enablement : Ansible change de librairie pour les connexions ssh en remplaçant paramiko par libssh. Elle se veut plus performante et peut être requis dans un contexte demandant du FIPS. Pensez à installer le paquet libssh-dev(el) suivant votre distribution pour pouvoir installer ansible-pylibssh. Mes premiers essais ne notent pas une amélioration sensible des performances... à voir sur d'autres machines et dans la durée...

IoT

  • openHAB 3.0 Release et Release Notes : OpenHAB est une plateforme open source de gestion de périphétiques IoT et d'automatisation autour de ces périphériques. Elle est développée en Java, support 2000 "Things" (objets, équipements, protocoles). La version 3.0 apporte une refonte et l'unification de l'UI et des composants, le passage à Java 11 et plein d'autres choses. La migration depuis une version 2.x se fait assez simplement. Avec le nouveau moteur de règle, j'ai pu supprimer mon code spécifique. Reste encore la partie "Pages" à appréhender... J'avais préféré OpenHAB à Jeedom et Home Assistant
  • Meet Raspberry Silicon: Raspberry Pi Pico now on sale at $4 : la fondation Raspberry Pi se lance dans les micro-controlleurs avec le Pico au prix de 4$.
  • Raspberry Pi PICO la carte Microcontrôleur de la Fondation : un article très détaillé sur la prise en main du pico.

Observabilité

Système

Time Series

Web, Ops & Data - Avril 2020

traefikscalewaykubernetestelegrafcassandrakafkaconfluenthelminfluxdbwarp10timescaledbdocker-composeapache-pulsarpubsubdeprek8conftestoparaspberrypigitlabsidecar

Code et Outillage

Container & orchestration

(Big) Data

Time Series

Web

  • jQuery 3.5.0 Released! : une faille XSS a été identifiée sur jQuery.htmlFilter pour toutes les versions inférieures à 3.5.0 ; il est vivement encouragé de mettre à jour vos sites. Pour le reste, je vous renvoie à la lecture de l'article.

Web, Ops & Data - Novembre 2019

dockerdocker-composedocker-hubkubernetesregistryquayredhatscannersécuritéhelmk3spodjenkinspipelineredistimeseriesmachine-learningpredictionksqlkafka-streams

Rendez-vous le 17 décembre prochain à la troisième édition du Paris Time Series Meetup consacré à TSL (billet introductif à TSL : TSL: a developer-friendly Time Series query language for all our metrics) et le module RedisTimeSeries qui apporte des fonctionnalités et des structures Time Seriies à Redis.

Cloud

  • The RIPE NCC has run out of IPv4 Addresses : Le RIPE NCC vient d'annoncer avoir attribué son dernier bloc d'IP v4 en /22. La réserve d'IPv4 est donc épuisée mais pour autant cela ne veut pas dire que toutes les IPv4 sont utilisées. Par ailleurs le RIPE NCC précise que de nouveaux blocs devraient voir le jour au fur et à mesure que des organisations revendent des plages inutilisées ou cessent leur activité. Le mécanisme d'attribution se fera alors sous la forme d'une liste d'attente. Ce n'est donc pas l'IPcalypse même si on s'en rapproche de plus en plus et s'il faut prévoir de passer à IPV6 de plus en plus rapidement.

Container et Orchestration

  • Red Hat Introduces open source Project Quay container registry : De la même manière que RedHat publie l'upstream d'Ansible Tower avec le projet AWX, RedHat va fournir l'upstream de Quay (registry docker) et Clair (scanner vulnérabilités) sous le nom de Project Quay
  • Helm 3.0.0 has been released! : si tout le monde attendait la suppression de tiller, ce n'est pas la seule nouveauté. Le billet donne aussi plein de liens sur la migration vers helm 3, la politique de support de Helm 2 (bug & sécurité pour 6 mois et sécurité uniquement les 6 mois suivants), etc.
  • Mirantis acquires Docker Enterprise, Docker Restructures and Secures $35 Million to Advance Developer Workflows for Modern Applications et Docker’s Next Chapter: Advancing Developer Workflows for Modern Apps : Mirantis rachète la branche "Entreprise" de Docker Inc et les actifs associés (employés et propriété intellectuelle). Docker Inc va se focaliser sur l'expérience utilisateur (Docker Desktop, Docker-Compse, Docker-Apps, etc). Pour cela, en plus d'une restructuration du capital, ils ont sécurisé 35 millions de dollars. Il est quand même étonnant de voir qu'à court terme, en dehors de la vente à Mirantis, Docker Inc n'a plus de sources de revenus...
  • What Docker Inc’s Reorganization Means For Docker Swarm : Suite à l'annonce précédente, il est légitime de se demander ce que va devenir Swarm. Le produit est donc géré par Mirantis et ces derniers ont embauché la personne en charge de Swarm et lui ont apparemment donné des garanties de pérénité du projet. Il conviendra de rester prudent sur le sujet même si j'espère que le projet Swarm continuera à exister. En effet, il est bien pratique et léger dans beaucoup de cas qui ne requiert pas Kubernetes.
  • k3s 1.0 : k3s, la version allégée mais certifiée de k8s atteint la version 1.0. Très pratique pour faire du k8s sur des raspberry pi et assimilés.
  • KSS - Kubernetes pod status on steroid : un petit script python qui permet d'avoir un status d'un pod et de son/ses container(s)

Data

  • Introducing ksqlDB : Confluent, l'entreprise derrière Apache Kafka et la Confluent Platform sort une nouvelle version de ksql qui est renommé ksqlDB. ksql se voit donc ajouter un connecteur sql pour des enrichissements depuis des sources de données externes, ainsi qu'un système de requêtage dynamiques de topics Kafka pour le présenter sous la forme d'une base de données et prendre en compte les changements au fur et à mesure qu'ils arrivent. Ce n'est donc pas une base de données à proprement parler mais nommer les choses en informatique, c'est une chose compliquée...

Outillage

  • Welcome to the Matrix : Le plugin Declarative Pipeline se dote d'une propriété matrix qui va permettre de faire la même action avec des configurations différentes plutôt que d'avoir un jenkinsfile pour chaque option/déclinaison du job. Le parallelisme semble supporté par défaut et un système d'inclusion/exclusion permet de mieux définir la combinaison des possibles. Dans l'exemple donné qui croise des systèmes d'exploitation et des navigateurs, cela permet par ex de ne pas lancer le job utilisant Micrsoft Edge sous Linux (même si...).

Tech

Time Series

Web, Ops & Data - Juin 2018

mysqlrediskubernetesawsterraformhashicorpcdcdebeziumkafkaazureelasticsearchksqlkapacitordockerdocker-composedocker-appbuildkithashicorpconsulservice-meshistio

Big Data, Machine Learning & co

Cloud

Container & Orchestration

  • Making Compose Easier to Use with Application Packages : Docker Inc. sort un nouveau produit appelé "docker-app". Il se veut comme une surcouche à docker-compose en permettant d'injecter des variables dans vos fichiers docker-compose.yml. Ainsi, vous n'auriez plus qu'un seul fichier docker-compose avec ses variables et les valeurs de ses variables dans des fichiers additionnels. Lors de l'exécution du container, docker-app réconcilie les deux et lance le conteneur avec les bonnes valeurs. Docker Swarm et Kubernetes seraient supportés si l'on en croit les exemples. Rigolo, sur le principe, c'est exactement ce que je fais pour une mission actuellement...
  • Découverte de Buildkit : dans le cadre du découpage de Docker en programme modulaire indépendant, Moby avait lancé Buildkit. Il s'agit du builder d'images. L'article présente son fonctionnement et son architecture.
  • HashiCorp Consul 1.2: Service Mesh : Hashicorp sort en beta son offre de service mesh basé sur Consul. Après le "Service Discovery" et le "Service Configuration", voilà le Service Mesh. A voir dans la vraie vie mais on retrouve apparemment pas mal de fonctionnalités disponibles dans Istio.

(No)SQL

  • Vitess : J'en avais entendu parler, j'ai profité d'un épisode de Software Engineering Daily pour en savoir un petit peu plus : Je ne suis pas encore au bout du podcast mais cela semble être une couche entre l’application et la DB - elle analyse la requête et la distribue ensuite au sein du cluster. Vitess permettrait notamment que le développeur n’ait pas à connaitre la logique de clustering/sharding des données. L’overhead n’a pas encore été mentionné.
  • Redis 5.0 RC1 : la version 5.0 de Redis pointe le bout de son nez avec notamment le type de donnée Stream - cf Introduction to redis streams
  • Streaming Data out of the Monolith: Building a Highly Reliable CDC Stack : un CDC, Change Data Capture, est un système qui capture les changements de données (INSERT, UPDATE, DELETE) d'une source de données. BlaBlaCar explique ici comment ils ont mis en place leur CDC sur la base de Debezium et Kafka. Un des défis à relever étant la gestion de la déduplication des données.
  • Elasticsearch 6.3.0 Released : plein de nouveautés mais la plus symoblique étant un début de support d'un requêtage SQL dans Elasticsearch.

Sécurité

  • Attacking Private Networks from the Internet with DNS Rebinding : TL;DR Following the wrong link could allow remote attackers to control your WiFi router, Google Home, Roku, Sonos speakers, home thermostats and more. il est donc possible d'abuser un navigateur via un DNS malicieux et donc être en mesure de scanner le réseau local de la personne abusée. Il faut donc considérer le réseau local comme une zone hostile et y appliquer les bonnes pratiques habituelles (authentification, urls en https, etc)

Timeseries

Astuce(s) du mois

Faîtes-vous plaisir et écouter le podcast Artisan Développeur - dans des formats de 10mn environ, un sujet autour de l'agilité, des tests, du TDD, de la responsabilité des développeurs, de SaFE, et de tout ce qui fait partie de notre quotidien de développeurs sont abordés. Depuis quelques épisodes, cela se fait en duo avec d'autres personnes (comme JP Lambert) ce qui rend les échanges encore plus intéressants. Vous retrouvez le podcast sur Soundcloud, Pocketcasts, etc.

Web, Ops & Data - Février 2018

grafanadockerdocker-composekafkagraphqlswarmgithttpscertificatsécuritéinspec

API, Rest, GraphQL

  • GraphQL at the REST-aurant : une introduction à GraphQL et à ses avantages par rapport à un modèle REST en faisant une analogie avec un REST-aurant. J'ai découvert les "persisted queries".

Container & orchestration

  • Going Production with Docker and Swarm : une présentation repassant les bonnes et mauvaises pratiques de Docker et Docker Swarm, les outils disponibles, des éléments de sizing de cluster swarm, etc. Globalement en phase avec ce que je pratique chez un client actuellement. Prochaine étape, ne plus utiliser "latest" comme référence d'images !

Dataviz

  • What’s New in Grafana v5.0 : Grosse refonte de Grafana pour l'arrivée de cette version 5.0 : nouveau système de dashboard, gestion des permissions, gestion de groupes, gestion de dossiers, nouvelle UX, etc.

Git

  • --force considered harmful; understanding git's --force-with-lease : Si l'usage de git --force est déconseillée si ce n'est proscrite, sa variante git --force-with-lease est plus intéressante et permet d'éviter d'écraser le travail de vos camarades alors que vous pensiez juste faire un push en force sur une branche distante suite à un rebase local.
  • Advantages of monolithic version control : le débat mono-dépot vs multi-dépots est récurrent - celui- ci donne des raisons pro mono dépôt. Au delà du mono/multi dépôt, c'est surtout l'architecture d'une application et sa modularité qui sont prépondérants.

Kafka

Sécurité & Compliance

  • La fin d’une époque… : si vous utilisez des certificats issues de chez Thawte, GeoTrust et RapidSSL ayant été générés avant le 1er juin 2016 pour la 1er vague ou avant le 1er décembre 2017 (date de rachat de l'autorité de Symantec par Digicert), alors vos sites risquent d'être bloqués par les version de printemps et d'automne de Firefox et Chrome. Il vous faut renouveller vos certificats. Si votre certificat a été généré après le 1er Décembre 2017, vous n'avez rien à faire.
  • Chef InSpec 2.0 Puts the Security into DevSecOps : la spécification InSpec permet de définir/tester/valider l'état d'une machine au regard de règles de conformité et de sécurité. Cette spécification a été initiée par l'entreprise Chef (éditrice du logiciel du même nom et d'Habitat entre autres). La version 2.0 vient de sortir et apporte une intégration AWS/Azure, de nouvelles ressources de validation (docker, configuration serveurs web, clés & certificats, etc) et une amélioration des performances.

Astuce(s) du mois

Lorsque l'on déploie une même application dans plusieurs contextes via docker-compose, il est intéressant d'utiliser le COMPOSE_PROJECT_NAME qui permet de donner un préfixe à vos réseaux et containers docker a minima.

L'inconvénient est qu'il faut ajouter à vos commandes un -p <project_name> :

docker-compose -p instancea build --pull
docker-compose -p instancea up -d
docker-compose -p instancea logs -f
docker-compose -p instancea stop <service>
docker-compose -p instancea down
...

Ainsi, vos conteneurs seront nommés instancea_<service name>_<occurence> et votre réseau instancea_<network name>.

Mais il est possible d'aller plus loin avec les fichiers d'environnement .env.

Dans votre fichier .env à la racine de votre dossier où se trouve votre fichier docker-compose.yml, définissez la/les variable(s) dont vous avez besoin. Ici, nous allons nous limiter à COMPOSE_PROJET_NAME mais ne vous privez pas.

COMPOSE_PROJECT_NAME=instancea

A partir de ce moment-là, plus besoin de précier l'argument -p <project name>, vos commandes redeviennent :

docker-compose build --pull
docker-compose up -d
docker-compose logs -f
docker-compose stop <service>
docker-compose down
...

... et pour autant, vos réseaux et containers ont le bon préfix car le fichier .env est lu à l'exécution de la commande docker-compose avant de parser docker-compose.yml.

On peut aller encore plus loin en utilisant ce COMPOSE_PROJECT_NAME dans le taggage des images d'un container par ex ou

version: '3'
services:
  nginx:
    build:
      context: ./nginx/
    image: "registry.mycompany.com/nginx:${COMPOSE_PROJECT_NAME}"

Lors de la phase de build, l'image sera tagguée avec le nom passé au projet compose. Ensuite, vous pouvez poussez sur la registry de votre entreprise puis déployer cette version sur votre cluster Swarm par ex.

A noter justement une limitation actuelle de docker stack deploy <stack name> -c docker-compose.yml qui ne lit pas le fichier .env en amont et donc COMPOSE_PROJECT_NAME reste vide lors de la lecture du fichier docker-compose.yml.

Une solution possible est par ex dans le script (simplifié) de déploiement :

cd $BUILDDIR/compose/
source .env

# Remplace la variable COMPOSE_PROJECT_NAME par sa valeur
sed -i -e "s/\${COMPOSE_PROJECT_NAME}/${COMPOSE_PROJECT_NAME}/g" docker-compose.yml

docker stack deploy ${COMPOSE_PROJECT_NAME} -c docker-compose.yml

Et voilà !

Grav, Docker-Compose et Traefik

dockerdocker-composetraefikgrav

Pour un projet en cours de finalisation, j'ai utilisé le CMS Grav et j'ai décidé tant pour mon développement en local que pour l'environnement de production de déployer cela sous la forme de container docker et d'utiliser Traefik comme reverse-proxy et m'appuyer notamment sur son support natif et dynamique des containers docker.

Premiers pas...

J'avais initialement publié une image nsteinmetz/grav basée sur l'image officielle PHP:apache mais elle ne me convenait pas totalement :

  • Utilisation d'apache2 alors que j'ai basculé depuis longtemps sur nginx
  • L'image PHP:apache est basée sur Debian (taille plus importante qu'une image basée sur Alpine)
  • Pas d'utilisation des volumes (je n'ai pas pris le temps de les déclarer)

Pour mémoire et à toutes fins utiles, le Dockerfile - nsteinmetz/docker-grav :

FROM php:7-apache
ADD https://github.com/getgrav/grav/releases/download/1.1.8/grav-admin-v1.1.8.zip /tmp/grav-admin-v1.1.8.zip
RUN apt update && \
    apt upgrade -y && \
    apt install -y \
        unzip \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libmcrypt-dev \
        libpng12-dev \
        pkg-config && \
    unzip /tmp/grav-admin-v1.1.8.zip -d /tmp/ && \
    mv /tmp/grav-admin/* /var/www/html/ && \
    mv /tmp/grav-admin/.htaccess /var/www/html/ && \
    chown www-data:www-data -R /var/www/html && \
    docker-php-ext-install -j$(nproc) mcrypt && \
    docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ && \
    docker-php-ext-install -j$(nproc) gd &&\
    docker-php-ext-install -j$(nproc) zip &&\
    a2enmod rewrite && \
    rm -rf /var/lib/apt/lists/*
COPY php.conf /etc/apache2/conf-enabled/ 
COPY server-signature.conf /etc/apache2/conf-enabled/

Avec php.conf :

php_admin_flag display_errors off
php_admin_flag expose_php off

php_admin_value post_max_size "40M"
php_admin_value upload_max_filesize "40M"

et server-signature.conf :

ServerSignature Off
ServerTokens Prod

Améliorations

Les améliorations apportées :

  • Passage à docker-compose pour avoir plus de flexibilité au moment de démarrer les containers en fonction des projets utilisant Grav,
  • Passage à des images basées sur alpine (plus légères)
  • Passage à une architecture PHP-FPM + Nginx

Cela donne :

├── app
│   ├── Dockerfile
│   ├── security.conf
│   └── uploads.conf
└── web
│   ├── Dockerfile
│   └── php-fpm.conf
├── docker-compose.yml

Petites précisions à ce niveau :

  • app correspond au container php-fpm
    • security.conf contient des options de sécurité PHP (ne pas exposer la version de PHP, ne pas afficher les erreurs, etc)
    • uploads.conf contient des options liés aux uploads PHP (taille max de fichiers, etc)
  • web est le container nginx
    • php-fpm.conf est la configuration de mon virtualhost nginx

Revue du container "app" (php-fpm)

On a app/Dockerfile :

FROM php:7-fpm-alpine
ADD https://github.com/getgrav/grav/releases/download/1.1.8/grav-admin-v1.1.8.zip /tmp/grav-admin-v1.1.8.zip
RUN apk update &&\
    apk upgrade &&\
    unzip /tmp/grav-admin-v1.1.8.zip -d /tmp/ && \
    mv /tmp/grav-admin/* /var/www/html/ && \
    mv /tmp/grav-admin/.htaccess /var/www/html/ && \
    chown www-data:www-data -R /var/www/html &&\
    apk add libjpeg libjpeg-turbo libjpeg-turbo-dev libpng libpng-dev freetype freetype-dev &&\
    docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ && \
    docker-php-ext-install mcrypt zip gd &&\
    rm -rf /var/cache/apk/* &&\
    rm -rf /tmp/grav-admin-v1.1.8.zip &&\
    cd /var/www/html && ./bin/gpm update --no-interaction
COPY uploads.conf /usr/local/etc/php-fpm.d/uploads.conf
COPY security.conf /usr/local/etc/php-fpm.d/security.conf
VOLUME ["/var/www/html", "/var/www/html/assets", "/var/www/html/backup", "/var/www/html/cache", "/var/www/html/images", "/var/www/html/logs", "/var/www/html/tmp"]

A noter, même s'il n'y a rien d'exceptionnel :

  • Initialisation du container en récupérerant la version de Grav, gestion des dépendances et des permissions
  • La dernière ligne de RUN va mettre à jour les plugins inclus nativement dans Grav
  • Les volumes déclarés permettent de sortir du container toutes les zones non stateless : logs, cache, contenus, etc sur la base de la documentation officielle de Grav ; j'ai ajouté néanmoins les répertoire backups et tmp.

Ensuite, app/security.conf:

[www]

php_admin_flag[display_errors] = off
php_admin_flag[expose_php] = off

et app/uploads.conf :

[www]

php_admin_value[post_max_size] = "40M"
php_admin_value[upload_max_filesize] = "40M"

J'ai fait le choix de surcharger l'instance php-fpm par défaut (ie: www) et j'utilise php_admin_* afin d'interdire toute surcharge de ces variables par l'application.

Revue du container "web" (nginx)

web/Dockerfile :

FROM nginx:stable-alpine
RUN rm /etc/nginx/conf.d/default.conf
ADD php-fpm.conf /etc/nginx/conf.d/php-fpm.conf

Je supprime le virtualhost fourni par défaut et je fournis le mien en lieu et place.

web/php-fpm.conf :

server {
    listen 80;
    server_name _;
    charset utf-8;
    
    root /var/www/html/;
    index index.html index.php;

    # Uploads to 100M
    client_max_body_size 100m;

    location / {
        try_files $uri $uri/ /index.php?_url=$uri;
    }

    ## Begin - Security

    # don't send the nginx version number in error pages and Server header
    server_tokens off;

    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Frame-Options SAMEORIGIN;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data: ; style-src 'self' 'unsafe-inline'; font-src 'self'; child-src; object-src 'none'";

    # deny all direct access for these folders
    location ~* /(.git|cache|bin|logs|backup|tests)/.*$ { return 403; }
    # deny running scripts inside core system folders
    location ~* /(system|vendor)/.*\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
    # deny running scripts inside user folder
    location ~* /user/.*\.(txt|md|yaml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
    # deny access to specific files in the root folder
    location ~ /(LICENSE.txt|composer.lock|composer.json|nginx.conf|web.config|htaccess.txt|\.htaccess) { return 403; }
    ## End - Security

    ## Begin - PHP
    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
    }
    ## End - PHP
    
    location ~* ^.+\.(ico|js|gif|jpg|jpeg|png|bmp)$ {
        expires 30d;
    }
}

A noter :

  • Le fichier est inspiré de la configuration officielle nginx donnée pour Grav
  • Ajout de directives de sécurité (X-Content-Type-Options, X-XSS-Protection, X-Frame-Options et Content-Security-Policy)
  • Interdiction d'accès à des répertoires
  • Déclaration de php-fpm où le point d'attention est juste d'indiquer app:9000, car app est le nom de mon service.
  • Mise en cache des images

Et un docker-compose.yml pour enrober le tout

version: '2'
services:
    web:
      build: ./web/
      depends_on:
        - app
      volumes_from:
        - app
      ports:
        - "80:80"
    app:
      build: ./app/
      volumes:
        - ./user:/var/www/html/user
        - ./assets:/var/www/html/assets
        - ./backup:/var/www/html/backup
        - ./cache:/var/www/html/cache
        - ./images:/var/www/html/images
        - ./logs:/var/www/html/logs
        - ./tmp:/var/www/html/tmp

Pour builder puis lancer vos containers en mode daemon :

docker-compse up -d --build

Traefik en reverse-proxy

Traefik est un reverse-proxy moderne et il a le bon goût de s'interfacer notamment avec l'API de Docker. On peut alors déclarer dynamiquement nos containers à traefik et celui-ci les prend en compte dynamiquement.

Démarrer Traefik

Pour mon poste en local, j'ai décidé de lancer Traefik de la façon suivante :

docker run -d -v /dev/null:/traefik.toml -v /var/run/docker.sock:/var/run/docker.sock -p 80:80 -p 443:443 -p 8080:8080 --name traefik traefik:camembert --web --docker --docker.domain=docker.localhost --logLevel=DEBUG

Pour les détails :

  • -v /dev/null:/traefik.toml permet de démarrer Traefik sans fichier de configuration
  • -v /var/run/docker.sock:/var/run/docker.sock permert au container Traefik de communiquer avec Docker et son API
  • J'expose les ports 80, 443 et 8080. Le dernier permettra d'accéder au dashboard fourni nativement par Traefik
  • --web : lance l'interface web (dashboard)
  • --docker --docker.domain=docker.localhost : active le support de docker et fourni un domaine par défaut à tous les containers docker.
  • --logLevel=DEBUG : permet d'avoir des logs verbeux si problème via docker logs -f traefik

Rendre son application "traefik-aware"

Il "suffit" d'indiquer des labels à vos services :

version: '2'
services:
    web:
      build: ./web/
      depends_on:
        - app
      volumes_from:
        - app
      labels:
        - "traefik.backend=grav-project"
        - "traefik.frontend.rule=Host:project.grav"
        - "traefik.port=80"
        - "traefik.protocol=http"
        - "traefik.frontend.entryPoints=http"
        - "traefik.docker.network=nom_du_reseau"
    app:
      build: ./app/
      volumes:
        - ./user:/var/www/html/user
        - ./assets:/var/www/html/assets
        - ./backup:/var/www/html/backup
        - ./cache:/var/www/html/cache
        - ./images:/var/www/html/images
        - ./logs:/var/www/html/logs
        - ./tmp:/var/www/html/tmp
      labels:
        - "traefik.enable=false" 

Explications pour le service web :

  • je lui indique un nom de backend (peu importe le nom) qui sert juste à Traefik pour "nommer" votre container
  • l'url (de frontend) sur laquelle Traefik devra réagir pour vous interfacer avec votre container (ici en tapant http://project.grav/ dans mon navigateur, je dois arriver sur mon container)
  • le protocol et le port indiquent que je me connecte sur le port 80 de mon container avec le protocole http
  • l'entryPoint indique que je vais me connecter à Traefik sur le port 80 pour me connecter ensuite à mon conteneur.
  • le nom du réseau que vous a créé docker lors de l'initialisation du projet. Pour le récupérer, faire un docker network ls.

En gros on a :

Vous <=> Votre navigateur <=> Traefik Frontend (Host:project.grav (frontend.rule) + protocole http (EntryPoint)) <=> Traefik Backend (grav-project + port 80 + protocole http) <=> Container Web

Explications pour le service app :

  • Je ne souhaite pas exposer ce service dans Traefik, je désactive alors ce service (par défault, il y a une auto-découverte de tous les services).

Pour finir

Il ne me reste plus qu'à :

  • Faire une entrée DNS ou éditer /etc/hosts pour project.grav
  • Ouvrir votre navigateur sur http://project.grav/

Sauf que cela ne marche pas à ce stade (si vous utilisez traefik dans un container docker). En effet, lors du docker-compose up -d, docker a créé un réseau pour votre application. Or par défaut, Traefik n'y a pas accès. Il vous faut faire:

docker network connect <nom_du_reseau> <container-traefik>

Et ce coup-ci, votre site propulsé par Grav s'affiche.

Vous pouvez retrouver les fichiers et remonter vos commentaires sur cerenit/docker-grav

Une fois prochaine; je vous parlerais d'Ansible, Docker et Traefik pour déployer vos projets aisément.

1 / 1