
Cliquez sur un ou plusieurs tags pour appliquer un filtre sur la liste des notes de type "Journaux" :
Résultat de la recherche (1722 notes) :
Vendredi 7 mars 2025
Journal du vendredi 07 mars 2025 à 11:54
#JaiDécouvert Edward Deming via :
La nécessaire polarisation sur l’impact (le sens) a été forgée par des théoriciens des organisations comme Eliyahu Goldratt (auteur notamment de Le BUT, et père de la théorie des contraintes) ou Edward Deming (la principale autorité morale du lean management), qui constatent qu’invariablement, les moyens se substituent aux fins dans les grandes organisations en silos. Cette perte de sens est particulièrement douloureuse dans le secteur public où les gens sont et restent par vocation, par volonté de servir l’intérêt général.
Journal du vendredi 07 mars 2025 à 11:10
Cette après-midi, je vais participer au rassemblement de Stand Up For Science #Paris :
13h30 – Rassemblement place Jussieu, mêlant étudiants, citoyens, chercheurs et universitaires.
Puis marche au travers du Quartier Latin (Jussieu - rue des Ecoles - Place de la Sorbonne - Boulevard Saint-Michel - Port Royal) ponctuée de happenings et d’interventions au Collège de France et place de la Sorbonne.
Jeudi 6 mars 2025
Journal du jeudi 06 mars 2025 à 10:41
Alexandre m'informe de la sortie d'un nouveau modèle de Thinkpad : le ThinkPad T14s 2-in-1.
Peut-être le futur remplacement de mon Thinkpad T14s AMD Gen 3.
J'ai l'impression que globalement, tous les laptops non Apple progressent beaucoup ces quatre dernières années, tant au niveau de la qualité qu'au niveau des fonctionnalités.
J'ai l'impression que c'est une forte rupture après une décennie de stagnation que j'estime entre 2011 à 2021.
Mercredi 5 mars 2025
Journal du mercredi 05 mars 2025 à 21:51
J'utilise LibreWolf depuis le 4 jours.
Je rencontre un problème sur le site Claude.ia. Après la génération de quelques lignes de réponses, l'opération s'arrête et LibreWolf se bloque — freeze. Après quelques secondes, le message d'erreur suivant apparaît :
« This page is slowing down LibreWolf. To speed up your browser, stop the page ».
J'ai trouvé une solution ici.
J'ai ajouté https://claude.ai
dans la liste des exceptions de protection renforcée contre le pistage.
Après cela, les "freeze" ont disparu.
Journal du mercredi 05 mars 2025 à 16:02
J'ai lu le billet de Mitchell Hashimoto « As code ».
Voir aussi configuration as code.
Mardi 4 mars 2025
Journal du mardi 04 mars 2025 à 23:06
Cette liste d'applications de prise de notes est impressionnante !
Journal du mardi 04 mars 2025 à 12:32
Suite à 2025-03-01_2137.
J'ai actualisé mon fichier librewolf/userChrome.css
pour afficher les boutons de contrôles de fenêtre directement dans la toolbar de LibreWolf.
Cela donne ceci :
Ou ceci avec sidebery fermé :
Pour réaliser cela, je me base sur les fichiers CSS et le contenu des issues du projet firefox-csshacks.
Journal du mardi 04 mars 2025 à 00:01
#JaiLu « Triple Buffering, a debrief » au sujet de Linux Desktop, GNOME en particulier (via).
Lundi 3 mars 2025
Divers types d'issues, une issue Vision ou Epic est floue, une issue task est précise
En mars 2024, je me suis demandé comment utiliser correctement les termes Epic, Issue, User Story, Goal, Job Story, Vision, Pitch, Feature, Task, Bug, Spike, Dette technique, Theme.
Voici quelques réflexions à ce propos.
Tout d'abord, tous les artefacts suivants sont des Issues : Epic, User Story, Job Story, Vision, Pitch, Feature, Bug, Spike, Task.
Ensuite, Feature, Bug, Spike et Dette technique indiquent la finalité de l'issue, définissant la nature du travail à réaliser.
User Story et Job Story sont des méthodes de formulation d'issues.
J'ai mis beaucoup de temps à réaliser que les termes Epic, Vision, Theme, Pitch, Goal et Task permettent d'indiquer le niveau d'imprécision d'un objectif.
Exemple allant du flou très prononcé à une version faiblement floue :
- Vision – Le niveau le plus large et abstrait, décrivant une aspiration à long terme.
- Theme – Une direction stratégique regroupant plusieurs objectifs ou Epics.
- Pitch – Une proposition d'idée ou une justification d'un projet, pouvant inclure des objectifs mais restant plus conceptuel.
- Goal – Un objectif spécifique à atteindre, souvent mesurable.
- Epic – Une grande fonctionnalité ou un ensemble de tâches qui contribuent à un objectif plus large.
- Task – Niveau le plus précis, une tâche est une unité de travail concrète et actionnable.
Une ou plusieurs Merge Requests constituent une réponse formelle, exprimée en code, parmi toutes les réponses possibles à une demande formulée dans une issue.
Seule cette réponse formelle, exprimée en code, est véritablement précise. Même l'issue, aussi détaillée soit-elle, conserve toujours une part de flou.
Attention tout de même : quand je dis qu'une issue de type Vision est floue, cela ne veut pas dire que son auteur peut bâcler sa rédaction.
Si, par exemple, la description est limitée à 500 mots, l'auteur doit exploiter au mieux cette limite pour présenter sa vision avec précision. L'objectif n'est pas de créer du flou volontairement, mais plutôt d'exprimer clairement un concept qui, par nature, comporte encore des zones d'incertitude à explorer.
Voici quelques exemples d'issue floue publiés ici :
Une issue, en tant que texte écrit, comporte une part inévitable d'ambiguïté et nécessite donc son auteur pour être défendue :
C’est que l’écriture, Phèdre, a, tout comme la peinture, un grave inconvénient. Les œuvres picturales paraissent comme vivantes ; mais, si tu les interroges, elles gardent un vénérable silence. Il en est de même des discours écrits. Tu croirais certes qu’ils parlent comme des personnes sensées ; mais, si tu veux leur demander de t’expliquer ce qu’ils disent, ils te répondent toujours la même chose. Une fois écrit, tout discours roule de tous côtés ; il tombe aussi bien chez ceux qui le comprennent que chez ceux pour lesquels il est sans intérêt ; il ne sait point à qui il faut parler, ni avec qui il est bon de se taire. S’il se voit méprisé ou injustement injurié, il a toujours besoin du secours de son père, car il n’est pas par lui-même capable de se défendre ni de se secourir.
Conséquence pratique de tout cela :
- L'auteur d'une issue doit être disponible et accorder du temps à la personne qui va implémenter son issue.
- La personne qui implémente cette issue doit accepter l'imprécision de cette issue. En posant des questions, le développeur doit aider l'auteur à rendre cette issue plus précise.
- L'auteur de l'issue doit accepter de recevoir une implémentation qui ne correspond pas exactement à sa vision… et dans ce cas, il doit soit l'accepter ou accorder plus de temps à cette issue afin d'effectuer plusieurs itérations de correction de l'implémentation.
Ces règles pratiques sont aussi valables lorsqu'une issue est déclinée dans des issues avec un niveau de précision supérieur. Par exemple, lors de la rédaction d'issues de type Epic à partir d'une issue de type Vision.
« Permettre à l'auteur de défendre son texte » ne signifie pas exclusivement un dialogue oral. Ce dialogue peut s'effectuer :
- Par chat synchrone ;
- Par commentaire d'issue asynchrone ;
- Par visioconférence ;
- etc
Je pense que le niveau de précision d'une issue détermine le mode de communication à privilégier. Pour les issues de haut niveau d'abstraction — très floues (Vision, Theme, Pitch), la communication orale se révèle généralement plus efficace, car elle permet des échanges dynamiques et immédiats sur des concepts abstraits.
En revanche, pour les issues plus précises (Tasks, certaines Features), je privilégie une approche asynchrone avec des questions écrites détaillées. Cette méthode offre à l'auteur le temps nécessaire pour réfléchir et affiner sa rédaction. Je ne recours à la communication orale que lorsque des problèmes de compréhension persistent malgré les échanges écrits, afin de débloquer rapidement la situation.
Je cherche des solutions pour bien indiquer le niveau de précision des issues que j'écris.
Voici quelques exemples d'introductions d'issues :
Cette issue est de type "vision", c'est donc normal qu'elle soit imprécise. Les zones d'ombre seront affinées progressivement dans des sous-issues spécifiques. Pour clarifier certains aspects, des échanges oraux pourront être organisés afin de répondre à vos questions et d'enrichir cette vision.
Autre exemple :
Cette issue a été rédigée avec un souci particulier de précision. Si vous identifiez des erreurs, des incohérences ou si certains points nécessitent des éclaircissements, n'hésitez pas à les signaler dans les commentaires. Pour toute difficulté de compréhension ou doute persistant, je reste disponible pour organiser une session en visioconférence afin de faciliter nos échanges.
Samedi 1 mars 2025
Journal du samedi 01 mars 2025 à 21:37
Note de type #mémento pour documenter mes paramètres de configuration LibreWolf.
Je me suis basé sur le repository firefox-csshacks
pour implémenter mon fichier userChrome.css
.
Liste des extensions que j'ai installées :
- https://github.com/mbnuqw/sidebery
- https://github.com/andreicristianpetcu/always_open_in_current_tab
- https://github.com/cavi-au/Consent-O-Matic
- https://addons.mozilla.org/en-US/firefox/addon/darkreader/
- https://github.com/pistom/hohser
- https://github.com/GoogleChromeLabs/link-to-text-fragment
- https://github.com/zeraye/searxng-firefox-extension
- https://github.com/nc7s/whatwesay
- https://github.com/dessant/web-archives
- https://sponsor.ajay.app/
- https://github.com/lawrencehook/remove-youtube-suggestions
- https://flagfox.wordpress.com/
- https://github.com/tom-james-watson/old-reddit-redirect
- https://addons.mozilla.org/en-US/firefox/addon/bitwarden-password-manager/
- https://addons.mozilla.org/en-US/firefox/addon/nitter/
- https://github.com/fabiocchetti/wide-github
- https://addons.mozilla.org/en-US/firefox/addon/languagetool/
Journal du samedi 01 mars 2025 à 18:43
Suite aux mises à jour des conditions d'utilisation et de la politique de confidentialité de Firefox j'ai décidé :
- De contribuer financièrement à la hauteur de 10$ par mois au projet Servo.
- De remplacer Firefox par LibreWolf.
Quelques liens à ce sujet :
- 26 février 2025 - article de Mozilla : Introducing a terms of use and updated privacy notice for Firefox
- Thread Hacker News de 1090 commentaires
- Thread Lobster de 153 commentaires
- 28 février 2025 - article de Mozilla : An update on our Terms of Use
- Thread Hacker News de 302 commentaires
Voici quelques informations au sujet des forks de Firefox.
Le projet Waterfox a débuté en 2011.
Waterfox supporte les extensions Firefox 🙂.
Pocket est désactivé par défaut 🙂.
J'ai lu l'article de Waterfox : « A Comment on Mozilla's Policy Changes ».
Waterfox est disponible sur Flathub : https://github.com/flathub/net.waterfox.waterfox.
Je découvre qu'une version Android de Waterfox est disponible : https://github.com/BrowserWorks/Waterfox-Android.
J'ai lu l'article Wikipedia de LibreWolf et les pages "Features" et "FAQ".
Le projet LibreWolf a commencé en 2020, il est bien plus jeune que Waterfox.
#JaiDécouvert IronFox (https://gitlab.com/ironfox-oss/IronFox/)
J'ai installé LibreWolf sous Fedora :
$ curl -fsSL https://repo.librewolf.net/librewolf.repo | pkexec tee /etc/yum.repos.d/librewolf.repo
$ sudo dnf install librewolf
Le site web du projet LibreWolf m'a inspiré davantage confiance que Waterfox.
Suite à cela, j'ai décidé de migrer vers LibreWolf.
Commande pour définir LibreWolf comme navigateur par défaut sous Fedora :
$ xdg-settings set default-web-browser librewolf.desktop
Journal du samedi 01 mars 2025 à 17:03
J'ai passé une heure à lire l'article de LinuxFr : « Une intelligence artificielle libre est-elle possible ? ». J'y ai appris de nombreuses choses et je l'ai trouvé plutôt accessible. Merci à l'auteur https://linuxfr.org/users/liorel.
J'ai beaucoup aimé cette manière de présenter ce qu'est l'Intelligence artificielle :
Commençons par définir notre objet d’étude : qu’est-ce qu’une IA ? Par « intelligence artificielle », on pourrait entendre tout dispositif capable de faire réaliser par un ordinateur une opération réputée requérir une tâche cognitive. Dans cette acception, un système expert qui prend des décisions médicales en implémentant les recommandations d’une société savante est une IA. Le pilote automatique d’un avion de ligne est une IA.
Cependant, ce n’est pas la définition la plus couramment employée ces derniers temps. Une IA a battu Lee Sedol au go, mais ça fait des années que des ordinateurs battent les humains aux échecs et personne ne prétend que c’est une IA. Des IA sont employées pour reconnaître des images alors que reconnaître un chien nous semble absolument élémentaire, mais l’algorithme de Youtube qui te suggère des vidéos pouvant te plaire parmi les milliards hébergées fait preuve d’une certaine intelligence et personne ne l’appelle IA. Il semble donc que le terme « IA » s’applique donc à une technique pour effectuer une tâche plus qu’à la tâche en elle-même, ou plutôt à un ensemble de techniques partageant un point commun : le réseau de neurones artificiels.
Dans la suite de cette dépêche, j’utiliserai donc indifféremment les termes d’IA et de réseau de neurones.
J'ai bien aimé la section « Un exemple : la régression linéaire » 👌.
Je n'ai pas compris grand-chose à la section « Le neurone formel ». Elle contient trop d'outils mathématiques qui m'échappent, comme :
- « la fonction f doit être monotone (idéalement strictement monotone) »
- « et non linéaire (sinon mettre les neurones en réseau n’a aucun intérêt, autant faire directement une unique régression linéaire) »
- « La fonction logistique »
- « La fonction Rectified Linear Unit »
On ajoute un ensemble de neurones qu’on pourrait qualifier de « sensitifs », au sens où ils prennent en entrée non pas la sortie d’un neurone antérieur, mais directement l’input de l’utilisateur, ou plutôt une partie de l’input : un pixel, un mot…
#JaiDécouvert les neurones « sensitifs ».
Se pose alors la question : combien de neurones par couche, et combien de couches au total ?
On peut considérer deux types de topologies : soit il y a plus de neurones par couche que de couches : le réseau est plus large que long, on parlera de réseau large. Soit il y a plus de couches que de neurones par couche, auquel cas le réseau est plus long que large, mais on ne va pas parler de réseau long parce que ça pourrait se comprendre « réseau lent ». On parlera de réseau profond. C’est de là que viennent les Deep et les Large qu’on voit un peu partout dans le marketing des IA. Un Large Language Model, c’est un modèle, au sens statistique, de langage large, autrement dit un réseau de neurones avec plus de neurones par couche que de couches, entraîné à traiter du langage naturel.
Je suis très heureux de découvrir cette distinction entre profond et large. Je découvre que ces termes, omniprésents dans le marketing des IA, reflètent en réalité des caractéristiques architecturales précises des réseaux de neurones.
On constate empiriquement que certaines topologies de réseau sont plus efficaces pour certaines tâches. Par exemple, à nombre de neurones constant, un modèle large fera mieux pour du langage. À l’inverse, un modèle profond fera mieux pour de la reconnaissance d’images.
je peux assez facilement ajuster un modèle de régression logistique (qui est une variante de la régression linéaire où on fait prédire non pas une variable quantitative, mais une probabilité)
J'ai une meilleure idée de ce qu'est un modèle de régression logistique.
En définitive, on peut voir le réseau de neurones comme un outil qui résout approximativement un problème mal posé. S’il existe une solution formelle, et qu’on sait la coder en un temps acceptable, il faut le faire. Sinon, le réseau de neurones fera un taf acceptable.
Ok.
Posons-nous un instant la question : qu’est-ce que le code source d’un réseau de neurones ? Est-ce la liste des neurones ? Comme on l’a vu, ils ne permettent ni de comprendre ce que fait le réseau, ni de le modifier. Ce sont donc de mauvais candidats. La GPL fournit une définition : le code source est la forme de l’œuvre privilégiée pour effectuer des modifications. Dans cette acception, le code source d’un réseau de neurones serait l’algorithme d’entraînement, le réseau de neurones de départ et le corpus sur lequel le réseau a été entraîné.
👍️
Vendredi 28 février 2025
Journal du vendredi 28 février 2025 à 14:00
À partir de Décodage Fiscal, j'ai élaboré le tableau suivant :
(Ma source dans un Google Sheet)
Précision : je n'ai pas intégré les possibilités de déduction de charges d'exploitation, de loyers déductible, etc en SASU.
Jeudi 27 février 2025
Journal du jeudi 27 février 2025 à 11:14
Alexandre m'a fait découvrir l'existence de la version desktop de Framework.
Ma première impression, je trouve cela fun, mais je n'ai pas encore plus le temps d'étudier le sujet.
Thread Hacker News sur le sujet : « Framework's first desktop is a strange–but unique–mini ITX gaming PC ».
#Vidéo dans laquelle le CEO de Framework explique le projet : https://www.youtube.com/watch?v=-lErGZZgUbY
Journal du jeudi 27 février 2025 à 11:02
Au mois d'août 2024, je disais :
Je cherche depuis plusieurs années une solution pour surveiller la date d'expiration des noms de domaine en analysant le contenu de Whois.
#JaiDécouvert cet exporter Prometheus qui correspond exactement à mon besoin : https://github.com/shift/domain_exporter
Ce matin, en travaillant sur la note "Je découvre Beszel", #JaiDécouvert que Gatus permet de monitorer l'expiration d'un domaine :
You can monitor the expiration of a domain with all endpoint types except for DNS by using the
[DOMAIN_EXPIRATION]
placeholder.The aforementioned placeholder resolves to a duration (e.g. 734h22m5s), as such, the value you should compare it to should also be a duration (e.g. 720h, 1h30m). Here's an example of what a condition may look like:
[DOMAIN_EXPIRATION] > 720h
The condition above will fail if the domain expires in less than 720 hours (30 days).
Journal du jeudi 27 février 2025 à 10:41
En travaillant sur la note "Je découvre Beszel", #JaiDécouvert ici un autre projet de monitoring intéressant : Dozzle (https://dozzle.dev/).
Dozzle is a small lightweight application with a web based interface to monitor Docker logs. It doesn’t store any log files. It is for live monitoring of your container logs only.
Là aussi, Dozzle est un projet en Golang, commencé fin 2018.
Dozzle est une alternative à Loki + Grafana.
#JaimeraisUnJour déployer Dozzle pour le tester et si ce test est concluant, je l'intégrerai peut-être à ma stack minimaliste de monitoring en complément de Beszel et Gatus.
Un ami m'a partagé le projet Beszel (https://beszel.dev/).
Beszel is a lightweight server monitoring platform that includes Docker statistics, historical data, and alert functions.
It has a friendly web interface, simple configuration, and is ready to use out of the box. It supports automatic backup, multi-user, OAuth authentication, and API access.
Beszel est codé en Golang, il est très récent, il a commencé en été 2024, c'est sans doute pour cela que je ne l'avais jamais croisé.
De prime abord, j'ai pensé que Beszel était un outil de Status / Uptime pages comme Uptime Kuma ou Gatus, mais ce n'est pas le cas.
Je qualifierai plutôt Beszel d'alternative "plug and play" de Prometheus + Grafana + node_exporter + cAdvisor.
Alors que l'annonce de Beszel a fait "choux blanc" sur Hacker News « Beszel: Lightweight server resource monitoring with history, Docker stats,alerts », le projet a suscité plus de réaction — 270 commentaires — sur Subreddit SelfHosted : « I just released Beszel, a server monitoring hub with historical data, docker stats, and alerts. It's a lighter and simpler alternative to Grafana + Prometheus or Checkmk. Any feedback is appreciated! ».
Les retours sont très positifs 🙂 :
« There is beauty in simplicity. Very nice little application! »
« Kiss »
« Just installed on all of my servers, gorgeous project, simple but also not simple. »
« Awesome work. I think you identified a good use case for the self hosting community, a simple server monitor running as a simple service. I will give it a go soon! »
« I never installed Grafana and Prometheus because it’s overkill for my little server.. but this looks really good! I’ll give it a go »
Prometheus propose bien plus d'exporter que Beszel, mais je pense que Beszel est un bon point de départ pour une stack de monitoring minimaliste.
À l'avenir, mon choix par défaut en matière monitoring sera probablement un couple Beszel + Gatus. Si des besoins plus avancés émergent, comme du monitoring poussé de PostgreSQL, Redis ou d'autres services, j'envisagerai alors de commencer la mise en place du couple Prometheus + Grafana.
Mercredi 26 février 2025
Mardi 25 février 2025
Journal du mardi 25 février 2025 à 23:29
#JaiDécouvert cette page web qui permet de savoir quel LLM peut être exécuté sur une machine en particuler : https://canirunthisllm.com/ll
Journal du mardi 25 février 2025 à 22:12
Un ami me demande :
Réponse courte : je pense qu'un NPU ne te sera d'aucune utilité pour exécuter un LLM de qualité sur ton laptop 😔.
Quand mon ami parle d'une « IA en local », je suppose qu'il souhaite exécuter un agent conversationnel qui exploite un LLM, du type ChatGPT, Claude.ia, LLaMa, DeepSeek, etc.
Sa motivation première est la confidentialité.
Cela fait depuis juin 2023 que je souhaite moi aussi self host un LLM, avant tout pour éviter le vendor locking, maitriser son coût et éviter la "la merdification des choses".
En juin 2024, je pensais moi aussi que les NPU étaient une solution technique pour self hosted un LLM. Mais depuis, j'ai compris que j'étais dans l'erreur.
Je trouve que ce commentaire résume aussi bien la fonction des NPU :
Also, people often mistake the reason for an NPU is "speed". That's not correct. The whole point of the NPU is rather to focus on low power consumption.
...
I have a sneaking suspicion that the real real reason for an NPU is marketing. "Oh look, NVDA is worth $3.3T - let's make sure we stick some AI stuff in our products too."
D'après ce que j'ai compris, voici ce que les NPU exécutent en local (ce qui inclut également la technologie Microsoft nommée Copilot) :
- L'accélération des modèles d'IA pour la reconnaissance vocale, la transcription en temps réel, et la traduction.
- Traitement plus rapide des images et vidéos pour des effets en direct (ex. flou d'arrière-plan, suppression du bruit audio).
- Réduction de la consommation électrique en exécutant certaines tâches IA en local, sans solliciter massivement le CPU/GPU.
Je pense que les fonctionnalités MS Windows Copilot qui utilisent des LLM sont exécutées sur des serveurs mutualisés avec de gros GPU.
Si j'ai bien compris, pour faire tourner efficacement un LLM en local, il est essentiel de disposer d'une grande quantité de RAM avec une bande passante élevée.
Par exemple :
- Une carte NVIDIA RTX 5090 avec 32Go de RAM (2700 €)
- Une carte NVIDIA RTX 3090 avec 24Go de RAM d'accasion (1000 €)
- Une Puce Apple M4 Max avec CPU 16 cœurs, GPU 40 cœurs et Neural Engine 16 cœurs 128 Go de mémoire unifiée (plus de 5000 €)
- Une Puce Apple M4 Pro avec CPU 12 cœurs, GPU 16 cœurs, Neural Engine 16 cœurs 64 Go de mémoire unifiée (2400 €)
Je ne suis pas disposé à investir une telle somme dans du matériel que je ne parviendrai probablement jamais à rentabiliser. À la place, il me semble plus raisonnable d'opter pour des Managed Inference Service tels que Replicate.com ou Scaleway Managed Inference.
Voici les tarifs de Scaleway Generative APIs :
Il y a quelques semaines, j'ai connecté Open WebUI à l'API de Scaleway Managed Inference avec succès. Je pense que je vais utiliser cette solution sur le long terme.
Si je devais garantir une confidentialité absolue dans un cadre professionnel, je déploierais Ollama sur un serveur dédié équipé d'un GPU :
Journal du mardi 25 février 2025 à 14:20
Alexandre vient de partager ce thread : « Asdf Version Manager Has Been Re-Written in Golang »
Je découvre que Asdf n'est pas mort ! La version 0.16.0
publié le 30 janvier 2025 a été réécrite en Golang !
La raison principale semble être une volonté d'amélioration de la vitesse de Asdf :
With improvements ranging from 2x-7x faster than asdf version 0.15.0!
Depuis cette date, Mise a publié un benchmark qui compare la vitesse d'exécution de Asdf et Mise : https://mise.jdx.dev/dev-tools/comparison-to-asdf.html#asdf-in-go-0-16.
Comme mon ami Alexandre, certains utilisateurs sont inquiets de voir Mise faire trop de choses :
I tried mise a while back, and the main reason I went away from it is like you said, it does too much. It tries to be asdf, direnv and a task runner. I just want a tool manager, and is the reason why I switched to aquaproj/aqua.
J'ai migré de Asdf vers Mise en novembre 2023 et pour le moment, je n'ai pas envie, ni de raison pratique particulière pour retourner à Asdf.
De plus, je suis plutôt satisfait d'avoir remplacé direnv par Mise, voir Je pense pouvoir maintenant remplacer Direnv par Mise 🤞.
Journal du mardi 25 février 2025 à 09:35
Dans cette note, je souhaite décrire et expliquer comment j'intègre des sessions de terminal dans des documentations.
Convention mainstream que j'ai adoptée
Je suis la convention mainstream suivante pour représenter des sessions terminal (de type bash, zsh…) :
Première partie :
$ echo "Hello, world!" Hello, world! $ ls -l total 0 -rw-r--r-- 1 user user 0 Feb 25 10:00 file.txt
Seconde partie :
$ sudo su # systemctl restart nginx $ exit $ uptime # Affiche l'uptime uptime 10:00:00 up 1 day, 2:45, 1 user, load average: 0.15, 0.10, 0.05
Les lignes commençant par $
ou #
indiquent les commandes saisies par l'utilisateur, tandis que les autres correspondent aux sorties du terminal.
Il m'arrive également d'ajouter des commentaires en fin de ligne à l'aide de # …
.
Origine de cette convention ?
J'ai cherché à retracer l'origine de cette pratique et elle semble très ancienne, probablement adoptée dès les débuts d'Unix en 1971.
On retrouve cette syntaxe notamment dans le livre The Unix Programming Environment (pdf), publié en 1984.
Ne pas inclure de $
si un bloc ne contient aucune sortie de commande
La règle MD014
de Markdownlint aborde ce sujet :
MD014 - Dollar signs used before commands without showing output
Tags: code
Aliases: commands-show-output
This rule is triggered when there are code blocks showing shell commands to be typed, and the shell commands are preceded by dollar signs ($):
$ ls $ cat foo $ less bar
The dollar signs are unnecessary in the above situation, and should not be included:
ls cat foo less bar
However, an exception is made when there is a need to distinguish between typed commands and command output, as in the following example:
$ ls foo bar $ cat foo Hello world $ cat bar baz
Rationale: it is easier to copy and paste and less noisy if the dollar signs are omitted when they are not needed. See https://cirosantilli.com/markdown-style-guide#dollar-signs-in-shell-code for more information.
Pendant un certain temps, j’ai suivi la recommandation de ne pas inclure de $
dans un bloc de commande lorsqu’il n’affiche aucune sortie.
Après quelques années, j’ai décidé de ne plus appliquer cette règle pour la raison suivante :
- Lorsque la documentation mélange des fichiers de configuration et des commandes sans
$
, j’ai du mal à distinguer ce qui doit être exécuté dans un terminal et ce qui relève de la configuration.
Pour éviter toute ambiguïté, j’ai adopté une approche radicale : toujours utiliser $
pour indiquer une commande à exécuter, même si le bloc ne contient pas de sortie.
Je n'aime pas les $
dans les blocs de commande, car que je ne peux pas copier / coller facilement !
Je comprends tout à fait cette remarque. Cependant, ces "screenshots" de session de terminal n'ont pas vocation à être copiées / collées en masse.
Ils ont avant tout une fonction explicative.
Ce sont des sortes de "screenshot".
Si j'éprouve le besoin de faire souvent des "copier / coller" d'exemples de session terminal, alors je considère que c'est le signe qu'un script "helper" serait plus approprié pour exécuter ce groupe de commandes d’un seul coup.
Par exemple, je peux remplacer ce contenu :
Ensure that the following prerequisites have been installed: mise and direnv, see instruction in ../README.md.
$ mise trust $ mise install $ scw version Version 2.34.0
Par celui-ci (qui indique l'existence du script ./scripts/mise-install.sh
) :
Ensure that the following prerequisites have been installed: mise and direnv, see instruction in ../README.md (or execute
./scripts/mise-install.sh
).$ mise trust $ mise install $ scw version Version 2.34.0
Cela évite les copier-coller répétitifs tout en conservant la clarté de l’explication.
Dimanche 23 février 2025
Journal du dimanche 23 février 2025 à 18:25
En mars 2024, je me suis interrogé sur les points communs et les différences entre les termes suivants : "Mission", "Projet", "Objectif", "Goal", Epic et North Star.
Dans cette note, je souhaite partager quelques réflexions sur le concept de North Star.
La principale caractéristique de la North Star — ou étoile polaire — est son unicité. Ainsi, je définis un objectif comme une "North Star" lorsque celui-ci constitue l’unique objectif principal d’une organisation.
D'autre part, en faisant des recherches j'ai constaté que "North Star" est surtout utilisé dans l'univers Startup pour décrire une metrics unique et principale, nommée "North Star metric".
North Star semble peu utilisé pour décrire un objectif principal.
En gestion de projet logiciel, quelle est la définition de "Theme" ?
J'ai du mal à bien définir le terme thème en gestion de projet logiciel.
Dans cette note, je vais décrire les deux définitions que je connais.
Voici une définition de Ken Rubin, auteur du livre Essential Scrum :
A collection of related user stories. A theme provides a convenient way to indicate that a set of stories have something in common, such as being in the same functional area.
Un Theme peut-être assigné à tout type d'issue, par exemple Epic ou User Story.
Les auteurs du livre Product Roadmaps Relaunched ont une autre définition de Theme :
As we’ve touched on, in the relaunched roadmapping process we use themes and subthemes to express customer needs. This is probably a new concept for many of you, so let’s define what we mean by these terms.
Themes are an organizational construct for defining what’s important to your customers at the present time.
...
So, again, themes and subthemes represent the needs and problems your product will solve for. A need is generally something the customer doesn’t have yet, whereas a problem is something that’s not working right (with the existing product, or whatever substitute they might currently be using). Even though these two terms suggest subtle differences, the important point is that both refer to a gap or pain in the customer’s experience. When identifying the themes and subthemes for your roadmap, remember to consider both needs and problems from all angles.
Jared Spool, paraphrasing our very own Bruce McCarthy, says, “Themes help teams stay focused without prematurely committing to a solution that may not be the best idea later on.” As Spool points out, it is important to focus most of the roadmapping effort on customer needs and problems because “the viability of a feature may shift dramatically, while the nature of an important customer problem will likely remain the same.”
Dans ce livre, un Theme représente un besoin client important à un instant donné.
D'après ce que j'ai compris, Product Roadmaps Relaunched adopte une définition plus restrictive du concept de thème que Essential Scrum. Dans Product Roadmaps Relaunched, un thème sert uniquement à décrire des fonctionnalités de façon imprécise.
Exemple tiré du livre Product Roadmaps Relaunched :
- Theme: Billing & payments
- Subtheme: Billing & payments API integration
- Subtheme: API integration testing
Pour résumer :
- Essential Scrum inclut des thèmes qui ne sont pas seulement liés aux fonctionnalités, mais aussi à la stratégie globale, à l’organisation, voire aux aspects techniques et processus internes.
- Product Roadmaps Relaunched reste focalisé sur l'expérience utilisateur et les besoins clients, avec des thèmes qui expriment des fonctionnalités sans trop rentrer dans les considérations techniques ou organisationnelles.
#JaiDécidé d'adopter la définition de "Theme" donnée dans Essential Scrum.
Samedi 22 février 2025
Journal du samedi 22 février 2025 à 18:14
Pour le moment, le seul reproche que je peux faire à avante.nvim, c'est que je ne peux pas utiliser Neovim (me balader dans le code, éditer un fichier) pendant qu'une réponse est en train d'être rédigée dans la sidebar.
J'ai trouvé cette issue qui semble correspondre à ce problème : feature: Cursor Movement Issue During Chat Response Generation.
Je viens de poster ce message, pour indiquer que je pense que ce problème est plus ou moins corrigé. J'arrive à déplacer librement mon curseur pendant la génération de réponse par avante.nvim.
Toutefois, la saisie de texte reste lente.
Jeudi 20 février 2025
Workflow de gestion des secrets d'un projet basé sur Age et des clés ssh
Cette note est aussi disponible au format vidéo : https://www.youtube.com/watch?v=J9jsd4m9YkQ.
De 2018 à 2023, j'utilisais l'outil "pass" (https://www.passwordstore.org/) couplé avec GNU Privacy Guard pour chiffrer et déchiffrer les secrets dans mes projets professionnels.
Bien que cette méthode fonctionnait, elle s'avérait laborieuse.
La procédure documentant l'installation, la création des clés et la configuration de gnupg était l'étape posant le plus de difficultés d'onboarding des développeurs sur ces projets.
Au feeling, je dirais que trois développeurs sur quatre bloquaient à cette étape.
En parallèle à cette méthode, j'ai essayé d'utiliser la cli de Bitwarden, mais l'expérience n'a pas été très concluante, principalement à cause de problèmes de latence lors de son exécution.
Aujourd'hui, j'ai exploré une nouvelle méthode basée sur age et son support natif des clés ssh.
Voici le repository Git du résultat de cette exploration : age-secret-skeleton
.
Le résultat est très positif et je pense avoir trouvé ma nouvelle méthode de chiffrement des secrets dans mes projets 🙂.
Pour en savoir plus, vous pouvez à la fois suivre le README.me du repository et continuer la lecture de cette note.
Détail des fichiers du repository
.
├── .envrc
├── .gitignore
├── .mise.toml
├── README.md
├── scripts
│ ├── decrypt_secrets.sh
│ └── encrypt_secrets.sh
├── .secret
├── .secret.age
├── .secret.skel
└── ssh-keys
├── john-doe.pub
└── stephane-klein.pub
/.secret
: fichier qui contient les secrets en clair. Ce fichier est ignoré par.gitignore
afin qu'il ne soit pas présent dans le repository git/.secret.age
: fichier qui contient le contenu du fichier.secret
chiffré avec age. Ce fichier est ajouté au repository git./ssh-keys/
: ce dossier contient les clés publiques ssh des personnes qui ont accès au contenu de.secret.age
/scripts/decrypt_secrets.sh
: permet de déchiffrer avec age le contenu de.secret.age
et écrit le résultat en clair dans.secret
/scripts/encrypt_secrets.sh
: permet de chiffrer avec age le contenu de.secret
vers.secret.age
. Ce script doit être exécuté quand le contenu de.secret
est modifié ou quand une nouvelle clé est ajoutée dans/ssh-keys/
/.envrc
: Dans ce skeleton, ce fichier charge uniquement les variables d'environnement présentes dans.secret
mais dans un vrai projet, il permet de charger automatiquement des variables d'environnement qui ne sont pas des secrets./.secret.skel
: ce fichier contient l'exemple de contenu du fichier.secret
, sans les secrets. Par exemple :
# You can either request these secrets from Stéphane Klein (contact@stephane-klein.info)
# or, if your public ssh key is present in `./ssh-keys/` use the ./scripts/decrypt_secrets.sh command
# which will automatically decrypt the .secret.age file to .secret
export POSTGRES_PASSWORD="..."
export SCW_SECRET_KEY="..."
Ce fichier n'est pas nécessaire au bon fonctionnement du workflow mais je le trouve utile pour :
- documenter le contenu de
.secret
aux personnes qui ont juste accès au dépôt Git - permettre de review les modifications de
.secret.skel
dans des Merge Request.
Utilisation des clés ssh
L'un des avantages majeurs de age par rapport à pass + gnupg est son support natif des clés SSH pour chiffrer et déchiffrer les secrets.
Ainsi, je n'ai plus besoin de demander aux développeurs deux types de clés (SSH et gnupg) : une seule clé SSH suffit.
De plus, il me semble qu'un grand nombre de développeurs possèdent déjà une clé SSH, alors que je pense que gnupg reste une technologie bien moins répandue.
Détail d'implémentation des scripts
Vvoici le contenu de /scripts/encrypt_secrets.sh
:
#!/usr/bin/env bash
set -e
cd "$(dirname "$0")/../"
# Prepare recipient arguments for age
recipient_args=()
for pubkey in ./ssh-keys/*.pub; do
if [ -f "$pubkey" ]; then
recipient_args+=("-R" "$pubkey")
fi
done
# Execute age with all public keys
age "${recipient_args[@]}" -o .secret.age .secret
La boucle permet de passer toutes les clés ssh du dossier /ssh-keys/*
en paramètre d' age.
Voici le contenu de /scripts/decrypt_secrets.sh
:
#!/usr/bin/env bash
set -e
cd "$(dirname "$0")/../"
# Prepare identity arguments for age
identity_args=()
for key in ~/.ssh/id_*; do
if [ -f "$key" ] && ! [[ "$key" == *.pub ]]; then
identity_args+=("-i" "$key")
fi
done
# Execute age with all identity files
age -d "${identity_args[@]}" -o .secret .secret.age
cat << EOF
Secret decrypted in .secret
Don't forget to run the command:
$ source .envrc
EOF
La boucle permet de passer en paramètre toutes les clés privées ssh du dossier ~/.ssh/
en espérant en trouver une qui correspond à une clé publique du dossier /ssh-keys/
.
Plusieurs niveaux de sécurisation
Si je veux cloisonner les secrets en limitant leur accès à des groupes d'utilisateurs distincts, je peux utiliser des secrets différents selon l'environnement.
Par exemple :
.
├── production
│ ├── .secret.age
│ └── ssh-keys
└── sandbox
├── .secret.age
└── ssh-keys
Cette structure me permet de donner à certains utilisateurs accès aux secrets de l'environnement sandbox
, sans leur donner accès à ceux de production
.
Aller plus loin avec par exemple Vault ?
Je pense qu'il est possible d'aller plus loin en matière de sécurité avec des solutions comme Vault, mais trouve que la méthode basée sur age reste plus simple à déployer dans une petite équipe.
Jeudi 13 février 2025
Journal du jeudi 13 février 2025 à 14:50
Suite à ce commentaire et celui-ci, je m'adresse dans cette note à Anarcat (francophone) et Martín Marqués pour expliquer ce que j'essaie de faire dans le POC https://github.com/stephane-klein/poc-barman, ce que j'ai réussi à faire et présenter aussi mes difficultés.
J'ai traduit cette note en anglais et je l'ai postée sur "GitHub Barman discussion" : https://github.com/EnterpriseDB/barman/discussions/1067.
Mon objectif dans le repository poc-barman
est d'essayer d'utiliser barman dans un container Docker sidecar pour sauvegarder un container PostgreSQL.
Une de mes contraintes est d'effectuer un minimum de changements au niveau du container PostgreSQL que je souhaite sauvegarder. Je souhaite pouvoir utiliser une image Docker PostgreSQL mainstream https://hub.docker.com/_/postgres, sans changement.
Je souhaite utiliser le mode de sauvegarde de barman nommé streaming backups method
: backup_method = postgres
qui se base sur la commande pg_basebackup
(commande officielle intégrée à PostgreSQL).
Je souhaite utiliser la nouvelle fonctionnalité pg_basebackup --incremental...
de la version 17 de PostgreSQL.
Voici ma configuration de barman : https://github.com/stephane-klein/poc-barman/blob/4df58ecc5af6d2d1f7607c364400f8c5ba012496/docker-compose.yml#L15
Et voici ma configuration de PostgreSQL 17 :
- https://github.com/stephane-klein/poc-barman/blob/4df58ecc5af6d2d1f7607c364400f8c5ba012496/docker-compose.yml#L15
- et https://github.com/stephane-klein/poc-barman/blob/4df58ecc5af6d2d1f7607c364400f8c5ba012496/init-barman.sh#L1
J'ai implémenté un script nommé ./scripts/reset.sh
qui effectue un test de bout automatiquement.
Voici son screencast :
Voici ce qu'il fait :
- Il coupe tous les containers et efface les volumes
- Il lance les containers
postgres1
etbarman
et injecte quelques données danspostgres1
- Il initialise
barman
- Il effectue une sauvegarde complète de
postgres1
- Il restaure la sauvegarde vers
postgres2
et lancepostgres2
et affiche les données de la tabledummy
- Il effectue une sauvegarde incrémentielle après avoir injecté quelques nouvelles données dans
postgres1
- Il restaure la sauvegarde de
postgres1
en utilisantpg_combinebackup
verspostgres2
préalablement coupé et effacé - Ici j'ai un échec au lancement de
postgres2
basé sur la restauration de la sauvegarde incrémentielle
Questions que je me pose :
- Pourquoi la restauration basée sur la sauvegarde incrémentielle échoue ?
- Est-ce que mon scénario de test d'usage de barman est correct, est-ce qu'il me manque des étapes ou est-ce que je fais des opérations non nécessaires ?
- Est-ce que j'ai fait des erreurs importantes ?
Voici ci-dessous la version anglaise posté ici.
Subject: Streaming Incremental Backup Configuration with PostgreSQL 17 using Docker Sidecar
Hello,
In the poc-barman
repository, I'm trying to use barman in a Docker sidecar container to backup a PostgreSQL container.
One of my constraints is to make minimal changes to the PostgreSQL container that I want to backup. I want to be able to use a mainstream Docker PostgreSQL image https://hub.docker.com/_/postgres, without modifications.
I want to use the barman backup mode called streaming backups method
: backup_method = postgres
which is based on the pg_basebackup
command (official command integrated into PostgreSQL).
I want to use the new pg_basebackup --incremental...
feature from PostgreSQL version 17.
Here is my barman configuration: https://github.com/stephane-klein/poc-barman/blob/4df58ecc5af6d2d1f7607c364400f8c5ba012496/docker-compose.yml#L15
And here is my PostgreSQL 17 configuration:
- https://github.com/stephane-klein/poc-barman/blob/4df58ecc5af6d2d1f7607c364400f8c5ba012496/docker-compose.yml#L15
- and https://github.com/stephane-klein/poc-barman/blob/4df58ecc5af6d2d1f7607c364400f8c5ba012496/init-barman.sh#L1
I implemented a script called ./scripts/reset.sh
that performs an end-to-end test automatically.
Here's its screencast:
Here's what it does:
- It stops all containers and erases the volumes
- It starts the
postgres1
andbarman
containers and injects some data intopostgres1
- It initializes
barman
- It performs a full backup of
postgres1
- It restores the backup to
postgres2
, startspostgres2
, and displays the data from thedummy
table - It performs an incremental backup after injecting some new data into
postgres1
- It restores
postgres1
backup usingpg_combinebackup
topostgres2
which was previously stopped and erased - Here I have a failure when starting
postgres2
based on the incremental backup restoration
Questions:
- Why does the restoration based on the incremental backup fail?
- Is my barman usage test scenario correct, am I missing steps or am I performing unnecessary operations?
- Have I made any significant mistakes?
Best regards,
Stephane
Journal du jeudi 13 février 2025 à 14:09
Suite de mes notes 2025-02-09_1705, 2025-02-12_1044, 2025-02-12_1511, 2025-02-12_1534 et 2025-02-12_2305 au sujet de barman pour sauvegarder des bases de données PostgreSQL
Je ne sais pas pourquoi je dois lancer
select pg_switch_wal();
.
J'ai découvert dans ce commentaire qu'il existe une commande nommée : barman switch-wal
.
Je pense avoir compris qu'avant d'exécuter barman backup…
il est nécessaire d'exécuter :
$ barman switch-wal
$ barman cron
$ barman check postgres1
Server postgres1:
PostgreSQL: OK
superuser or standard user with backup privileges: OK
PostgreSQL streaming: OK
wal_level: OK
replication slot: OK
directories: OK
retention policy settings: OK
backup maximum age: OK (no last_backup_maximum_age provided)
backup minimum size: OK (0 B)
wal maximum age: OK (no last_wal_maximum_age provided)
wal size: OK (0 B)
compression settings: OK
failed backups: OK (there are 0 failed backups)
minimum redundancy requirements: OK (have 0 backups, expected at least 0)
pg_basebackup: OK
pg_basebackup compatible: OK
pg_basebackup supports tablespaces mapping: OK
systemid coherence: OK (no system Id stored on disk)
pg_receivexlog: OK
pg_receivexlog compatible: OK
receive-wal running: OK
archiver errors: OK
$ barman backup postgres1 --immediate-checkpoint
Starting backup using postgres method for server postgres1 in /var/lib/barman/postgres1/base/20250213T100353
Backup start at LSN: 0/4000000 (000000010000000000000004, 00000000)
Starting backup copy via pg_basebackup for 20250213T100353
Copy done (time: 1 second)
Finalising the backup.
This is the first backup for server postgres1
WAL segments preceding the current backup have been found:
000000010000000000000002 from server postgres1 has been removed
Backup size: 22.3 MiB
Backup end at LSN: 0/6000000 (000000010000000000000006, 00000000)
Backup completed (start time: 2025-02-13 10:03:53.072228, elapsed time: 1 second)
Processing xlog segments from streaming for postgres1
000000010000000000000003
000000010000000000000004
WARNING: IMPORTANT: this backup is classified as WAITING_FOR_WALS, meaning that Barman has not received yet all the required WAL files for the backup consistency.
This is a common behaviour in concurrent backup scenarios, and Barman automatically set the backup as DONE once all the required WAL files have been archived.
Hint: execute the backup command with '--wait'
total 4.0K
$ ls /var/lib/barman/postgres1/base/ -lha
total 8.0K
drwxr-xr-x 1 barman barman 60 Feb 13 10:00 .
drwxr-xr-x 1 barman barman 88 Feb 13 09:59 ..
drwxr-xr-x 1 barman barman 30 Feb 13 09:59 20250213T095917
$ barman list-backups postgres1
postgres1 20250213T103723 - F - Thu Feb 13 10:37:24 2025 - Size: 22.3 MiB - WAL Size: 0 B - WAITING_FOR_WALS
J'ai réussi dans le POC https://github.com/stephane-klein/poc-barman à dérouler toutes les étapes du backup complet jusqu'à la restauration d'une base de données.
Toutefois, pour le moment, je n'ai toujours pas réussi à restaurer un backup incrémental 🙁.
À cet endroit, j'ai l'erreur suivante :
$ docker compose up postgres2
postgres2-1 | PostgreSQL Database directory appears to contain a database; Skipping initialization
postgres2-1 |
postgres2-1 | 2025-02-13 13:20:07.594 UTC [1] LOG: starting PostgreSQL 17.2 (Debian 17.2-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
postgres2-1 | 2025-02-13 13:20:07.594 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres2-1 | 2025-02-13 13:20:07.594 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres2-1 | 2025-02-13 13:20:07.596 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres2-1 | 2025-02-13 13:20:07.598 UTC [1] LOG: could not open directory "pg_tblspc": No such file or directory
postgres2-1 | 2025-02-13 13:20:07.600 UTC [29] LOG: database system was interrupted; last known up at 2025-02-13 13:20:03 UTC
postgres2-1 | 2025-02-13 13:20:07.643 UTC [29] LOG: could not open directory "pg_tblspc": No such file or directory
postgres2-1 | 2025-02-13 13:20:07.643 UTC [29] LOG: starting backup recovery with redo LSN 0/8000028, checkpoint LSN 0/8000080, on timeline ID 1
postgres2-1 | 2025-02-13 13:20:07.643 UTC [29] LOG: could not open directory "pg_tblspc": No such file or directory
postgres2-1 | 2025-02-13 13:20:07.649 UTC [29] FATAL: could not open directory "pg_tblspc": No such file or directory
postgres2-1 | 2025-02-13 13:20:07.651 UTC [1] LOG: startup process (PID 29) exited with exit code 1
postgres2-1 | 2025-02-13 13:20:07.651 UTC [1] LOG: aborting startup due to startup process failure
postgres2-1 | 2025-02-13 13:20:07.652 UTC [1] LOG: database system is shut down
Mercredi 12 février 2025
Journal du mercredi 12 février 2025 à 23:05
Suite de ma note 2025-02-12_1511.
J'ai passé 5h40 sur un POC de barman, mais je n'ai pas eu beaucoup plus de succès qu'avec pgBackRest. Décidément, ces outils ne m'aiment pas 😔.
Repository du POC : https://github.com/stephane-klein/poc-barman
La commande barman check streaming-server
retourne le message WAL archive: FAILED (please make sure WAL shipping is setup)
. Pour fixer cette erreur, je dois faire les manipulations suivantes que je trouve bizarre :
$ ./scripts/enter-in-pg1.sh
postgres=# select pg_switch_wal();
pg_switch_wal
---------------
0/206A330
(1 row)
et ensuite :
$ docker compose exec barman bash
root@5482aa5f8420:/# su barman
barman@5482aa5f8420:/$ barman cron
Starting WAL archiving for server streaming-server
barman@5482aa5f8420:/$ barman check streaming-server
Server streaming-server:
PostgreSQL: OK
superuser or standard user with backup privileges: OK
PostgreSQL streaming: OK
wal_level: OK
replication slot: OK
directories: OK
retention policy settings: OK
backup maximum age: OK (no last_backup_maximum_age provided)
backup minimum size: OK (0 B)
wal maximum age: OK (no last_wal_maximum_age provided)
wal size: OK (0 B)
compression settings: OK
failed backups: OK (there are 0 failed backups)
minimum redundancy requirements: OK (have 0 backups, expected at least 0)
pg_basebackup: OK
pg_basebackup compatible: OK
pg_basebackup supports tablespaces mapping: OK
systemid coherence: OK (no system Id stored on disk)
pg_receivexlog: OK
pg_receivexlog compatible: OK
receive-wal running: OK
archiver errors: OK
Je ne sais pas pourquoi je dois lancer select pg_switch_wal();
.
J'ai pourtant configuré checkpoint_timeout='60s'
:
command: >
postgres
-c wal_level=replica
-c summarize_wal=on
-c checkpoint_timeout='60s'
-c max_wal_size='100MB'
Je pensais que ce paramètre effectuait la même action que pg_switch_wal();
mais je constate que non.
Aussi, je constate que je dois aussi lancer pg_switch_wal();
pour que la commande suivante se termine :
barman@5482aa5f8420:/$ barman backup streaming-server --wait
Starting backup using postgres method for server streaming-server in /var/lib/barman/streaming-server/base/20250212T221703
Backup start at LSN: 0/5000B40 (000000010000000000000005, 00000B40)
Starting backup copy via pg_basebackup for 20250212T221703
Copy done (time: 1 second)
Finalising the backup.
Backup size: 22.3 MiB
Backup end at LSN: 0/7000000 (000000010000000000000007, 00000000)
Backup completed (start time: 2025-02-12 22:17:03.190492, elapsed time: 1 second)
Waiting for the WAL file 000000010000000000000007 from server 'streaming-server'
Processing xlog segments from streaming for streaming-server
000000010000000000000005
Processing xlog segments from streaming for streaming-server
000000010000000000000006
Je ne comprends pas non plus pourquoi.
Journal du mercredi 12 février 2025 à 15:53
Jusqu'à aujourd'hui, j'utilise la commande sleep infinity
pour garder en "vie" un container Docker qui n'exécute aucun service.
Exemple de docker-compose.yml
:
services:
ubuntu:
image: ubuntu
command: sleep infinity
Ce qui me permet d'entrer dans le container après son lancement en background :
$ docker compose up -d ubuntu
$ docker compose exec ubuntu bash
root@357466c4b52c:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
Aujourd'hui, j'ai découvert via Copilot une alternative préférable à sleep infinity
:
services:
ubuntu:
image: ubuntu
command: tail -f /dev/null
Cela fonctionne de la même manière, mais semble avoir l'avantage de ne pas dépendre de la dépendance sleep
🤔.
Journal du mercredi 12 février 2025 à 15:11
Je pense comprendre que pgBackRest ne permet pas d'utiliser des INET sockets pour communiquer avec PostgreSQL.
Toutefois, je me dis que je pourrais partager le volume
PGDATA
avec le sidecar pgBackRest pour lui donner accès à l'Unix Socket du Streaming Replication Protocol 🤔.
Je viens de me rappeler que pgBackRest a une seconde contrainte qui semble l'empêcher de fonctionner en Docker sidecar :
Backing up a running PostgreSQL cluster requires WAL archiving to be enabled. Note that at least one WAL segment will be created during the backup process even if no explicit writes are made to the cluster.
pg-primary:/etc/postgresql/15/demo/postgresql.conf
⇒ Configure archive settings :archive_command = 'pgbackrest --stanza=demo archive-push %p' archive_mode = on max_wal_senders = 3 wal_level = replica
Cela signifie que l'exécutable pgbackrest
doit être installé dans l'image Docker PostgreSQL.
Cela me pose un problème parce que mon objectif est de pouvoir utiliser un système de sauvegarde en Docker sidecar sans avoir à utiliser une image Docker PostgreSQL modifiée.
Cette contrainte ne semble pas présente avec barman qui propose 3 méthodes de backup :
La méthode postgres
utilise pg_basebackup et je pense qu'elle peut fonctionner en Docker sidecar.
#JaiDécidé d'explorer cette piste.
Journal du mercredi 12 février 2025 à 11:41
En rédigeant la note 2025-02-12_1044, je me suis demandé quelle est la différence de performance entre un Unix Socket et un INET socket.
Durant mes recherches, j'ai découvert qu'Unix Socket est plus rapide que INET sockets. Je n'ai pas été surpris, j'avais cette intuition.
Toutefois, j'ai été surpris d'apprendre que le gain est non négligeable, de 30% à 50% de gains !
Exemple :
On my machine, Ryzen 3900X, Ubuntu 22,
A basic C++ TCP server app that only sends 64K packets, and a basic c++ receiver that pulls 100GB of these packets and copies them to it's internal buffer only, single-threaded:
- achieves
~30-33 GBit/sec
for TCP connection (~4.0GB/sec
) (not MBit)- and
~55-58GBit/sec
for a socket connection, (~7.3 GB/sec
)- and
~492Gbit/sec
for in-process memcopy (~61GB /sec
)
Conséquence : je vais essayer d'utiliser des Unix sockets autant que je peux.
Journal du mercredi 12 février 2025 à 11:37
#JaiDécouvert le site Linux Performance de Brendan Gregg.
Journal du mercredi 12 février 2025 à 10:44
En travaillant sur le projet Projet 23 - "Ajouter le support pg_basebackup incremental à restic-pg_dump-docker", j'ai découvert que PostgreSQL propose deux protocoles de communication :
- Le premier est le plus connu "Frontend/Backend Protocol". C'est celui qui est utilisé par la commande
psql
ou les librairies telles que Postgres.js (en NodeJS), Psycopg (en Python)… - Le second nommé "Streaming Replication Protocol"
Sans vraiment comprendre, en 2020, j'avais activé le protocole streaming replication dans ce POC postgresql-streaming-replication-playground
. Mais je n'avais jamais pris conscience de l'existence de ce second protocole.
Les développeurs de PostgreSQL semblent avoir décidé de créer un second protocole parce qu'ils n'ont pas du tout le même objectif.
Streaming Replication Protocol est optimisé dans la transmission des WAL et des snapshots (copie de l'intégralité du dossier PGDATA
).
Le protocole Streaming Replication Protocol est entre autres utilisé par pg_basebackup, barman, pgBackRest, ou Patroni.
Comment activer Streaming Replication Protocol ?
Les images Docker Postgres setup par défaut le fichier pg_hba.conf suivant :
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
local replication all trust
host replication all 127.0.0.1/32 trust
host replication all ::1/128 trust
host all all all scram-sha-256
J'ai compris que par défaut, toutes ces lignes configurent l'accès au Frontend/Backend Protocol.
Seules les lignes qui contiennent replication
configurent l'accès au Streaming Replication Protocol.
Pour permettre l'accès au Streaming Replication Protocol par réseau TCP/IP en dehors du container Docker il est nécessaire d'ajouter la ligne suivante :
host replication all all scram-sha-256
Suite à cette découverte, j'ai repensé à :
Pour faire face à ce problème, j'ai exploré fin 2023 une solution basée sur pgBackRest : Implémenter un POC de pgBackRest.
Je suis plus ou moins arrivé au bout de ce POC mais je n'ai pas été satisfait du résultat.
Je n'ai pas réussi à configurer pgBackRest en "pure Docker sidecar".
De plus, j'ai trouvé la restauration du backup difficile à exécuter.
et je me suis demandé si mon échec de configuration de pgBackRest en Docker sidecar n'était pas seulement dû au fait que je n'avais pas activé Streaming Replication Protocol 🤔.
La réponse semble être "oui" et "non".
Je suis tombé sur l'issue suivante : pgbackrest with postgresql in docker.
The problem might be harder than you think unfortunately. If the pgBackRest process is running on the VM (docker host), it will try to connect to PG locally using the unix socket, not the tcp "localhost" connection.
Je pense comprendre que pgBackRest ne permet pas d'utiliser des INET sockets pour communiquer avec PostgreSQL.
Toutefois, je me dis que je pourrais partager le volume PGDATA
avec le sidecar pgBackRest pour lui donner accès à l'Unix Socket du Streaming Replication Protocol 🤔.
Entre mon exploration de pg_basebackup, mes envies de tester barman et de continuer mon POC pgBackRest… je me dis que je ne suis pas encore au bout de ce Yak!.
Mardi 11 février 2025
Journal du mardi 11 février 2025 à 16:18
Suite de mes notes 2025-02-03_1718 et 2025-02-04_1136 au sujet des régimes de TVA.
Cette après-midi, j'ai envoyé le message suivant à mon centre des impôts :
Bonjour,
J'ai bien noté de votre réponse suivante lors de notre dernier échange par message :
Je vous remercie d’envoyer une lettre d’option à la TVA datée et signée en spécifiant le régime demandé.
J'ai trouvé un modèle de lettre que je n'ai pas encore totalement rempli :
Avant de faire mon choix, j'ai quelques questions :
- a. En régime réel simplifié de TVA, comment est calculé le montant de l'acompte ? J'ai lu qu'il est basé sur le chiffre d'affaires N-1, mais est-ce qu'il est possible de modifier le montant de cet acompte si je sais déjà que mon chiffre d'affaires sera en baisse ou en hausse ?
- b. Pouvez-vous me confirmer que ma déclaration devrait se faire sur la page web indiquée dans le screenshot en pièce jointe ?
- c. Est-ce que la déclaration doit s'effectuer en fonction de la date d'émission de la facture ou alors de sa date d'encaissement ?
Cordialement, Stéphane Klein
Fort de l'expérience tirée de mon précédent message, j'ai décidé d'appeler le centre des impôts pour obtenir des réponses à mes questions.
Ce fut une excellente décision : voici les réponses que j'ai acquises à l'oral.
- a. En régime réel simplifié de TVA, comment est calculé le montant de l'acompte ? J'ai lu qu'il est basé sur le chiffre d'affaires N-1, mais est-ce qu'il est possible de modifier le montant de cet acompte si je sais déjà que mon chiffre d'affaires sera en baisse ou en hausse ?
Réponse :
Oui, il est possible de modifier manuellement le montant de l'acompte. Toutefois, en déclarant un acompte inférieur à celui basé sur le chiffre d'affaires de l'année N-1, l'administration fiscale tolère une marge d'erreur de 10 % par rapport au chiffre d'affaires de l'année N.
Prenons l'exemple d'une entreprise en régime réel simplifié de TVA.
- En N-1, son chiffre d'affaires était de 100 000 €.
- Le montant des acomptes de TVA est donc calculé sur cette base.
L'entreprise prévoit une baisse d'activité en N et estime son chiffre d'affaires à 85 000 €. Elle souhaite ajuster son acompte en conséquence.
Tolérance de 10 % sur le chiffre d'affaires N : Si, en fin d'année N, le chiffre d'affaires réel est finalement de 90 000 €, alors l'acompte déclaré (basé sur 85 000 €) reste dans la marge d'erreur de 10 % et ne posera pas de problème fiscal.
En revanche, si le chiffre d'affaires réel s'avère être de 95 000 € ou plus, alors l'acompte a été sous-estimé au-delà de la tolérance, ce qui pourrait entraîner un redressement ou des pénalités.
Pouvez-vous me confirmer que ma déclaration devrait se faire sur la page web indiquée dans le screenshot en pièce jointe ?
La réponse est non.
c. Est-ce que la déclaration doit s'effectuer en fonction de la date d'émission de la facture ou alors de sa date d'encaissement ?
Pour une activité de prestation de services, la TVA est déclarée sur la base de la date d’encaissement de la facture, et non de sa date d’émission.
Information supplémentaire que j'ai reçue.
Le seuil de franchise en base de TVA de 34 400 € en prestations de services est calculé sur la base d'une année civile. Concernant ma micro-entreprise, j'ai encaissé moins de 34 400 € au 31 décembre 2024. Par conséquent, je n'étais pas obligé de quitter le régime de franchise en base de TVA. Toutefois, j'ai facturé de la TVA dans ma 4ᵉ facture de 2024, par conséquent, je dois la déclarer, quoi qu'il arrive.
Suite à ces réponses, j'ai décidé d'opter pour l'option "Régime réel simplifié d'imposition à la TVA". Je vais envoyer un courrier (template) pour faire cette demande.
Journal du mardi 11 février 2025 à 12:30
#JaiDécouvert ici le site web Décodage Fiscal (https://decodage-fiscal.fr/).
Par le passé, j'avais déjà repéré et utilisé d'autres outils similaires, notamment l'outil officiel de l'URSSAF : L'assistant officiel des entrepreneurs (https://mon-entreprise.urssaf.fr/).
À ce jour, Décodage Fiscal est celui que je trouve le plus complet, avec la meilleure interface utilisateur.
Dimanche 9 février 2025
Journal du dimanche 09 février 2025 à 17:05
J'utilise depuis 2019 les containers Docker suivant en sidecar pour sauvegarder automatiquement et régulièrement directement un volume Docker et un volume PostgreSQL :
restic-pg_dump-docker est très pratique et facile d'usage, voici un exemple d'utilisation dans un docker-compose.yml
:
restic-pg-dump:
image: stephaneklein/restic-pg_dump:latest
environment:
AWS_ACCESS_KEY_ID: "admin"
AWS_SECRET_ACCESS_KEY: "password"
RESTIC_REPOSITORY: "s3:http://minio:9000/bucket1"
RESTIC_PASSWORD: secret
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_HOST: postgres
POSTGRES_DB: postgres
postgres:
image: postgres:16.1
environment:
POSTGRES_USER: postgres
POSTGRES_DB: postgres
POSTGRES_PASSWORD: password
ports:
- "5432:5432"
volumes:
- ./volumes/postgres/:/var/lib/postgresql/data/
healthcheck:
test: ["CMD", "sh", "-c", "pg_isready -U $$POSTGRES_USER -h $$(hostname -i)"]
interval: 10s
start_period: 30s
Il suffit de configurer les paramètres d'accès à l'instance PostgreSQL à sauvegarder et ceux de l'Object Storage où uploader les backups. Rien de plus, 😉.
Pour plus de paramètres, voir la section Configuration du README.md.
Cependant, je ne suis pas totalement satisfait de restic-pg_dump-docker. Cet outil effectue seulement des sauvegardes complètes de la base de données.
Ceci ne pose généralement pas trop de problème quand la base de données est d'une taille modeste, mais c'est bien plus compliqué dès que celle-ci fait, par exemple, plusieurs centaines de mégas.
Pour faire face à ce problème, j'ai exploré fin 2023 une solution basée sur pgBackRest : Implémenter un POC de pgBackRest.
Je suis plus ou moins arrivé au bout de ce POC mais je n'ai pas été satisfait du résultat.
Je n'ai pas réussi à configurer pgBackRest en "pure Docker sidecar".
De plus, j'ai trouvé la restauration du backup difficile à exécuter.
Un élément a changé depuis septembre 2024. Comme je le disais dans cette note 2024-11-03_1151, la version 17 de PostgreSQL propose de nouvelles options de sauvegarde :
- l'outil pg_basebackup qui permet de réaliser les sauvegardes incrémentales,
- et un nouvel utilitaire, pg_combinebackup, qui permet de reconstituer une sauvegarde complète à partir de sauvegardes incrémentales.
Cette nouvelle méthode semble apporter certains avantages par rapport aux solutions basées sur WAL comme pgBackRest ou barman.
Une consommation d'espace réduite :
In this mailing list thread on the Postgres-hackers mailing list, Jakub from EDB ran a test. This is a pgbench test. The idea is that the data size doesn't really change much throughout this test. This is a 24 hour long test. At the start the database is 3.3GB. At the end, the database is 4.3GB. Then, as it's running, it's continuously running pgbench workloads. In those 24 hours, if you looked at the WAL archive, there were 77 GB of WAL produced.
That's a lot of WAL to replay if you wanted to restore to a particular point in time within that timeframe!
Jakub ran one full backup in the beginning and then incremental backups every two hours. The full backup in the beginning is 3.4 GB, but then all the 11 other backups are 3.5 in total, they're essentially one 10th of a full backup size.
Une vitesse de restauration grandement accélérée :
A 10x time safe
What Jakub tested then was the restore to a particular point in time. Previously, to restore to a particular point in time would take more than an hour to replay the WAL versus in this case because we have more frequent, incremental backups, it's going to be much, much faster to restore. In this particular test case 78 minutes compared to 4 minutes. This is a more than a 10 times improvement in recovery time. Of course you won't necessarily always see this amount of benefit, but I think this shows why you might want to do this. It is because you want to enable more frequent backups and incremental backups are the way to do that.
Nombre 2024 j'ai passé un peu de temps à étudier les solutions de backup qui utilisent la nouvelle fonctionnalité de PostgreSQL 17, mais je n'avais rien trouvé
Je viens à nouveau de chercher dans les archives de Postgre Weely, sur GitHub, sur le forum de Restic, etc., et je n'ai rien trouvé d'intéressant.
#JaiDécidé de prendre les choses en main et de faire évoluer le projet restic-pg_dump-docker pour y ajouter le support du backup incrémental de PostgreSQL 17.
Voir : Projet 23 - "Ajouter le support pg_basebackup incremental à restic-pg_dump-docker".
Vendredi 7 février 2025
Journal du vendredi 07 février 2025 à 16:12
Exemples d'outils qui suivent de modèle Orchestration Push Mode :
Exemples d'outils qui suivent le modèle Orchestration Pull Mode :
Journal du vendredi 07 février 2025 à 14:03
Pendant l'année 2014, Athoune m'a fait découvrir les concepts DevOps "Baking" et "Frying".
Je le remercie, car ce sont des concepts que je considère très importants pour comprendre les différents paradigmes de déploiement.
Je n'ai aucune idée dans quelles conditions il avait découvert ces concepts. J'ai essayé de faire des recherches limitées à l'année 2014 et je suis tombé sur cette photo :
J'en déduis que cela devait être un sujet à la méthode dans l'écosystème DevOps de 2014.
Cet ami me l'avait très bien expliqué avec une analogie du type :
« Le baking en DevOps, c’est comme dans un restaurant où les plats sont préparés en cuisine et ensuite apportés tout prêt salle à la table du client. Le frying, c’est comme si le plat était préparé directement en salle sur la table du client. »
Bien que cette analogie ne soit pas totalement rigoureuse, elle m'a bien permis de saisir, en 2014, le paradigme Docker qui consiste à préparer des images de container en amont. Ce paradigme permet d'installer, de configurer ces images "en cuisine", donc pas sur les serveurs de production, "de goûter les plats" et de les envoyer ensuite de manière prédictible sur le serveur de production.
Ces images peuvent être construites soit sur la workstation du développeur ou mieux, sur des serveurs dédiés à cette fonction, comme Gitlab-Runner…
Définitions proposées par LLaMa :
Baking (ou "Image Baking") : Il s'agit de créer une image de serveur prête à l'emploi, avec tous les logiciels et les configurations nécessaires déjà installés et configurés. Cette image est ensuite utilisée pour déployer de nouveaux serveurs, qui seront ainsi identiques et prêts à fonctionner immédiatement. L'avantage de cette approche est qu'elle permet de réduire le temps de déploiement et d'assurer la cohérence des environnements.
Frying (ou "Server Frying") : Il s'agit de déployer un serveur "nu" et de le configurer et de l'installer à la volée, en utilisant des outils d'automatisation tels que Ansible, Puppet ou Chef. Cette approche permet de personnaliser la configuration de chaque serveur en fonction des besoins spécifiques de l'application ou du service.
Exemple :
Cas d'usage Baking Frying Docker Construire une image complète ( docker build
) et la stocker dans un registreLancer un conteneur minimal et installer les dépendances au démarrage. Machines virtuelles (VMs) Créer une image VM avec Packer et la déployer telle quelle Démarrer une VM de base et appliquer un script d’installation à la volée CI/CD Compiler et packager une application en image prête à être déployée Construire l’application à chaque déploiement sur la machine cible
En 2014, lorsque le concept de baking m’a été présenté, j’ai immédiatement été enthousiasmé, car il répondait à trois problèmes que je cherchais à résoudre :
- Réduire les risques d’échec d’une installation sur le serveur de production
- Limiter la durée de l’indisponibilité (pendant la phase d’installation)
- Éviter d'augmenter la charge du serveur durant les opérations de build lors de l’installation
Depuis, j'évite au maximum le frying et j'ai intégré le baking dans ma doctrine d'artisan développeur.
Comment tu déploies tes containers Docker en production sans Kubernetes ?
Début novembre un ami me posait la question :
Quand tu déploies des conteneurs en prod, sans k8s, tu fais comment ?
Après 3 mois d'attente, voici ma réponse 🙂.
Mon contexte
Tout d'abord, un peu de contexte. Cela fait 25 ans que je travaille sur des projets web, et tous les projets sur lesquels j'ai travaillé pouvaient être hébergés sur un seul et unique serveur baremetal ou une Virtual machine, sans jamais nécessiter de scalabilité horizontale.
Je n'ai jamais eu besoin de serveurs avec plus de 96Go de RAM pour faire tourner un service en production. Il convient de noter que, dans 80% des cas, 8 Go ou 16 Go étaient largement suffisants.
Cela dit, j'ai également eu à gérer des infrastructures comportant plusieurs serveurs : 10, 20, 30 serveurs. Ces serveurs étaient généralement utilisés pour héberger une infrastructure de soutien (Platform infrastructure) à destination des développeurs. Par exemple :
- Environnements de recettage
- Serveurs pour faire tourner Gitlab-Runner
- Sauvegarde des données
- Etc.
Ce contexte montre que je n'ai jamais eu à gérer le déploiement de services à très forte charge, comme ceux que l'on trouve sur des plateformes telles que Deezer, le site des impôts, Radio France, Meetic, la Fnac, Cdiscount, France Travail, Blablacar, ou encore Doctolib. La méthode que je décris dans cette note ne concerne pas ce type d'infrastructure.
Ma méthode depuis 2015
Dans cette note, je ne vais pas retracer l'évolution complète de mes méthodes de déploiement, mais plutôt me concentrer sur deux d'entre elles : l'une que j'utilise depuis 2015, et une déclinaison adoptée en 2020.
Voici les principes que j'essaie de suivre et qui constituent le socle de ma doctrine en matière de déploiement de services :
- Je m'efforce de suivre le modèle Baking autant que possible (voir ma note 2025-02-07_1403), sans en faire une approche dogmatique ou extrémiste.
- J'applique les principes de The Twelve-Factors App.
- Je privilégie le paradigme Remote Task Execution, ce qui me permet d'adopter une approche GitOps.
- J'utilise des outils d'orchestration prenant en charge le mode push (voir note 2025-02-07_1612), comme Ansible, et j'évite le mode pull.
En pratique, j'utilise Ansible pour déployer un fichier docker-compose.yml sur le serveur de production et ensuite lancer les services.
Je précise que cette note ne traite pas de la préparation préalable du serveur, de l'installation de Docker, ni d'autres aspects similaires. Afin de ne pas alourdir davantage cette note, je n'aborde pas non plus les questions de Continuous Integration ou de Continuous Delivery.
Imaginons que je souhaite déployer le lecteur RSS Miniflux connecté à un serveur PostgreSQL.
Voici les opérations effectuées par le rôle Ansible à distance sur le serveur de production :
-
- Création d'un dossier
/srv/miniflux/
- Création d'un dossier
-
- Upload de
/srv/miniflux/docker-compose.yml
avec le contenu suivant :
- Upload de
services:
postgres:
image: postgres:17
restart: unless-stopped
environment:
POSTGRES_DB: miniflux
POSTGRES_USER: miniflux
POSTGRES_PASSWORD: password
volumes:
- postgres:/var/lib/postgresql/data/
healthcheck:
test: ['CMD', 'pg_isready']
interval: 10s
start_period: 30s
miniflux:
image: miniflux/miniflux:2.2.5
ports:
- 8080:8080
environment:
DATABASE_URL: postgres://miniflux:password@postgres/miniflux?sslmode=disable
RUN_MIGRATIONS: 1
CREATE_ADMIN: 1
ADMIN_USERNAME: johndoe
ADMIN_PASSWORD: secret
healthcheck:
test: ["CMD", "/usr/bin/miniflux", "-healthcheck", "auto"]
depends_on:
postgres:
condition: service_healthy
volumes:
postgres:
name: miniflux_postgres
-
- Depuis le dossier
/srv/miniflux/
lancement de la commandedocker compose up -d --remove-orphans --wait --pull always
- Depuis le dossier
Voilà, c'est tout 🙂.
En 2020, j'enlève "une couche"
J'aime enlever des couches et en 2020, je me suis demandé si je pouvais pratiquer avec élégance la méthode Remote Execution sans Ansible.
Mon objectif était d'utiliser seulement ssh et un soupçon de Bash.
Voici le résultat de mes expérimentations.
J'ai besoin de deux fichiers.
_payload_deploy_miniflux.sh
deploy_miniflux.sh
Voici le contenu de _payload_deploy_miniflux.sh
:
#!/usr/bin/env bash
set -e
PROJECT_FOLDER="/srv/miniflux/"
mkdir -p ${PROJECT_FOLDER}
cat <<EOF > ${PROJECT_FOLDER}docker-compose.yaml
services:
postgres:
image: postgres:17
restart: unless-stopped
environment:
POSTGRES_DB: miniflux
POSTGRES_USER: miniflux
POSTGRES_PASSWORD: {{ .Env.MINIFLUX_POSTGRES_PASSWORD }}
volumes:
- postgres:/var/lib/postgresql/data/
healthcheck:
test: ['CMD', 'pg_isready']
interval: 10s
start_period: 30s
miniflux:
image: miniflux/miniflux:2.2.5
ports:
- 8080:8080
environment:
DATABASE_URL: postgres://miniflux:{{ .Env.MINIFLUX_POSTGRES_PASSWORD }}@postgres/miniflux?sslmode=disable
RUN_MIGRATIONS: 1
CREATE_ADMIN: 1
ADMIN_USERNAME: johndoe
ADMIN_PASSWORD: {{ .Env.MINIFLUX_ADMIN_PASSWORD }}
healthcheck:
test: ["CMD", "/usr/bin/miniflux", "-healthcheck", "auto"]
depends_on:
postgres:
condition: service_healthy
volumes:
postgres:
name: miniflux_postgres
EOF
cd ${PROJECT_FOLDER}
docker compose pull
docker compose up -d --remove-orphans --wait
Voici le contenu de deploy_miniflux.sh
:
#!/usr/bin/env bash
set -e
cd "$(dirname "$0")/../"
gomplate -f _payload_deploy_miniflux.sh | ssh root@$SERVER1_IP 'bash -s'
J'utilise gomplate pour remplacer dynamiquement les secrets dans le script _payload_deploy_miniflux.sh
.
En conclusion, pour déployer une nouvelle version, j'ai juste à exécuter :
$ ./deploy_miniflux.sh
Je trouve cela minimaliste et de plus, l'exécution est bien plus rapide que la solution Ansible.
Ce type de script peut ensuite être exécuté aussi bien manuellement par un développeur depuis sa workstation, que via GitLab-CI ou même Rundeck.
Pour un exemple plus détaillé, consultez ce repository : https://github.com/stephane-klein/poc-bash-ssh-docker-deployement-example
Bien entendu, si vous souhaitez déployer votre propre application que vous développez, vous devez ajouter à cela la partie baking, c'est-à-dire, le docker build
qui prépare votre image, l'uploader sur un Docker registry… Généralement je réalise cela avec GitLab-CI/CD ou GitHub Actions.
Objections
Certains DevOps me disent :
- « Mais on ne fait pas ça pour de la production ! Il faut utiliser Kubernetes ! »
- « Comment ! Tu n'utilises pas Kubernetes ? »
Et d'autres :
- « Il ne faut au grand jamais utiliser
docker-compose
en production ! »
Ne jamais utiliser docker compose en production ?
J'ai reçu cette objection en 2018. J'ai essayé de comprendre les raisons qui justifiaient que ce développeur considère l'usage de docker compose en production comme un Antipattern.
Si mes souvenirs sont bons, je me souviens que pour lui, la bonne méthode conscistait à déclarer les états des containers à déployer avec le module Ansible docker_container (le lien est vers la version de 2018, depuis ce module s'est grandement amélioré).
Je n'ai pas eu plus d'explications 🙁.
J'ai essayé d'imaginer ses motivations.
J'en ai trouvé une que je ne trouve pas très pertinente :
- Uplodaer un fichier
docker-compose.yml
en production pour ensuite lancer des fonctions distantes sur celui-ci est moins performant que manipulerdocker-engine
à distance.
J'en ai imaginé une valable :
- En déclarant la configuration de services Docker uniquement dans le rôle Ansible cela garantit qu'aucun développeur n'ira modifier et manipuler directement le fichier
docker-compose.yml
sur le serveur de production.
Je trouve que c'est un très bon argument 👍️.
Cependant, cette méthode a à mes yeux les inconvénients suivants :
- Je maitrise bien mieux la syntaxe de docker compose que la syntaxe du module Ansible community.docker.docker_container
- J'utilise docker compose au quotidien sur ma workstation et je n'ai pas envie d'apprendre une syntaxe supplémentaire uniquement pour le déploiement.
- Je pense que le nombre de développeurs qui maîtrisent docker compose est suppérieur au nombre de ceux qui maîtrisent le module Ansible
community.docker.docker_container
. - Je ne suis pas utilisateur maximaliste de la méthode Remote Execution. Dans certaines circonstances, je trouve très pratique de pouvoir manipuler docker compose dans une session ssh directement sur un serveur. En période de stress ou de debug compliqué, je trouve cela pratique. J'essaie d'être assez rigoureux pour ne pas oublier de reporter mes changements effectués directement le serveur dans les scripts de déploiements (configuration as code).
Tu dois utiliser Kubernetes !
Alors oui, il y a une multitude de raisons valables d'utiliser Kubernetes. C'est une technologie très puissante, je n'ai pas le moindre doute à ce sujet.
J'ai une expérience dans ce domaine, ayant utilisé Kubernetes presque quotidiennement dans un cadre professionnel de janvier 2016 à septembre 2017. J'ai administré un petit cluster auto-managé composé de quelques nœuds et y ai déployé diverses applications.
Ceci étant dit, je rappelle mon contexte :
Cela fait 25 ans que je travaille sur des projets web, et tous les projets sur lesquels j'ai travaillé pouvaient être hébergés sur un seul et unique serveur baremetal ou une Virtual machine, sans jamais nécessiter de scalabilité horizontale.
Je n'ai jamais eu besoin de serveurs avec plus de 96Go de RAM pour faire tourner un service en production. Il convient de noter que, dans 80% des cas, 8 Go ou 16 Go étaient largement suffisants.
Je pense que faire appel à Kubernetes dans ce contexte est de l'overengineering.
Je dois avouer que j'envisage d'expérimenter un usage minimaliste de K3s (attention au "3", je n'ai pas écrit k8s) pour mes déploiements. Mais je sais que Kubernetes est un rabbit hole : Helm, Kustomize, Istio, Helmfile, Grafana Tanka… J'ai peur de tomber dans un Yak!.
D'autre part, il existe déjà un pourcentage non négligeable de développeur qui ne maitrise ni Docker, ni docker compose et dans ces conditions, faire le choix de Kubernetes augmenterait encore plus la barrière à l'entrée permettant à des collègues de pouvoir comprendre et intervenir sur les serveurs d'hébergement.
C'est pour cela que ma doctrine d'artisan développeur consiste à utiliser Kubernetes seulement à partir du moment où je rencontre des besoins de forte charge, de scalabilité.
Journal du vendredi 07 février 2025 à 10:48
Note de type #mémento pour ajouter le support healthcheck
à nginx-proxy et nginx-proxy acme-companion.
J'ai effectué des recherches dans les dépôts GitHub des projets :
- nginx-proxy « health », j'ai trouvé :
- acme-companion « health », j'ai trouvé :
J'ai aussi trouvé « Adding health check support to nginx-proxy nginx.tmpl file · nginx-proxy/nginx-proxy » qui est un sujet qui m'intéresse, mais pas en lien avec le sujet de cette note.
N'ayant rien trouvé de clés en main, voici ci-dessous mon implémentation.
Je ne suis pas certain qu'elle soit très robuste 🤔.
Elle a tout de même l'avantage de me permettre d'utiliser l'option --wait
dans docker-compose up -d --remove-orphans --wait
.
J'ai partagé aussi posté un commentaire à l'issue pour partager mon implémentation.
# docker-compose.yml
services:
nginx-proxy:
image: nginxproxy/nginx-proxy:1.6.4
container_name: nginx-proxy
restart: unless-stopped
network_mode: "host"
volumes:
- ./vhost.d/:/etc/nginx/vhost.d:rw
- ./htpasswd:/etc/nginx/htpasswd:ro
- html:/usr/share/nginx/html
- certs:/etc/nginx/certs:ro
- /var/run/docker.sock:/tmp/docker.sock:ro
healthcheck:
test: ["CMD-SHELL", "nginx -t && kill -0 $$(cat /var/run/nginx.pid)"]
interval: 10s
timeout: 2s
retries: 3
acme-companion:
image: nginxproxy/acme-companion:2.5.1
restart: unless-stopped
volumes_from:
- nginx-proxy
depends_on:
- "nginx-proxy"
environment:
DEFAULT_EMAIL: contact@stephane-klein.info
volumes:
- certs:/etc/nginx/certs:rw
- acme:/etc/acme.sh
- /var/run/docker.sock:/var/run/docker.sock:ro
healthcheck:
test: ["CMD-SHELL", "ps aux | grep -v grep | grep -q '/bin/bash /app/start.sh'"]
interval: 30s
timeout: 3s
retries: 3
start_period: 10s
volumes:
html:
certs:
acme:
Jeudi 6 février 2025
Je viens de découvrir le projet Fastlane (https://fastlane.tools/).
Je pense que c'est l'outil qui me manquait pour suivre le paradigme configuration as code dans mon "Projet 17 - Créer un POC de création d'une app smartphone avec Capacitor".
Ce projet a commencé en 2014 par Felix Krause et repris par Google en 2017 : « fastlane is joining Google - Felix Krause ».
Mais, je découvre que Google semble avoir arrêter de financer le développement du projet en 2023 : Google is no longer sponsoring Fastlane | Hacker News.
Depuis, le projet semble être toujours actif avec de nombreuses release : https://github.com/fastlane/fastlane/releases.
Fonctionnalités de Fastlane qui m'intéressent tout particulièrement :
Fastlane permet aussi d'automatiser de nombreuses autres tâches que je n'ai pas encore pris le temps d'explorer : https://docs.fastlane.tools/actions/.
Installation de Fastlane avec Mise que j'ai testée sous Fedora et MacOS :
[tools]
ruby = '3.1.6' # for fastlane
fastlane = "2.226.0"
[alias]
fastlane = "https://github.com/mollyIV/asdf-fastlane.git"
(Toujours aussi pénibles ces outils développés en Ruby 😔)
À noter que sous MacOS j'ai dû lancer :
$ mise install -f fastlane
Parce que lors du premier lancement de mise install
, j'ai l'impression qu'il a essayé d'installer fastlane
avec l'instance ruby native de l'OS.
J'ai cherché s'il existe une option pour préciser que fastlane
doit utiliser ruby
installé par Mise, mais je n'ai pas trouvé.
17:05 - Solution pour contourner le problème mentionné ci-dessus :
$ mise install ruby
$ mise install
Mercredi 5 février 2025
Journal du mercredi 05 février 2025 à 18:32
Un ami m'a fait découvrir uv (https://github.com/astral-sh/uv).
Je trouve cela amusant de constater que Rust prend en charge de plus en plus d'outils pour différents langages 😉.
Le projet a commencé fin 2023.
Voici un thread Hacker News de 200 commentaires à ce sujet qui date de février 2024 : Uv: Python packaging in Rust .
L'article de ce thread contient beaucoup d'éléments intéressants : https://astral.sh/blog/uv
Son nom uv
semble être une référence à uvloop.
J'en ai profité pour migrer le playground mise-python-flask-playground
de pip vers uv : https://github.com/stephane-klein/mise-python-flask-playground/commit/2f1678798cfc6749dcfdb514a8fe4a3e54739844.
J'ai lancé une installation et effectivement, sa rapidité est très impressionnante :
$ uv pip install -r requirements.txt
Resolved 15 packages in 245ms
Prepared 15 packages in 176ms
Installed 15 packages in 37ms
+ alembic==1.14.1
+ blinker==1.9.0
+ click==8.1.8
+ flask==3.1.0
+ flask-migrate==4.1.0
+ flask-sqlalchemy==3.1.1
+ greenlet==3.1.1
+ itsdangerous==2.2.0
+ jinja2==3.1.5
+ mako==1.3.9
+ markupsafe==3.0.2
+ psycopg2-binary==2.9.10
+ sqlalchemy==2.0.37
+ typing-extensions==4.12.2
+ werkzeug==3.1.3
uv ne propose pas seulement une amélioration de l'installation de packages Python, mais propose beaucoup d'autres choses comme :
- L'installation de Python : https://docs.astral.sh/uv/guides/install-python/
Pour cette partie, dans un but d'unification, je continuerai à utiliser Mise pour installer une version précise de Python. De plus, Mise intègre nativement UV : https://mise.jdx.dev/mise-cookbook/python.html#mise-uv
- Système pour lancer des scripts Python : https://docs.astral.sh/uv/guides/scripts/
Exemple :
$ uv run example.py
Je pense avoir compris que cela lance ce script avec les dépendances du virtual environment du projet. Un peu comme fonctionne npm, yarn ou pnpm qui permet aux scripts d'utiliser les packages présents dans ./node_modules/
.
- Permet de lancer des outils : https://docs.astral.sh/uv/guides/tools/
Par exemple, le linter Python ruff, exemple :
$ uv tool run ruff
- uv met à disposition des images Docker : https://docs.astral.sh/uv/guides/integration/docker/
J'ai un peu parcouru la documentation de pyproject.toml : https://packaging.python.org/en/latest/guides/writing-pyproject-toml/.
J'ai lu aussi la section uv - Locking environments.
Suite à ces lectures, j'ai migré le playground mise-python-flask-playground
vers pyproject.toml : https://github.com/stephane-klein/mise-python-flask-playground/commit/c17216464778df4bc00bf782d5a889cb3f198051.
Je ne suis pas certain que ces commandes soient une bonne pratique :
$ uv pip compile requirements.in -o requirements.txt
$ uv pip install -r requirements.txt
Je précise que je n'ai pas eu l'occasion de tester l'installation sous Windows, hier j'ai essayé, mais je n'ai pas réussi à installer WSL2 sous Windows dans un Virtualbox lancé sous Fedora. Je suis à la recherche d'une personne pour tester si mes instructions d'installation sont valides ou non.
Merci à Alexandre 🤗 qui a pris le temps de tester l'installation sous WSL2 du playground que j'ai présenté dans "Playground qui présente comment je setup un projet Python Flask en 2025".
Le playground : https://github.com/stephane-klein/mise-python-flask-playground
Après quelques petites corrections https://github.com/stephane-klein/mise-python-flask-playground/commits/main/ Alexandre a réussi avec succès à installer et lancer tous les services sous Windows 11 avec WSL2.
C'est une très bonne nouvelle 🙂.
Cela ajoute une « corde à mon arc ». Jusqu'à présent, je précisais bien que mes development kit n'étaient pas compatible MS Windows. Je le mentionnais même dans mes annonces d'embauche, pour ne pas surprendre les candidats.
Maintenant, mes environnements de développement sont compatibles Linux, MacOS, et Linux 🙂.
Je n'ai pas réussi à installer WSL2 sous Windows dans un Virtualbox lancé sous Fedora
Après avoir réussi à lancer Windows 11 sous ma Fedora dans VirtualBox (voir 2025-02-04_1646), j'ai essayé d'installer et de lancer WSL2, mais je n'ai pas réussi 🙁.
Je suis resté bloqué à cette étape :
vagrant@WIN11 C:\Users\vagrant>wsl --install
Ubuntu est déjà installé.
Lancement de Ubuntu...
Installing, this may take a few minutes...
WslRegisterDistribution failed with error: 0x80370102
Please enable the Virtual Machine Platform Windows feature and ensure virtualization is enabled in the BIOS.
For information please visit https://aka.ms/enablevirtualization
Press any key to continue...
L’opération a réussi.
Même avec ces options :
win11.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--nested-hw-virt", "on"]
vb.customize ["modifyvm", :id, "--paravirtprovider", "kvm"]
vb.customize ["modifyvm", :id, "--cpu-profile", "host"]
vb.cpus = 4
vb.memory = 16000
end
end
Windows ne semble pas vouloir lancer Hyper-v dans un VirtualBox.
J'ai essayé différents paramètres pour --paravirtprovider
, sans succès.
Si quelqu'un a la solution, je suis preneur ! (contact@stephane-klein.info).
Playground qui présente comment je setup un projet Python Flask en 2025
Je pense que cela doit faire depuis 2015 que je n'ai pas développé une application en Python Flask !
Entre 2008 et 2015, j'ai beaucoup itéré dans mes méthodes d'installation et de setup de mes environnements de développement Python.
D'après mes souvenirs, si je devais dresser la liste des différentes étapes, ça donnerai ceci :
- 2006 : aucune méthode, j'installe Python 🙂
- 2007 : je me bats avec setuptools et distutils (mais ça va, c'était plus mature que ce que je pouvais trouver dans le monde PHP qui n'avait pas encore imaginé composer)
- 2008 : je trouve la paie avec virtualenv
- 2010 : j'ai peur d'écrire des scripts en Bash alors à la place, j'écris un script
bootstrap.py
dans lequel j'essaie d'automatiser au maximum l'installation du projet - 2012 : je me bats avec buildout pour essayer d'automatiser des éléments d'installation. Avec le recul, je réalise que je n'ai jamais rien compris à buildout
- 2012 : j'utilise Vagrant pour fixer les éléments d'installation, je suis plutôt satisfait
- 2015 : je suis radicale, j'enferme tout l'environnement de dev Python dans un container de développement, je monte un path volume pour exposer le code source du projet dans le container. Je bricole en
entrypoint
avec la commande "sleep".
Des choses ont changé depuis 2015.
Mais, une chose que je n'ai pas changée, c'est que je continue à suivre le modèle The Twelve-Factors App et je continue à déployer tous mes projets packagé dans des images Docker. Généralement avec un simple docker-compose.yml
sur le serveur, ou alors Kubernetes pour des projets de plus grande envergure… mais cela ne m'arrive jamais en pratique, je travaille toujours sur des petits projets.
Choses qui ont changé : depuis fin 2018, j'ai décidé de ne plus utiliser Docker dans mes environnements de développement pour les projets codés en NodeJS, Golang, Python…
Au départ, cela a commencé par uniquement les projets en NodeJS pour des raisons de performance.
J'ai ensuite découvert Asdf et plus récemment Mise. À partir de cela, tout est devenu plus facilement pour moi.
Avec Asdf, je n'ai plus besoin "d'enfermer" mes projets dans des containers Docker pour fixer l'environnement de développement, les versions…
Cette introduction est un peu longue, je n'ai pas abordé le sujet principal de cette note 🙂.
Je viens de publier un playground d'un exemple de projet minimaliste Python Flask suivant mes pratiques de 2025.
Voici son repository : mise-python-flask-playground
Ce playground est "propulsé" par Docker et Mise.
J'ai documenté la méthode d'installation pour :
- Linux (Fedora (distribution que j'utilise au quotidien) et Ubuntu)
- MacOS avec Brew
- MS Windows avec WSL2
Je précise que je n'ai pas eu l'occasion de tester l'installation sous Windows, hier j'ai essayé, mais je n'ai pas réussi à installer WSL2 sous Windows dans un Virtualbox lancé sous Fedora. Je suis à la recherche d'une personne pour tester si mes instructions d'installation sont valides ou non.
Briques technologiques présentes dans le playground :
- La dernière version de Python installée par Mise, voir .mise.toml
- Une base de données PostgreSQL lancé par Docker
- J'utilise named volumes comme expliqué dans cette note : 2024-12-09_1550
- Flask-SQLAlchemy
- Flask-Migrate
- Une commande
flask initdb
avec Click pour reset la base de données - Utiliser d'un template Jinja2 pour qui affiche les
users
en base de données
Voici quelques petites subtilités.
Dans le fichier alembic.ini j'ai modifié le paramètre file_template
parce que j'aime que les fichiers de migration soient classés par ordre chronologique :
[alembic]
# template used to generate migration files
file_template = %%(year)d%%(month).2d%%(day).2d_%%(hour).2d%%(minute).2d%%(second).2d_%%(slug)s
20250205_124639_users.py
20250205_125437_add_user_lastname.py
Ici le port de PostgreSQL est généré dynamiquement par docker compose :
postgres:
image: postgres:17
...
ports:
- 5432 # <= ici
Avec cela, fini les conflits de port quand je lance plusieurs projets en même temps sur ma workstation.
L'URL vers le serveur PostgreSQL est générée dynamiquement par le script get_postgres_url.sh
qui est appelé par le fichier .envrc
. Tout cela se passe de manière transparente.
J'initialise ici les extensions PostgreSQL :
def init_db():
db.drop_all()
db.session.execute(db.text('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"'))
db.session.execute(db.text('CREATE EXTENSION IF NOT EXISTS "unaccent"'))
db.session.commit()
db.create_all()
et ici dans la première migration :
def upgrade():
op.execute('CREATE EXTENSION IF NOT EXISTS "uuid-ossp";')
op.execute('CREATE EXTENSION IF NOT EXISTS "unaccent";')
op.create_table('users',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('firstname', sa.String(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
Je découvre Colima, installation minimaliste de Docker sous MacOS
#JaiDécouvert le projet Colima : https://github.com/abiosoft/colima
Colima - container runtimes on macOS (and Linux) with minimal setup.
Support for Intel and Apple Silicon Macs, and Linux
- Simple CLI interface with sensible defaults
- Automatic Port Forwarding
- Volume mounts
- Multiple instances
- Support for multiple container runtimes
- Docker (with optional Kubernetes)
- Containerd (with optional Kubernetes)
- Incus (containers and virtual machines)
Colima est une solution minimaliste qui permet d'installer sous MacOS docker-engine sans Docker Desktop.
Thread Hacker News à ce sujet de 2023 : Colima: Container runtimes on macOS (and Linux) with minimal setup.
Méthode d'installation que je suis sous MacOS avec Brew :
$ brew install colima docker docker-compose
$ cat << EOF > ~/.docker/config.json
{
"auths": {},
"currentContext": "colima",
"cliPluginsExtraDirs": [
"/opt/homebrew/lib/docker/cli-plugins"
]
}
EOF
$ brew services start colima
Comme indiqué ici, la modification du fichier ~/.docker/config.json
permet d'activer de plugin docker compose
, ce qui permet d'utiliser, par exemple :
$ docker compose ps
Qui est, depuis 2020, la méthode recommandée d'utiliser docker compose
sans -
.
Vérification, que tout est bien installé et lancé :
$ colima status
INFO[0000] colima is running using macOS Virtualization.Framework
INFO[0000] arch: aarch64
INFO[0000] runtime: docker
INFO[0000] mountType: sshfs
INFO[0000] socket: unix:///Users/m1/.colima/default/docker.sock
$ docker info
Client: Docker Engine - Community
Version: 27.5.1
Context: colima
Debug Mode: false
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 1
Server Version: 27.4.0
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Using metacopy: false
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 88bf19b2105c8b17560993bee28a01ddc2f97182
runc version: v1.2.2-0-g7cb3632
init version: de40ad0
Security Options:
apparmor
seccomp
Profile: builtin
cgroupns
Kernel Version: 6.8.0-50-generic
Operating System: Ubuntu 24.04.1 LTS
OSType: linux
Architecture: aarch64
CPUs: 2
Total Memory: 1.914GiB
Name: colima
ID: 7fd5e4bd-6430-4724-8238-e420b3f23609
Docker Root Dir: /var/lib/docker
Debug Mode: false
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
J'ai suivi de loin l'histoire de Docker Desktop qui est devenu "propriétaire". Je viens prendre le temps d'étudier un peu le sujet, et voici ce que j'ai trouvé :
August 2021: Docker Desktop for Windows and MacOS was no longer available free of charge for enterprise users. Docker ended free Docker Desktop use for larger business customers and replaced its Free Plan with a Personal Plan. Docker on Linux distributions remained unaffected.
Sur le site officiel, sur la page "docker.desktop", quand je clique sur « Choose plan » je tombe sur ceci :
Je n'ai pas tout compris, j'ai l'impression qu'il est tout de même possible d'installer et d'utiliser gratuitement Docker Desktop.
Au final, tout cela n'a pas beaucoup d'importance pour moi, je ne trouve aucune utilité à Docker Desktop, par conséquent, sous MacOS j'utilise Colima.
J'ai vu qu'il est possible d'installer Colima sous Linux, mais je ne l'utilise pas, car je n'y vois aucun intérêt pour le moment.
J'ai adhéré à la Fédération nationale des micro-entrepreneurs
La FNAE a fait cela matin un "live" au sujet de cet amendement visant à modifier l'article 293b du Code Général des Impôts en réduisant le seuil de TVA à 25 000 € !
Bien que la page de l'amendement indique "rejeté", celui-ci semble avoir été adopté par 49-3.
Au moment où j'écris cette note, ce live n'est pas encore uploadé sur le compte YouTube de la FNAE : https://www.youtube.com/@Federation-auto-entrepreneurFr/videos.
J'ai trouvé ce live de qualité, et il m’a permis d’apprendre de nouvelles choses.
Il y a quelque jours, j'ai ouvert le thread suivant sur Pragmatic Entrepreneurs Forum : « Avis sur l’adhésion à la FNAE – Fédération Nationale des Auto-Entrepreneurs ? ».
Suite au live de matin, j'ai décidé d'adhérer à la FNAE.
Pour le moment, j'ai choisi l'offre à 12 € par an, mais je vais peut-être évoluer vers l'offre à 139 € principalement pour les soutenir.
Mardi 4 février 2025
Journal du mardi 04 février 2025 à 16:46
Je souhaite créer un playground d'un development kit pour Python + PostgreSQL (via Docker) + Flask + Flask-Migrate, basé sur Mise.
J'ai la contrainte suivante : le development kit doit fonctionner sous MS Windows !
Je me dis que c'est une bonne occasion pour moi de tester Windows Subsystem for Linux 🙂.
Problème : je ne possède pas d'instance MS Windows.
#JaiDécouvert que depuis 2015, Microsoft met à disposition des ISOs officiels de MS Windows :
- ISO pour Windows 10 : https://www.microsoft.com/fr-fr/software-download/windows10ISO
- ISO pour Windows 11 : https://www.microsoft.com/fr-fr/software-download/windows11
- Virtual machine MS Windows pour VirtualBox et d'autres : https://developer.microsoft.com/en-us/windows/downloads/virtual-machines/
J'ai testé dans ce playground le lancement d'une Virtual machine MS Windows avec Vagrant : https://github.com/stephane-klein/vagrant-windows-playground
.
Cela a bien fonctionné 🙂.
J'ai aussi découvert le repository windows-vagrant
qui semble permettre de construire différents types d'images MS Windows avec Packer. Je n'ai pas essayé d'en construire une.
Journal du mardi 04 février 2025 à 14:57
Petite note de type #mémento.
Si je rencontre l'erreur suivante avec Vagrant - VirtualBox :
$ vagrant up
...
Command: ["startvm", "2fa1ff70-52d8-4875-b48d-7c2df56f1507", "--type", "gui"]
Stderr: VBoxManage: error: VirtualBox can't enable the AMD-V extension. Please disable the KVM kernel extension, recompile your kernel and reboot (VERR_SVM_IN_USE)
VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component ConsoleWrap, interface IConsole
La solution est la suivante :
$ sudo modprobe -r kvm_amd
$ sudo modprobe -r kvm
Pas de notes plus récentes | [ Notes plus anciennes (836) >> ]