
[{"content":" Automatisering: waar is het goed voor? # Automatisering ontstaat wanneer iemand stuit op een probleem dat diegene nooit meer handmatig wil oplossen. :-)\nStel je de taak voor om een ​​complexe softwareapplicatie uit te rollen over een groot aantal servers. Als dit handmatig gebeurt, vereist het enorme nauwkeurigheid en uren werk, en blijft het gevoelig voor menselijke fouten. Dankzij automatisering kan de uitrol niet alleen aanzienlijk worden versneld, maar ook talloze keren met precies dezelfde nauwkeurigheid worden herhaald. Die herhaalbaarheid is een groot voordeel, vooral in omgevingen waar consistentie cruciaal is, zoals bij IT-productiesystemen.\nLaten we een praktijkvoorbeeld nemen: stel dat je systeembeheerder bent en een serveromgeving met ongeveer 100 servers beheert. Elke week moet je een reeks taken uitvoeren, zoals het aanmaken van gebruikers, het patchen van systemen, het inrichten van servers, het aanmaken van nieuwe virtuele machines (VM\u0026rsquo;s), het configureren van switchpoorten en het aanpassen van configuratiebestanden.\nJe zou al deze taken zelf kunnen uitvoeren, server voor server, maar dat kost veel tijd en kan overweldigend zijn\u0026hellip; of\u0026hellip; je kunt het automatiseren!\nAutomatisering werkt als een takenlijst waarop je precies aangeeft wat er moet gebeuren en in welke volgorde. Je kunt taken automatiseren op één enkele server of op honderden servers tegelijk, zoals het installeren van software-updates of het wijzigen van systeemconfiguraties. Automatisering helpt ervoor te zorgen dat alles efficiënt en consistent gebeurt, zonder dat je elke taak handmatig hoeft uit te voeren.\nOp deze manier maakt automatisering het beheer en onderhoud van een groot netwerk van servers en netwerkapparatuur eenvoudiger.\nWaarom automatiseren? # Efficiëntie: Automatisering helpt taken en processen te stroomlijnen, waardoor ze sneller en efficiënter verlopen. Dit bespaart tijd en verkleint de kans op fouten. Consistentie: Automatisering zorgt ervoor dat taken en processen altijd op dezelfde manier worden uitgevoerd; dit is belangrijk voor het behoud van kwaliteit en naleving van regels (compliance). Schaalbaarheid: Automatisering maakt het eenvoudiger om naar behoefte op- of af te schalen, wat vooral nuttig is in snel veranderende omgevingen. - Kostenbesparingen: Hoewel de initiële opzet van automatisering kosten met zich meebrengt, zijn de besparingen op de lange termijn aanzienlijk. Minder handmatige tussenkomst betekent minder tijd besteed aan routinetaken, waardoor IT-professionals zich kunnen richten op meer strategische activiteiten. Grotere werktevredenheid en betere focus: Door IT-professionals te ontlasten van monotone en repetitieve taken, kunnen zij zich concentreren op uitdagendere en lonendere projecten. Dit kan leiden tot een hogere werktevredenheid en een lager risico op burn-out. Verbeterde betrouwbaarheid: Automatisering helpt het risico op menselijke fouten te verkleinen, wat de betrouwbaarheid van systemen en processen ten goede komt. Toewijzing van middelen: Dankzij automatisering kunnen middelen (zoals rekenkracht of bandbreedte) optimaal en op basis van de vraag worden toegewezen, zonder menselijke tussenkomst. Deze dynamische toewijzing kan leiden tot kostenbesparingen en betere systeemprestaties. Dus, over dat Ansible\u0026hellip; # Ansible is een veelgebruikte open-source tool waarmee je taken kunt automatiseren, zoals het uitrollen van software, het wijzigen van systeemconfiguraties of het beheren van systemen. Ansible wordt vaak gezien als een tool voor configuratiebeheer. Het kan diverse taken uitvoeren op doelsystemen om ervoor te zorgen dat de configuratie altijd consistent blijft. Dit noemen we policy enforcement (het afdwingen van beleid). Een ander voordeel is dat het pakketversies kan afdwingen; zo kun je er bijvoorbeeld voor zorgen dat op alle doelsystemen dezelfde versie van Apache is geïnstalleerd.\nAnsible is een push-gebaseerd systeem. Dit betekent dat Ansible de verbinding initieert met je servers of switches en daarop taken uitvoert (waarvoor je Ansible-modules en -playbooks gebruikt). Het kan worden ingezet om uiteenlopende taken te automatiseren, waaronder het installeren van software, het aanpassen van configuratiebestanden en meer.\nEen van de belangrijkste voordelen van Ansible is dat het eenvoudig in gebruik is en geen specifieke programmeerkennis vereist. Het maakt gebruik van een eenvoudige taal genaamd \u0026ldquo;YAML\u0026rdquo; om de taken te beschrijven die Ansible moet uitvoeren. Bovendien kun je er taken mee automatiseren op één enkele server of op honderden servers tegelijk.\nAnsible wordt voornamelijk gebruikt door systeembeheerders, netwerk- en beveiligingsbeheerders en DevOps-engineers om de uitrol en het beheer van applicaties en systemen te automatiseren. Het is echter geschikt voor iedereen die taken op een of meer servers wil automatiseren.\nAnsible blijft open-source, maar is ook overgenomen door Red Hat. Red Hat heeft Ansible opgenomen in zijn dienstenaanbod en biedt ondersteuning voor zakelijke klanten (enterprise-klanten).\nRed Hat biedt een enterprise-versie van Ansible aan, genaamd het Ansible Automation Platform (voorheen bekend als Ansible Tower). Naast extra functionaliteiten, zoals de ansible-navigator, beschikt deze versie ook over een grafische gebruikersinterface. Hierover later meer in de cursus!\nToepassingen van Ansible # Ansible is een krachtige tool voor het automatiseren van de configuratie en het beheer van servers en andere infrastructuur. Enkele veelvoorkomende toepassingen van Ansible zijn:\nProvisioning en configuratiebeheer: Ansible kan worden gebruikt om het opzetten en configureren van servers te automatiseren, inclusief het installeren van software en het configureren van services. Orchestrator: Ansible kan worden ingezet om taken op meerdere systemen tegelijk uit te voeren, in een specifieke volgorde die door een beheerder is vastgelegd. Een voorbeeld hiervan is het installeren van NGINX op een systeem, waarna de nieuwe server aan een bestaande load balancer wordt toegevoegd. Applicatiedeployment: Ansible kan worden gebruikt om het proces van het uitrollen (deployen) en schalen van applicaties over meerdere servers te automatiseren. Cloud-provisioning: Ansible kan worden gebruikt voor het provisioneren en beheren van resources op cloudplatforms zoals AWS en GCP. Netwerkautomatisering: Ansible kan worden gebruikt om de configuratie en het beheer van netwerkapparatuur, zoals routers en switches, te automatiseren. Beveiligingsautomatisering: Ansible kan worden gebruikt om beveiligingstaken te automatiseren, zoals het instellen van firewalls en het implementeren van compliance-beleid. Continuous Integration/Continuous Deployment (CI/CD): Ansible kan dienen als tool om het proces van het bouwen, testen en uitrollen van software te automatiseren. Kort gezegd\u0026hellip; schrijf het script één keer en pluk er voor altijd de vruchten van!\nAnsible-architectuur # Overzicht # Agentless # Een van de belangrijkste voordelen van Ansible is dat het agentless is. Dit maakt het ook eenvoudig op te zetten en te gebruiken binnen een organisatie. Ansible vereist geen speciale agents of software op de servers die het beheert.\nDit betekent dat Ansible kan worden gebruikt op een grote verscheidenheid aan tools en systemen. Naast servers kunnen ze ook worden gebruikt om acties te automatiseren op netwerkapparatuur zoals switches, routers en firewalls! Andere tools die met agents werken, zouden netwerkapparaten niet kunnen configureren, omdat er op deze systemen geen agent kan worden geïnstalleerd.\nDaarentegen vereisen veel andere automatiseringstools (zoals Chef \u0026amp; Puppet) dat er agents worden geïnstalleerd op de servers die worden beheerd; dit kan tijdrovend en complex zijn.\nBij Ansible hoef je de software slechts op één machine te installeren – de zogenaamde \u0026ldquo;control machine\u0026rdquo; – waarna je deze kunt gebruiken om al je servers te beheren.\nEen ander voordeel van het feit dat Ansible agentless (zonder agents) werkt, is dat het minder zwaar is voor de systeembronnen. Omdat er geen agents op de beheerde servers geïnstalleerd hoeven te worden, verbruikt het geen extra resources zoals CPU en geheugen. Dit kan vooral belangrijk zijn in omgevingen waar de beschikbare middelen beperkt zijn.\nAl met al maakt het agentless-karakter van Ansible het tot een eenvoudige, lichtgewicht en effectieve tool voor het automatiseren van taken in uiteenlopende omgevingen.\nAnsible in het kort: # Taal \u0026amp; ontwerp: Ansible-playbooks worden geschreven in YAML, een voor mensen leesbare standaard voor dataserialisatie. Hierdoor is het voor mensen zonder programmeerervaring eenvoudiger om Ansible-configuraties te begrijpen en te schrijven. Zonder agent (agentless): Ansible vereist geen agent op de beheerde nodes. Voor de communicatie wordt doorgaans SSH (of WinRM voor Windows-hosts) gebruikt; er is dus geen extra software nodig op de nodes die worden beheerd. Push-gebaseerd: Ansible maakt gebruik van een push-mechanisme, waarbij de control-machine de configuratie naar de nodes pusht. Statusbeheer: Ansible kan worden gebruikt voor zowel configuratiebeheer (om de gewenste systeemstatus te behouden) als voor het uitvoeren van ad-hoc taken. Meer hierover bij \u0026lsquo;idempotentie\u0026rsquo;! Idempotentie # Wanneer we zeggen dat Ansible idempotent is, betekent dit dat je hetzelfde playbook of dezelfde taak meerdere keren op hetzelfde systeem kunt uitvoeren. Na de eerste succesvolle uitvoering zullen volgende uitvoeringen geen wijzigingen meer aanbrengen, tenzij er iets aan het systeem is veranderd ten opzichte van de gewenste status. Ansible zorgt ervoor dat het systeem in de opgegeven status blijft, zonder acties onnodig te herhalen.\nWaarom is idempotentie belangrijk? # Consistentie: Zorgt voor consistente configuraties, zelfs als playbooks meerdere keren worden uitgevoerd. Efficiëntie: Voorkomt overbodige handelingen. Als een taak een systeem al in de gewenste status heeft gebracht, is het niet nodig om die taak opnieuw uit te voeren. Veiligheid: Vermindert het risico op onbedoelde bijwerkingen die kunnen ontstaan ​​bij het herhaaldelijk uitvoeren van commando\u0026rsquo;s. Voorspelbaarheid: Systeembeheerders en ontwikkelaars kunnen erop vertrouwen dat het uitvoeren van een playbook geen onverwachte gevolgen heeft als het systeem zich al in de gewenste status bevindt. Voorbeelden # Bestand aanmaken: Als je in Ansible een taak hebt die ervoor zorgt dat een bestand bestaat, zal Ansible dat bestand de eerste keer dat de taak wordt uitgevoerd mogelijk aanmaken. Bij volgende uitvoeringen zal Ansible echter herkennen dat het bestand al bestaat en niet proberen het opnieuw aan te maken, tenzij bepaalde kenmerken van het bestand (zoals rechten of inhoud) afwijken van de gewenste status. Pakketinstallatie: Als je een taak hebt om een ​​softwarepakket te installeren, zal Ansible het pakket de eerste keer dat je de taak uitvoert, installeren. Bij volgende uitvoeringen ziet Ansible dat het pakket al is geïnstalleerd en slaat het de installatiestap over, tenzij de versie moet worden gewijzigd of het pakket moet worden verwijderd. Ansible-Core installeren # In deze cursus richten we ons op het installeren van Ansible op Linux. Het is echter ook mogelijk om Ansible op Windows Server te installeren! Voor deze cursus gebruiken we RHEL (Red Hat Enterprise Linux) versie 9. Dit werkt ook op CentOS (de gratis open-source community-editie). Ik heb ook de installatiecommando\u0026rsquo;s voor op Debian gebaseerde systemen, zoals Ubuntu, opgenomen.\nMet de volgende commando\u0026rsquo;s (open hier de vervolgkeuzelijst) installeer je Ansible-Core. Zoals we in een eerder hoofdstuk hebben gezien, is Ansible-Core de CLI-versie. De open-source (en gratis) versie van Ansible is hieromheen gebouwd. We richten ons op het CLI-gedeelte van Ansible, maar we leren ook hoe we gebruikersinterfaces (UI\u0026rsquo;s) voor Ansible kunnen installeren. #### Installatie-instructies\nOp RHEL gebaseerd (8 en hoger) sudo dnf install ansible-core Test en controleer of Ansible werkt\nansible localhost -m ping Op Debian gebaseerd sudo apt update sudo apt install software-properties-common sudo add-apt-repository --yes --update ppa:ansible/ansible sudo apt install ansible Test en controleer of Ansible werkt\nansible localhost -m ping Authenticatie via SSH-sleutelparen # Nu we ons verdiepen in de wereld van automatisering – met name op het gebied van serverbeheer en orkestratie – is het belangrijk om inzicht te krijgen in de verschillende methoden waarmee we veilig toegang kunnen krijgen tot en controle kunnen uitoefenen over onze externe machines. Een van de fundamentele onderdelen van veilig beheer op afstand is het gebruik van SSH-sleutelparen.\nTerugblik: wat is SSH? # SSH, wat staat voor Secure Shell, is een cryptografisch netwerkprotocol dat veilig inloggen en het uitvoeren van opdrachten op een externe machine mogelijk maakt. Velen van jullie zijn wellicht al bekend met het gebruik van SSH om toegang te krijgen tot externe servers met behulp van een gebruikersnaam en wachtwoord. Er bestaat echter een veiligere en efficiëntere methode: authenticatie via sleutelparen.\nBegrip van sleutelparen # Sleutelparen bestaan ​​uit twee delen:\nPrivésleutel (Private Key): Dit is de sleutel die je geheimhoudt; deze wordt vaak veilig opgeslagen op je computer of in een beveiligde opslaglocatie. Zie het als een digitale handtekening. Publieke sleutel (Public Key): Zoals de naam al doet vermoeden, kan deze sleutel met de buitenwereld worden gedeeld. Deze wordt doorgaans aan externe servers toegevoegd om toegang te verlenen aan iedereen die over de bijbehorende privésleutel beschikt. Wanneer je verbinding probeert te maken met een server, gebruikt je SSH-client de privésleutel om een ​​digitale handtekening te genereren. De server verifieert deze\nPraktijktoepassing: Ansible # Ansible is een van de toonaangevende automatiseringstools in de IT-wereld. Het kan systemen configureren, software uitrollen en complexere IT-taken orkestreren. Ansible gebruikt SSH om verbinding te maken met en commando\u0026rsquo;s uit te voeren op externe servers. Door authenticatie via een sleutelpaar (keypair) in te stellen, geef je Ansible naadloze toegang om servers efficiënt en veilig te beheren.\nEen sleutelpaar genereren en gebruiken # Voer op je lokale machine (of de machine die als Ansible-control node fungeert) het volgende commando uit:\nssh-keygen -t rsa -b 4096 Hiermee wordt een sleutelpaar gegenereerd en opgeslagen in de homedirectory van de gebruiker, in de verborgen map .ssh. Standaard worden de volgende sleutels aangemaakt:\n~/.ssh/id_rsa # Dit is de privésleutel; deze blijft te allen tijde op het apparaat staan ~/.ssh/id_rsa.pub # Dit is de publieke sleutel; dit deel wordt naar externe servers gekopieerd De publieke sleutel verspreiden # Om Ansible verbinding te laten maken met externe hosts, moet je de gegenereerde publieke sleutel (id_rsa.pub) toevoegen aan het bestand ~/.ssh/authorized_keys op elke doelhost.\nJe kunt het bestand handmatig bewerken en je publieke sleutel op een nieuwe regel in het bestand plakken.\nnano ~/.ssh/authorized_keys Als je al een host hebt die toegang heeft tot de externe doelhost, kun je een nieuwe sleutel kopiëren met het volgende commando:\nssh-copy-id -i ~/.ssh/id_rsa.pub user@target_host voorbeeld: ssh-copy-id -i ~/.ssh/id_rsa.pub davy.cavens@5.75.2.6 Hiermee wordt de sleutel \u0026lsquo;id_rsa.pub\u0026rsquo; gekopieerd naar de externe doelhost 5.75.2.6. ### Belangrijke aandachtspunten\nBescherm altijd uw privésleutel. Deel of verspreid deze niet. Maak regelmatig back-ups van uw privésleutel, maar zorg ervoor dat deze veilig worden opgeslagen. Overweeg periodiek om uw sleutels te roteren om veiligheidsredenen. Bij gebruik van cloudservices bieden veel aanbieders manieren om automatisch publieke SSH-sleutels in nieuwe instances of VM\u0026rsquo;s te injecteren, wat de distributiestap vereenvoudigt (of gebruik Terraform, zoals we later in deze cursus zullen zien!). Als best practice dient u de rechten van de privésleutel te beperken met het commando chmod 600 ~/.ssh_id.rsa Alternatieven voor Ansible # Er zijn ook andere tools die vergelijkbare taken uitvoeren, al maken de meeste daarvan gebruik van agents die op de eindpunten moeten worden geïnstalleerd.\nPuppet # Puppet is een open-source tool voor configuratiebeheer die de provisioning en het beheer van infrastructuur automatiseert. Puppet is ontwikkeld in Ruby en stelt beheerders in staat om de gewenste status van hun infrastructuur te definiëren met behulp van een declaratieve taal. Zodra deze gewenste status is vastgelegd, zorgt Puppet ervoor dat de infrastructuur hieraan voldoet en corrigeert het eventuele afwijkingen. Een grote kracht van Puppet is het volwassen ecosysteem, met een schat aan vooraf gedefinieerde modules die beschikbaar zijn in de Puppet Forge. Organisaties gebruiken Puppet om consistentie te waarborgen, beveiligingsbeleid af te dwingen en de provisioning van nieuwe servers en applicaties te versnellen.\nSamenvattend:\nTaal \u0026amp; ontwerp: Puppet-configuraties worden geschreven in een declaratieve, domeinspecifieke taal. Hiermee kunnen gebruikers aangeven \u0026lsquo;wat\u0026rsquo; ze willen bereiken, zonder noodzakelijkerwijs in detail te treden over \u0026lsquo;hoe\u0026rsquo; dit moet gebeuren. Agent-gebaseerd: Puppet vereist doorgaans een agent op elke beheerde node. Deze agent meldt zich periodiek bij de master voor configuratie-updates. Pull-gebaseerd: Puppet werkt meestal volgens een pull-model, waarbij de agents configuraties ophalen van de masterserver. Volwassen ecosysteem: Puppet Forge biedt een uitgebreide verzameling vooraf gedefinieerde modules. Chef # Chef is een andere krachtige open-source automatiseringstool die infrastructuur beheert als code (Infrastructure as Code). In tegenstelling tot de declaratieve aanpak van Puppet hanteert Chef een procedurele stijl, waarbij beheerders \u0026lsquo;recipes\u0026rsquo; (recepten) in Ruby schrijven om te specificeren hoe een bepaald onderdeel van de infrastructuur moet worden geconfigureerd. Deze recepten worden vervolgens gebundeld in \u0026lsquo;cookbooks\u0026rsquo; (kookboeken) om de gewenste configuratie tot in detail te beschrijven. Chef blinkt uit in flexibiliteit, wat verregaande aanpassingen en nauwkeurige controle over systemen mogelijk maakt. De \u0026lsquo;knife\u0026rsquo;-commandlinetool en Chef Supermarket – waar door de community bijgedragen kookboeken te vinden zijn – vormen belangrijke onderdelen van het Chef-ecosysteem.\nEen kort overzicht:\nTaal \u0026amp; ontwerp: Chef gebruikt Ruby voor het schrijven van configuraties, specifiek in een procedurele stijl. Beheerders beschrijven via \u0026lsquo;recipes\u0026rsquo; precies \u0026lsquo;hoe\u0026rsquo; het systeem de gewenste status moet bereiken. Agent-gebaseerd: Chef vereist een agent, de zogenaamde Chef-client, op elke beheerde node. Pull-gebaseerd: Net als Puppet werkt Chef voornamelijk volgens een pull-model, waarbij de Chef-client de nieuwste \u0026lsquo;cookbooks\u0026rsquo; van de Chef-server ophaalt. Flexibele aanpasbaarheid: De procedurele stijl biedt nauwkeurige controle over de systeemconfiguratie, wat ideaal is voor gebruikers met programmeerkennis. ","date":"26 Januarie 2026","externalUrl":null,"permalink":"/ansible/introdictie/","section":"Ansibles","summary":"","title":"Ansible Introductie","type":"ansible"},{"content":" Wat is docker # Logo Omschrijving Docker is een open-source platform dat het mogelijk maakt om applicaties te automatiseren, verpakken, deployen en beheren als containers. Containers zijn lichtgewicht, draagbare en geïsoleerde omgevingen die alles bevatten wat een applicatie nodig heeft om te draaien, inclusief de code, runtime, systeemtools, bibliotheken en instellingen. concepten # Laten we deze concepten eens wat nader bekijken:\nOpen-source platform:\nDit betekent dat de broncode van Docker vrij beschikbaar is en dat iedereen deze kan bekijken, aanpassen en bijdragen aan de ontwikkeling ervan. Dit bevordert transparantie, samenwerking en innovatie binnen de Docker community. * Automatiseren:\nDocker automatiseert veel taken die betrokken zijn bij het beheren van applicaties, zoals het bouwen, testen en deployen. Dit bespaart tijd en vermindert de kans op fouten. Verpakken:\nDocker verpakt applicaties en hun afhankelijkheden in containers, waardoor ze gemakkelijk kunnen worden verplaatst en uitgevoerd op verschillende systemen. Uitrollen (Deployen):\nDocker maakt het eenvoudig om applicaties te deployen naar verschillende omgevingen, zoals ontwikkel-, test- en productieomgevingen. Beheren:\nDocker biedt tools voor het beheren van containers, zoals het starten, stoppen, monitoren en schalen van containers. Lichtgewicht:\nDocker containers zijn veel lichter dan virtuele machines (VM\u0026rsquo;s) omdat ze de kernel van het host-besturingssysteem delen. Dit betekent dat ze minder resources verbruiken en sneller opstarten. Draagbaar:\nDocker containers kunnen op elk systeem worden uitgevoerd dat Docker ondersteunt, ongeacht het onderliggende besturingssysteem. Dit maakt het gemakkelijk om applicaties te verplaatsen tussen verschillende omgevingen. Geïsoleerd:\nDocker containers zijn geïsoleerd van elkaar en van het host-besturingssysteem. Dit betekent dat applicaties in containers geen conflicten kunnen veroorzaken met andere applicaties of het host-systeem. Analogie # Stel je voor dat je een verhuisbedrijf bent. Je moet de inboedel van een huis verhuizen naar een nieuwe locatie. Je kunt alles los in de vrachtwagen gooien, maar dat is chaotisch en inefficiënt. Het is veel beter om alles in dozen te verpakken.\nDocker is als een verhuisbedrijf dat applicaties \u0026ldquo;verpakt\u0026rdquo; in containers. Deze containers zijn als dozen die alles bevatten wat de applicatie nodig heeft om te functioneren. Dit maakt het gemakkelijk om de applicatie te \u0026ldquo;verhuizen\u0026rdquo; naar een andere server of omgeving, zonder dat je je zorgen hoeft te maken over ontbrekende onderdelen of compatibiliteitsproblemen.\nVoorbeeld # Een webapplicatie die is gebouwd met Node.js, MongoDB en Nginx kan worden verpakt in drie afzonderlijke Docker containers: één voor de Node.js applicatie, één voor de MongoDB database en één voor de Nginx webserver. Deze containers kunnen vervolgens worden uitgevoerd op een enkele server of worden gedistribueerd over meerdere servers. Deze cursus behandelt de basisprincipes van Docker, inclusief de installatie, het bouwen van images met Dockerfiles, het orkestreren van multi-container applicaties met Docker Compose, het beheren van data persistentie met volumes en het configureren van netwerken tussen containers.\nUitbreiding # De cursus is gestructureerd om je stapsgewijs door de belangrijkste aspecten van Docker te leiden:\nInstallatie:\nJe leert hoe je Docker kunt installeren op verschillende besturingssystemen, zoals Windows, macOS en Linux. Docker images:\nJe leert wat Docker images zijn, hoe je ze kunt vinden en downloaden van Docker Hub (een openbare registry voor Docker images), en hoe je ze kunt inspecteren om te zien wat erin zit. Docker containers:\nJe leert hoe je Docker containers kunt starten, stoppen, herstarten en verwijderen. Je leert ook hoe je met containers kunt interacteren via de command-line interface (CLI). Dockerfile:\nJe leert hoe je Dockerfiles kunt schrijven om je eigen custom Docker images te bouwen. Dockerfiles zijn tekstbestanden die de instructies bevatten voor het bouwen van een image. Docker Compose:\nJe leert hoe je Docker Compose kunt gebruiken om multi-container applicaties te definiëren en te beheren. Docker Compose is een tool die het gemakkelijk maakt om applicaties met meerdere containers te orkestreren. Docker Volumes:\nJe leert hoe je Docker Volumes kunt gebruiken om data persistentie in containers te bereiken. Docker Volumes zijn mechanismen die het mogelijk maken om data op te slaan buiten de lifecycle van een container, zodat de data niet verloren gaat wanneer de container wordt gestopt of verwijderd. Docker Netwerken:\nJe leert hoe je Docker Netwerken kunt configureren om communicatie tussen containers mogelijk te maken. Docker Netwerken zijn virtuele netwerken die containers met elkaar en met de buitenwereld kunnen verbinden. Uitbreiding: # Docker is meer dan alleen een technologie, het is een compleet platform dat tools en services biedt voor het bouwen, verzenden en uitvoeren van applicaties in containers. Het bestaat uit de volgende componenten:\nDocker Engine:\nDe core component van Docker die verantwoordelijk is voor het bouwen en uitvoeren van containers. Het is een client-server applicatie met een daemon proces, een REST API en een command-line interface (CLI). Docker Hub:\nEen cloud-based registry service waar je Docker images kunt opslaan en delen. Het biedt ook functionaliteiten zoals het automatisch bouwen van images, vulnerability scanning en integratie met GitHub en Bitbucket. Docker Compose:\nEen tool voor het definiëren en uitvoeren van multi-container Docker applicaties. Met Docker Compose kun je de services van je applicatie definiëren in een YAML-bestand en ze met een enkel commando starten, stoppen en updaten. Docker Swarm:\nEen native orchestratie tool voor Docker die het mogelijk maakt om een cluster van Docker Engines te beheren en containers over deze engines te distribueren. Docker is belangrijk omdat het de ontwikkeling, het testen en de deployment van applicaties vereenvoudigt. Het maakt het mogelijk om applicaties te verpakken met al hun afhankelijkheden in een enkele container, die vervolgens op elke machine kan worden uitgevoerd die Docker ondersteunt. Dit elimineert de problemen die vaak gepaard gaan met het configureren van applicaties in verschillende omgevingen. De traditionele manier om applicaties te deployen is om ze direct op servers te installeren, waarbij je ervoor moet zorgen dat alle afhankelijkheden, zoals bibliotheken en systeemtools, correct zijn geïnstalleerd en geconfigureerd. Dit kan leiden tot conflicten tussen applicaties en problemen met compatibiliteit tussen verschillende omgevingen.\nDocker lost dit probleem op door applicaties te isoleren in containers. Elke container heeft zijn eigen set afhankelijkheden en is geïsoleerd van andere containers en het host-besturingssysteem. Dit zorgt ervoor dat applicaties consistent draaien in verschillende omgevingen en dat er geen conflicten ontstaan tussen applicaties.\nVoorbeeld: # Stel je voor dat je een webapplicatie hebt die afhankelijk is van een specifieke versie van Python en een aantal Python bibliotheken. Zonder Docker zou je Python en de bibliotheken op elke server moeten installeren waar je de applicatie wilt deployen. Met Docker kun je een Docker image bouwen die Python, de bibliotheken en je applicatiecode bevat. Deze image kan vervolgens worden uitgevoerd op elke server met Docker, zonder dat je Python en de bibliotheken handmatig hoeft te installeren.\nKey Takeaways: # Docker is een compleet platform dat tools en services biedt voor het bouwen, verzenden en uitvoeren van applicaties in containers. Docker is belangrijk omdat het de ontwikkeling, het testen en de deployment van applicaties vereenvoudigt. Docker elimineert de problemen die vaak gepaard gaan met het configureren van applicaties in verschillende omgevingen. Docker is een open-source platform dat containerisatietechnologie gebruikt om applicaties te verpakken en te draaien. Containers zijn lichtgewicht, draagbare en geïsoleerde omgevingen die alles bevatten wat een applicatie nodig heeft om te draaien. Docker vereenvoudigt de ontwikkeling, het testen en de deployment van applicaties. Deze cursus behandelt de basisprincipes van Docker, inclusief installatie, images, containers, Dockerfiles, Docker Compose, volumes en netwerken. you need to learn Docker RIGHT NOW!! // Docker Containers 101 # Leerdoelen \u0026amp; Waardepropositie # Na het voltooien van deze cursus zul je in staat zijn om:\nDocker te installeren en te configureren op verschillende besturingssystemen. Docker images te vinden, downloaden en inspecteren. Docker containers te starten, beheren en ermee te interacteren. Dockerfiles te schrijven om custom Docker images te bouwen. Docker Compose te gebruiken om multi-container applicaties te definiëren en te beheren. Docker volumes te gebruiken voor data persistentie in containers. Docker netwerken te configureren voor communicatie tussen containers. Waardepropositie # Docker is een essentiële tool geworden voor softwareontwikkelaars, systeembeheerders en DevOps engineers. Het vereenvoudigt de ontwikkeling, het testen en de deployment van applicaties, waardoor de efficiëntie en productiviteit aanzienlijk worden verbeterd. Door Docker te leren, zul je in staat zijn om:\nApplicaties sneller en eenvoudiger te deployen. De consistentie van applicaties te garanderen in verschillende omgevingen. De schaalbaarheid en resource-efficiëntie van applicaties te verbeteren. De samenwerking en communicatie binnen development teams te bevorderen. Expansion # Laten we eens dieper ingaan op de waardepropositie van Docker:\nSneller en eenvoudiger deployen:\nDocker containers elimineren de \u0026ldquo;it works on my machine\u0026rdquo; problematiek, omdat de applicatie en al haar afhankelijkheden in één pakket zitten. Dit betekent dat de applicatie op elke machine met Docker op dezelfde manier zal draaien, ongeacht de configuratie van die machine. Dit versnelt het deployment proces aanzienlijk. Consistentie in verschillende omgevingen:\nDocker zorgt ervoor dat applicaties consistent draaien in verschillende omgevingen, zoals ontwikkel-, test- en productieomgevingen. Dit komt doordat de container alle afhankelijkheden van de applicatie bevat, inclusief de runtime, bibliotheken en systeemtools. Dit elimineert de problemen die kunnen ontstaan door verschillen in configuratie tussen omgevingen. Verbeterde schaalbaarheid en resource-efficiëntie:\nDocker containers zijn lichtgewicht en delen de kernel van het host-besturingssysteem. Dit betekent dat ze minder resources verbruiken dan VM\u0026rsquo;s. Bovendien kunnen Docker containers eenvoudig worden geschaald om aan de veranderende behoeften van applicaties te voldoen. Bevorderde samenwerking en communicatie:\nDocker maakt het gemakkelijk om applicaties te delen en te beheren binnen development teams. Docker images kunnen worden opgeslagen in een registry, zoals Docker Hub, en vervolgens door andere teamleden worden gedownload en gebruikt. Dit bevordert de samenwerking en communicatie binnen het team. Voorbeeld: # Een development team kan een Docker image bouwen voor hun webapplicatie en deze opslaan in Docker Hub. Het operations team kan vervolgens deze image downloaden en gebruiken om de applicatie te deployen naar de productieomgeving. Dit proces is veel efficiënter dan het handmatig installeren en configureren van de applicatie op elke server.\nKey Takeaways: # Docker biedt talloze voordelen, zoals draagbaarheid, consistentie, efficiëntie, schaalbaarheid en isolatie. Docker is een essentiële tool geworden voor softwareontwikkelaars, systeembeheerders en DevOps engineers. Docker vereenvoudigt de ontwikkeling, het testen en de deployment van applicaties, waardoor de efficiëntie en productiviteit aanzienlijk worden verbeterd. Virtualisatie vs. Containerisatie # Virtualisatie en containerisatie zijn beide methoden om applicaties te isoleren van de onderliggende infrastructuur.\nVirtualisatie # creëert virtuele machines (VM\u0026rsquo;s) die elk hun eigen besturingssysteem en kernel hebben. Dit resulteert in een hoge mate van isolatie, maar het is ook resource-intensief.\nUitbreiding: # Bij virtualisatie wordt een hypervisor gebruikt om een laag tussen de hardware en de VM\u0026rsquo;s te creëren. De hypervisor is verantwoordelijk voor het toewijzen van resources aan de VM\u0026rsquo;s en het isoleren van de VM\u0026rsquo;s van elkaar. Elke VM heeft zijn eigen besturingssysteem, kernel, bibliotheken en applicaties. Dit resulteert in een hoge mate van isolatie, maar het betekent ook dat elke VM veel resources verbruikt, zoals CPU, geheugen en schijfruimte.\nContainerisatie # daarentegen deelt de kernel van het host-besturingssysteem met alle containers. Dit maakt containers veel lichter en sneller dan VM\u0026rsquo;s.\nUitbreiding: # Bij containerisatie wordt een container engine, zoals Docker Engine, gebruikt om containers te beheren. Containers delen de kernel van het host-besturingssysteem, maar hebben hun eigen filesystem, processen en netwerk stack. Dit maakt containers veel lichter en sneller dan VM\u0026rsquo;s, omdat ze geen eigen besturingssysteem hoeven te draaien.\nDiagram: # Het diagram laten zien hoe VM\u0026rsquo;s een hypervisor gebruiken en hun eigen besturingssysteem hebben, terwijl containers een container engine gebruiken en de kernel van het host-besturingssysteem delen.\nKey Takeaways: # Virtualisatie en containerisatie zijn beide methoden om applicaties te isoleren van de onderliggende infrastructuur.\nVirtualisatie creëert VM\u0026rsquo;s met hun eigen besturingssysteem en kernel, wat resource-intensief is.\nContainerisatie deelt de kernel van het host-besturingssysteem met alle containers, wat containers veel lichter en sneller maakt dan VM\u0026rsquo;s.\nDe voordelen van Docker # Docker biedt talloze voordelen,\nwaaronder:\nDraagbaarheid:\nDocker containers kunnen op elk systeem worden uitgevoerd dat Docker ondersteunt, ongeacht het onderliggende besturingssysteem.\nDocker containers zijn platformonafhankelijk. Dit betekent dat je een Docker image kunt bouwen op je laptop (bijvoorbeeld met Linux) en deze vervolgens kunt uitvoeren op een server met een ander besturingssysteem (bijvoorbeeld Windows Server). Dit is mogelijk omdat de container alle afhankelijkheden bevat die nodig zijn om de applicatie uit te voeren, inclusief de runtime, bibliotheken en systeemtools. Consistentie:\nDocker containers zorgen ervoor dat applicaties consistent draaien in verschillende omgevingen. Dit komt doordat de container alle afhankelijkheden van de applicatie bevat, inclusief de runtime, bibliotheken en systeemtools. Dit elimineert de \u0026ldquo;it works on my machine\u0026rdquo; problematiek, die vaak ontstaat doordat er verschillen zijn in de configuratie van ontwikkel-, test- en productieomgevingen. Efficiëntie:\nDocker containers zijn lichtgewicht en delen de kernel van het host-besturingssysteem. Dit betekent dat ze minder resources verbruiken dan VM\u0026rsquo;s, die elk hun eigen besturingssysteem en kernel hebben. Dit maakt Docker containers ideaal voor omgevingen met beperkte resources, zoals cloud omgevingen. Schaalbaarheid:\nDocker containers kunnen eenvoudig worden geschaald om aan de veranderende behoeften van applicaties te voldoen. Je kunt bijvoorbeeld meerdere instances van een Docker container starten om de load te verdelen over meerdere servers. Dit is veel eenvoudiger dan het schalen van VM\u0026rsquo;s, wat vaak handmatige configuratie vereist. Isolatie:\nDocker containers isoleren applicaties van elkaar en van het host-besturingssysteem. Dit betekent dat applicaties in containers geen conflicten kunnen veroorzaken met andere applicaties of het host-systeem. Dit verbetert de beveiliging en stabiliteit van applicaties. Voorbeeld: # Een bedrijf kan Docker gebruiken om een microservices architectuur te implementeren. Elke microservice kan worden verpakt in een aparte Docker container. Deze containers kunnen vervolgens worden gedistribueerd over meerdere servers en onafhankelijk van elkaar worden geschaald.\nKey Takeaways: # Docker biedt talloze voordelen, zoals draagbaarheid, consistentie, efficiëntie, schaalbaarheid en isolatie.\nDeze voordelen maken Docker een aantrekkelijke oplossing voor het ontwikkelen, testen en deployen van applicaties.\nDocker terminologie # Docker image:\nEen read-only template die de instructies bevat voor het maken van een Docker container.\nDocker container:\nEen draaiende instantie van een Docker image. Docker Hub:\nEen openbare registry voor het opslaan en delen van Docker images. Docker Engine:\nDe core component van Docker die containers bouwt en uitvoert. Docker CLI:\nDe command-line interface voor interactie met Docker. **Expansion:** Laten we deze termen eens nader bekijken: Docker image:\nEen Docker image is een read-only template die de instructies bevat voor het maken van een Docker container. Het image bevat alles wat nodig is om een applicatie uit te voeren, inclusief de applicatiecode, runtime, bibliotheken, systeemtools en configuratiebestanden. Docker images zijn opgebouwd uit lagen, waarbij elke laag een verandering in het filesystem van het image vertegenwoordigt. Docker container:\nEen Docker container is een draaiende instantie van een Docker image. Wanneer je een Docker image uitvoert, creëert Docker een container die een geïsoleerde omgeving biedt voor de applicatie. De container heeft zijn eigen filesystem, processen en netwerk stack. Docker Hub:\nDocker Hub is een cloud-based registry service waar je Docker images kunt opslaan en delen. Het is de grootste openbare registry voor Docker images en bevat een grote verzameling van officiële en community-gegenereerde images. Docker Engine:\nDocker Engine is de core component van Docker die verantwoordelijk is voor het bouwen en uitvoeren van containers. Het is een client-server applicatie met een daemon proces, een REST API en een command-line interface (CLI). Docker CLI:\nDe Docker CLI is de command-line interface waarmee je kunt interacteren met Docker Engine. Met de CLI kun je images downloaden, containers starten, stoppen en beheren, en andere Docker-gerelateerde taken uitvoeren. Voorbeeld: # Je kunt een Docker image downloaden van Docker Hub voor een webserver, zoals Nginx. Dit image bevat de Nginx webserver software en alle afhankelijkheden die nodig zijn om Nginx uit te voeren. Wanneer je dit image uitvoert, creëert Docker een container die een geïsoleerde omgeving biedt voor de Nginx webserver. Je kunt vervolgens de Nginx webserver configureren en je website bestanden toevoegen aan de container.\nKey Takeaways: # Docker images zijn read-only templates die de instructies bevatten voor het maken van Docker containers.\nDocker containers zijn draaiende instances van Docker images. * Docker Hub is een openbare registry voor het opslaan en delen van Docker images.\nDocker Engine is de core component van Docker die containers bouwt en uitvoert. * Docker CLI is de command-line interface voor interactie met Docker.\nVoorbeeld: # Een Docker image voor een webserver kan bijvoorbeeld de webserver software (bijv. Apache of Nginx), de applicatiecode en alle benodigde bibliotheken bevatten. Wanneer dit image wordt uitgevoerd als een container, draait de webserver in een geïsoleerde omgeving, onafhankelijk van andere applicaties op het systeem.\nUitbreiding: # Laten we dit voorbeeld eens uitbreiden met een concreet scenario. Stel je voor dat je een website wilt ontwikkelen met behulp van de volgende technologieën:\nPHP:** De programmeertaal die gebruikt wordt voor de backend van de website. * **MySQL:** De database die gebruikt wordt om data op te slaan. * **Nginx:** De webserver die gebruikt wordt om de website te hosten. Zonder Docker zou je PHP, MySQL en Nginx op je ontwikkelmachine moeten installeren en configureren. Dit kan een tijdrovend en foutgevoelig proces zijn.\nMet Docker kun je een Docker image bouwen voor elk van deze componenten. Je kunt bijvoorbeeld een Docker image bouwen voor PHP die de PHP interpreter, de benodigde extensies en je applicatiecode bevat.\nJe kunt ook een Docker image bouwen voor MySQL die de MySQL server en je database schema bevat. En je kunt een Docker image bouwen voor Nginx die de Nginx webserver en je website configuratie bevat.\nVervolgens kun je deze images uitvoeren als containers. De PHP container zal je applicatiecode uitvoeren, de MySQL container zal je database hosten en de Nginx container zal de website hosten. De containers kunnen met elkaar communiceren via een Docker netwerk.\nDit heeft de volgende voordelen:\nEenvoudige installatie en configuratie:\nJe hoeft PHP, MySQL en Nginx niet handmatig te installeren en configureren op je ontwikkelmachine. Consistentie:\nDe applicatie zal op dezelfde manier draaien op je ontwikkelmachine als op de productieserver, omdat de containers alle afhankelijkheden bevatten. Isolatie:\nDe componenten van de applicatie zijn geïsoleerd van elkaar en van het host-besturingssysteem, wat de beveiliging en stabiliteit verbetert. Key Takeaways: # Docker images bevatten alles wat een applicatie nodig heeft om te draaien, inclusief de code, runtime, systeemtools, bibliotheken en instellingen.\nDocker containers zijn draaiende instances van Docker images.\nDocker containers draaien in een geïsoleerde omgeving, onafhankelijk van andere applicaties op het systeem.\n","date":"26 Januarie 2026","externalUrl":null,"permalink":"/docker/introductie/","section":"Dockers","summary":"","title":"Docker Introductie","type":"docker"},{"content":" Versiebeheer: Wat is het? # Wat en waarom # Wanneer men digitale documenten aanmaakt en veracht dat men deze in de loop van de tijd dient aan te passen omdat er fouten in de inhoud kunnen voorkomen of omdat in de documenten aanpassingen en toevoegingen verwacht worden, is het handig om bij een wijziging van de in houd de vorige inhoud alsnog bij te houden om zodoende indien het nodig is hierop terug te vallen. In software development is het aangeraden om zo de historiek van de aanpassingen bij te houden.\nDe verschillende versies van de documenten zou men manueel kunnen bij houden door kopieën te maken en deze in folders te plaatsen, die verwijzen naar de versie door een nummering, waarin eventueel een verwijzing naar de datum zit.\nDeze manier van werken is echter omslachtig. Men dient een goede naamgeving te voorzien en het geheel onderhouden is tijdrovend en kan op termijn zelfs onoverzichtelijk worden.\nDaar bovenop komt dat als men met meerderen aan een project werkt, dat men dan ook nog de individuele wijzigingen moet synchroniseren (merging) wat het er zeker niet gemakkelijker op maakt.\nOm die reden wordt er in zulke situaties gebruik gemaakt van versiebeheer. Versies worden automatisch gearchiveerd waardoor men gemakkelijk terug kan gaan naar een oudere versie, die in de database – de repository – opgeslagen is. Een bijkomend voordeel is dat bij het archiveren bijgehouden wordt wie er wijzigingen doorvoerde en waarom. Het merging van verschillende wijzigingen wordt met deze werkwijze ook vereenvoudigd.\n‌Soorten versiebeheer # Er bestaan twee soorten versiebeheer: Gecentraliseerd versiebeheer Gedistribueerd versiebeheer Gecentraliseerd Gedistribueerd Bij gecentraliseerd versiebeheer wordt de code gecentraliseerd op één server. Dit heeft tot gevolg dat men steeds via deze server moet synchroniseren. Is de server niet beschikbaar, dan zal men geen toegang hebben tot het project en zal men enkel met lokale bestanden kunnen werken tot de server weer beschikbaar is. Voorbeelden van dit type versiebeheer zijn OpenCVS en Subversion. Het probleem in voorgaande methodiek wordt opgelost met een gedistribueerd versiebeheer. Iedere gebruiker heeft een copy van het project en als de server niet bereikbaar is, kunnen gebruikers onderling synchroniseren. GIT en Visual Team Services maken gebruik van deze aanpak. Afhankelijk van het gekozen versiebeheer wordt het beheer van het project gedaan:\nDe opslag van een nieuwe versie kan de opslag van het volledige bestand zijn of enkel de opslag van de wijzigingen ten opzichte van de vorige versie. De opslag kan gebeuren voor individuele bestanden in het project of de volledige folder, waar het project in opgeslagen is Het synchroniseren kan op verschillende wijzen gebeuren zoals met HTTP(S), FTP,RCP/IP en andere protocollen. ‌Keuze versiebeheer voor deze cursus # In deze cursus werd voor Git in combinatie met GitHUB gekozen. Voordelen van het gebruik van Git zijn:\nMomenteel is het de meest populaire tool Git is performant Het is Open Source en gratis Het is chaalbaar De gebruikersinterface kan zowel command line (het meest uitgebreid) als via GUI ‌De werking van een gedistibueerd versiebeheer # Het algemeen model # Vanaf de remote repo(sitory) die op de server staat, wordt de laatste versie afgehaald naar een lokale repository. Dit noemt men een Pull.\nUit deze locale repository worden bestanden aangepast of er worden bestanden aan toegevoegd. Het definitief terug toewijzen van gewijzigde of bijgevoegde bestanden doet men met een commit.\nWanneer men de remote repository wilt updaten, voert men een push uit.\nBovenstaande schema toont de werking voor één gebruiker. Indien er meerdere gebruikers zijn, zijn er uiteraard of meerdere lokale repositories, die hun eigen leven leiden tot ze gepushed worden. Wanneer een push uitgevoerd wordt dient men steeds de nodige voorzorgen te nemen. Dit komt later aan bod\nHet Git model # In het geval van Git wordt er tussen de lokale repository en de bestanden van de gebruiker een staging area geplaatst. The staging arera is bedoeld om de toegevoegde en gewijzigde bestanden vooraf in een omgeving (de staging area) te plaatsen om ze daar te reviewen. Eén keer dit gedaan is kan er een commit uitgevoerd worden. De staging area kan overgeslagen worden, maar het wordt sterk geadviseerd dit niet te doen.\n","date":"26 Januarie 2026","externalUrl":null,"permalink":"/git/introductie/","section":"Gits","summary":"","title":"Introductie","type":"git"},{"content":"","externalUrl":"https://n9o.xyz","permalink":"/users/0-e8b2eb823290677fbba3390d5cef2c35/","section":"Users","summary":"","title":"n9o.xyz","type":"users"},{"content":"Docker kan worden geïnstalleerd op Windows, macOS en Linux. De installatieprocedure verschilt per besturingssysteem.\nInstallatie op Windows: # Docker Desktop for Windows kan worden gedownload van de Docker website.\nSysteemvereisten: Docker Desktop for Windows vereist Windows 10 Professional of Enterprise 64-bit (build 15063 of later) of Windows 11 64-bit. Virtualisatie moet ingeschakeld zijn in de BIOS. Installatie: Download het installatiebestand van de Docker website en voer het uit. Volg de instructies in de installer. Na de installatie moet je je computer herstarten. Verificatie: Open een command prompt en voer het commando docker --version uit. Als Docker correct is geïnstalleerd, zie je de versie van Docker Engine. WSL 2: Docker Desktop for Windows gebruikt standaard WSL 2 (Windows Subsystem for Linux 2) als backend. Dit biedt betere performance en compatibiliteit met Linux containers. Installatie op MacOS # Docker Desktop for Mac kan worden gedownload van de Docker website.\nSysteemvereisten: Docker Desktop for Mac vereist macOS 10.15 of later. Virtualisatie moet ingeschakeld zijn. Installatie: Download het installatiebestand van de Docker website en voer het uit. Volg de instructies in de installer. Na de installatie moet je je computer herstarten. Verificatie: Open een terminal en voer het commando docker --version uit. Als Docker correct is geïnstalleerd, zie je de versie van Docker Engine. Installatie op Linux: # Docker kan worden geïnstalleerd via de package manager van de specifieke Linux distributie.\nDe installatieprocedure voor Docker op Linux verschilt per distributie. Over het algemeen kun je Docker installeren via de package manager van je distributie. Raadpleeg de Docker documentatie voor de specifieke instructies voor je distributie.\nDocker kan worden geïnstalleerd op Windows, macOS en Linux. De installatieprocedure verschilt per besturingssysteem. * Raadpleeg de Docker documentatie voor de specifieke instructies voor je besturingssysteem.\nInstallation on Ubuntu # Je kunt Docker Engine op verschillende manieren installeren, afhankelijk van je behoeften:\nDocker Engine wordt meegeleverd met Docker Desktop voor Linux. Dit is de makkelijkste en snelste manier om aan de slag te gaan. Configureer en installeer Docker Engine vanuit de apt-repository van Docker. Installeer het handmatig en beheer upgrades handmatig. Gebruik een script. Alleen aanbevolen voor test- en ontwikkelomgevingen. Voordat je Docker Engine voor de eerste keer op een nieuwe hostmachine installeert, moet je de Docker-repository configureren. Daarna kun je Docker vanuit de repository installeren en bijwerken. 1 apt-repository Configureer de apt-repository van Docker.\n# Voeg de officiële GPG-sleutel van Docker toe: sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc # Voeg de repository toe aan de Apt-bronnen: echo \\ \u0026#34;deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \\ $(. /etc/os-release \u0026amp;\u0026amp; echo \u0026#34;$VERSION_CODENAME\u0026#34;) stable\u0026#34; | ```bash sudo tee /etc/apt/sources.list.d/docker.list \u0026gt; /dev/null sudo apt-get update Opmerking Als je een op Ubuntu gebaseerde distributie gebruikt, zoals Linux Mint, moet je mogelijk UBUNTU_CODENAME gebruiken in plaats van VERSION_CODENAME.\n2 Installeer de Docker-pakketten. Voer het volgende uit om de nieuwste versie te installeren:\nsudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 3 Controleer Verificatie: Open een terminal en voer het commando uit\ndocker --version Als Docker correct is geïnstalleerd, zie je de versie van Docker Engine.\n4 Controleer Controleer of de installatie van Docker Engine is geslaagd door de hello-world-image uit te voeren.\nsudo docker run hello-world Met dit commando wordt een test-image gedownload en in een container uitgevoerd. Wanneer de container draait, wordt er een bevestigingsbericht getoond en stopt het proces.\nJe hebt Docker Engine nu succesvol geïnstalleerd en gestart.\nFoutmelding\nKrijg je foutmeldingen bij het uitvoeren zonder root-rechten?\nDe gebruikersgroep \u0026lsquo;docker\u0026rsquo; bestaat wel, maar bevat geen gebruikers; daarom moet je sudo gebruiken om Docker-commando\u0026rsquo;s uit te voeren. Ga door naar de post-installatie voor Linux om gebruikers zonder speciale rechten Docker-commando\u0026rsquo;s te laten uitvoeren en voor andere optionele configuratiestappen.\nsudo usermod -aG docker $USER Installatie op CentOS/RHEL: # 1 Werk je repositories bij Werk je repositories bij\nsudo yum update 2 Voeg de repository toe Voeg de repository toe\nsudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/do 3 Controleer Verificatie: Open een terminal en voer het commando uit\ndocker --version Als Docker correct is geïnstalleerd, zie je de versie van Docker Engine.\n4 Controleer Controleer of de installatie van Docker Engine is geslaagd door de hello-world-image uit te voeren.\nsudo docker run hello-world Met dit commando wordt een test-image gedownload en in een container uitgevoerd. Wanneer de container draait, wordt er een bevestigingsbericht getoond en stopt het proces.\n","date":"26 Januarie 2026","externalUrl":null,"permalink":"/docker/installatie/","section":"Dockers","summary":"","title":"Installatie","type":"docker"},{"content":"Git is een open source, gedistribueerd versiebeheersysteem (of softwarebroncode-managementsysteem) ontwikkeld door Linus Torvalds in 2005 voor het beheren van de Linux-kernel.\nSoftware # Om met Git te kunnen werken op je pc, heb je software nodig. Je hebt daarbij de keuze uit GUI tools (zoals Sourcetree, GitHub Desktop, Tower, …) of je kan werken met een CLI (Command Line Interface). In deze cursus verkiezen wij het laatste omdat via de CLI alle mogelijkheden ter beschikking zijn (in tegenstelling tot in de grafische omgevingen). Bovendien leidt deze werkwijze tot een beter begrip van de Git-filosofie/technologie, waardoor het in principe eenvoudig zou moeten zijn om – indien gewenst – over te schakelen op een GUI-client naar voorkeur.\nUbuntu MacOs Windows Gebruikers van Linux hebben altijd een beetje geluk bij Git. Zij hebben namelijk al een bash shell op hun systeem.\nsudo apt-get update sudo apt-get install git En je bent klaar!\nmacOS heeft via XCode een ingeboude Git client maar deze is echter verouderd. Je kan deze updaten via brew (opens new window).\nIn de Terminal app volg je de instructies van brew.sh (opens new window)op. Als brew werkt doe je:\nbrew install git Ò En je bent klaar!\nIn deze download bevindt zich de Git Bash (CLI), shell-integratie en 2 grafische tools.\nInstalleer met de standaard instellingen.\nGit bash geeft je een bash shell op je windows systeem, deze shell is vaak voor onze DevOps tools makkelijker dan CMD of PowerShell\nGit versus GitHub # GitHub is een website/hosting service voor software, gebouwd rond het Git-versiebeheersysteem.\nEr worden verschillende extra features aangeboden zoals wiki’s, social coding, project \u0026amp; team management, …\nAlternatieven voor GitHub die gelijkaardige services bieden zijn Assembla, Bitbucket, Codebase, GitLab, …\nGitHub-account # Maak een GitHub-account aan op https://github.com (opens new window). Vergeet niet om je mailadres te bevestigen (je ontvangt hiervoor een link via mail) om gebruik te kunnen maken van alle mogelijkheden!\nGebruik je Thomas More mailadres en vraag een upgrade van je account via (https://education.github.com/). Naast een Pro GitHub account krijg je ook nog vele voordelen op andere websites.\n","date":"26 Januarie 2026","externalUrl":null,"permalink":"/git/installatie/","section":"Gits","summary":"","title":"Installatie en Configuratie","type":"git"},{"content":" Ad-hoc-commando\u0026rsquo;s # Ansible ad-hoc-commando\u0026rsquo;s zijn eenmalige commando\u0026rsquo;s die op een of meer externe machines worden uitgevoerd, zonder dat daarvoor een volledig playbook hoeft te worden gemaakt. Deze commando\u0026rsquo;s worden uitgevoerd met het ansible-commando, gevolgd door een doelhost of -groep, en een module met bijbehorende argumenten.\nAd-hoc-commando\u0026rsquo;s worden doorgaans gebruikt om snel en eenvoudig eenvoudige taken uit te voeren, maar ze kunnen ook worden ingezet om informatie over externe machines te verzamelen, updates en onderhoud uit te voeren, en nog veel meer.\nHet is belangrijk op te merken dat bij ad-hoc-commando\u0026rsquo;s een groot risico op menselijke fouten bestaat; ze worden daarom niet aanbevolen voor complexe taken of taken die herhaalbaar moeten zijn.\nDe basissyntaxis van een ad-hoc-commando ziet er als volgt uit:\nansible \u0026lt;hostname/groep\u0026gt; -m \u0026lt;module\u0026gt; -a \u0026lt;module-argumenten\u0026gt; hostname/groep: De doelhost of groep hosts waarop het commando wordt uitgevoerd. -m module: De uit te voeren module. Ansible beschikt over een breed scala aan ingebouwde modules voor uiteenlopende taken, zoals bestandsbeheer, pakketbeheer, servicebeheer, enzovoort. -a module-argumenten: De argumenten die aan de module worden meegegeven. Deze argumenten variëren afhankelijk van de module die wordt uitgevoerd. Dit is een optionele parameter. Voorbeelden # Het volgende commando dient als voorbeeld:\nansible all -m ping In dit voorbeeld wordt de ping-module gebruikt om de connectiviteit met alle servers in het inventory-bestand te controleren. De optie -m geeft aan welke module moet worden gebruikt; in dit geval is dat de ping-module. Omdat er bij ping geen argumenten hoeven te worden meegegeven, is de optie -a niet nodig. Laten we nog een voorbeeld bekijken:\nansible all -m shell -a \u0026#39;/bin/echo hello\u0026#39; Dit commando gebruikt de shell-module om het commando \u0026rsquo;/bin/echo hello\u0026rsquo; uit te voeren op alle servers in het inventory-bestand; dit resulteert in de uitvoer \u0026lsquo;hello\u0026rsquo; op alle servers.\nHerinner je je de \u0026lsquo;Ansible Facts\u0026rsquo; waar we het over hadden nog? Je kunt alle details over een host (of dat nu je localhost of een doelhost is) opvragen met dit commando:\nansible -m setup \u0026lt;target\u0026gt; Dit commando toont alle standaardparameters die Ansible verzamelt over de doelhost.\nOm \u0026lsquo;Facts\u0026rsquo; over je Ansible-controller te verzamelen, voer je het volgende commando uit:\nansible -m setup localhost Je krijgt dan een uitvoer te zien die er ongeveer zo uitziet:\nPraktische toepassingen # Probleemoplossing (troubleshooting) # Een collega kan je vragen om snel de status van een service op specifieke servers te controleren. Bijvoorbeeld: \u0026ldquo;Kun je even kijken of de webserver op server X, Y en Z draait?\u0026rdquo;\nDit is een eenvoudige taak waarvoor geen gedetailleerd plan of uitgebreide instructies nodig zijn; dit is vergelijkbaar met hoe een ad-hoc-commando in Ansible wordt gebruikt om snel en eenvoudig een simpele taak uit te voeren.\nHiervoor kun je het volgende commando gebruiken:\nansible web-server -m shell -a \u0026#39;systemctl status apache2\u0026#39; Gebruikers aanmaken # Om een ​​gebruiker aan te maken met een ad-hoc-commando, moet je eerst het wachtwoord hashen. Dit kan met het commando mkpasswd. Voer vervolgens het volgende commando uit:\nansible all -m user -a \u0026#39;name=\u0026lt;NAME-OF-USER\u0026gt; password=\u0026#34;\u0026lt;HASHED-PW-OF-MKPASSWD\u0026gt;\u0026#34;\u0026#39; -k -b -K Een praktisch voorbeeld hiervan is:\nansible all -m user -a \u0026#39;name=james password=\u0026#34;$y$j9T$pKYQTlln/gQtf.YQffQZ.1$E0.mDXGMPBI3qbTyxZ3sHoNoAniyxsuS2Wmoc4y5I83\u0026#34;\u0026#39; -k -b -K Dit is een Ansible-commando dat wordt gebruikt om een ​​gebruiker genaamd \u0026ldquo;james\u0026rdquo; met een specifiek wachtwoord aan te maken op alle doelmachines die in de Ansible-inventory zijn opgegeven. Hier volgt een uitleg van de verschillende opties en vlaggen (flags) die in dit commando worden gebruikt:\nansible: Dit is het commando om Ansible uit te voeren, gevolgd door de lijst met doelmachines waarop het commando moet draaien (in dit geval betekent \u0026ldquo;all\u0026rdquo; alle machines in de inventory). -m user: Hiermee wordt de te gebruiken module opgegeven; in dit geval is dat de \u0026ldquo;user\u0026quot;-module. De \u0026ldquo;user\u0026rdquo;-module wordt gebruikt om gebruikers op doelmachines te beheren. -a \u0026rsquo;name=james password=\u0026quot;\u0026lt;hashed password\u0026gt;\u0026rdquo;\u0026rsquo;: Dit is het argument voor de \u0026ldquo;user\u0026rdquo;-module. Hiermee worden de parameters opgegeven voor het aanmaken van de gebruiker \u0026ldquo;james\u0026rdquo;. De parameters omvatten de naam en het wachtwoord van de gebruiker. Het wachtwoord is een gehashte tekenreeks (hash), en daarom staat het tussen aanhalingstekens. -k: Hiermee wordt de gebruiker gevraagd om een ​​wachtwoord in te voeren voor authenticatie bij de doelmachines. -b: Hiermee wordt aangegeven dat de gebruiker met beheerdersrechten moet worden aangemaakt op de doelmachines. -K: Hiermee wordt de gebruiker gevraagd om het sudo-wachtwoord voor de doelmachines in te voeren, aangezien er beheerdersrechten nodig zijn om een ​​nieuwe gebruiker aan te maken. # Uw eerste ad-hocverbinding tot stand brengen In dit voorbeeld doorlopen we stap voor stap hoe u een host aan uw inventory-bestand toevoegt en een \u0026ldquo;ping\u0026rdquo;-test uitvoert naar de doelhost.\nDit is geen ICMP-gebaseerde ping, maar een SSH-verbindingstest.\nEen host aanmaken in onze inventory # Het standaard inventory-bestand bevindt zich in de volgende map: /etc/ansible/\nDit bestand heet \u0026lsquo;hosts\u0026rsquo;. Laten we het bewerken!\nsudo nano /etc/ansible/hosts Merk op dat we dit met sudo-rechten doen, aangezien onze standaardgebruiker geen schrijfrechten heeft voor dit bestand.\nLaten we een host genaamd \u0026lsquo;KASM\u0026rsquo; toevoegen.\n[TMLab] kasm ansible_host=192.168.1.1 ansible_user=davy.cavens ansible_password=DavysSecretPassword ansible_become_password=DavysSecretRootPassword Laten we dit stap voor stap doornemen:\n\\[TMLab\\]: Dit geeft een groep aan in het inventory-bestand. Deze groep heet TMLab. Als we later meer hosts toevoegen, kunnen we op alle hosts tegelijkertijd commando\u0026rsquo;s uitvoeren door de groepsnaam te gebruiken. De volgende regel bevat verschillende parameters; we zullen deze stuk voor stuk uitleggen. kasm: dit is een label/alias die we aan de host toevoegen om deze eenvoudig te kunnen aanspreken. Deze naam mag geen koppelteken (-) bevatten, maar wel underscores ( _ ). ansible_host=192.168.1.1: Deze parameter vertelt Ansible met welk IP-adres verbinding moet worden gemaakt om de doelhost te bereiken. ansible_user=davy.cavens: Deze parameter stelt de gebruikersnaam in die Ansible gebruikt bij het opzetten van de verbinding. ansible_password=DavysSecretPassword: Deze parameter stelt het wachtwoord in dat wordt gebruikt om verbinding te maken met de host. Dit kan ook een SSH-sleutelpaar zijn, maar in dit voorbeeld gebruiken we een wachtwoord. - ansible_become_password: dit is het wachtwoord dat wordt gebruikt wanneer een taak als root wordt uitgevoerd. Zo, we zijn klaar met het inventory-bestand! Sla het bestand op en sluit het af (als je nano gebruikt: druk op CTRL + C en sla het bestand onder dezelfde naam op wanneer daarom wordt gevraagd).\nWe kunnen nu ons eerste ad-hoccommando testen.\nVerbinding maken met de host # Voer het volgende commando in om verbinding te maken met de host:\nansible kasm -m ping Laten we dit even ontleden:\nansible: dit is het commando dat wordt gebruikt om ad-hoccommando\u0026rsquo;s uit te voeren. kasm: dit is de naam van ons doel (zie het inventory-bestand dat we zojuist hebben bewerkt). -m ping: hiermee geven we aan Ansible door welke module we op de host willen gebruiken; we gebruiken hier de module \u0026lsquo;ping\u0026rsquo;. Zoals eerder vermeld, voert dit een SSH-verbindingstest uit. Verwachte uitvoer: # Als alles goed gaat en de host bereikbaar is (en je de juiste parameters hebt ingevoerd), zou je de volgende uitvoer moeten zien:\nAnsible Facts # Wat zijn Ansible Facts? \u0026lsquo;Facts\u0026rsquo; in Ansible zijn systeemspecifieke gegevens die worden verzameld van beheerde nodes. Deze informatie wordt opgeslagen in variabelen die Ansible kan uitlezen en gebruiken in playbooks.\nHoe verzamel je facts? Wanneer je een playbook uitvoert, verzamelt Ansible standaard facts over de externe host met behulp van de setup-module.\n--- - hosts: all tasks: - debug: var: ansible_distribution Bij het uitvoeren van dit playbook wordt de naam van de distributie (zoals Ubuntu, CentOS, enz.) van de beheerde node weergegeven. Enkele veelvoorkomende \u0026lsquo;facts\u0026rsquo; zijn:\nansible_os_family: De OS-familie (zoals RedHat, Debian) ansible_distribution: De naam van de distributie (zoals CentOS, Ubuntu) ansible_distribution_version: De specifieke versie van de distributie ansible_interfaces: Lijst met netwerkinterfaces Je kunt de volledige lijst met \u0026lsquo;facts\u0026rsquo; ophalen met het volgende commando:\nansible all -m setup Dit commando toont de \u0026lsquo;facts\u0026rsquo; die zijn verzameld voor alle hosts die in je inventory-bestand staan ​​vermeld.\nDe uitvoer ziet er ongeveer zo uit als in het onderstaande voorbeeld:\nOverzicht van playbooks # Stel dat je meerdere acties tegelijkertijd op meerdere systemen wilt uitvoeren. Je zou een ad-hoc commando kunnen gebruiken en je op meerdere hosts richten\u0026hellip; maar zou het niet veel eenvoudiger zijn om een ​​reeks commando\u0026rsquo;s in één bestand te combineren en deze op zoveel doelen als je wilt uit te voeren\u0026hellip; allemaal tegelijk?!\nZoek niet verder! Een Ansible-playbook is een set instructies in YAML-formaat die een reeks taken en de volgorde waarin ze moeten worden uitgevoerd op een of meer externe hosts definieert. Met playbooks kun je repetitieve taken automatiseren, zoals serverconfiguratie, software-installatie en applicatie-deployment. Ze bieden ook een manier om de gewenste status van een systeem te beheren en ervoor te zorgen dat die status in de loop van de tijd behouden blijft.\nWacht even\u0026hellip; YAML?! # YAML staat voor \u0026ldquo;YAML Ain\u0026rsquo;t Markup Language\u0026rdquo; en is een voor mensen leesbaar formaat voor dataserialisatie. Het wordt vaak gebruikt bij softwareontwikkeling en configuratiebeheer voor het opslaan en uitwisselen van gegevens. Het is zo ontworpen dat het gemakkelijk te lezen en te schrijven is voor mensen, en eenvoudig te verwerken (parsen) door machines.\nYAML is een tekstformaat dat inspringing gebruikt (spaties, GEEN tabs!) en speciale tekens om de structuur van de gegevens aan te geven. Het wordt vaak gebruikt om complexe datastructuren weer te geven, zoals lijsten, dictionaries en geneste structuren. Hier zijn enkele basisconcepten van YAML:\nDatatypen: YAML ondersteunt diverse datatypen, waaronder strings (tekstreeksen), getallen, booleans en null-waarden. Strings kunnen tussen aanhalingstekens staan ​​of zonder aanhalingstekens worden geschreven als ze geen speciale tekens bevatten. Getallen kunnen worden geschreven in decimale, hexadecimale of wetenschappelijke notatie. Lijsten: Lijsten in YAML worden aangegeven met een koppelteken (-) gevolgd door een spatie; elk item in de lijst springt in. Bijvoorbeeld: - item 1 - item 2 - item 3 Dictionaries: Dictionaries in YAML worden weergegeven als sleutel-waardeparen, gescheiden door een dubbele punt ( : ) en ingesprongen. Bijvoorbeeld: key1: value1 key2: value2 key3: value3 Commentaar: Commentaar in YAML begint met het teken # en loopt door tot het einde van de regel. Commentaar wordt door de parser genegeerd en kan worden gebruikt voor uitleg of context. Meerregelige strings: YAML maakt het mogelijk dat strings over meerdere regels lopen door gebruik te maken van het teken |. Bijvoorbeeld: long_string: | Dit is een lange string die over meerdere regels loopt zonder speciale tekens. Structuur van een playbook # De structuur van een Ansible-playbook ziet er als volgt uit:\nName: Een (voor mensen leesbare) naam voor het playbook. Hosts: De lijst met hosts of groepen hosts waarop het playbook gericht moet zijn. - Variabelen: Alle variabelen die nodig zijn voor de taken die in het playbook zijn gedefinieerd. Deze kunnen inline, in een apart variabelenbestand of in een inventory-bestand worden gedefinieerd. Taken (Tasks): De lijst met taken die op de doelhosts moeten worden uitgevoerd. Elke taak definieert een reeks acties die op de hosts moeten worden uitgevoerd. Handlers: Handlers zijn vergelijkbaar met taken, maar worden alleen geactiveerd wanneer ze door een andere taak worden aangeroepen (via een notificatie). Ze worden doorgaans gebruikt om een ​​service te herstarten of een configuratiebestand opnieuw te laden nadat dit is gewijzigd. Rollen (Roles): Een verzameling taken, handlers en variabelen die is georganiseerd als een herbruikbaar geheel en in meerdere playbooks kan worden opgenomen. Includes: Hiermee kan het ene playbook een ander playbook of een takenlijst opnemen. Dit kan worden gebruikt om grote playbooks op te splitsen in kleinere, beter beheersbare delen. De basisopzet van de structuur is als volgt:\n--- - name: Example playbook hosts: target_hosts vars: variable1: value1 variable2: value2 tasks: - name: Task 1 \u0026lt;task_definition\u0026gt; - name: Task 2 \u0026lt;task_definition\u0026gt; handlers: - name: Handler 1 \u0026lt;handler_definition\u0026gt; - name: Handler 2 \u0026lt;handler_definition\u0026gt; In dit voorbeeld heeft het playbook de naam \u0026ldquo;Example playbook\u0026rdquo; en is het gericht op de hosts die in de groep \u0026ldquo;target_hosts\u0026rdquo; zijn gedefinieerd. Het definieert twee variabelen, \u0026ldquo;variable1\u0026rdquo; en \u0026ldquo;variable2\u0026rdquo;, en bevat twee taken en twee handlers. Elke taak en handler krijgt een naam voor eenvoudige identificatie, en de definities staan ​​eronder vermeld.\nIn een Ansible-playbook zijn diverse elementen optioneel. Dit zijn onder andere:\nVariabelen: Playbooks kunnen worden uitgevoerd zonder dat er variabelen worden gedefinieerd. Variabelen worden echter vaak gebruikt om waarden vast te leggen die door de taken worden gebruikt; ze maken het playbook flexibeler en herbruikbaarder. Handlers: Handlers zijn optioneel; niet elk playbook heeft ze nodig. Handlers worden gebruikt om op specifieke gebeurtenissen te reageren; als er geen gebeurtenissen zijn die een reactie vereisen, kunnen handlers worden weggelaten. Roles: Roles zijn optioneel en worden gebruikt om taken en handlers te organiseren in herbruikbare modules. Als een playbook geen hergebruik van een set taken en handlers vereist, kunnen roles worden weggelaten. Includes: Includes zijn optioneel; een playbook kan worden uitgevoerd zonder extra playbooks of takenlijsten te includen. Includes worden gebruikt om grote playbooks op te splitsen in kleinere, beter beheersbare delen. Het playbook uitvoeren # Zodra het YAML-bestand met alle relevante taken is aangemaakt, kun je het playbook uitvoeren. Dit doe je met het volgende commando:\nansible-playbook \u0026lt;pad naar playbook .yml-bestand\u0026gt; Voorbeeld-playbook (Debian) # Laten we eens een pakket installeren! In dit voorbeeld maken we een playbook aan met de naam \u0026lsquo;apache-playbook.yml\u0026rsquo;\n1 Maak een nieuw bestand aan met nano of vi: nano apache-playbook.yml 2 Voer de volgende inhoud in het bestand in: --- - name: Install and start Apache hosts: webserver become: true tasks: - name: Install Apache apt: name: apache2 state: present - name: Start Apache service: name: apache2 state: started Dit playbook gaat ervan uit dat er een groep hosts of een specifieke host met de naam \u0026lsquo;webserver\u0026rsquo; beschikbaar is. Aan dit playbook is de naam \u0026ldquo;Install and start Apache\u0026rdquo; gegeven en het is gericht op een groep hosts genaamd \u0026ldquo;webserver\u0026rdquo;. Om iets op een Linux-host te installeren, heb je verhoogde rechten (oftewel root-rechten) nodig. Het trefwoord become is ingesteld op true om aan te geven dat de taken moeten worden uitgevoerd met verhoogde rechten (bijv. uitgevoerd als root).\nDe eerste taak, \u0026ldquo;Install Apache\u0026rdquo;, gebruikt de apt-module om het Apache-pakket te installeren met behulp van de parameters name en state. De parameter name specificeert het te installeren pakket en de parameter state geeft aan of het pakket aanwezig (present), afwezig (absent) of bijgewerkt (updated) moet zijn. De tweede taak, \u0026ldquo;Start Apache\u0026rdquo;, gebruikt de service-module om de Apache-service te starten met behulp van de parameters name en state. De parameter name specificeert de naam van de te starten service en de parameter state geeft aan of de service gestart, gestopt of opnieuw gestart moet worden. Stel dat we een pakket willen verwijderen, dan kunnen we een taak als volgt definiëren:\n- name: Install Apache apt: name: apache2 state: absent \u0026lsquo;Absent\u0026rsquo; betekent dat het pakket (indien aanwezig) van het systeem wordt verwijderd.\nAls we willen controleren of het pakket is bijgewerkt naar de nieuwste versie, kunnen we de status \u0026ldquo;updated\u0026rdquo; gebruiken:\n- name: Install Apache apt: name: apache2 state: updated 3 Sla het bestand op. 4 Het playbook kan worden uitgevoerd met het volgende commando (ervan uitgaande dat je je in dezelfde map bevindt als het yaml-bestand): ansible-playbook apache-playbook.yml Voorbeeld-playbook (CentOS / RHEL) # Waar de apt-module wordt gebruikt voor pakketbeheer op Debian-gebaseerde systemen, wordt de yum-module gebruikt voor pakketbeheer op Red Hat-gebaseerde systemen, zoals CentOS en Fedora. Hier zijn enkele voorbeelden van het gebruik van de yum-module in Ansible-playbooks:\nEen pakket installeren met yum:\n- name: Install the Apache web server yum: name: httpd state: present In dit voorbeeld wordt de yum-module gebruikt om het httpd-pakket (de Apache-webserver) te installeren en wordt de status ingesteld op present. Dit betekent dat de yum-module ervoor zorgt dat het httpd-pakket op het systeem wordt geïnstalleerd.\nEen pakket verwijderen met yum:\n- name: Remove the Apache web server yum: name: httpd state: absent In dit voorbeeld wordt de yum-module gebruikt om het httpd-pakket (de Apache-webserver) te verwijderen en wordt de status ingesteld op absent. Dit betekent dat de yum-module ervoor zorgt dat het httpd-pakket van het systeem wordt verwijderd.\nEen pakket bijwerken met yum:\n- name: Update the Apache web server yum: name: httpd state: latest In dit voorbeeld wordt de yum-module gebruikt om het httpd-pakket (de Apache-webserver) bij te werken en wordt de status ingesteld op latest. Dit betekent dat de yum-module ervoor zorgt dat de nieuwste versie van het httpd-pakket op het systeem wordt geïnstalleerd.\nZoals je ziet, is de syntaxis identiek aan die van de APT-module. Let altijd goed op naar welke Linux-distributie je pakketten pusht!\nVariabelen in playbooks # Laten we het nu hebben over variabelen. Variabelen in Ansible-playbooks worden gebruikt om waarden op te slaan die in meerdere taken kunnen worden hergebruikt, of om taken flexibeler en aanpasbaarder te maken. Hier is een voorbeeld van een playbook dat gebruikmaakt van variabelen:\n--- - name: Hello World hosts: localhost vars: hello_there: \u0026#34;Hello, world!\u0026#34; tasks: - name: show variable debug: var: hello_there In dit voorbeeld wordt de debug-module gebruikt om de waarde van de variabele hello_there weer te geven. Wanneer het playbook wordt uitgevoerd, toont de uitvoer de inhoud van de variabele:\nTASK [Debug my_variable] ********************************************************************* ok: [localhost] =\u0026gt; { \u0026#34;my_variable\u0026#34;: \u0026#34;Hello, world!\u0026#34; } Een ander voorbeeld is het volgende:\n--- - name: Install and configure nginx hosts: webserver become: true vars: nginx_version: \u0026#34;1.21.0\u0026#34; nginx_config_path: \u0026#34;/etc/nginx/nginx.conf\u0026#34; tasks: - name: Install nginx apt: name: nginx={{ nginx_version }} state: present - name: Copy nginx configuration file copy: src: files/nginx.conf dest: \u0026#34;{{ nginx_config_path }}\u0026#34; In dit playbook definiëren we twee variabelen: nginx_version en nginx_config_path. De variabele nginx_version bepaalt welke versie van nginx moet worden geïnstalleerd, en de variabele nginx_config_path geeft het pad aan waarheen het nginx-configuratiebestand moet worden gekopieerd.\nIn de eerste taak, \u0026ldquo;Install nginx\u0026rdquo;, wordt de apt-module gebruikt om nginx te installeren, en wordt de variabele nginx_version gebruikt om de te installeren versie op te geven.\nIn de tweede taak, \u0026ldquo;Copy nginx configuration file\u0026rdquo;, wordt de copy-module gebruikt om een ​​configuratiebestand van de lokale machine naar de externe host te kopiëren, en wordt de variabele nginx_config_path gebruikt om het doelpad voor het bestand op te geven.\nEen voorbeeld voor een Cisco-switch:\n--- - hosts: switches vars: vlan_id: 20 vlan_name: Ansible_VLAN tasks: - name: Ensure Fa2/0/5 is configured for access vlan 20 cisco.ios.ios_l2_interface: name: FastEthernet2/0/5 mode: access access_vlan: { { vlan_id } } Dit playbook maakt verbinding met een switch en configureert VLAN 20 op poort fa2/0/5. Ook wordt de poort in de \u0026lsquo;access\u0026rsquo;-modus gezet. Mooi, toch?\nHandlers # Handlers zijn speciale soorten taken die alleen worden geactiveerd wanneer ze door een andere taak worden aangestuurd (via een \u0026rsquo;notification\u0026rsquo;). Met andere woorden: ze worden één keer uitgevoerd, nadat alle taken in een bepaalde \u0026lsquo;play\u0026rsquo; zijn voltooid, maar alleen als ze door een andere taak zijn aangestuurd of \u0026lsquo;genotificeerd\u0026rsquo;.\nHandlers worden vaak gebruikt voor taken die moeten worden uitgevoerd als gevolg van een wijziging. Een typisch voorbeeld is het herstarten van een service nadat het bijbehorende configuratiebestand is aangepast.\nHier volgt een basisuitleg van de werking van handlers:\nNotificatiemechanisme: Wanneer een taak de status van een systeem wijzigt (bijv. door een configuratiebestand aan te passen), kan deze een handler \u0026rsquo;notificeren\u0026rsquo; (aansturen). Uitvoering slechts één keer: Ongeacht hoeveel taken een bepaalde handler aansturen, wordt die handler slechts één keer uitgevoerd (na afloop van alle taken in de play). Volgorde: Handlers worden uitgevoerd in de volgorde waarin ze zijn gedefinieerd, niet in de volgorde waarin ze worden aangestuurd. Handlers forceren (flushing): Als je wilt afdwingen dat handlers vóór het einde van de play worden uitgevoerd, kun je de taak meta: flush_handlers gebruiken. Hier is een eenvoudig voorbeeld om het concept van een \u0026lsquo;handler\u0026rsquo; te verduidelijken: --- - hosts: webserver tasks: - name: Install nginx apt: name: nginx state: present - name: Copy nginx configuration copy: src: /path/to/my/nginx.conf dest: /etc/nginx/nginx.conf notify: Restart nginx handlers: - name: Restart nginx service: name: nginx state: restarted In het bovenstaande voorbeeld:\nKan de taak \u0026ldquo;Copy nginx configuration\u0026rdquo; het nginx-configuratiebestand op de doelmachine wijzigen. Als er een wijziging optreedt (d.w.z. de inhoud van het configuratiebestand verschilt van de bron), geeft de taak een melding (notify) aan de handler \u0026ldquo;Restart nginx\u0026rdquo;. Nadat alle taken zijn uitgevoerd, controleert Ansible of de handler \u0026ldquo;Restart nginx\u0026rdquo; een melding heeft ontvangen. Als de handler een melding heeft ontvangen, wordt deze uitgevoerd en wordt de nginx-service herstart. Als er geen melding is ontvangen (d.w.z. geen wijziging in het configuratiebestand), wordt de handler niet uitgevoerd. Door handlers te gebruiken, zorgen we ervoor dat services of applicaties alleen worden herstart wanneer dat nodig is, waardoor mogelijke downtime of verstoring van de dienstverlening tot een minimum wordt beperkt.\nEen playbook ontleed – stap-voor-stapvoorbeeld # In dit hoofdstuk leggen we stap voor stap uit hoe een playbook is opgebouwd. Om dit te kunnen doen, hebben we natuurlijk een voorbeeld nodig!\nDit wordt ons voorbeeld-playbook: # --- - name: Install a webserver hosts: webservers become: yes tasks: - name: Install HTTPD yum: name: httpd state: latest - name: Check if index template file is present template: src: files/index.html dest: /var/www/html/ - name: start the httpd service service: name: httpd state: started enabled: yes Wat doet het playbook? # Het playbook installeert eerst HTTPD, een Apache-webserverpakket dat wordt gebruikt in op RHEL gebaseerde besturingssystemen (CentOS, RHEL, Oracle Linux, enz.). Na de installatie van het pakket kopieert het een bestand van de Ansible-controller naar de doelhost. Vervolgens wordt geprobeerd de service te starten en in te schakelen (enable). Even ter herinnering: door de service te starten, zorg je ervoor dat de daemon op de doelhost draait. Door de service ook in te schakelen, wordt deze automatisch gestart wanneer het systeem opstart. Als je de service alleen zou starten zonder deze in te schakelen, zou de service niet automatisch starten bij het opstarten of herstarten van het systeem.\nDe play # Een \u0026lsquo;play\u0026rsquo; is het grootste onderdeel van je playbook. In dit voorbeeld probeert de play die we hebben gemaakt een webserver te installeren. Zoals je kunt zien, kan een play uit meerdere taken (tasks) bestaan.\nZoals je ook kunt zien, begint het playbook met drie streepjes (\u0026mdash;). Dit geeft aan dat het om een ​​YAML-bestand gaat en markeert het begin van het bestand. Dit geldt niet alleen voor Ansible-bestanden; het is een eigenschap die inherent is aan YAML zelf.\nVervolgens begint de play met een -name-instructie: dit is het hoofdgedeelte van het playbook en bevat informatie die van toepassing is op alle plays en taken in het playbook.\nDe volgende elementen zijn aanwezig:\n- name: \u0026lt;NAME\u0026gt; # Dit geeft een label aan voor het volledige playbook, # voorbeelden zijn \u0026#39;update OS\u0026#39; of \u0026#39;install a webserver\u0026#39;. hosts: \u0026lt;targets\u0026gt; # Hiermee wordt het doel (target) van het playbook ingesteld. # Als het trefwoord \u0026#39;all\u0026#39; wordt opgegeven, is dit van toepassing op ALLE hosts # in een gekozen inventory-bestand become: yes # Geeft aan dat alle taken als root worden uitgevoerd ### Taken De taken zijn configuratiestappen die je zou uitvoeren bij het handmatig installeren van een pakket. De eerste taak probeert het HTTPD-pakket te installeren. Dit komt overeen met het commando `sudo yum install httpd`. De volgende taak kopieert een bestand naar /var/www/html/ en de laatste taak start de service en schakelt deze in. Deze laatste taak komt overeen met de commando\u0026#39;s `sudo systemctl start httpd` en `sudo systemctl enable httpd`. [![65.png](https://boeken.barttho.be/bookstack/public/uploads/images/gallery/2025-09/scaled-1680-/65-png.png)](https://boeken.barttho.be/bookstack/public/uploads/images/gallery/2025-09/scaled-1680-/65-png.png) ### Modules Een module is een zelfstandig script dat Ansible namens jou uitvoert. Dit komt overeen met een commando. De module \u0026#34;yum\u0026#34; komt bijvoorbeeld overeen met het Linux-commando \u0026#34;yum\u0026#34;, enzovoort. Modules interageren met verschillende aspecten van een systeem, zoals bestanden, services, pakketbeheerders of netwerkbronnen, waardoor Ansible ze op een idempotente manier kan beheren (d.w.z. herhaalde bewerkingen resulteren in dezelfde status in plaats van een cumulatief effect). [![66.png](https://boeken.barttho.be/bookstack/public/uploads/images/gallery/2025-09/scaled-1680-/66-png.png)](https://boeken.barttho.be/bookstack/public/uploads/images/gallery/2025-09/scaled-1680-/66-png.png) ### De uitvoer van een playbook interpreteren Playbooks maken gebruik van kleurcodering om aan te geven of er problemen zijn opgetreden of dat er wijzigingen hebben plaatsgevonden. \u0026lt;table border=\u0026#34;1\u0026#34; id=\u0026#34;bkmrk-color-behavior-green\u0026#34; style=\u0026#34;border-collapse: collapse; width: 100%;\u0026#34;\u0026gt;\u0026lt;colgroup\u0026gt;\u0026lt;col style=\u0026#34;width: 50%;\u0026#34;\u0026gt;\u0026lt;/col\u0026gt;\u0026lt;col style=\u0026#34;width: 50%;\u0026#34;\u0026gt;\u0026lt;/col\u0026gt;\u0026lt;/colgroup\u0026gt;\u0026lt;tbody\u0026gt;\u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;**Kleur** \u0026lt;/td\u0026gt;\u0026lt;td\u0026gt;**Gedrag** \u0026lt;/td\u0026gt;\u0026lt;/tr\u0026gt;\u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;\u0026lt;span style=\u0026#34;color: rgb(22, 145, 121);\u0026#34;\u0026gt;**Groen**\u0026lt;/span\u0026gt; \u0026lt;/td\u0026gt;\u0026lt;td\u0026gt;Er is niets gewijzigd\u0026lt;/td\u0026gt;\u0026lt;/tr\u0026gt;\u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;**\u0026lt;span style=\u0026#34;color: rgb(241, 196, 15);\u0026#34;\u0026gt;Geel/Oranje\u0026lt;/span\u0026gt;** \u0026lt;/td\u0026gt;\u0026lt;td\u0026gt;Ansible heeft met succes een parameter gewijzigd of een commando uitgevoerd\u0026lt;/td\u0026gt;\u0026lt;/tr\u0026gt;\u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;**\u0026lt;span style=\u0026#34;color: rgb(224, 62, 45);\u0026#34;\u0026gt;Rood\u0026lt;/span\u0026gt;** \u0026lt;/td\u0026gt;\u0026lt;td\u0026gt;Er is een fout opgetreden; Ansible kon een parameter niet wijzigen of een commando niet uitvoeren\u0026lt;/td\u0026gt;\u0026lt;/tr\u0026gt;\u0026lt;/tbody\u0026gt;\u0026lt;/table\u0026gt; Een voorbeeld hiervan is de onderstaande afbeelding: [![67.png](https://boeken.barttho.be/bookstack/public/uploads/images/gallery/2025-09/scaled-1680-/67-png.png)](https://boeken.barttho.be/bookstack/public/uploads/images/gallery/2025-09/scaled-1680-/67-png.png) # Loops en andere statements \u0026lt;main class=\u0026#34;v-main\u0026#34; data-booted=\u0026#34;true\u0026#34; id=\u0026#34;bkmrk-loops-in-ansible-pla\u0026#34;\u0026gt;# Loops in Ansible Playbooks Loops zijn een krachtige functie in Ansible waarmee je een taak of een reeks taken meerdere keren kunt herhalen met verschillende invoerwaarden. In Ansible kun je loops gebruiken met het `loop`-trefwoord om over een lijst te itereren, of met de `with_`-syntaxis om over de resultaten van een lookup te itereren. Hier is een eenvoudig voorbeeld dat een lus gebruikt om meerdere gebruikers op een externe machine aan te maken: name: Gebruikers aanmaken user: name: \u0026ldquo;{{ item }}\u0026rdquo; state: present loop: alice bob charlie In dit voorbeeld wordt de `user`-module gebruikt om een ​​nieuwe gebruiker aan te maken met de naam die is opgegeven via de `item`-variabele; deze variabele neemt achtereenvolgens elke waarde uit de lijst `[\u0026#39;alice\u0026#39;, \u0026#39;bob\u0026#39;, \u0026#39;charlie\u0026#39;]` aan. De parameter `state` is ingesteld op `present` om ervoor te zorgen dat de gebruiker wordt aangemaakt als deze nog niet bestaat. Je kunt ook lussen (loops) gebruiken om door een lijst met dictionaries te itereren. Het volgende playbook gebruikt bijvoorbeeld een lus om meerdere virtual hosts aan te maken op een Apache-webserver: name: Configure virtual hosts apache2_vhost: servername: \u0026ldquo;{{ item.servername }}\u0026rdquo; documentroot: \u0026ldquo;{{ item.documentroot }}\u0026rdquo; loop: { servername: \u0026ldquo;example.com\u0026rdquo;, documentroot: \u0026ldquo;/var/www/example\u0026rdquo; } { servername: \u0026ldquo;example.net\u0026rdquo;, documentroot: \u0026ldquo;/var/www/example_net\u0026rdquo; } In dit voorbeeld wordt de `apache2_vhost`-module gebruikt om een ​​nieuwe virtual host aan te maken met de `servername` en `documentroot` die zijn opgegeven via de `item`-variabele; deze variabele doorloopt elke dictionary in de lijst. Het trefwoord `loop` wordt gebruikt om door de lijst met dictionaries te itereren. # If/Else-statements in Ansible-playbooks Met if/else-statements kun je taken voorwaardelijk uitvoeren, afhankelijk van de status van het systeem. In Ansible kun je if/else-logica toepassen met het trefwoord `when`, waarbij een voorwaarde wordt opgegeven waaraan moet worden voldaan om de taak uit te voeren. Hier is een eenvoudig voorbeeld waarin een if-statement wordt gebruikt om een ​​taak alleen uit te voeren als een bestand bestaat: name: Copy file if it exists copy: src: /path/to/local/file dest: /path/to/remote/file when: ansible_facts[\u0026lsquo;file_exists\u0026rsquo;] In dit voorbeeld wordt de `copy`-module gebruikt om een ​​bestand van de lokale machine naar de externe machine te kopiëren, maar alleen als de variabele `file_exists` de waarde `true` heeft. De variabele `file_exists` wordt ingesteld via de variabele `ansible_facts`, die informatie over het externe systeem bevat. Je kunt ook \u0026#39;else\u0026#39;-statements gebruiken om een ​​andere taak uit te voeren als de voorwaarde onwaar is. Het volgende playbook kopieert bijvoorbeeld een bestand als dit bestaat, en maakt een leeg bestand aan als dat niet het geval is: name: Copy or create file copy: src: /path/to/local/file dest: /path/to/remote/file when: ansible_facts[\u0026lsquo;file_exists\u0026rsquo;] become: yes become_user: root delegate_to: localhost tags:\nfile vars: file_contents: \u0026ldquo;This file was created because it didn\u0026rsquo;t exist\u0026rdquo;\nname: Create empty file copy: content: \u0026quot;\u0026quot; dest: /path/to/remote/file when: not ansible_facts[\u0026lsquo;file_exists\u0026rsquo;] become: yes become_user: root delegate_to: localhost tags:\n# Met \u0026#39;with_items\u0026#39; Je kunt ook een dictionary opnemen om je Ansible-playbook geoptimaliseerd te houden. In plaats van meerdere taken te maken die sterk op elkaar lijken, kun je de `with_items`-operator gebruiken om een ​​aangepaste dictionary te doorlopen en de acties binnen dezelfde playbook-taak uit te voeren. Het volgende voorbeeld toont een dictionary waarmee meerdere VLAN\u0026#39;s op een switch worden geconfigureerd: ```json --- - name: Configure Cisco IOS Switch hosts: switch connection: network_cli gather_facts: no become: yes vars: data_vlan_id: 10 voice_vlan_id: 20 wifi_vlan_id: 30 backup_vlan_id: 40 guests_vlan_id: 50 interconnect_vlan_id: 60 access_ports: \u0026#34;range gi2/0/1-12\u0026#34; uplink_ports: \u0026#34;range gi2/0/23-24\u0026#34; port_channel: 1 tasks: - name: Set access port descriptions ios_interfaces: config: - name: \u0026#34;{{ access_ports }}\u0026#34; description: Access Port configured by Ansible enabled: true - name: Create VLANs ios_vlans: config: - vlan_id: \u0026#34;{{ item.id }}\u0026#34; name: \u0026#34;{{ item.name }}\u0026#34; state: active with_items: - { id: \u0026#34;{{ data_vlan_id }}\u0026#34;, name: \u0026#34;data\u0026#34; } - { id: \u0026#34;{{ voice_vlan_id }}\u0026#34;, name: \u0026#34;voice\u0026#34; } - { id: \u0026#34;{{ wifi_vlan_id }}\u0026#34;, name: \u0026#34;wifi\u0026#34; } - { id: \u0026#34;{{ backup_vlan_id }}\u0026#34;, name: \u0026#34;backup\u0026#34; } - { id: \u0026#34;{{ guests_vlan_id }}\u0026#34;, name: \u0026#34;guests\u0026#34; } - { id: \u0026#34;{{ interconnect_vlan_id }}\u0026#34;, name: \u0026#34;interconnect\u0026#34; } In dit specifieke playbook worden 6 VLAN\u0026rsquo;s aangemaakt, elk met een unieke ID en naam. De VLAN-ID\u0026rsquo;s en -namen worden gedefinieerd aan de hand van variabelen (data_vlan_id, voice_vlan_id, enz.), die hun waarden krijgen vanuit de Ansible-inventory of het playbook.\nDe eerste taak heet \u0026ldquo;Set access port descriptions\u0026rdquo;. Deze maakt gebruik van de module ios_interfaces om de beschrijving en de status (ingeschakeld/uitgeschakeld) voor specifieke toegangspoorten (access ports) te configureren. De toegangspoorten worden gedefinieerd door de variabele access_ports. Deze taak gebruikt YAML-lijstsyntaxis om de configuratiewaarden op te geven. De sleutel config wordt gebruikt om een ​​lijst met toe te passen configuraties te specificeren. In dit geval wordt één enkele configuratie opgegeven, waarbij de sleutel name wordt gebruikt om de toegangspoort te identificeren en de sleutel description om de beschrijving in te stellen. De sleutel enabled wordt op true gezet om de interface in te schakelen. De tweede taak heet \u0026ldquo;Create VLANs\u0026rdquo;. Deze maakt gebruik van de module ios_vlans om VLAN\u0026rsquo;s te configureren op het doelnetwerkapparaat. Deze taak gebruikt een lus (with_items) om meerdere VLAN-configuraties aan te maken. De sleutel config wordt gebruikt om een ​​lijst met toe te passen VLAN-configuraties te specificeren. Elke VLAN-configuratie wordt opgegeven met behulp van YAML-dictionary-syntaxis. De sleutel vlan_id stelt het VLAN-ID in en de sleutel name stelt de VLAN-naam in. De sleutel state wordt op active gezet om ervoor te zorgen dat het VLAN wordt aangemaakt en ingeschakeld. ","date":"25 Januarie 2026","externalUrl":null,"permalink":"/ansible/comandos/","section":"Ansibles","summary":"","title":"Ansible Commando's","type":"ansible"},{"content":"","externalUrl":"https://madoke.org/","permalink":"/users/1-96d3e57dcc931de55cc23a825d40be2c/","section":"Users","summary":"","title":"madoke.org","type":"users"},{"content":" What is een Docker image # Docker-images zijn de fundamentele bouwstenen voor het maken van containers. Het zijn sjablonen die alleen-lezen zijn (read-only) en die de applicatiecode, runtime-omgeving, systeembibliotheken en alle andere afhankelijkheden bevatten die nodig zijn om de applicatie te laten draaien. Images worden gemaakt op basis van instructies in een Dockerfile en worden opgeslagen in registers (registries), zoals Docker Hub.\nJe kunt een Docker-image eigenlijk zien als een blauwdruk of sjabloon voor het creëren van een virtuele omgeving die alles bevat wat je applicatie nodig heeft om te werken, zoals de code, bibliotheken, systeemtools en configuratiebestanden. Het is als een momentopname van je applicatie en de bijbehorende afhankelijkheden, vastgelegd op een bepaald tijdstip.\nWat is dan een container? # Een Docker-container is een instantie van zo\u0026rsquo;n image die als een apart, geïsoleerd proces op je computer draait. Je kunt het zien als een lichtgewicht virtuele machine die alleen bevat wat nodig is om je applicatie te laten draaien. Elke container heeft zijn eigen bestandssysteem, netwerk en resources, maar ze maken allemaal gebruik van hetzelfde onderliggende Docker-image.\nKort samengevat: een Docker-image is een lichtgewicht bestand (alleen-lezen) met de instructies om een ​​Docker-container te maken, terwijl een Docker-container een draaiende instantie van een Docker-image is. Deze bevat alle noodzakelijke onderdelen om je applicatie te laten draaien, maar is geïsoleerd van het hostbesturingssysteem en andere containers.\nRegistry # Docker Hub # Docker-registers zijn gecentraliseerde opslag- en distributiesystemen voor Docker-images. Hiermee kun je images met anderen delen en samenwerken aan projecten. Docker Hub is het standaard openbare register van Docker; hier worden duizenden officiële images en images van de community gehost. Naast Docker Hub kun je ook gebruikmaken van private registries of je eigen registry opzetten om images te hosten.\nLinuxserver.io - Fleet # Bouwen en onderhouden van community-images # Wij zijn een groep gelijkgestemde enthousiastelingen van over de hele wereld die de grootste verzameling Docker-images op het web bouwen en onderhouden; de principes achter vrije en open-source software vormen de kern van ons werk. Ons hoofddoel is het aanbieden van gebruiksvriendelijke en gestroomlijnde Docker-images, voorzien van duidelijke en beknopte documentatie.\nHome | LinuxServer.io\nMenu | Fleet\n","date":"26 Januarie 2026","externalUrl":null,"permalink":"/docker/images/","section":"Dockers","summary":"","title":"Images","type":"docker"},{"content":" The ansible config file # Ansible.cfg # The ansible.cfg file is the configuration file for Ansible. It can be used to set various options and settings that control the behavior of Ansible and how it operates.\nSome common options that can be set in the ansible.cfg file include:\ninventory: This specifies the path to the inventory file that lists the hosts that Ansible will operate on. library: This specifies the path to the directory containing Ansible modules. module_utils: This specifies the path to the directory containing utility modules used by Ansible. log_path: This specifies the path to the file where Ansible will log its output. roles_path: This specifies the path to the directory containing Ansible roles. There are many other options that can be set in the ansible.cfg file, and you can find more information about them in the Ansible documentation.\nThe ansible.cfg file contains settings for tweaking the ansible service on the control node.\nFirst, we will be generating a ansible.cfg default configuration file. The following command will generate a file with all settings disabled: ansible-config init --disabled \u0026gt; ansible.cfg The following modification to the ansible file is for testing purposes only. We will set the host_key_checking variable to False to allow us to connect to target hosts without verifying the SSH key. In a production environment, it is strongly recommended to import the keys. When you are in the /etc/ansible directory, edit the ansible.cfg file. sudo nano ansible.cfg Next, find the host_key_checking entry (you can search in nano by pressing CTRL + W and entering the search term) Remove the \u0026lsquo;;\u0026rsquo; in front of the entry and enter the following: host_key_checking=False The inventory file # Ansible Inventory is a file that contains a list of hosts, which are the servers or devices that Ansible will manage. In its most basic form, the inventory file is just a flat list of hosts (or also called \u0026ldquo;Targets\u0026rdquo;). However, in more advanced , enterprise deployments, the inventory file is frequently hosted on a Git repository (Github or Gitlab for example). The added value of extra source control helps teams collaborate and track changes made to the inventory file.\nThe inventory file defines groups of hosts, which allow you to apply actions to multiple servers at once. In this chapter, we will start with some simple examples of how to define hosts with usernames and passwords in the inventory file, and then show how to use groups and variables.\nWhen you installed ansible, a default inventory file can be found in the directory /etc/ansible/hosts.\nInventory breakdown # the following structure is used within a basic inventory file.\n[\u0026lt;group name\u0026gt;] \u0026lt;optional alias name\u0026gt; \u0026lt;IP address\u0026gt; \u0026lt;parameters\u0026gt; [\u0026lt;group name\u0026gt;:vars] \u0026lt;specific variable\u0026gt;=\u0026lt;value\u0026gt; Using this structure, we could construct the following inventory: [linux_hosts] webserver1 ansible_host=192.168.5.2 ansible_user=davy ansible_password=SuperVeiligWachtwoordVanDavy Special characters in passwords # When the password you are using to connect to a target hosts contains special characters (like \u0026lsquo;#\u0026rsquo;, \u0026lsquo;!\u0026rsquo;, \u0026lsquo;ç\u0026rsquo;,\u0026hellip; ), Ansible will attempt to parse it as a special character. If you want to negate this (so it can be used like a normal character), you have to add a backslash \u0026lsquo;\\\u0026rsquo;. An example: you have a target hosts with the following password:\nThisIsADifficult#password\nThe following would cause an error:\nwebserver1 ansible_host=10.10.10.10 ansible_user=davy ansible_password=ThisIsADifficult#password To negate the special # character, it has to be defined as follows:\nwebserver1 ansible_host=10.10.10.10 ansible_user=davy ansible_password=ThisIsADifficult\\#password The backslash will not be used in the password when connecting to the host, it simply negates the special character when ansible parses the inventory file. Parameter overview # The inventory file can be used to define variables for hosts, groups, and even all hosts in the inventory. These variables can be used to customize the behavior of Ansible playbooks, such as setting connection parameters, defining host-specific variables, and more.\nHere are some of the commonly used parameters that can be used in an inventory file:\nansible_host: the IP address or hostname of the host. This is used by Ansible to connect to the host via SSH or other connection plugins. ansible_user: the username to use when connecting to the host. ansible_port: the SSH port number to use when connecting to the host. The default value is 22. ansible_ssh_private_key_file: the path to the private key file to use for SSH authentication. ansible_password: the password to use when connecting to the host. This is not recommended for security reasons and should be used only as a last resort. ansible_ssh_pass: an alternative to ansible_password that specifies the password to use when connecting to the host via SSH. This is also not recommended for security reasons and should be used only as a last resort. ansible_connection: the connection plugin to use when connecting to the host. The default value is ssh, but other plugins such as winrm, local or docker can be used for connecting to different types of hosts. ansible_become: a boolean value that determines whether to use privilege escalation when running commands on the host. The default value is false. ansible_become_user: the username to use for privilege escalation when running commands on the host. ansible_become_password: the password to use for privilege escalation when running commands on the host. This is not recommended for security reasons and should be used only as a last resort. ansible_shell_type: the shell type to use when running commands on the host. The default value is sh, but other shells such as bash or zsh can be used. Variables in the inventory file # Say you have a group of 10 servers who have a simular naming convention and can be queried by using the same username and password. Say they are named as follows:\nWebserver01 Webserver02 \u0026hellip; Webserver10 Instead of adding 10 lines into the inventory file, you could add them as one single line using the following pattern:\nwebserver[01-10].lab.local ansible_user=webadmin ansible_password=Webadminsecretpass Basic Examples # Linux Server # Suppose we have a Linux server with IP address 192.168.1.10, and we want to manage it with Ansible using the username ansibleuser and password password123. We can define this host in our inventory file like this:\n[linux_servers] linux1 ansible_host=192.168.1.10 ansible_user=ansibleuser ansible_password=password123 In this example, we have created a group called \\[linux-servers\\] and added our Linux server to that group. We have also specified the ansible_user and ansible_password variables to tell Ansible how to connect to the server.\nWindows Server # Similarly, suppose we have a Windows server with IP address 192.168.1.20, and we want to manage it with Ansible using the username ansibleuser and password password123. We can define this host in our inventory file like this:\n[windows_servers] win1 ansible_host=192.168.1.20 ansible_user=ansibleuser ansible_password=password123 ansible_connection=winrm ansible_winrm_transport=ntlm In this example, we have created a group called \\[windows-servers\\] and added our Windows server to that group. We have also specified the ansible_user, ansible_password, ansible_connection, and ansible_winrm_transport variables to tell Ansible how to connect to the server using WinRM.\nCisco Switch # Suppose we have a Cisco switch with IP address 192.168.1.30, and we want to manage it with Ansible using the username ansibleuser and password password123. We can define this host in our inventory file like this:\n[cisco_switches] access_SWBlockD ansible_host=192.168.1.30 ansible_user=ansibleuser ansible_password=password123 ansible_connection=network_cli In this example, we have created a group called \\[cisco-switches\\] and added our Cisco switch to that group. We have also specified the ansible_user, ansible_password, and ansible_connection variables to tell Ansible how to connect to the switch using the network_cli connection plugin.\nUsing Groups and Variables # Group Vars # In the previous examples, we specified the username and password for each host individually. If we have many hosts, it can be tedious to specify these variables for each one. Instead, we can use group variables to specify the variables for a group of hosts.\nFor example, suppose we have a group of Linux servers and we want to use the same username and password for all of them. We can define a group variable in our inventory file like this:\n[linux_servers] server1 ansible_host=192.168.1.10 server2 ansible_host=192.168.1.11 [linux_servers:vars] ansible_user=ansibleuser ansible_password=password123 In this example, we have defined a group of Linux servers, and then defined a group variable for that group using the \\[groupname:vars\\] syntax. The ansible_user and ansible_password variables will apply to all hosts in the linux-servers group.\nChild groups # Child groups are defined using the \\[child-group:children\\] syntax in the inventory file, where child-group is the name of the child group, and children is the keyword that specifies the parent group. Any settings defined in the parent group will be inherited by the child group, including any host or variable definitions.\nChild groups are useful for organizing your inventory file and simplifying the definition of properties and variables for related hosts. You can use them to group hosts by function, environment, or any other category that makes sense for your infrastructure.\nExample 1: Child Groups in the Linux Server Group # Suppose we have a group of Linux servers that we want to divide into two child groups, web-servers and db-servers, and we want to define different variables for each child group.\nWe can define our inventory file like this:\n[linux_servers] server1 ansible_host=192.168.1.10 server2 ansible_host=192.168.1.11 server3 ansible_host=192.168.1.12 [web_servers:children] linux_servers [db_servers:children] linux_servers [web-servers:vars] http_port=8080 [db-servers:vars] db_port=3306 In this example, we have created a group called linux-servers with three hosts. We have then defined two child groups, web-servers and db-servers, that both inherit from linux-servers. We have also defined different variables for each child group.\nWhen we run an Ansible playbook that targets web-servers, Ansible will run the playbook against all hosts in the web-servers group, which includes all hosts in the parent group linux-servers. Ansible will also use the http_port variable for all hosts in the web-servers group.\nSimilarly, when we run an Ansible playbook that targets db-servers, Ansible will run the playbook against all hosts in the db-servers group, which includes all hosts in the parent group linux-servers. Ansible will also use the db_port variable for all hosts in the db-servers group.\nExample 2: Child Groups in the Windows Server Group # Suppose we have a group of Windows servers that we want to divide into two child groups, dev-servers and prod-servers, and we want to define different connection variables for each child group.\n[windows_servers] server1 ansible_host=192.168.1.20 server2 ansible_host=192.168.1.21 server3 ansible_host=192.168.1.22 [dev_servers:children] windows_servers [prod_servers:children] windows_servers [dev_servers:vars] ansible_user=devuser ansible_password=devpass [prod_servers:vars] ansible_user=produser ansible_password=prodpass In this example, we have created a group called windows-servers with three hosts. We have then defined two child groups, dev-servers and prod-servers, that both inherit from windows-servers. We have also defined different connection variables for each child group.\nWhen we run an Ansible playbook that targets dev-servers, Ansible will run the playbook against all hosts in the dev-servers group, which includes all hosts in the parent group windows-servers. Ansible will also use the ansible_user and ansible_password variables for all hosts in the dev-servers group.\nSimilarly, when we run an Ansible playbook that targets prod-servers, Ansible will run the playbook against all hosts in the prod-servers group, which includes all hosts in the parent group windows-servers. Ansible will also use the ansible_user and ansible_password variables for all hosts in the prod-servers group.\nConfiguring Ansible to use keypair authentication # In the Ansible configuration file (ansible.cfg), specify the private key:\n[defaults] private_key_file = ~/.ssh/id_rsa Or alternatively, set it in the inventory file (this is the preferred way as it\u0026rsquo;s way more granular)\nAdd the following entry at the host or group you wish to authenticate to using a keypair:\nansible_ssh_private_key_file=~/.ssh/id_rsa Full example rule: kasm ansible_host=172.16.90.10 ansible_user=davy.cavens ansible_ssh_private_key_file=~/.ssh/id_rsa Modules and plugins # As you can see in the example commands on the previous page, ansible uses \u0026lsquo;modules\u0026rsquo;. Ansible modules are small pieces of code that are responsible for carrying out specific tasks on remote hosts. Modules can be thought of as building blocks that are combined together to form playbooks or specify actions for ad-hoc commands, which are then used to automate tasks on one or more remote hosts. Modules can be written in any programming language and are responsible for defining the tasks that are carried out during an Ansible playbook run.\nWe\u0026rsquo;ll go through some of the most frequently used modules.\nFile # The file module is used to manage files and directories on remote hosts. This module can be used to create, modify, and delete files and directories, as well as change file permissions and ownership.\nThe following example creates a specific file on a remote host:\n- name: Create file hosts: webservers tasks: - name: Create file with specific content file: path: /var/www/html/index.html state: touch owner: apache group: apache mode: \u0026#39;0644\u0026#39; content: \u0026#34;\u0026lt;html\u0026gt;\u0026lt;head\u0026gt;\u0026lt;title\u0026gt;Hello World\u0026lt;/title\u0026gt;\u0026lt;/head\u0026gt;\u0026lt;body\u0026gt;\u0026lt;h1\u0026gt;Hello World\u0026lt;/h1\u0026gt;\u0026lt;/body\u0026gt;\u0026lt;/html\u0026gt;\u0026#34; Copy # The copy module is used to copy files from the Ansible control machine to one or more remote hosts. This module can also be used to set file permissions and ownership.\nThe following example copies a file to a remote host:\n- name: Copy file hosts: webservers tasks: - name: Copy file to remote host copy: src: /path/to/local/file dest: /path/to/remote/file owner: apache group: apache mode: \u0026#39;0644\u0026#39; Yum \u0026amp; APT # The yum and APT modules are used to manage packages on remote hosts. This includes installing, updating or removing packages. Yum is used for RHEL based distributions, APT is used for Debian based distributions.\nAn example using Yum:\n- name: Install package hosts: webservers tasks: - name: Install package using YUM yum: name: httpd state: present Service # The service module is used to manage services on remote hosts. This module can be used to start, stop, restart, and enable/disable services.\nThe following example starts a service on a remote host:\n- name: Start service hosts: webservers tasks: - name: Start service on remote host service: name: httpd state: started Shell # The shell module is used to execute arbitrary shell commands on remote hosts. This module can be used to run complex commands that cannot be handled by other Ansible modules.\nThe following example runs a shell command on a remote host:\n- name: Run command hosts: webservers tasks: - name: Run command on remote host shell: ls -la /var/www/html Template # The template module is used to generate files from templates on the Ansible control machine and copy them to one or more remote hosts. This module can be used to create configuration files that are customized for each remote host.\nThe following example generates a file from a template and copies it to the remote host:\n- name: Generate file hosts: webservers tasks: - name: Generate file from template and copy to remote host template: src: /path/to/template.conf.j2 dest: /etc/httpd/conf.d/custom.conf Lineinfile # The lineinfile module can be used to add a line to a specific file on the target\u0026rsquo;s filesystem.\nAn example:\n- name: Add a line to a file lineinfile: path: /etc/hosts line: 192.168.1.99 foo.lab.net foo Other modules? # The ansible Galaxy contains more than 700 different modules. Not all modules are installed on an ansible controller by default.\nYou can install non-default modules using the ansible-galaxy command:\nansible-galaxy collection install cisco.ios You can find an overview of all modules in the Ansible Galaxy\nCollections # In Ansible, collections are a distribution format for Ansible content that can include playbooks, roles, modules, and plugins. Collections allow you to package and distribute Ansible content, whether it\u0026rsquo;s for sharing with others or for your own organizational use. They provide a structured way to deliver various components in a single package, simplifying the management, installation, and use of Ansible content.\nBefore collections, most Ansible content was either distributed as standalone roles via Ansible Galaxy or integrated directly into Ansible itself. Collections aim to offer more scalability and distribution flexibility than the older methods.\nFeatures and Benefits of Collections # Structured Layout: Collections have a defined directory structure, which allows content creators to organize and package their content in a predictable way. Versioning: You can version a collection, making it easier to manage and use different versions of content. Dependency Management: Collections can declare dependencies on other collections or content, ensuring that all required components are present. Examples # Vendor-Specific Collections: Many IT vendors have started packaging their modules and plugins into collections. For instance, Cisco, Juniper, or Red Hat might have their own collections for managing their specific products. Function-Specific Collections: Collections might focus on specific functions or tasks, like a collection for monitoring solutions, one for database management, and another for web server setups. Community Collections: The Ansible community might create collections for general purposes or specific needs, and these can be shared and distributed through platforms like Ansible Galaxy. Using Collections # Here\u0026rsquo;s a basic example to illustrate how you might use a collection in a playbook:\n--- - hosts: localhost gather_facts: no tasks: - name: Use a module from a collection namespace.collection_name.module_name: parameter1: value1 In this example, namespace is the namespace of the collection (often the name of the organization or individual who created it), collection_name is the name of the collection, and module_name is the name of the module within that collection.\nInstalling Collections # To install a collection from Ansible Galaxy:\nansible-galaxy collection install namespace.collection_name For instance, if you wanted to install the community collection for managing Kubernetes:\nansible-galaxy collection install community.kubernetes This is another example to install the community edition of the Cisco collection:\nansible-galaxy collection install cisco.ios In summary, collections in Ansible provide a way to bundle, distribute, and version Ansible content in an organized and scalable manner. Whether you\u0026rsquo;re a content creator or an end user, collections offer a streamlined approach to managing and using Ansible\u0026rsquo;s expansive capabilities.\nWhere are they stored? # All collections that you have downloaded are stored locally on your controller. When you download a collection, they are stored in a hidden .ansible folder on your user\u0026rsquo;s home directory. Take a look at the following screenshot for more details:\nYou can also list all the collections and their saved directories by entering the following command:\nansible-galaxy collection list This will show the following (example) output:\nUpdating a collection # To update a collection, you can simply enter the following command:\nansible-galaxy collection install -U \u0026lt;collection.name\u0026gt; The following example updates the cisco.ios collection:\nansible-galaxy collection install -U cisco.ios This will have the following output:\nIf the collection has any dependencies, they are updated as well.\nInteresting links # Ansible online documentation Ansible Galaxy ","date":"25 Januarie 2026","externalUrl":null,"permalink":"/ansible/componenten/","section":"Ansibles","summary":"","title":"Ansible Componenten","type":"ansible"},{"content":" Workflow # Basic workflow # De basis van Git (terminologie, commando’s, het concept branches) is eigenlijk niet zo moeilijk om te doorgronden, als je je de moeite getroost om deze sectie in detail door te nemen.\nBasisterminologie en commando’s # Alles begint met een remote repository (meestal afgekort tot repo). Dit kan je vergelijken met een folder met daarin alle projectbestanden en de ganse historiek van wijzigingen (van deze bestanden). In deze cursustekst hosten we deze remote repo op GitHub.\nVeronderstel dat er 2 programmeurs zijn die aan een project werken, nl. Alice en Bob\\[6\\]. Zij starten met het downloaden van een kopie van de remote projectrepository op hun pc. Dit proces wordt ook wel het clonen van de remote repo genoemd en wordt uitgevoerd met het Git-commando clone. Het resultaat is een kopie van de projectbestanden (ook de working tree genoemd), alsook een .git subfolder die de lokale repository (de historiek van alle bestanden) bevat. Deze map is niet bedoeld om gelezen te worden door mensen. Het Git commando gaat achterliggend hier alles regelen voor ons. Verwijder deze map ook niet want dit breekt je Git!\nVeronderstel vervolgens dat Alice wijzigingen aanbrengt aan het projectbestand stijl.css\\[7\\]. Zij doet dit in haar (lokale) working tree.\nOm dit gewijzigd bestand toe te voegen aan de lokale repository zijn er 2 acties nodig:\n- Allereerst moet het gewijzigde bestand *stijl.css* worden toegevoegd aan de zogenaamde **staging area** of index. Dit gebeurt via het Git-commando **add**. - Vervolgens wordt het bestand verplaatst van de staging area naar de lokale repo via het Git-commando **commit** en worden de wijzigingen lokaal bevestigd. Je vraagt je misschien af wat het nut is van de staging area/index en de extra tussenstap die moet gebeuren. In de staging area worden alle bestanden bewaard die met een volgende commit moeten worden toegevoegd aan de lokale repo. Op die manier kunnen we in 1 commit een aantal (bij elkaar horende) wijzigingen tegelijkertijd doorvoeren. De volgende actie die Alice onderneemt is het uploaden van de gecommitte wijzigingen in haar lokale repo naar de remote repository. Dit gebeurt met het Git-commando push.\nOp dit moment zijn de lokale repo van Alice en de remote repo gesynchroniseerd en opnieuw aan elkaar gelijk.\nOndertussen heeft Bob het bestand index.html gewijzigd (in zijn working tree). Ook hij bevestigt deze wijzigingen door deze toe te voegen aan zijn lokale repository via de Git-commando’s add en commit.\nNu wil ook Bob zijn lokale repo uploaden naar/synchroniseren met de remote repo. Als hij dit echter probeert (met het Git-commando push), resulteert dit in een foutmelding. Git merkt immers op dat de remote repo wijzigingen bevat (van Alice) die zich nog niet in de lokale repo van Bob bevinden.\nBob moet op dit moment eerst deze verschillen (tussen de remote en zijn lokale repo) downloaden. Dit kan hij doen met het Git-commando pull.\nNu zijn de lokale repo van Bob en de remote repo opnieuw aan elkaar gelijk en kan Bob zijn wijzigingen aan index.html pushen.\nDe basiscommando’s in meer detail # In deze sectie baseren we ons in grote mate op het hierboven uitgewerkte scenario om de basiscommando’s van Git in detail te illustreren.\nWe leggen daarbij ook uit hoe bestanden (en de wijzigingen ervan) worden bewaard in Git. Deze kennis is belangrijk om Git ten volle te kunnen begrijpen en gebruiken.\nInstellen van je identiteit (en default editor) # Vooraleer je met Git begint te werken, stel je best je identiteit (naam en email) in, zodat duidelijk is wie welke wijzigingen heeft aangebracht. Je gebruikt daarvoor de commando’s\ngit config --global user.name \u0026#34;Your Full Name\u0026#34; git config --global user.email \u0026#34;email\u0026#34; Tijdens de installatie is ook een editor gekozen die we later kunnen/zullen gebruiken (bij het ingeven van commentaar bij commits of bij het terugdraaien van commits). De default optie is de VIM-editor, maar desgewenst kan je ook opteren voor een alternatief. Zo kan je de klassieke Kladblok/Notepad-applicatie instellen als editor op Windows of nano op Linux.\nWindows:\ngit config --global core.editor notepad Linux\ngit config --global core.editor nano Opzetten van een startrepository (lokaal en remote) # In deze sectie wijken we een beetje af van het scenario uit de vorige sectie, waar we ervan uitgingen dat er al een remote repository bestond. Deze (remote repo) moet echter ooit door iemand aangemaakt worden, en deze stap illustreren we hieronder.\nJe kan op verschillende manieren een remote repository aanmaken, waarbij het verschil zit in welke volgorde en hoe (via Git Bash of via GitHub) je de verschillende stappen uitvoert. De door ons gekozen volgorde lijkt ons het eenvoudigst voor beginners.\nOpzetten van een lokale repository # We vertrekken van een heel eenvoudig project project_itf_git dat Alice heeft aangemaakt op haar computer, en waarvan zij een remote versie op Git(Hub) wil plaatsen om samen met Bob aan te werken. De folderinhoud van haar project is als volgt:\n[ De folder css bevat het bestand stijl.css en de folder .idea bevat allerlei configuratiebestanden van de voor dit project door Alice gebruikte IDE (Integrated Development Environment) Webstorm.\nHet is niet de bedoeling dat deze laatste folder (.idea) wordt opgenomen in de repository. Deze bestanden bevatten immers geen code en zijn enkel van toepassing voor Alice. Zij maakt daarom een tekstbestand .gitignore aan in de root van haar project. In dit bestand geeft ze met een speciale syntax aan welke bestanden ze niet wenst op te nemen in de repository. Als Alice enkel de .idea-folder niet wenst op te nemen, ziet dit bestand er dus zo uit:\nJe kan dit .gitignore-bestand later ook nog toevoegen/veranderen, maar je moet dan wel enkele bijkomende commando’s uitvoeren om bestanden die reeds in de repository zijn opgenomen (en die je vanaf dan wenst uit te sluiten) te verwijderen. Het is dus ideaal als je op voorhand weet/goed nadenkt over welke bestanden je niet wenst op te nemen in de repo.\nNaast een .gitignore-bestand kan je ook best een README.md-bestand aanmaken in de root van je project. Dit bestand heeft opnieuw een specifieke syntax en wordt door GitHub gebruikt op de startpagina van de remote repository. Voorlopig specifieert Alice enkel een titel (#) en 1 verduidelijkende paragraaf:\nNa het toevoegen van deze 2 bestanden, is Alice klaar om van haar project een lokale repository te maken. Zij navigeert in Windows Verkenner naar de folder waar het project zich bevindt, klikt rechts op de folder en kiest voor Git Bash Here:\nEen (minder handig) alternatief is om Git Bash gewoon te openen en in de bash te navigeren naar de juiste map. (Op Linux hebben we die handige knop jammergenoeg niet)\nHet eerste wat Alice doet, is het initialiseren van deze folder als een (lege) Git-repository door middel van het commando git init. Dit commando initialiseert de .git subfolder en maakt een lokale branch aan met de naam master. In feite is deze master-branch gewoon een pointer die steeds naar de laatste commit verwijst (zie verder).\nDaarna worden via het commando git add . alle bestanden (uitgezonderd deze die zijn uitgesloten via .gitignore) uit deze map toegevoegd aan de staging area, zodat ze klaar staan om op te worden genomen in de volgende (in dit geval de eerste) commit. De wildcard . duidt op de volledige folder, inclusief subfolders en bestanden die beginnen met .\nHet is mogelijk dat je hierbij waarschuwingen krijgt over LF en CRLF, maar die mag je negeren.\nTen slotte moet Alice alle bestanden uit de staging area nog committen (opnemen in de lokale repository). Dit doet ze met het commando git commit -m “comment”, waarbij ze ook nuttig en betekenisvol commentaar kan voorzien.\nJe mag je comment zowel tussen dubbele quotes (“”) als enkele quotes (”) plaatsen.\nAls Alice het commando git commit intypt (zonder de optie -m mee te geven), wordt de default editor geopend om je commentaar in te geven.\nWe zoomen even in op wat er achter de schermen is gebeurd, waarbij we voor de eenvoud de bestanden .gitignore en README.md negeren en dus (even) veronderstellen dat ons project slechts uit 2 bestanden bestaat, nl. stijl.css en index.html. Git bewaart voor elke commit\neen uniek identificatienummer (~ een SHA checksum van alle bestanden in de commit) pointers (of verwijzingen) naar snapshots (ook wel blobs genoemd) van de specifieke bestanden in de commit. Ook voor deze pointers/verwijzingen worden unieke SHA checksums (van de specifieke bestanden) gebruikt. Grafisch kan dit als volgt worden voorgesteld:\nWe zullen verder zien dat een Git-repository eigenlijk niet meer is dan zo’n reeks van commits die worden bewaard zoals hierboven beschreven. Een branch is een pointer die verwijst naar het einde van die reeks. De default branch wordt – zoals eerder aangehaald – meestal main genoemd.\nElke keer je een commit doet, zal deze main-branch worden aangepast (en schuift hij verder door naar de meeste recente commit).\nVerder is er nog de pointer HEAD, die verwijst naar de lokale branch waar je je momenteel bevindt. Deze pointer wordt belangrijker als je met meerdere branches wil gaan werken. In deze cursus werken we met 1 branch en wijst HEAD gewoon naar (dezelfde commit als) main.\nOpzetten van een remote repository # Alice wil van haar lokale repo een remote kopie maken op GitHub. Daarvoor meldt ze zich aan op GitHub en maakt ze een nieuwe (lege) remote repository aan met naam project_itf_git. Ze heeft reeds een .gitignore– en README-bestand, dus ze maakt de overeenkomstige, juiste keuzes:\nMet het commando\ngit remote add \u0026lt;remote-name\u0026gt; \u0026lt;remote-url\u0026gt; geeft Alice de net aangemaakte remote repo op GitHub een naam die ze kan gebruiken in Git Bash.\nAls \u0026lt;remote-name\u0026gt; wordt bijna altijd origin gebruikt. Welke \u0026lt;remote-url\u0026gt; je moet gebruiken, wordt gesuggereerd op GitHub:\nTen slotte pusht Alice haar lokale repository naar GitHub via\ngit push -u \u0026lt;remote-name\u0026gt; \u0026lt;branch-name\u0026gt; De \u0026lt;remote-name\u0026gt; is bijna altijd origin (zie hierboven), de \u0026lt;branch-name\u0026gt; is de naam van de lokale branch (main). Er wordt nu een gelijknamige main-branch aangemaakt in de remote repo. De optie -u zorgt voor een koppeling tussen de lokale en remote repo (zodat we in de toekomst enkel git push moeten gebruiken als commando).\nTIP: gebruik altijd git push indien je dit bovenstaande moet uitvoeren geeft dit commando je letterlijk het juiste commando om te copy pasten!\nHet is mogelijk dat tijdens het pushen je GitHub-credentials worden gevraagd.\nDe remote repo is nu gelijk aan de lokale repo van Alice, zoals grafisch geïllustreerd in de figuur hieronder:\nAls Alice met git status opvraagt in welke status de bestanden (in haar lokale repo) zich bevinden, wordt dit bevestigd: On branch main en Your branch is up to date with ‘origin/main’.\nAls allerlaatste actie nodigt Alice Bob uit om met haar samen te werken aan deze remote repository via de GitHub-tab Settings, keuze Collaborators. Ze zoekt hierbij op de GitHub-gebruikersnaam van Bob.\nCollaborators toevoegen via GitHub\nBob ontvangt een mail waarin hij de uitnodiging tot samenwerken moet bevestigen.\nClonen van een remote repository # Bob wil nu de remote repo (die Alice net heeft gemaakt) clonen in een lokale repository. Hij gebruikt daarvoor het commando\ngit clone \u0026lt;remote-url\u0026gt; De \u0026lt;remote-url\u0026gt; heeft Bob van Alice gekregen of kan hij opzoeken via haar GitHub-account: De lokale repository (kopie van de remote repository) komt in een automatisch aangemaakte folder met dezelfde naam als de remote repo (in dit geval project_itf_git).\nMet het commando\ngit clone \u0026lt;remote-url\u0026gt; \u0026lt;local folder\u0026gt; kan je zelf een lokale folder \u0026lt;local folder\u0026gt; opgeven waarin de clone moet terechtkomen. Ook deze folder wordt automatisch aangemaakt.\nNavigeer eerst naar de juiste folder vooraleer je het clone-commando uitvoert.\nNu is ook de lokale repository van Bob gelijk aan de remote repository (en de lokale repo van Alice):\nWijzigen van bestand(en) in lokale en remote repository # Stagen en committen van lokaal gewijzigd bestand (Alice) # Het commando git status gaf ook de boodschap nothing to commit, working tree clean weer. Dit betekent dat Alice nog geen bestanden heeft gewijzigd (sinds het aanmaken van de repository).\nVeronderstel nu dat Alice enkele wijzigingen aanbrengt aan het stijl.css bestand. Als ze vervolgens opnieuw de status controleert (via git status), kan ze aflezen dat stijl.css modified is maar dat dit bestand zich in haar working tree en nog niet in de staging area bevindt (Changes not staged for commit:).\nVooraleer Alice dit bestand toevoegt aan de staging area, kan zij (indien gewenst) de verschillen tussen de versie in de lokale repo en de versie in de working tree bekijken via het commando git diff: in het rood (en voorafgegaan door -) wordt de verwijderde tekst/code aangegeven (hier niet van toepassing), in het groen (en voorafgegaan door +) wordt aangegeven wat er is bij getypt.\nMet het commando git diff worden de verschillen van alle (hier slechts 1) gewijzigde bestanden getoond. Met git diff \u0026lt;file\u0026gt; kan je de verschillen van een specifiek bestand opvragen. Je kan bij lange uitvoer met \u0026lt;spatiebalk\u0026gt; naar de volgende pagina, en met \u0026lt;q\u0026gt; kan je het bekijken van de verschillen beëindigen.\nGebruik het git diff-commando op geregelde basis ter controle, telkens voor je gewijzigde bestanden gaat stagen (toevoegen aan de staging area).\nDe wijzigingen zijn ok, dus nu voegt Alice dit bestand toe aan de staging area met het commando git add \u0026lt;file\u0026gt;. Als daarna de status opnieuw wordt opgevraagd, lezen we opnieuw af dat stijl.css modified is én dat dit bestand zich in Alice’s staging area bevindt (Changes to be committed:).\nHet git add-commando kent vele varianten door verschillende opties te gebruiken:\ngit add --all voegt alle nieuwe/gewijzigde bestanden toe aan de staging area `git add css/*.css voegt alle nieuwe/gewijzigde CSS-bestanden in de map css toe aan de staging area, Git ondersteund bash globbing. Ook op dit moment kan je (desgewenst) nog nakijken wat de verschillen zijn tussen (de bestanden in) de lokale repo en de staging area. Je gebruikt hiervoor de commando’s\ngit diff --staged # of git diff --staged \u0026lt;file\u0026gt; Het is nu tijd om dit gewijzigd stijlbestand te committen (op te nemen in de lokale repo van Alice). Alice doet dit met het commando\ngit commit -m \u0026#34;comment\u0026#34; Er bestaan richtlijnen om goede commit-commentaren/boodschappen te schrijven. Kies alvast voor betekenisvol commentaar, geschreven in een gebiedende wijs.\nAls je online op zoek gaat naar informatie over Git, zal je wellicht ook het commando\\\ngit commit -a -m \u0026#34;comment\u0026#34; tegen komen. Dit commando slaat de staging area over en voegt de gewijzigde bestanden vanuit je working tree rechtstreeks toe aan de lokale repo. Nieuwe bestanden worden echter niet toegevoegd, en bovendien is het moeilijk om op deze manier je commits georganiseerd (gewijzigde bestanden die bij elkaar horen vormen 1 commit) te houden. We raden dan ook aan om dit verkorte commando niet te gebruiken! We zoomen opnieuw even in op wat er nu precies gebeurt in de lokale repo van Alice.\nGit berekent voor deze nieuwe commit opnieuw een unieke SHA checksum, en linkt deze commit met de initiële commit (via een pointer/verwijzing naar de vorige commit). De HEAD en main pointer schuiven op naar rechts en verwijzen nu naar de laatste commit.\nOpnieuw worden ook SHA-pointers naar snapshots/blobs van de specifieke bestanden in de nieuwe commit bewaard.\nHet bestand index.html is niet gewijzigd, en aldus verandert de pointer naar de overeenkomstige blob dan ook niet.\nHet bestand stijl.css is wel gewijzigd. Daarom wordt er via een pointer verwezen naar een nieuw snapshot/blob van dit bestand.\nVaak worden de repositories compacter voorgesteld waar we de (huidige toestand van de) lokale repo van Alice en de remote repo weergeven.\nPushen van lokale repo naar remote repo (Alice) # We merken dat de lokale repo van Alice 1 commit voor ligt op de remote repo. Dit wordt bevestigd door de commando’s git status (Your branch is ahead of ‘origin/main’ by 1 commit.) of git log (waarover later nog meer).\nAlice kan nu haar wijzigingen pushen naar de remote repo d.m.v. het commando git push.\nOp dit moment zijn de lokale repo van Alice en de remote repo opnieuw synchroon, wat bevestigd wordt door de uitvoer van de commando’s git status en git log.\nWijzigen van bestand(en) in lokale en remote repository # Stagen en committen van lokaal gewijzigd bestand (Alice) # Het commando git status gaf ook de boodschap nothing to commit, working tree clean weer. Dit betekent dat Alice nog geen bestanden heeft gewijzigd (sinds het aanmaken van de repository).\nVeronderstel nu dat Alice enkele wijzigingen aanbrengt aan het stijl.css bestand. Als ze vervolgens opnieuw de status controleert (via git status), kan ze aflezen dat stijl.css modified is maar dat dit bestand zich in haar working tree en nog niet in de staging area bevindt (Changes not staged for commit:).\nVooraleer Alice dit bestand toevoegt aan de staging area, kan zij (indien gewenst) de verschillen tussen de versie in de lokale repo en de versie in de working tree bekijken via het commando git diff: in het rood (en voorafgegaan door -) wordt de verwijderde tekst/code aangegeven (hier niet van toepassing), in het groen (en voorafgegaan door +) wordt aangegeven wat er is bij getypt.\nMet het commando git diff worden de verschillen van alle (hier slechts 1) gewijzigde bestanden getoond. Met git diff \u0026lt;file\u0026gt; kan je de verschillen van een specifiek bestand opvragen. Je kan bij lange uitvoer met \u0026lt;spatiebalk\u0026gt; naar de volgende pagina, en met \u0026lt;q\u0026gt; kan je het bekijken van de verschillen beëindigen.\nGebruik het git diff-commando op geregelde basis ter controle, telkens voor je gewijzigde bestanden gaat stagen (toevoegen aan de staging area).\nDe wijzigingen zijn ok, dus nu voegt Alice dit bestand toe aan de staging area met het commando git add \u0026lt;file\u0026gt;. Als daarna de status opnieuw wordt opgevraagd, lezen we opnieuw af dat stijl.css modified is én dat dit bestand zich in Alice’s staging area bevindt (Changes to be committed:).\nHet git add-commando kent vele varianten door verschillende opties te gebruiken:\ngit add --all voegt alle nieuwe/gewijzigde bestanden toe aan de staging area `git add css/*.css voegt alle nieuwe/gewijzigde CSS-bestanden in de map css toe aan de staging area, Git ondersteund bash globbing. Ook op dit moment kan je (desgewenst) nog nakijken wat de verschillen zijn tussen (de bestanden in) de lokale repo en de staging area. Je gebruikt hiervoor de commando’s\ngit diff --staged # of git diff --staged \u0026lt;file\u0026gt; Het is nu tijd om dit gewijzigd stijlbestand te committen (op te nemen in de lokale repo van Alice). Alice doet dit met het commando\ngit commit -m \u0026#34;comment\u0026#34; Er bestaan richtlijnen om goede commit-commentaren/boodschappen te schrijven. Kies alvast voor betekenisvol commentaar, geschreven in een gebiedende wijs.\nAls je online op zoek gaat naar informatie over Git, zal je wellicht ook het commando\\\ngit commit -a -m \u0026#34;comment\u0026#34; tegen komen. Dit commando slaat de staging area over en voegt de gewijzigde bestanden vanuit je working tree rechtstreeks toe aan de lokale repo. Nieuwe bestanden worden echter niet toegevoegd, en bovendien is het moeilijk om op deze manier je commits georganiseerd (gewijzigde bestanden die bij elkaar horen vormen 1 commit) te houden. We raden dan ook aan om dit verkorte commando niet te gebruiken! We zoomen opnieuw even in op wat er nu precies gebeurt in de lokale repo van Alice.\nGit berekent voor deze nieuwe commit opnieuw een unieke SHA checksum, en linkt deze commit met de initiële commit (via een pointer/verwijzing naar de vorige commit). De HEAD en main pointer schuiven op naar rechts en verwijzen nu naar de laatste commit.\nOpnieuw worden ook SHA-pointers naar snapshots/blobs van de specifieke bestanden in de nieuwe commit bewaard.\nHet bestand index.html is niet gewijzigd, en aldus verandert de pointer naar de overeenkomstige blob dan ook niet.\nHet bestand stijl.css is wel gewijzigd. Daarom wordt er via een pointer verwezen naar een nieuw snapshot/blob van dit bestand.\nVaak worden de repositories compacter voorgesteld waar we de (huidige toestand van de) lokale repo van Alice en de remote repo weergeven.\nPushen van lokale repo naar remote repo (Alice) # We merken dat de lokale repo van Alice 1 commit voor ligt op de remote repo. Dit wordt bevestigd door de commando’s git status (Your branch is ahead of ‘origin/main’ by 1 commit.) of git log (waarover later nog meer).\nAlice kan nu haar wijzigingen pushen naar de remote repo d.m.v. het commando git push.\nOp dit moment zijn de lokale repo van Alice en de remote repo opnieuw synchroon, wat bevestigd wordt door de uitvoer van de commando’s git status en git log.\n","date":"25 Januarie 2026","externalUrl":null,"permalink":"/git/workflow/","section":"Gits","summary":"","title":"Workflow","type":"git"},{"content":"","externalUrl":"https://code-chimp.com","permalink":"/users/2-4bc0917e04c4859cedb32a48bff27846/","section":"Users","summary":"","title":"code-chimp.com","type":"users"},{"content":" Cheat sheet voor basic workflow # # Aanmaken van lokale start repo # _README.md_ en _.gitignore_ bestand aanmaken git init git add . git commit -m \u0026#34;startbestanden\u0026#34; # Pushen van lokale start repo naar remote repo # remote repo aanmaken op GitHub* git remote add origin https://github.com/... git push -u origin main # Clonen van remote repo # Bash openen in gewenste folder git clone https://github.com/... # Gewijzigde bestanden stagen en committen git add \u0026lt;file(s)\u0026gt; git commit -m \u0026#34;comment\u0026#34; # Lokale commits uploaden naar remote repo git push #Verschillen weergeven tussen versie in lokale repo en versie in working tree git diff of git diff \u0026lt;file\u0026gt; # Verschillen weergeven tussen versie in lokale repo en versie in staging area git diff --staged* # of git diff --staged \u0026lt;file\u0026gt; # Status (van working tree en staging area) weergeven git status Teamwork workflow # Je hebt nu al geleerd hoe je GitHub en Git kunt gebruiken om versiebeheer op je projecten te doen. In deze tutorial gaan we een stap verder en gebruiken we Git om in teamverband aan dezelfde codebase te werken.\nWerken met “branches” # Nadat je het project hebt gecloned op je computer kunnen we beginnen te werken aan code veranderingen. We doen dit in branches. Branches, ook wel feature branches genoemd, maken een kopie van de hoofdcode die zich op de “main” branch bevindt. Het is een slechte gewoonte om direct naar de “main” branch te pushen als je in teams werkt. Een uitzondering op deze regel is de eerste commit.\nIn een branch kun je zoals gebruikelijk één of meer commits maken, deze geven de wijzigingen weer om een bepaald deel van de code toe te voegen. Om een nieuwe branch te maken kun je het volgende doen met Git\n$ git branch \u0026lt;branch naam\u0026gt; De branchnaam moet het deel bevatten dat je van plan bent toe te voegen, en ook meestal je naam, zodat je geen conflicten met je teamgenoten hebt. Een naam zou bijvoorbeeld jefke-add-contact-page kunnen zijn, merk op dat branchnamen geen spaties mogen bevatten!\nTakken maken doe je met git branch. Na het aanmaken van de branch moet je overschakelen naar het gebruik van die branch. Dit kan gedaan worden met git checkout.\n$ git checkout [branch naam] Dit commando zal de bestanden op je harde schijf aanpassen aan de bestanden in de branch. Het is dus normaal dat je nieuwere bestanden nog niet ziet. Het maakt een eigen kopie zodat je tijdens je werk niet “gestoord” wordt door wijzwgingen op de main branch.\nJe kunt nu zoals gewoonlijk werken en git add en git commit gebruiken om je wijzigingen vast te leggen. Je kunt git push gebruiken als je op een branch zit om de branch naar GitHub te pushen\nEen volledige workflow zou bijvoorbeeld zijn\ngit branch add-contact-page git checkout add-contact-page touch contact.html # voorbeeld verandering!!! geen onderdeel van de workflow git add . git commit -m \u0026#34;Een contactpagina gemaakt\u0026#34; git push --set-upstream origin maartje-add-contact-page # eerste keer nodig, gebruik gewoon git push` voor latere wijzigingen in de branch Pull Requests # Pull requests, ook wel Merge Requests genoemd in andere Git oplossingen, zijn verzoeken die gedaan worden om code van een bepaalde branch samen te voegen in de “main” branch van het repository. Je kunt dit doen nadat je voor de eerste keer “git push” gedaan hebt, door naar de repository op Github te gaan en naar “Pull Requests” te gaan, hier kun je klikken op “New Pull Request”.\n","date":"26 Januarie 2026","externalUrl":null,"permalink":"/git/appendix/","section":"Gits","summary":"","title":"Appendix","type":"git"},{"content":"Hier zijn enkele basiscommando\u0026rsquo;s voor Docker om je op weg te helpen:\ndocker run: Start een container op basis van een image. docker ps: Toont een lijst van alle actieve containers. docker images: Toont een lijst van alle beschikbare images op je machine. docker pull: Haalt een image op uit een registry (bijv. Docker Hub). docker push: Uploadt een image naar een registry. docker rm: Verwijdert een container. docker rmi: Verwijdert een image. docker build: Bouwt een image op basis van een Dockerfile. docker exec: Voert een commando uit binnen een actieve container. docker stop: Stopt een actieve container. docker start: Start een gestopte container. Praktische voorbeelden # docker run: Start een container op basis van een image. docker run -it --name UbuntuContainer ubuntu:20.04 Dit commando maakt een nieuwe container aan met de naam \u0026ldquo;UbuntuContainer\u0026rdquo; op basis van de Ubuntu 20.04-image en opent een interactieve terminalsessie.\ndocker ps: Toont een lijst van alle actieve containers. docker ps docker ps -a: Toont een lijst van alle containers, inclusief gestopte containers. docker ps -a docker start: Start een gestopte container. docker start UbuntuContainer docker stop: Stopt een actieve container. docker stop UbuntuContainer docker rm: Verwijdert een container. docker rm UbuntuContainer Om alle gestopte containers te verwijderen, kun je dit gebruiken: docker container prune docker images: Toont een lijst van alle beschikbare images op je lokale machine. docker images docker rmi: Verwijdert een image. docker rmi ubuntu:20.04 Om ongebruikte images te verwijderen, kun je dit gebruiken: docker image prune docker pull: Haalt een image op uit een registry (bijv. Docker Hub). docker pull nginx docker exec: Voert een commando uit binnen een draaiende container. docker exec -it UbuntuContainer bash Dit commando opent een interactieve terminalsessie in de \u0026ldquo;my-ubuntu\u0026rdquo;-container.\ndocker logs: Toont de logs van een container. docker logs UbuntuContainer docker cp: Kopieert bestanden of mappen tussen een container en het lokale bestandssysteem. docker cp UbuntuContainer:/hello.txt . Dit commando kopieert het bestand \u0026ldquo;hello.txt\u0026rdquo; van de \u0026ldquo;my-ubuntu\u0026rdquo;-container naar de huidige map op de lokale machine.\nDocker Compose # Het gebruik van ad-hoc Docker-commando\u0026rsquo;s is ideaal voor applicaties die slechts één Docker-container nodig hebben om te draaien. Maar wat als je een applicatie hebt die interactie vereist tussen meerdere Docker-containers op dezelfde host? Je zou ze allemaal afzonderlijk kunnen downloaden en uitvoeren, maar dat kan al snel erg omslachtig worden! Om in deze behoefte te voorzien, is Docker Compose ontwikkeld! Docker Compose is een tool voor het definiëren en beheren van Docker-applicaties die uit meerdere containers bestaan. Hiermee kun je meerdere containers configureren, bouwen en uitvoeren als één geheel, wat het beheer van complexe applicaties bestaande uit meerdere services vereenvoudigt. Docker Compose gebruikt een YAML-configuratiebestand genaamd docker-compose.yml om de services, netwerken en volumes te definiëren die nodig zijn voor een applicatie.\nBelangrijkste kenmerken van Docker Compose: # Vereenvoudigt het beheer van applicaties met meerdere containers: Met Docker Compose kun je de volledige applicatiestack – inclusief containers, netwerken en volumes – beheren via één enkel commando in plaats van meerdere Docker-commando\u0026rsquo;s. Stroomlijnt de configuratie: Docker Compose stelt je in staat om de services, netwerken en volumes van je applicatie te definiëren in één enkel, voor mensen leesbaar YAML-bestand. Dit vereenvoudigt de configuratie en maakt deze makkelijker te begrijpen en te onderhouden. Ondersteunt versiebeheer en samenwerking: Door het docker-compose.yml-bestand op te slaan in een versiebeheersysteem, kun je wijzigingen in de configuratie van je applicatie bijhouden, samenwerken met teamleden en indien nodig eenvoudig terugkeren naar eerdere configuraties. - Maakt omgevingsspecifieke configuraties mogelijk: Docker Compose ondersteunt het gebruik van omgevingsvariabelen en meerdere compose-bestanden, waardoor je configuraties kunt maken die specifiek zijn voor ontwikkeling, testen en productie. Praktijkvoorbeeld # In dit voorbeeld gebruiken we Docker Compose om een ​​monitoringoplossing genaamd LibreNMS te installeren. Zet een cloud-VM op. Als je niet zeker weet hoe je dit in Oracle Cloud doet, kun je de handleiding Setting up a cloud VM in OCI raadplegen of Terraform gebruiken voor de implementatie.\nZodra dat is gebeurd, kun je de volgende commando\u0026rsquo;s uitvoeren:\n1 een map aanmaken Maak een map aan en ga naar die map:\nmkdir librenms cd librenms 2 Download Download en pak de compose-bestanden uit\nwget https://github.com/librenms/docker/archive/refs/heads/master.zip unzip master.zip 3 compose-map Ga naar de compose-map cd docker-master/examples/compose Deze commando\u0026rsquo;s maken een nieuwe map genaamd \u0026rsquo;librenms\u0026rsquo; aan en downloaden en pakken het zip-bestand van de LibreNMS GitHub uit. Dit zip-bestand bevat alle benodigde bestanden om de LibreNMS-containers te implementeren.\n4 apt-repository Wanneer je je in de compose-map bevindt, zie je dat er een verborgen .env-bestand is aangemaakt. Je kunt dit controleren met het volgende commando:\nls -al 5 .env Bewerk vervolgens dit bestand met het volgende commando:\nnano .env Dit bestand bevat variabelen die in het docker-compose-bestand worden gebruikt. Pas het wachtwoord aan en voer je eigen wachtwoord in.\nDaarna zijn we klaar om de containers te starten!\n6 Docker compose Voer Docker compose uit\ndocker compose up -d En dat is alles! Alle benodigde images en containers worden voor je gedownload en gestart. Makkelijk, toch?\n7 controleren Je kunt controleren of alle containers succesvol zijn geïnitialiseerd met het volgende commando:\ndocker ps Als je Portainer hebt geïnstalleerd, kun je dit ook controleren via de Portainer-interface (GUI).\nOpmerking Als je LibreNMS in je project wilt gebruiken, houd er dan rekening mee dat bij het toevoegen van een host ICMP-communicatie (ping) mogelijk moet zijn vanuit het monitoringsysteem naar de doel-VM of -host.\n","date":"26 Januarie 2026","externalUrl":null,"permalink":"/docker/commando/","section":"Dockers","summary":"","title":"commando's","type":"docker"},{"content":" Ansible Vault # What is Ansible Vault? # When using playbooks or ad-hoc commands, it is possible that your commands have to include sensitive information like passwords, API keys or other credentials. Ansible Vault is a tool used to encrypt sensitive information. It provides a way to keep these secrets secure and prevent them from being accidentally shared or exposed. The vault uses Advanced Encryption Standard (AES) to encrypt data and can be integrated into ad-hoc commands and playbooks.\nBesides encrypting data to use in playbooks or ad-hoc commands, it can also be used to create an encrypted inventory file!\nCreating a vault # Creating a vault is pretty easy!\nansible-vault create \u0026lt;name of your vault\u0026gt; After this, you\u0026rsquo;ll be asked to enter a password. This password will be used to decrypt the vault when you wish to use the sensitive information.\nAn example of the content is the following:\napi_key: DitIsEenAPIKeyWaarde secret_password: DitIsEenSuperGeheimWachtwoord The first part is the name of the variable, the second part is the actual value.\nWhen typing in the ansible-vault, know that it will act as the vi text editor in Linux. To enter data, press \u0026lsquo;i\u0026rsquo;. To save and exit, press escape, enter \u0026lsquo;:wq\u0026rsquo; and press enter.\nEditing a vault # If you wish to add or change data in the vault file, enter the following command:\nansible-vault edit vault-secrets-wiki Integrating the vault into ad-hoc commands # To use an Ansible Vault file in an ad-hoc command, you can use the \u0026ndash;ask-vault-pass option to prompt for the password. For example, to run a command that uses an encrypted file, you could use the following command:\nansible all -m ping --ask-vault-pass --vault-password-file=.vault_pass In this example, the \u0026ndash;ask-vault-pass option prompts for the vault password, and the \u0026ndash;vault-password-file option specifies a file containing the password.\nIntegrating the vault into playbooks # Example 1 # Create a new Ansible Vault file using the ansible-vault create command. For example, ansible-vault create secrets.yml. Enter a password for the vault file when prompted. Be sure to remember this password, as it will be required to decrypt the file later. Add the sensitive variables you want to protect to the vault file using YAML syntax. For example, if you want to protect a variable named db_password, add the following to the vault file: db_password: secure_password Save and close the vault file. In your playbook, add a reference to the vault file and the variable you want to use. For example, if you want to use the db_password variable in a task, you can add the following: - name: Example task become: true vars_files: - secrets.yml vars: db_password: \u0026#34;{{ db_password }}\u0026#34; mysql_user: name: db_user password: \u0026#34;{{ db_password }}\u0026#34; In this example, the vars_files option references the secrets.yml vault file, and the vars option creates a new variable named db_password that references the value stored in the vault file.\nWhen running the playbook, Ansible will prompt you to enter the password for the vault file before it can be decrypted and used in the playbook. You can also specify the password using the \u0026ndash;ask-vault-pass option when running the playbook to avoid the prompt.\nAssuming you created a playbook called \u0026lsquo;playbook.yml\u0026rsquo; and the vault is called \u0026lsquo;secrets.yml\u0026rsquo;, an example to run the playbook would be the following:\nansible-playbook -i inventory.ini playbook.yml --ask-vault-pass --vault-password-file=secrets.yml Example 2 # Another example to do this would be the following:\n--- - name: Example playbook with lookup hosts: all become: true vars_files: - /home/ansible/vault/vault-secrets-wiki vars: password: \u0026#34;{{ lookup(\u0026#39;vault\u0026#39;, \u0026#39;~/secrets.yml\u0026#39;) }}\u0026#34; tasks: - name: Configure MySQL user mysql_user: name: db_user password: \u0026#34;{{ password }}\u0026#34; - name: Show the password debug: msg: \u0026#34;Oh no i\u0026#39;m printing the password in plaintext... take a look! {{ password }}\u0026#34; This example uses the lookup command to search the vault and makes it usable in the ansible tasks.\nAnsible Roles # What are Ansible Roles? # Roles provide a framework for fully independent, reusable collections of variables, tasks, templates, files, and modules which can be automatically loaded into playbooks.\nFor example, if you have a common setup routine for web servers, you can create a role called webserver and use it in any playbook that should set up a web server.\nRole Directory Structure: An Ansible role has a standard directory structure. Here\u0026rsquo;s a brief overview:\nroles/ webserver/ tasks/ main.yml handlers/ main.yml templates/ nginx.conf.j2 files/ sample.html vars/ main.yml defaults/ main.yml meta/ main.yml tasks: Contains the main list of tasks to be executed by the role. handlers: Contains handlers, which may be used by this role or even anywhere outside this role. templates: Contains templates that can use variables to generate host-specific files. files: Contains files which can be deployed without modification. vars: Variables associated with this role. defaults: Default lower-priority variables for this role. meta: Metadata for this role. Creating a Simple Role:\nCreate a directory structure:\nmkdir -p roles/webserver/tasks Define tasks for the role. Create a roles/webserver/tasks/main.yml:\n--- - name: Install Nginx apt: name: nginx state: present Use the role in a playbook:\n--- - hosts: web_servers roles: - webserver Advantages of Using Roles:\nReusability: Roles can be reused in multiple playbooks. Organization: By segregating different tasks, handlers, and variables into roles, the playbook becomes more organized. Sharing: Ansible roles can be easily shared via Ansible Galaxy, a community hub for sharing Ansible roles. Tips:\nRole Variables: Place default role-specific variables in the defaults/main.yml file, as they have the lowest precedence. Role Dependencies: In the meta/main.yml file, you can define any role dependencies to ensure they run before this role. Example: Using Ansible Vault in the inventory file # The inventory file can contain very sensitive information. This can contain usernames, links to private keys, sudo passwords,\u0026hellip; you name it!\nThis is information that you wouldn\u0026rsquo;t want to show in plain text! In this example we\u0026rsquo;ll secure our inventory file using ansible vault and variables.\nInventory file content # First, let\u0026rsquo;s fill up the inventory file:\n[TMLab] kasm ansible_host=172.16.90.10 ansible_become_password=\u0026#34;{{ sudo_kasm }}\u0026#34; librenms ansible_host=172.16.90.80 ansible_become_password=\u0026#34;{{ sudo_libre }}\u0026#34; [TMLab:vars] ansible_user=davy.cavens ansible_ssh_private_key_file=~/.ssh/id_rsa As you can see, we have defined 2 variables called sudo_kasm and sudo_libre. These contain the sudo passwords for the \u0026lsquo;kasm\u0026rsquo; and \u0026rsquo;librenms\u0026rsquo; host respectively.\nNow we\u0026rsquo;ve refered to certain variables in our inventory file\u0026hellip; but we haven\u0026rsquo;t set any values for the vaults yet!\nThe directory structure # To do this, we first have to create a directory structure:\ninventory/ ├── hosts # This is our inventory file ├── group_vars/ │ ├── my_group/ │ │ └── vault.yml # This contains encrypted passwords for a specific group in our inventory file └── host_vars/ └── my_host.yml # This can contain encrypted passwords for a specific host in our inventory files We\u0026rsquo;ll be using group_vars in our example.\nAs we\u0026rsquo;ve configured the group TMLab in our inventory file, the structure will look like the following:\ninventory/ ├── hosts # This is our inventory file ├── group_vars/ │ ├── TMLab/ │ │ └── secrets.yml # This contains encrypted passwords for a specific group in our inventory file Creating the vault # For this, we will create a vault for the group called TMLab. We\u0026rsquo;ll create a vault called secrets.yml.\nTo create the vault, navigate to the TMLab folder.\nIn this folder, enter the following command\nansible-vault create secrets.yml You\u0026rsquo;ll be asked to set a password for the vault.\nDO NOT FORGET THE PASSWORD TO THIS VAULT!\nThis will open a vi-like shell where you can enter your passwords. Remember what we entered in our inventory file? We referenced 2 specific variables: sudo_kasm and sudo_libre. These variables will need to exist in our vault file:\nsudo_kasm: Your-kasm-password sudo_libre: Your-libre-password Using the vault # We\u0026rsquo;ll do an ad-hoc command \u0026ldquo;ping\u0026rdquo;.\nTo reference both our inventory file and ask for a password, we\u0026rsquo;ll have to use the following command:\nNote: this command assumes you are in the same directory as your inventory file. If this is not the case, also enter the path to your inventory file.\nansible TMLab -i inventory --ask-vault-password -m ping After this, you\u0026rsquo;ll be asked to enter the vault password. As we are connecting to the TMLab group as our target, ansible knows that it needs to use the secrets.yml file in the group_vars/TMLab directory.\n68 Using it in a playbook # Say we have a playbook to update all CentOS hosts called \u0026ldquo;update_os.yml\u0026rdquo;:\n--- - name: Update packages hosts: all become: yes tasks: - name: Update packages yum: name: \u0026#39;*\u0026#39; state: latest update_cache: yes update_only: yes when: ansible_distribution == \u0026#39;CentOS\u0026#39; - name: Update Kernel specifically yum: name: \u0026#39;kernel\u0026#39; state: latest when: ansible_distribution == \u0026#39;CentOS\u0026#39; - name: Clean packages that arent needed yum: autoremove: yes when: ansible_distribution == \u0026#39;CentOS\u0026#39; To use the same vault as we referenced earlier, we can use the following command:\nansible-playbook update_os.yml --ask-vault-pass -i /ansible/inventory/hosts As earlier, a vault pass will be asked and if the hosts in the TMLab group are CentOS hosts, they will be updated:\nMultiple vaults in one inventory file # When you have multiple groups, each with a specific vault, running a playbook with the previous command will return an error.\nYou can reference a specific group in your ansible-playbook command. This example references specifically the group TMLab from our inventory file and uses only the vault pass for this group:\nansible-playbook update_os.yml -i hosts -l TMLab --ask-vault-password Example: Using Ansible Roles # To make the concept of roles more clear, let\u0026rsquo;s go through an example.\nOur usecase for this example will be deploying an apache webserver.\nDirectory structure # webserver-setup/ │ ├── site.yml │ └── roles/ └── apache/ ├── tasks/ │ └── main.yml ├── handlers/ │ └── main.yml ├── templates/ │ └── apache.conf.j2 └── vars/ └── main.yml In this directory structure, you can see we have a directory called \u0026lsquo;roles\u0026rsquo;. The subdirectory is called \u0026lsquo;apache\u0026rsquo;, that will be the name of our self-defined role. The real magic happens in the subdirectories of the Apache role!\nLet\u0026rsquo;s go through the components one by one.\nThe main playbook # The main playbook (outside the roles directory) is called \u0026lsquo;site.yml\u0026rsquo;. We will reference our created role here.\nThe playbook could look as follows:\n--- - name: Deploy Apache Webserver hosts: webservers become: yes roles: - apache As you can see, our playbook has a parameter called \u0026ldquo;roles\u0026rdquo;. This one references our apache role.\nInside the Apache role # Tasks # Within tasks, we\u0026rsquo;ve defined a main.yml task file. In this we can put all our tasks that we want to execute on the target. It could look like the example below:\n--- - name: Ensure Apache is installed apt: name: apache2 state: present - name: Ensure Apache configuration is in place template: src: apache.conf.j2 dest: /etc/apache2/sites-available/default.conf notify: restart apache As you can see, the task \u0026ldquo;ensure Apache configuration is in place\u0026rdquo; references a template. It will look in the \u0026rsquo;templates\u0026rsquo; directory for a file we reference here.\nTemplates # Templates are configuration templates which can be populated with variables. Here\u0026rsquo;s an example of our apache.conf.j2 file:\n\u0026lt;VirtualHost *:80\u0026gt; DocumentRoot \u0026#34;{{ document_root }}\u0026#34; ... \u0026lt;/VirtualHost\u0026gt; Handlers # Handlers are tasks in a playbook that run only once and are triggered by statements in other tasks. This is done specifically with the notify statement.\nThis task restarts the apache service:\n--- - name: restart apache service: name: apache2 state: restarted Variables # In our template, we referenced a variable. This also needs to be defined in a file within the \u0026lsquo;vars\u0026rsquo; directory:\n--- document_root: /var/www/html Running the playbook # We assume that we have an inventory file with a host group called \u0026lsquo;webservers\u0026rsquo;, as this is defined in our main playbook.\nTo run the playbook and the defined role, simply enter the following:\nansible-playbook site.yml # if using the default inventory file ansible-playbook -i path_to_inventory site.yml # If using a non-default inventory file Ansible and GIT # All our Ansible files have been hosted on the Ansible Controller itself. This may not cause any immediate issues, but what would happen if our Ansible Controller crashed and the files cannot be retrieved? We would lose all our files, which might be disastrous!\nWe can link our ansible files to a remote git repository, like GitHub. If our Ansible controller would crash, we would still have all our files available to us on GitHub. After setting up a new host, we can just pull the repository data to our new controller.\nIn this topic, we\u0026rsquo;ll learn how to link Ansible to Git.\nCreating a repository # Navigate to GitHub.com and create a repository\nMake a private repository called \u0026ldquo;Ansible\u0026rdquo; (or any other name you\u0026rsquo;d prefer)\nLinking an SSH key # Optional step, if you have not yet created an SSH key, you can generate a key using the ssh-keygencommand. If you already have a key (usually found stored as ~/.ssh/id_rsa.pub), show the public key\u0026rsquo;s content and copy it. Show the key using the following command cat ~/.ssh/id_rsa.pub Next, link the key to GitHub. Navigate to settings (click your user on the top right in GitHub):\nNext, navigate to \u0026ldquo;SSH and GPG Keys\u0026rdquo; and add a new SSH key\nEnter the SSH key we copied earlier\nCopy the git URL for later use:\nInitialize git locally # Now, we can initialize git locally on our Ansible controller.\nFirst, enter some global information (if you haven\u0026rsquo;t yet)\ngit config --global user.email \u0026#34;an-email@address\u0026#34; git config --global user.name \u0026#34;your name\u0026#34; Initialize your git repo\ngit init Now, add a git ignore file. I\nnano .gitignore Add the following content to the gitignore file. In this example, we will exclude all files that contain the word secret. (An example would be Ansible vaults).\n# .gitignore *secret* Add all files and subdirectories (This assumes your in the top level directory of your ansible folder)\ngit add * Let\u0026rsquo;s do a first commit now:\ngit commit -m \u0026#34;Initial commit of Ansible inventory.\u0026#34; Now, let\u0026rsquo;s add a remote repo. We will have to use the git link we copied from GitHub earlier!\ngit remote add origin git@YOUR-REPOSITORY Now, let\u0026rsquo;s push it to our remote repo\ngit push -u origin master Great! Now verify on your Master branch on github if it uploaded correctly:\n","date":"25 Januarie 2026","externalUrl":null,"permalink":"/ansible/advanced/","section":"Ansibles","summary":"","title":"Ansible advanced","type":"ansible"},{"content":"","externalUrl":"https://mucahitkurtlar.github.io","permalink":"/users/3-9d028495840ad385e6cb3ccf051dca22/","section":"Users","summary":"","title":"mucahitkurtlar.github.io","type":"users"},{"content":" Docker voorbeelden: installatie, Dockerfile, compose.yaml, volumes, netwerken # Hello World Image ★☆☆ # Uitleg:\nDit is het meest eenvoudige Docker-voorbeeld. Het downloadt en start de hello-world-image van Docker Hub. Deze image toont simpelweg de melding \u0026ldquo;Hello from Docker!\u0026rdquo; en stopt vervolgens. Het laat het basisproces zien van het downloaden en uitvoeren van een Docker-image.\nNginx-webserver ★☆☆ # docker run -d -p 80:80 nginx Uitleg:\nDit voorbeeld downloadt en start de officiële Nginx-webserver-image.\n-d: Start de container in \u0026lsquo;detached\u0026rsquo;-modus (op de achtergrond). -p 80:80: Koppelt poort 80 op de hostmachine aan poort 80 in de container, waardoor de webserver toegankelijk is via de browser van de host. Aangepaste image met Dockerfile: Eenvoudige Node.js-app ★★☆ # Dockerfile:\nFROM node:14 WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 3000 CMD [\u0026#34;npm\u0026#34;, \u0026#34;start\u0026#34;] Bouwen en uitvoeren:\ndocker build -t my-node-app . docker run -d -p 3000:3000 my-node-app Uitleg: Dit voorbeeld laat zien hoe je een aangepaste Docker-image bouwt met behulp van een Dockerfile voor een eenvoudige Node.js-applicatie.\nDockerfile: FROM node:14: Gebruikt de officiële Node.js 14-image als basis. WORKDIR /app: Stelt de werkmap in de container in op /app. COPY package*.json ./: Kopieert package.json en package-lock.json (indien aanwezig) naar de container. RUN npm install: Installeert de Node.js-dependencies. COPY . .: Kopieert de rest van de applicatiecode naar de container. - EXPOSE 3000: Geeft aan dat de container zal luisteren op poort 3000. CMD [\u0026quot;npm\u0026quot;, \u0026quot;start\u0026quot;]: Definieert het commando dat wordt uitgevoerd wanneer de container start (start de Node.js-app). Build: docker build -t my-node-app . bouwt de image en voorziet deze van de tag my-node-app. Run: docker run -d -p 3000:3000 my-node-app start de container in \u0026lsquo;detached\u0026rsquo;-modus en koppelt poort 3000 op de host aan poort 3000 in de container. Docker Compose: Web-app met database ★★☆ # docker-compose.yaml:\nversion: \u0026#34;3.8\u0026#34; services: web: image: nginx:latest ports: - \u0026#34;80:80\u0026#34; volumes: - ./html:/usr/share/nginx/html - ./nginx.conf:/etc/nginx/conf.d/default.conf depends_on: - db db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: example MYSQL_DATABASE: mydb volumes: - db_data:/var/lib/mysql volumes: db_data: nginx.conf:\nserver { listen 80; server_name localhost; root /usr/share/nginx/html; index index.html; location / { try_files $uri $uri/ =404; } location /phpmyadmin { proxy_pass http://db:80; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } Uitvoeren:\ndocker-compose up -d Uitleg:\nDit voorbeeld laat zien hoe je Docker Compose gebruikt om een ​​applicatie met meerdere containers te definiëren en uit te voeren, bestaande uit een webserver (Nginx) en een database (MySQL).\ndocker-compose.yaml: version: \u0026quot;3.8\u0026quot;: Specificeert de versie van het Docker Compose-bestandsformaat. services:: Definieert de services (containers) in de applicatie. web:: De webserverservice. image: nginx:latest: Gebruikt de officiële Nginx-image. ports: - \u0026quot;80:80\u0026quot;: Koppelt poort 80 op de host aan poort 80 in de container. volumes:: Koppelt de map ./html op de host aan /usr/share/nginx/html in de container, zodat je statische bestanden vanaf je lokale machine kunt serveren. Koppelt het bestand ./nginx.conf aan /etc/nginx/conf.d/default.conf om Nginx te configureren. depends_on: - db: Zorgt ervoor dat de db-service start vóór de web-service. db:: De databaseservice. image: mysql:5.7: Gebruikt de officiële MySQL 5.7-image. environment:: Stelt omgevingsvariabelen in voor de MySQL-container (root-wachtwoord en databasenaam). volumes: - db_data:/var/lib/mysql: Koppelt het benoemde volume db_data aan /var/lib/mysql om de databasegegevens te behouden (persistentie). volumes: - db_data:: Definieert een benoemd volume genaamd db_data. Uitvoeren: docker-compose up -d start de applicatie in \u0026lsquo;detached\u0026rsquo;-modus (op de achtergrond). ### #Named volume voor datapersistentie ★★☆ Dockerfile:\nFROM ubuntu:latest RUN apt-get update \u0026amp;\u0026amp; apt-get install -y apache2 VOLUME /var/www/html CMD [\u0026#34;apache2ctl\u0026#34;, \u0026#34;-D\u0026#34;, \u0026#34;FOREGROUND\u0026#34;] Bouwen en uitvoeren:\ndocker build -t my-apache-app . docker run -d -p 80:80 --name my-apache-container -v my-data:/var/www/html my-apache-app Toelichting:\nDit voorbeeld laat zien hoe een \u0026rsquo;named volume\u0026rsquo; (benoemd volume) wordt gebruikt om gegevens te behouden in een Docker-container die een Apache-webserver draait.\nDockerfile: VOLUME /var/www/html: Declareert /var/www/html (waar Apache websitebestanden opslaat) als een volume. Uitvoeren: -v my-data:/var/www/html: Koppelt de named volume my-data aan /var/www/html in de container. Wijzigingen aan bestanden in /var/www/html blijven behouden in de my-data-volume, zelfs als de container wordt gestopt of verwijderd. Bind Mount voor ontwikkeling ★★☆ # docker run -d -p 80:80 -v $(pwd):/usr/share/nginx/html nginx Uitleg:\nDit voorbeeld gebruikt een bind mount om de huidige werkmap ($(pwd)) op de hostmachine te koppelen aan /usr/share/nginx/html in de Nginx-container. Dit is handig voor ontwikkeling, omdat wijzigingen die je aanbrengt in bestanden in je lokale map direct zichtbaar zijn in de container.\nDoor de gebruiker gedefinieerd netwerk voor communicatie tussen containers ★★★ # docker-compose.yaml:\nversion: \u0026#34;3.8\u0026#34; services: web: image: nginx:latest ports: - \u0026#34;80:80\u0026#34; networks: - my-network app: image: my-node-app networks: - my-network networks: my-network: Uitleg:\nDit voorbeeld laat zien hoe je een door de gebruiker gedefinieerd netwerk aanmaakt en daar twee services (containers) aan koppelt.\ndocker-compose.yaml: networks:: Definieert een netwerk met de naam my-network. services:: Zowel de web- als de app-service zijn gekoppeld aan het my-network-netwerk. Containers die met hetzelfde door de gebruiker gedefinieerde netwerk zijn verbonden, kunnen met elkaar communiceren via hun servicenamen als hostnames. De app-container kan bijvoorbeeld de web-container bereiken via de hostname web. ### Multi-stage build voor een geoptimaliseerde image ★★★ Dockerfile:\n# Fase 1: De applicatie bouwen FROM node:14 AS build WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build # Fase 2: Een compacte productie-image maken FROM nginx:alpine COPY --from=build /app/dist /usr/share/nginx/html EXPOSE 80 CMD [\u0026#34;nginx\u0026#34;, \u0026#34;-g\u0026#34;, \u0026#34;daemon off;\u0026#34;] Toelichting:\nDit voorbeeld laat een multi-stage build zien om een ​​kleinere, meer geoptimaliseerde productie-image voor een Node.js-applicatie te maken.\nFase 1: Bouwt de applicatie in een Node.js-omgeving. Fase 2: Kopieert alleen de gebouwde bestanden (uit /app/dist) naar een compacte Nginx Alpine-image, waarbij de onnodige build-tools en dependencies uit de eerste fase worden weggelaten. Docker Compose met omgevingsvariabelen ★★☆ # docker-compose.yaml:\nversion: \u0026#34;3.8\u0026#34; services: web: image: my-node-app ports: - \u0026#34;80:3000\u0026#34; environment: NODE_ENV: production API_KEY: ${API_KEY} Toelichting:\nDit voorbeeld laat zien hoe je omgevingsvariabelen gebruikt in een Docker Compose-bestand.\nenvironment:: Definieert omgevingsvariabelen voor de web-service. NODE_ENV: production: Zet de omgevingsvariabele NODE_ENV op production. API_KEY: ${API_KEY}: Leest de waarde van API_KEY uit een omgevingsvariabele op de hostmachine. Zorg ervoor dat je de omgevingsvariabele API_KEY op je host instelt voordat je docker-compose up uitvoert. ### #Dockerfile met Healthcheck ★★☆ Dockerfile:\nFROM httpd:2.4 COPY ./public-html/ /usr/local/apache2/htdocs/ HEALTHCHECK --interval=5s --timeout=3s \\ CMD curl -f http://localhost/ || exit 1 Uitleg:\nDit voorbeeld laat zien hoe je een healthcheck aan een Dockerfile toevoegt.\nHEALTHCHECK: Definieert een healthcheck-commando dat door Docker wordt uitgevoerd om te controleren of de container gezond (healthy) is. --interval=5s: Geeft aan dat de healthcheck elke 5 seconden moet worden uitgevoerd. --timeout=3s: Geeft aan dat de healthcheck na 3 seconden een time-out moet geven. CMD curl -f http://localhost/ || exit 1: Het healthcheck-commando zelf. Het gebruikt curl om te controleren of de webserver reageert op poort 80. Als het verzoek mislukt, eindigt het commando met een code die niet nul is, wat aangeeft dat de container ongezond (unhealthy) is. Docker Compose met meerdere netwerken ★★★ # docker-compose.yaml:\nversion: \u0026#34;3.8\u0026#34; services: frontend: image: my-frontend-app networks: - frontend-network - backend-network backend: image: my-backend-app networks: - backend-network database: image: mysql:5.7 networks: - backend-network networks: frontend-network: backend-network: Uitleg:\nDit voorbeeld laat zien hoe je meerdere netwerken definieert en gebruikt in een Docker Compose-bestand.\nnetworks:: Definieert twee netwerken: frontend-network en backend-network. - services:: frontend: Is verbonden met zowel frontend-network als backend-network, waardoor communicatie met zowel de backend als de buitenwereld mogelijk is. backend: Is verbonden met backend-network, waardoor communicatie met de database mogelijk is. database: Is verbonden met backend-network, waardoor communicatie met de backend mogelijk is. Docker Compose met build-argumenten ★★☆ # docker-compose.yaml:\nversion: \u0026#34;3.8\u0026#34; services: Docker Compose met build-argumenten ★★☆ # docker-compose.yaml:\nversion: \u0026#34;3.8\u0026#34; services: my-app: build: context: . args: VERSION: 1.0 Dockerfile:\nFROM alpine:latest ARG VERSION RUN echo \u0026#34;Building version: $VERSION\u0026#34; Uitleg:\nDit voorbeeld laat zien hoe je build-argumenten gebruikt in een Docker Compose-bestand.\nbuild:: args:: Definieert een build-argument genaamd VERSION. Het VERSION-argument wordt vervolgens in de Dockerfile gebruikt om het build-proces aan te passen. Dockerfile met Entrypoint-script ★★★ # Dockerfile:\nFROM ubuntu:latest COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh ENTRYPOINT [\u0026#34;/entrypoint.sh\u0026#34;] CMD [\u0026#34;my-app\u0026#34;] entrypoint.sh:\n#!/bin/bash echo \u0026#34;Starting my-app...\u0026#34; exec \u0026#34;$@\u0026#34; Uitleg:\nDit voorbeeld laat zien hoe je een entrypoint-script gebruikt in een Dockerfile.\nENTRYPOINT [\u0026quot;/entrypoint.sh\u0026quot;]: Geeft aan dat /entrypoint.sh moet worden uitgevoerd als het entrypoint voor de container. CMD [\u0026quot;my-app\u0026quot;]: Specificeert het standaardcommando dat door het entrypoint-script moet worden uitgevoerd. Het entrypoint-script kan worden gebruikt om voorbereidende taken uit te voeren voordat de hoofdapplicatie start. In dit voorbeeld wordt simpelweg een bericht getoond, waarna het commando uit CMD wordt uitgevoerd.\nDocker Compose met schalen ★★☆ # docker-compose.yaml:\nversion: \u0026#34;3.8\u0026#34; services: web: image: nginx:latest ports: - \u0026#34;80:80\u0026#34; deploy: replicas: 3 Uitleg:\nDit voorbeeld laat zien hoe je een service schaalt in een Docker Compose-bestand.\ndeploy:: replicas: 3: Geeft aan dat er 3 instanties van de web-service moeten draaien. ### #Dockerfile met ONBUILD-instructie ★★★ Dockerfile (basis-image):\nFROM node:14 WORKDIR /app ONBUILD COPY package*.json ./ ONBUILD RUN npm install ONBUILD COPY . . Dockerfile (applicatie-image):\nFROM my-base-image CMD [\u0026#34;npm\u0026#34;, \u0026#34;start\u0026#34;] Uitleg:\nDit voorbeeld laat zien hoe de ONBUILD-instructie in een Dockerfile wordt gebruikt.\nONBUILD: Specificeert instructies die worden uitgevoerd wanneer de image als basis-image voor een andere image wordt gebruikt. In dit voorbeeld definieert de image my-base-image ONBUILD-instructies om bestanden te kopiëren en afhankelijkheden te installeren. Wanneer de applicatie-image wordt gebouwd, worden deze instructies automatisch uitgevoerd. Docker Compose met profielen ★★★ # docker-compose.yaml:\nversion: \u0026#34;3.8\u0026#34; services: web: image: my-web-app profiles: [\u0026#34;frontend\u0026#34;] api: image: my-api-app profiles: [\u0026#34;backend\u0026#34;] db: image: mysql:5.7 profiles: [\u0026#34;backend\u0026#34;] profiles: frontend: backend: Uitleg:\nDit voorbeeld laat zien hoe profielen in een Docker Compose-bestand worden gebruikt.\nprofiles: Hiermee kun je groepen services definiëren die gezamenlijk kunnen worden in- of uitgeschakeld. In dit voorbeeld maakt de web-service deel uit van het frontend-profiel, terwijl de api- en db-services deel uitmaken van het backend-profiel. Om alleen de frontend-services te starten, voer je uit: docker-compose up -d --profile frontend. Om alleen de backend-services te starten, voer je uit: docker-compose up -d --profile backend. Om alle services te starten, voer je uit: docker-compose up -d. ### #Dockerfile met .dockerignore ★★☆ .dockerignore:\nnode_modules .git Dockerfile:\nFROM node:14 WORKDIR /app COPY . . RUN npm install CMD [\u0026#34;npm\u0026#34;, \u0026#34;start\u0026#34;] Uitleg:\nDit voorbeeld laat zien hoe je een .dockerignore-bestand gebruikt om bestanden en mappen uit te sluiten van het kopiëren naar de Docker-image.\nHet .dockerignore-bestand bevat patronen die overeenkomen met de bestanden en mappen die moeten worden uitgesloten. In dit voorbeeld worden de mappen node_modules en .git uitgesloten. #Docker Compose met override-bestand ★★★ # docker-compose.yaml:\nversion: \u0026#34;3.8\u0026#34; services: web: image: my-web-app ports: - \u0026#34;80:80\u0026#34; docker-compose.override.yaml:\nversion: \u0026#34;3.8\u0026#34; services: web: environment: DEBUG: \u0026#34;true\u0026#34; Uitleg:\nDit voorbeeld laat zien hoe je een override-bestand gebruikt om de configuratie van services in een Docker Compose-bestand aan te passen.\nHet bestand docker-compose.override.yaml bevat configuratie die de configuratie in het bestand docker-compose.yaml overschrijft. In dit voorbeeld wordt de omgevingsvariabele DEBUG ingesteld voor de web-service in het override-bestand. ### #Docker Compose met depends_on en healthcheck ★★★ docker-compose.yaml:\nversion: \u0026#34;3.8\u0026#34; services: db: image: mysql:5.7 healthcheck: test: [\u0026#34;CMD\u0026#34;, \u0026#34;mysqladmin\u0026#34; ,\u0026#34;ping\u0026#34;, \u0026#34;-h\u0026#34;, \u0026#34;localhost\u0026#34;] interval: 10s timeout: 5s retries: 5 web: image: my-web-app ports: - \u0026#34;80:80\u0026#34; depends_on: db: condition: service_healthy Toelichting:\nDit voorbeeld combineert depends_on en healthcheck in een Docker Compose-bestand om services in een specifieke volgorde te starten, op basis van de gezondheidsstatus van hun afhankelijkheden.\ndb-service: Heeft een healthcheck ","date":"26 Januarie 2026","externalUrl":null,"permalink":"/docker/voorbeelden/","section":"Dockers","summary":"","title":"Voorbeelden","type":"docker"},{"content":" Ansible-Navigator # Ansible-navigator is a command-line tool and textual user interface (TUI) for Ansible. It provides a rich interface to assist users in exploring and interacting with their Ansible content.\nHere are some of the key features:\nTextual User Interface (TUI): The TUI mode is useful for those who are in terminal environments and need an interactive way to explore Ansible content without necessarily having a graphical user interface. Command-line Mode: For those familiar with Ansible and its CLI, ansible-navigator can operate in a command-line mode, allowing you to execute commands directly. Exploration: ansible-navigator allows users to view their Ansible playbooks, roles, tasks, and other components in an organized manner. Documentation: It can retrieve and display module documentation similarly to the ansible-doc command. Extensibility: ansible-navigator is built in such a way that new commands and features can be easily added. Integration with ansible-runner: ansible-navigator uses ansible-runner in the background to execute playbooks and tasks, providing a layer of abstraction and additional features. Code Viewer: This feature allows users to dive into the source code of roles, modules, and playbooks. Installing ansible-navigator # First, add the repository:\nsudo subscription-manager repos --enable ansible-automation-platform-2.4-for-rhel-9-x86_64-rpms Next, install it:\nsudo dnf install ansible-navigator Ansible Automation Controller, AWX and Semaphore # Ansible is a widely used automation tool that allows for configuration management, application deployment, continuous delivery, and many other IT needs. While the core component of Ansible is open source, there are additional tools and interfaces that have been developed to enhance its functionality and user experience. Three of the notable ones are Ansible Tower, Ansible AWX, and Ansible Semaphore.\nAnsible Automation Controller (AAC) # Ansible Automation Controller (formerly called Ansible Tower) is the commercial product offered by Red Hat.\nFeatures # User Interface: Offers a web-based interface, API, and CLI tool. Role-Based Access Control (RBAC): Ensures that only authorized users can access resources. Scheduling: Jobs can be scheduled to run at specific times. Real-time Job Status: Monitor job activity in real-time. Integration with Other Services: Integrates with other services like LDAP for user management, and logging solutions like Splunk or ELK. Licensing: It\u0026rsquo;s a licensed product, and you\u0026rsquo;ll have to pay to use it in production environments. Enterprise support: AAC is fully supported by Red Hat and support contracts can be purchased by enterprise customers Ansible AWX # AWX , maintained by Red Hat, is the open-source version of Ansible Automation Controller. Essentially, it\u0026rsquo;s the upstream project for AAC, meaning new features are typically developed in AWX before they might be adopted into the AAC product.\nFeatures # AWX Offers many of the same features as AAC, including the web-based interface, API, and some integrations.\nUpdates: AWX usually gets updates and new features faster than Tower, but it might also have more bugs since it\u0026rsquo;s at the cutting edge. Licensing: Being open-source, it\u0026rsquo;s free to use. Organizations that need the stability of a commercial product but also want to avoid costs often opt for AWX, accepting the trade-offs. Ansible Semaphore # Semaphore is an alternative to AWX and Tower, also open-source. It\u0026rsquo;s not developed by Red Hat.\nFeatures # Task Definitions: Define playbooks, templates, and SSH keys. Web Interface: Offers a simpler web-based interface to manage and track Ansible tasks. Access Control: Like AWX and Tower, Semaphore provides access controls to define who can access what. Task History: Allows users to review past tasks and their outcomes. Positioning: Semaphore is lighter and may be more suitable for teams that find AWX too heavy or complex but still need a web interface for Ansible. Deciding between these options often comes down to the specific needs of an organization. If a commercial product with support is needed, then Ansible Automation Controller is the choice. For those looking for an open-source alternative with many features, AWX is a great choice. If something lighter and simpler is desired, Semaphore might be the right fit.\n","date":"25 Januarie 2026","externalUrl":null,"permalink":"/ansible/enterprise/","section":"Ansibles","summary":"","title":"Ansible Enterprise","type":"ansible"},{"content":" Oefening 1 # Installatie Git # Git is beschikbaar op alle besturingssystemen. Voor Windows en OS-X kunnen binaire bestanden gedownload worden van https://git-scm.com. Voor Linux distributies is Git meestal al geïnstalleerd of beschikbaar via het package management systeem van de distributie. Mocht het toch niet beschikbaar zijn kan de broncode gedownload worden van https://mirrors.edge.kernel.org/pub/software/scm/git/ en kan Git handmatig gecompileerd worden.\nDe rest van dit document gaat er van uit dat je Windows gebruikt, desalniettemin zijn de instructies grotendeels ook van toepassing voor Linux en OS-X.\nTijdens de installatie kan je kiezen welke teksteditor gebruikt wordt om commit boodschappen te typen. Kies hier voor Visual Studio Code.\nGebruik in de rest van de installatie de default opties. Na de installatie zou het git commando beschikbaar moeten zijn in PowerShell en cmd.\nConfiguratie # Git houd bij wie wijzigingen doorvoert, natuurlijk moet jij als gebruiker wel meegegeven wat jouw naam en email adres zijn.\nDeze informatie is een essentieel onderdeel van Git en het is dan ook niet mogelijk om commits uit te voeren zonder dat Git correct geconfigureerd is. Gebruikt onderstaande commando’s om je identiteit in te stellen.\ngit config --global user.name “Voornaam Achternaam” git config --global user.email “rxxxxxxx@student.thomasmore.be” Git Branching # Maak de eerste 8 interactieve oefeningen op\nLearngitbranching # Oefening 2 # Aanmaken van een Git repository # Er worden verschillende gratis git repositories aangeboden. De meeste services staan het niet toe om privé repositories aan te maken met een gratis abonnement.\nMaak een account aan op github en maak een repository aan voor je project. Zorg ervoor dat het repository niet door onbevoegden bekeken kan worden.\nSSH Keys # Om de communicatie met de git server op een veilige manier te laten verlopen maken we gebruik van asymmetrische SSH encryptie.\nWindows bevat sinds kort een ingebouwde Open-SSH client. In de nieuwste versies van Windows 10 is deze geactiveerd, als je nog met een oudere versie werkt kan je deze via Instellingen \u0026gt; Apps \u0026gt; Apps en onderdelen \u0026gt; Optionele onderdelen \u0026gt; Een onderdeel toevoegen installeren.\nEens dit gebeurd is kan je een SSH key aanmaken, open hiervoor PowerShell (of cmd). Je kan kiezen waar je de SSH sleutel plaatst, de meeste programma’s gaan er echter van uit dat deze zich in %USERPROFILE%\\.ssh bevind, dit is dan ook de beste locatie. Navigeer in PowerShell naar je home folder en voer vervolgens onderstaand commando uit.\nssh-keygen Gebruikt de default waarden voor de namen van de bestanden, id_rsa.pub bevat je publieke sleutel. Dit is de sleutel die je met BitBucket moet delen. Het andere bestand id_rsa bevat je private key. Tijdens het genereren van je sleutels kan je een wachtwoord toevoegen om je private key te encrypteren. Volgens de best practices moet je je sleutel beveiligen. Dit betekend echter dat het wachtwoord elke keer je git commit of git pull uitvoert je het wachtwoord moet ingeven. Kies zelf of je al dan niet een wachtwoord toevoegt.\nSSH Keys registreren op github # Navigeer naar je profiel in github.\nZoek uit hoe je, jou key kan toevoegen. Open nu het id_rsa.pub bestand dat je aangemaakt hebt en kopieer de inhoud naar github.\n.gitignore # Bezoek https://www.gitignore.io en maak een .gitignore bestand aan voor jouw besturingssysteem en Visual Studio Code. Plaats dit bestand in je project directory.\nInitialiseren lokaal Git repository # Maak een nieuwe webpagina aan die als test zal dienen voor git. Open de folder waar je deze webpagina bewaard hebt in een terminal emulator (PowerShell/cmd) en gebruikt het\ngit init commando om lokaal een Git repository aan te maken. Gebruik vervolgens het commando\ngit add filename om je bestanden toe te voegen aan het repository. Gebruikt nu\ngit commit om je toegevoegde bestanden aan de staging area toe te voegen. Vooraleer je de toegevoegde bestanden kan uploaden naar een server moet je een remote server toevoegen, je BitBucket repository. Dit kan met het commando\ngit remote add linkNaarJeRepository De URL voor je repository kan je vinden op github.\nTenslotte moet nog een push uitgevoerd worden om je bestanden in het remote repository te krijgen. In de meeste gevallen is het commando git push voldoende. Maar omdat elke keer dat je lokaal een nieuwe branch aanmaakt moet het commando\ngit push -u origin branchName gebruikt worden om aan te geven welke upstream branch (-u) overeenkomt met de lokale branch. Gebruik dit commando om je website te pushen naar de masterbranch in je repository. Controleer tenslotte op de BitBucket website of al je bestanden correct zijn toegevoegd aan het repository.\nOefening 3 # De bestanden # Voorzie een werkdirectory ‘git01’, die voor het GIT project gebruikt zal worden.\nMaak vervolgens volgende tekstbestanden aan:\n• Bestandenlijst.txt\n• Hoofdstuk01.txt\n• Hoofdstuk02.txt\n• Hoofdstuk03.txt\n• Geen_onderdeel.doc\nZorg dat bestanden met de extensie ‘.doc’ niet meegenomen worden in het versiebeheer\nwanneer je het commando ‘git add .’ geeft\nVoeg alle bestanden met het voorgaande commando aan de staging area toe en maak\nde eerste repository (die alleen lege txt-bestanden bevat).\nInvulling bestanden # oefenbestanden Maak een branch aan en noem deze content/firstcontent.\nSchakel over naar de branch en plaats in ‘Bestandenlijst.txt’ alle bestandsnamen met\nextensie txt onder elkaar.\nZorg dat het bestand in de staging area aangepast wordt en maak een repository van de\nbranch aan. Geef als notitie (message) “Bestandenlijst ingevuld” mee. Pas ‘Hoofdstuk1.txt’ aan met de tekst uit meegeleverd bestand ‘info01.txt’.\nProbeer het bestand in de staging area up te daten en een repository van de branch aan\nte maken met notitie (message) “Hoofdstuk01 ingevuld”. Lukt dit? Zo niet, waarom niet? Pas ‘Hoofdstuk2.txt’ aan met de tekst uit meegeleverd bestand ‘info02.txt’.\nProbeer het bestand in de staging area up te daten en een repository van de branch aan\nte maken met notitie (message) “Hoofdstuk02 ingevuld”. Lukt dit? Zo niet, waarom niet? Pas ‘Hoofdstuk3.txt’ aan met de tekst uit meegeleverd bestand ‘info03.txt’.\nProbeer het bestand in de staging area up te daten en een repository van de branch aan\nte maken met notitie (message) “Hoofdstuk03 ingevuld”. Lukt dit? Zo niet, waarom niet? Pas ‘Geen_onderdeel.doc’ aan met volgende tekst: “Dit bestand is slechts een lokaal\nbestand en wordt niet in de repository opgenomen.”\nProbeer het bestand in de staging area up te daten en een repository van de branch aan\nte maken met notitie (message) “Bestandenlijst ingevuld”. Lukt dit? Zo niet, waarom\nniet? Controleer de versies met get commando ‘git log \u0026ndash;oneline \u0026ndash;decorate \u0026ndash;graph –-all’.\nWat kan je uit de getoonde informatie afleiden?\nDe eerste merge # De ingevulde bestanden moeten terug in de hoofdbranch ge-update worden om een\nnieuwe definitieve versie aan te maken:\nWissel naar de ‘Master’ of ‘Main’ branch en merge de aangemaakte branch met het\ncommando\ngit merge content/firstcontent Controleer de versies met get commando\ngit log --oneline --decorate --graph –-all 3-way branching # Maak een nieuwe branch aan, zijnde ‘content/newcontent01’ voeg vervolgens een lege\nlijn toe aan “Hoofdstuk01.txt”, zorg dat deze wijziging in een nieuwe repository\ntoegevoegd wordt.\nSchakel over naar de nieuw aangemaakte branch.\nControleer de versies met get commando\ngit log --oneline --decorate --graph –-all Voeg de tekst uit info04.txt achteraan in het bestand ‘Hoofdstuk02.txt” toe, en maak een\nnieuwe repository.\nSchakel terug over naar de Master branch en bekijk de history van de versies met\ngit log --oneline --graph --all Schakel terug over naar de Master branch en voer nu een volgend commando\ngit merge --no-ff content/firstchange De optie ‘no-ff’ zorgt dat fast forward niet gebruikt wordt.\nBekijk de history van de versies met\ngit log --oneline --graph --all Met bovenstaand commando kan je aldus grafisch de branches zien.\nMerging en conflicten # Maak een branch ‘content/spelling’ aan en schakel over naar deze branch.\nHaal de twee ‘dt’ fouten uit het tekstbestand ‘Hoofdstuk01.txt’ en maak een nieuwe repo\nmet als bericht ‘dt fouten verwijderd in Hfdstk01’.\nSchakel terug over naar de ‘Master’ branch en Zorg dat iedere zin met een hoofdletter\nbegint. Maak ook hier een repository met als bemerking ‘Hoofdletters in hfdstk01’\nVoor opnieuw een 3-way merge uit met de branch ‘content/spelling’.\nJe krijgt volgende melding:\nVraag de git status op, je krijgt volgende mededeling:\nStart de editor vanuit de command prompt op voor Hoofdstuk01.\nIn Hoofdstuk01.txt zijn tussen ‘\u0026lt;\u0026lt;\u0026lt;\u0026lt;\u0026lt;\u0026lt;\u0026lt; HEAD’ en ‘=======’ de lijnen, die lijnen in\nde versie van Master getoond, die van de branch content/spelling verschillen getoond.\nTussen ‘=======’ en ‘\u0026gt;\u0026gt;\u0026gt;\u0026gt;\u0026gt;\u0026gt;\u0026gt; content/spelling’ staan de overeenkomstige lijnen\nvan de branch content/spelling:\nMen kan nu in de editor de gewenste wijzigingen doorvoeren.\nZorg dat in het resultaat\ngeen ‘dt’ fouten meer staan de zinnen met hoofdletters beginne ‘\u0026lt;\u0026lt;\u0026lt;\u0026lt;\u0026lt;\u0026lt;\u0026lt; HEAD’, ‘=======’ en ‘\u0026gt;\u0026gt;\u0026gt;\u0026gt;\u0026gt;\u0026gt;\u0026gt; content/spelling’ verwijderd zijn Op het einde een lijn met de tekst “Dat was het dan.” Toegevoegd is. Sla het bestand op, update de staging area en geef het commando ‘git commit’.\nDe standaard editor, die je bij de installatie verkoos, wordt nu opgestart en je kan eeb\nuitgebreid neerschrijven wat er in de commit van de merge allemaal behouden is uit de\ntwee versies. Bijkomend # Er zijn nog volgende merge methodes kort aangehaald:\nSquashing merging:\nVanuit de Master: git merge --squash \u0026lt;branch, die gesquashed moet worden\u0026gt; Rebasing:\nVanuit de branch, die ge-rebased moet worden: git rebase master Cherypicking:\nVanuit Master: git cherry-pick \u0026lt;repo, die naar Master gekopieerd moet worden\u0026gt; Oefening 4 # AWS Hosting # Je zal voor IT Topics 2 een kleine website moeten maken, deze moet ergens gehost worden zodat de site van buitenaf bezocht kan worden. In de IT sector worden er bijzonder veel gratis services aangeboden aan studenten, een niet-exhaustief overzicht kan je vinden op https://education.github.com/pack.\nVoor IT Topics 2 maken we gebruikt van AWS. AWS is naast Microsoft Azure één van de belangrijkste platformen voor webhosting, machine learning, virtual machines, virtual private servers, … Als student krijg je $100 gratis credit op AWS.\nMaak een account aan op AWS Educate (https://aws.amazon.com/education/awseducate/). Dit MOET met je Thomas More emailadres, anders kan niet geverifieerd worden dat je student bent.\nAls je geregistreerd bent en je account goedgekeurd is zie je in de navigatiebalk de knop AWS Account staan. Klik hierop. Je zal hier opnieuw enkele registratie stappen moeten voltooien. Eens je account goedgekeurd is heb je toegang tot AWS.\nOpen je AWS Educate account en ga vervolgens naar de AWS Console. Hier zie je een hele hoop services. Zoek de AWS Amplify service en open deze. Amplify integreert zeer goed met Git repositories. Je kan een branch kiezen die in het oog gehouden moet worden. Elke keer er op deze branch een commit gedetecteerd wordt zijn de wijzigingen automatisch doorgevoerd naar je AWS Amplify website.\nMaak een nieuwe applicatie aan en kies voor github integratie.\nVerbind je AWS en github accounts en selecteer vervolgens het correcte repository en de correcte branch.\nDruk nog een paar keer op next. Tenslotte zal je repository door AWS verwerkt worden. Eens dit klaar is kan je je project bekijken op de bijhorende URL.\nAls je website correct getoond wordt breng je tenslotte een kleine wijziging aan in je lokale git repository en commit je deze. Het resultaat zou na een paar minuten zichtbaar moeten worden op je website.\n","date":"25 Januarie 2026","externalUrl":null,"permalink":"/git/oefeningen/","section":"Gits","summary":"","title":"Oefeningen","type":"git"},{"content":"","externalUrl":"https://brendanwallace.github.io","permalink":"/users/4-64ef36564d497eed256b9f4c56b1184e/","section":"Users","summary":"","title":"brendanwallace.github.io","type":"users"},{"content":" Een image ophalen # Om containers uit te voeren, moeten we eerst een aantal images ophalen.\nLaten we eens kijken welke images we momenteel op onze machine hebben, door\ncode : Bij een nieuwe Docker-installatie zouden we geen images moeten hebben. Laten we er een ophalen van Dockerhub.\nMeestal halen we images op van DockerHub op tag. Deze zien er als volgt uit:\ncode : We kunnen zoeken naar images met behulp van docker search \u0026lt;keyword\u0026gt; Je kunt images ook online vinden op DockerHub. Voer docker pull ubuntu:24.04 uit om een ​​image van Ubuntu 24.04 van DockerHub te halen. code : We kunnen ook verschillende versies op dezelfde image halen.\nVoer docker pull ubuntu:22.04 uit om een ​​image van Ubuntu 22.04 te halen code : Wanneer we `docker images dan opnieuw uitvoeren, zouden we het volgende moeten krijgen:\ncode : Na verloop van tijd kan je machine veel images verzamelen, dus het is handig om ongewenste images te verwijderen.\nVoer docker rmi \u0026lt;IMAGE ID\u0026gt; uit om de Ubuntu 22.04-image te verwijderen die we niet gaan gebruiken.\ncode : U kunt ook images verwijderen op tag of op een gedeeltelijke image-ID. In het vorige voorbeeld zou het volgende equivalent zijn geweest:\ncode : Het uitvoeren van docker images zou de verwijderde image moeten weerspiegelen.\nEen handige snelkoppeling om alle images van uw systeem te verwijderen is\nTest dit uit:\ndocker rmi $(docker images -a -q) Onze container uitvoeren # Met behulp van de Ubuntu 26.04-image die we hebben gedownload, kunnen we onze eerste container uitvoeren. In tegenstelling tot een traditioneel virtualisatieframework zoals VirtualBox of VMWare, kunnen we niet zomaar een virtuele machine starten die deze image uitvoert zonder iets anders: we moeten het een opdracht geven om uit te voeren.\nDe opdracht kan alles zijn wat u wilt, zolang deze maar op de image staat. In het geval van de Ubuntu-image is het een Linux-kernel met veel van de typische applicaties die je in een eenvoudige Linux-omgeving zou vinden.\nLaten we een heel eenvoudig voorbeeld doen. Voer\ndocker run ubuntu:14.04 /bin/echo \u0026#39;Hallo wereld!\u0026#39; uit. Wat doe de opdracht ?\ncode : Laten we controleren welke containers we hebben nadat we dit hebben uitgevoerd. Voer docker ps uit\ndocker ps Dat is vreemd: geen containers toch?\nLeg Uit\nLeg Uit: docker ps -a Oké, daar is onze container. Maar waarom is de status \u0026ldquo;Exited\u0026rdquo;?\nLeg Uit: Laten we de -it-vlaggen toevoegen, die Docker vertellen de opdracht interactief uit te voeren met uw terminal.\ndocker run -it ubuntu:24.04 /bin/bash Dit ziet er veel beter uit. Dit betekent dat u zich in een BASH-sessie bevindt in de Ubuntu-container. Let op: u voert uit als root en de container-ID die volgt. U kunt dit nu gebruiken als een normale Linux-shell. Probeer pwd en ls om naar het bestandssysteem te kijken. Commando en uitvoer: U kunt exit typen om de BASH-sessie te beëindigen, de opdracht te beëindigen en de container te stoppen. Standaard blijft uw terminal gekoppeld aan de container wanneer u docker run uitvoert. Wat als u niet gekoppeld wilt blijven? Door de vlag -d toe te voegen, kunnen we in de losgemaakte modus draaien, wat betekent dat de container blijft draaien zolang de opdracht actief is, maar de uitvoer niet wordt afgedrukt. Laten we /bin/sleep 3600 uitvoeren, waardoor de container 1 uur lang inactief wordt uitgevoerd: docker run -d ubuntu:24.04 /bin/sleep 3600 Als we de container controleren, zien we dat deze de sleep-opdracht in een nieuwe container uitvoert.\nuitvoer docker ps ? Nu de container op de achtergrond draait, wat als we hem opnieuw willen koppelen?\nDenkbaar, als dit iets was als een webserver of een ander proces waar we logs willen inspecteren terwijl het draait, zou het handig zijn om iets op de container te draaien zonder het huidige proces te onderbreken.\nHiervoor is er een andere opdracht, docker exec genaamd. docker exec voert een opdracht uit binnen een container die al draait. Het werkt precies zoals docker run, behalve dat het in plaats van een image-ID een container-ID gebruikt.\ncommando voor exec ? Dit maakt de opdracht docker exec handig voor het volgen van logs, of \u0026ldquo;BASH\u0026rdquo; in een actieve container.\nLaten we dat nu doen, door het volgende uit te voeren, waarbij de eerste paar tekens van de container-ID worden doorgegeven:\nDe container-ID die vooraan de BASH-prompt verschijnt, vertelt ons dat we ons in de container bevinden. Eenmaal in een sessie kunnen we met de container communiceren zoals elke SSH-sessie.\nLaten we de draaiende processen opsommen:\nps aux uitvoer ? Containers verwijderen # Nadat u met Docker-containers hebt gewerkt, wilt u misschien oude, verouderde containers verwijderen.\ndocker ps -a Uit ons vorige voorbeeld kunnen we met docker ps -a zien dat er een container rondhangt.\nOm dit te verwijderen, kunnen we de opdracht docker rm gebruiken die gestopte containers verwijdert.\ncode Een handige snelkoppeling voor het verwijderen van alle containers van uw systeem is\ndocker rm $(docker ps -a -q) Het kan vervelend zijn om oude containers te verwijderen telkens nadat u ze hebt uitgevoerd. Om dit aan te pakken, kunt u met Docker ook de \u0026ndash;rm-vlag opgeven voor de opdracht docker run, die de container verwijdert nadat deze is beëindigd.\ncode ? Aanpassen van een image # In deze oefening leren we hoe we een bestaande Docker-image kunnen wijzigen en deze als een nieuwe kunnen committen.\nOm dit te bereiken, wijzigen we de ubuntu:24.04-afbeelding om het ping-hulpprogramma op te nemen.\nInstellen # Download eerst de ubuntu:24.04-afbeelding met docker pull. (Je hebt dit misschien al id de vorige oefening voltooid.)\ncommando ? Een image wijzigen # Laten we de image in een nieuwe container uitvoeren en het ping-hulpprogramma installeren.\nStart eerst de container met /bin/bash:\ndocker run -it ubuntu:16.04 /bin/bash Probeer ping uit te voeren in de terminal.\nLukt dit en commando De Ubuntu-image voor Docker heeft alleen de minimale hoeveelheid software geïnstalleerd om de container te laten werken. Dat is echter niet erg: we kunnen de ping-opdracht installeren.\nMaar eerst werken we onze softwarelijst bij.\nIn Debian-gebaseerde Linux-omgevingen (zoals Ubuntu) kunt u nieuwe software installeren met behulp van de apt-pakketbeheerder. Voor degenen die ervaring hebben met Macs, is dit programma het equivalent van homebrew.\nOm de imagegrootte te verkleinen, heeft de Ubuntu-image standaard geen lijst met de beschikbare softwarepakketten. We moeten de lijst met beschikbare software bijwerken:\ncommando ? Nu kunnen we de ping-opdracht installeren.\ncommando om iputils-ping te installeren ? Ten slotte zouden we ping moeten kunnen gebruiken.\nPing je favoriete website. Wanneer je genoeg hebt gezien, Ctrl+C om te onderbreken en verlaat dan de container.\ncommando ? Wijzigingen committen # Het installeren van ping is op zichzelf niet zo bijzonder. Maar wat als je ping op al je ubuntu-containers wilt hebben? Je zou deze installatie opnieuw moeten doen elke keer dat je een nieuwe container start, en dat is niet zo leuk.\nDe Docker-manier is om een ​​nieuwe image te maken. Er zijn twee manieren om dit te doen:\n1) een nieuwe image vanaf nul bouwen\n2) een containerstatus committen als een nieuwe image.\nLaten we onze container vinden om de nieuwe image van te maken.\nGelukkig hebben we een Docker-container met ons ping-hulpprogramma al geïnstalleerd van de vorige stappen. Het zou nu gestopt moeten zijn, maar laten we de container-ID ervan vinden.\ndocker ps -a Laten we het nu committen als een nieuwe afbeelding.\ndocker commit neemt een container en stelt je in staat om de wijzigingen ervan te committen als een nieuwe image.\ndocker commit --help Gebruik: docker commit \\[OPTIES\\] CONTAINER \\[REPOSITORY\\[:TAG\\]]\nMaak een nieuwe afbeelding van de wijzigingen in een container\nOpties: -a, --author string Auteur (bijv. \u0026#34;John Hannibal Smith \u0026lt;hannibal@a-team.com\u0026gt;\u0026#34;) -c, --change list Pas Dockerfile-instructie toe op de gemaakte afbeelding (standaard []) --help Gebruik afdrukken -m, --message string Commit-bericht -p, --pause Pauzeer container tijdens commit (standaard true) Geef de container-ID, een auteur, commit-bericht door en geef het de naam \u0026lt;DockerHub-gebruikersnaam\u0026gt;/ping:\ncode ? Controleer vervolgens docker images om uw nieuwe image te zien:\ndocker images Voer ten slotte uw nieuwe image uit in een nieuwe container om het in actie te zien!\ndocker run -it --rm \u0026lt;CONTAINERNAAM\u0026gt; /bin/bash bijvoorbeeld: docker run -it --rm bart/ping /bin/bash Wat is de uitvoer ?\nImages bouwen # In deze oefening leren we hoe we een nieuwe Docker-image maken.\nOm dit te doen, zoals in \u0026ldquo;Images wijzigen\u0026rdquo;, voegen we het ping-hulpprogramma toe aan de ubuntu:24.04-image. De uitkomst van elk van deze oefeningen zou gelijk moeten zijn.\nInstellen # Download eerst de ubuntu:24.04-image met docker pull. (Je hebt dit misschien al als je de vorige oefening hebt voltooid.)\ndocker pull ubuntu:24.04 Als je nog steeds de image van de vorige oefening hebt, laten we die nu ook verwijderen. Zorg ervoor dat u eerst alle containers op basis van die image docker rm, anders mislukt het verwijderen van de image.\ncode verwijderen vorige image Een Dockerfile maken # Net als bij de oefening installeren we ping op Ubuntu om een ​​nieuwe image te maken. In tegenstelling tot die oefening voeren we echter geen containers uit of wijzigen we deze.\nIn plaats daarvan gebruiken we Dockerfile. De Dockerfile is een soort \u0026ldquo;recept\u0026rdquo; dat een lijst met instructies bevat over hoe je een nieuwe image bouwt.\nMaak een nieuw bestand met de naam Dockerfile in je werkmap:\n(Je kan dit doen in Visual Studio code of met nano)\nOpen Dockerfile met je favoriete teksteditor.\nIn het bestand moeten we een aantal belangrijke headers toevoegen.\nDe FROM-richtlijn specificeert op welke basisimage deze nieuwe image wordt gebouwd. (Ubuntu in ons geval.) De LABEL-richtlijn voegt een label toe aan de image. Handig voor het toevoegen van metagegevens. Voeg de volgende twee regels toe aan het begin van uw bestand:\n````bash` FROM ubuntu:24.04 LABEL author=\u0026ldquo;Bart Thonissen\u0026rdquo;\nVervolgens moeten we enkele opdrachten toevoegen om de afbeelding te wijzigen. De RUN-richtlijn voert een opdracht uit in de afbeelding en rolt alle wijzigingen in het bestandssysteem op in een commit. Een typisch Dockerfile bevat verschillende RUN-instructies, die elk hun wijzigingen bovenop de vorige committen. Om ping te installeren, moeten we apt-get update en apt-get install uitvoeren. Voeg eerst de opdracht apt-get update toe: ```bash RUN apt-get update Voeg vervolgens de opdracht apt-get install toe:\nRUN apt-get install -y iputils-ping Let op dat we de vlag -y hebben toegevoegd. Bij het bouwen van Docker-images worden deze opdrachten niet-interactief uitgevoerd. Normaal gesproken zal de opdracht apt-get u vragen om \u0026ldquo;Y/n?\u0026rdquo; als u wilt doorgaan. De vlag -y vermijdt die vraag door altijd \u0026ldquo;Y\u0026rdquo; te antwoorden.\nOns bestand zou er nu ongeveer zo uit moeten zien:\nFROM ubuntu:24.04 LABEL author=\u0026#34;Bart Thonissen\u0026#34; RUN apt-get update RUN apt-get install -y iputils-ping En daarmee zouden we klaar moeten zijn om onze image te bouwen.\nHet Dockerfile bouwen # Om Docker-images te bouwen van Dockerfiles, gebruiken we de opdracht docker build. De opdracht docker build leest een Dockerfile en voert de instructies uit om een ​​nieuwe image te maken.\nLaten we onze image bouwen.\nHet uitvoeren van de volgende builds en tags van de image:\nbouw het image met de tag ubuntu/ping\ncode Let ook op de uitvoer over \u0026ldquo;stappen\u0026rdquo; hier. Elke richtlijn in je Dockerfile wordt toegewezen aan een stap hier, en nadat elke stap is voltooid, wordt het een commit. Waarom is dit belangrijk?\nDocker legt elke commit op elkaar, net als een ui. Op die manier kan het de afbeeldingsgroottes klein houden, en bij het herbouwen van afbeeldingen kan het zelfs commits hergebruiken die niet worden beïnvloed door wijzigingen om builds sneller te laten verlopen.\nWe kunnen dit cachegedrag in actie zien als we gewoon dezelfde opdracht opnieuw uitvoeren:\nWat is het verschil nu met de vorige uitvoer ? Door docker images uit te voeren, kunnen we onze nieuw gebouwde image zien.\ncode Optimaliseren van de Dockerfile # Als we naar de nieuwe image kijken, zien we dat deze 159 MB groot is, vergeleken met de basisimage van 117 MB. Dat is een behoorlijk grote verandering in grootte voor het installeren van een aantal hulpprogramma\u0026rsquo;s. Dat neemt meer schijfruimte in beslag en voegt extra tijd toe aan pushes/pulls van deze image.\nMaar waarom is het zoveel groter? Het geheim zit in de RUN-opdrachten. Zoals eerder vermeld, worden alle wijzigingen in het bestandssysteem vastgelegd nadat de RUN-opdracht is voltooid. Dit omvat alle logs of tijdelijke gegevens die naar het bestandssysteem zijn geschreven en die mogelijk helemaal geen gevolgen hebben voor onze image.\nIn ons geval genereert het gebruik van apt-get veel van deze onzin die we niet nodig hebben in onze image. We moeten deze RUN-richtlijnen enigszins aanpassen.\nWe kunnen beginnen met het verwijderen van oude logs nadat de installatie is voltooid. Voeg het volgende toe aan het einde van de Dockerfile:\nRUN apt-get clean \\ \u0026amp;\u0026amp; cd /var/lib/apt/lists \u0026amp;\u0026amp; rm -fr *Release* *Sources* *Packages* \\ \u0026amp;\u0026amp; truncate -s 0 /var/log/*log Als u build opnieuw uitvoert, krijgt u\u0026hellip;\n...levert dit geen verbetering op? Wat is hier aan de hand? Blijkt dat, omdat commits op elkaar worden gestapeld, het niet uitmaakt of je het opruimt in een toekomstige RUN-richtlijn als er nog wat rommel rondhangt van een eerdere commit. Het zal permanent deel uitmaken van de geschiedenis, dus de afbeeldingsgrootte.\nOnze rommel komt toevallig van de opdracht apt-get update, die een hoop pakketlijsten achterlaat die we niet nodig hebben. De eenvoudigste manier om hiermee om te gaan, is door alle gerelateerde RUN-richtlijnen samen te vouwen.\nDe herschreven Dockerfile zou er zo uit moeten zien:\nFROM ubuntu:24.04 LABEL author=\u0026#34;Bart Thonissen\u0026#34; RUN apt-get update \\ \u0026amp;\u0026amp; apt-get install -y iputils-ping \\ \u0026amp;\u0026amp; apt-get clean \\ \u0026amp;\u0026amp; cd /var/lib/apt/lists \u0026amp;\u0026amp; rm -fr *Release* *Sources* *Packages* \\ \u0026amp;\u0026amp; truncate -s 0 /var/log/*log Na het opnieuw uitvoeren van build zien onze images er nu zo uit:\nDe nieuwe image is nu slechts\nMB groot ? Een grote verbetering.\nAndere Dockerfile-richtlijnen # Er zijn veel andere nuttige richtlijnen beschikbaar in de Dockerfile.\nEnkele belangrijke:\nCOPY: Kopieer bestanden van uw host naar de Docker-image. WORKDIR: Geef een standaarddirectory op om opdrachten uit te voeren. CMD: Geef een standaardopdracht op om uit te voeren. ENV: Geef een standaardomgevingsvariabele op. EXPOSE: Stel standaard een poort bloot. ARG: Geef een build-time argument op (voor meer configureerbare, geavanceerde builds.) Aangezien onze Dockerfile is gebouwd voor ping, voegen we de ENV- en CMD-richtlijnen toe.\nFROM ubuntu:24.04 LABEL author=\u0026#34;Bart Thonissen\u0026#34; ENV PING_TARGET \u0026#34;google.com\u0026#34; RUN apt-get update \\ \u0026amp;\u0026amp; apt-get install -y iputils-ping \\ \u0026amp;\u0026amp; apt-get clean \\ \u0026amp;\u0026amp; cd /var/lib/apt/lists \u0026amp;\u0026amp; rm -fr *Release* *Sources* *Packages* \\ \u0026amp;\u0026amp; truncate -s 0 /var/log/*log CMD [\u0026#34;sh\u0026#34;, \u0026#34;-c\u0026#34;, \u0026#34;ping $PING_TARGET\u0026#34;] Deze nieuwe richtlijnen betekenen dat onze image automatisch ping google.com uitvoert wanneer deze wordt uitgevoerd met docker run -it ubuntu/ping.\nImages Delen # In deze oefening leren we hoe je Docker-images deelt met DockerHub. DockerHub is GitHub voor Docker: een geweldige plek om community-afbeeldingen te vinden en je eigen afbeeldingen te uploaden.\nWe hebben onze ping-image van de oefening \u0026lsquo;Images bouwen\u0026rsquo; nodig, dus zorg ervoor dat je die oefening eerst voltooit, zodat je een afbeelding hebt om te delen.\nAan de slag # Om afbeeldingen op DockerHub te delen, heb je een DockerHub-account nodig. Je kunt je hier aanmelden.\nDe meeste functies op DockerHub zouden vrijwel hetzelfde moeten zijn als op GitHub: er is een zoekfunctie om nieuwe afbeeldingen, opslagplaatsen voor je afbeeldingen en organisaties te vinden.\nDe docker CLI-tool is ook geïntegreerd met DockerHub. Om bepaalde functies te gebruiken, moet je eerst inloggen:\ndocker login Log in met je Docker-ID om image van Docker Hub te pushen en te pullen. Als je geen Docker-ID hebt, ga dan naar https://hub.docker.com om er een te maken. Afbeeldingen zoeken # Gebruik de opdracht docker search om naar nieuwe afbeeldingen te zoeken:\n$ docker search kafka NAME DESCRIPTION STARS OFFICIAL AUTOMATED wurstmeister/kafka Multi-Broker Apache Kafka Image 319 [OK] spotify/kafka A simple docker image with both Kafka and ... 200 [OK] ches/kafka Apache Kafka. Tagged versions. JMX. Cluste... 70 [OK] sheepkiller/kafka-manager kafka-manager 61 [OK] $ Zodra je een image hebt gevonden die u bevalt, kunt u deze lokaal ophalen met docker pull, zoals behandeld in de oefening \u0026ldquo;Containers uitvoeren\u0026rdquo;.\nAfbeeldingen taggen # In de vorige oefening \u0026ldquo;Afbeeldingen bouwen\u0026rdquo; hebben we een afbeelding gebouwd en getagd als ubuntu/ping. Als u deze afbeelding verkeerd hebt getagd met iets anders dan uw DockerHub-gebruikersnaam (\u0026lt;DockerHub-gebruikersnaam\u0026gt;), is dat geen probleem: we kunnen deze opnieuw taggen.\nGebruik gewoon docker tag om een ​​nieuwe tag toe te voegen met uw DockerHub-gebruikersnaam en geef deze een versie:\n$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ping latest a980ae1c79ea 2 minutes ago 121MB ubuntu 16.04 6a2f32de169d 5 days ago 117MB $ docker tag ping ubuntu/ping:1.0 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE delner/ping 1.0 a980ae1c79ea 5 minutes ago 121MB ping latest a980ae1c79ea 5 minutes ago 121MB ubuntu 16.04 6a2f32de169d 5 days ago 117MB $ U kunt zien dat dezelfde image-ID nu is toegewezen aan zowel de oude als de nieuwe tag. Om de oude tag te verwijderen, voer je docker rmi uit met de oude image-tag:\n$ docker rmi ping Untagged: ping:latest $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu/ping 1.0 a980ae1c79ea 6 minutes ago 121MB ubuntu 16.04 6a2f32de169d 5 days ago 117MB $ Images pushen # Om een ​​image te pushen, hoef je alleen maar docker push aan te roepen met de tag.\n$ docker push BartTho/ping:1.0 The push refers to a repository [docker.io/delner/ping] 3b372b8ab44b: Pushed ab4b9ad8d212: Mounted from library/ubuntu 57e913ee49e5: Mounted from library/ubuntu 2ea6deead2b0: Mounted from library/ubuntu 7cbd4b94e525: Mounted from library/ubuntu e86a0c422723: Mounted from library/ubuntu 1.0: digest: sha256:1881fd1efdde061d3aede939b8696c0e6d0b36e9f8b38abccb1074bc60592a60 size: 1568 $ Het zal automatisch een nieuwe openbare repository op DockerHub onder de organisatie in de tag. Door uw gebruikersnaam op te geven, wordt er een nieuwe repository gemaakt op https://hub.docker.com/r/\u0026lt;USERNAME\u0026gt;/ping/. Bekijk gerust uw nieuwe repo-pagina!\nHet is ook mogelijk om images te pushen naar niet-DockerHub-repositories, zoals die van AWS Elastic Container Registry, door het repository-gedeelte van de tag te wijzigen zodat deze overeenkomt met de juiste URL.\nVolumes # In deze oefening leren we werken met Docker-volumes, voor het persistent maken van gegevens tussen containers.\nOm dit te bereiken, zullen we een Apache HTTPD-webserver instellen en enkele HTML-bestanden persistent maken in een volume.\nDe server instellen # Om onze Apache HTTPD-server uit te voeren, voert u deze opdracht uit:\n$ docker run --rm -d --name apache -p 80:80 httpd:2.4 d87e0a193dde5652ac762d8849983c2cadb5116b80c8a61a4180e350d678b4d2 Deze opdracht start een nieuwe container vanaf HTTP 2.4, noemt deze apache, bindt poort 80 aan de hostmachine (hier later meer over) en stelt een vlag in om de container te verwijderen wanneer deze stopt.\nNadat het is gestart, kunnen we surfen naar onze webserver via localhost.\nhttp://localhost\nDit is het standaard index.html-bestand dat is meegeleverd met een nieuwe Apache 2.4-installatie. Laten we dit HTML-bestand vervangen door nieuwe inhoud.\nOm dit te doen, gebruiken we de opdracht docker cp, vergelijkbaar met scp, die bestanden kopieert tussen de host en containers. Laten we het index.html-bestand geven uit de directory waarin deze README zich bevindt:\n$ docker cp index.html apache:/usr/local/apache2/htdocs/ $ Het eerste pad is het bronpad, dat ons nieuwe bestand op onze hostmachine vertegenwoordigt, en het tweede pad onze bestemming. apache is de naam van de container waarnaar we willen kopiëren, en /usr/local/apache2/htdocs/ is waar de webserver HTML vandaan serveert.\nCurl opnieuw uitvoeren ziet er nu iets anders uit:\n$ curl localhost \u0026lt;html\u0026gt;\u0026lt;body\u0026gt;\u0026lt;h1\u0026gt;Het werkt in Docker!\u0026lt;/h1\u0026gt;\u0026lt;/body\u0026gt;\u0026lt;/html\u0026gt; $ Een mogelijk dataprobleem # Deze container zal gedurende zijn hele levensduur ons nieuwe HTML-bestand blijven bedienen.\nContainers in Docker worden echter in de praktijk als vluchtig beschouwd. Ze kunnen onverwachts doodgaan en in bepaalde implementaties zonder waarschuwing worden verwijderd. Als u afhankelijk bent van de containerstatus voor uw toepassing, kunt u belangrijke gegevens verliezen wanneer dergelijke containers doodgaan. Dit is met name een probleem voor toepassingen zoals databases, die geacht worden te worden beschouwd als permanente datastores.\nIn het geval van onze HTTPD-server zorgt het simpelweg stoppen van de container ervoor dat deze automatisch wordt verwijderd. We kunnen een andere container op zijn plaats zetten, maar deze zal onze wijzigingen niet meer bevatten.\n$ docker stop apache apache $ docker run --rm -d --name apache -p 80:80 httpd:2.4 9bd0620e3d8464456c368b1fe9b82733282d980a7c3f854b8cba7726f0a02958 $ curl localhost \u0026lt;html\u0026gt;\u0026lt;body\u0026gt;\u0026lt;h1\u0026gt;It works!\u0026lt;/h1\u0026gt;\u0026lt;/body\u0026gt;\u0026lt;/html\u0026gt; $ Om onze gegevens te bewaren tussen storingen of systeemupgrades, kunnen we volumes gebruiken om onze gegevens over generaties containers heen te bewaren.\nVolumes beheren # Volumes in Docker zijn bestandsopslagplaatsen die onafhankelijk van uw Docker-containers staan. De functie is hetzelfde als de EBS-volumes van Amazon Web Services en andere koppelbare media zoals USB-sticks. Ze kunnen worden gemaakt, verwijderd en gekoppeld aan containers op specifieke locaties binnen een image, zoals u dat zou doen met de opdracht mount in Linux.\nOm uw volumes te vermelden, voert u docker volume ls uit:\n$ docker volume ls DRIVER VOLUME NAME $ Om een ​​nieuw volume te maken, voert u docker volume create uit en geeft u het een volumenaam.\n$ docker volume create myvolume myvolume $ docker volume ls DRIVER VOLUME NAME local myvolume $ Om een ​​volume te verwijderen, voert u docker volume rm uit en geeft u het de volumenaam.\n$ docker volume rm myvolume myvolume $ docker volume ls DRIVER VOLUME NAME $ Volumes op containers mounten # Maak eerst een nieuw volume met de naam httpd_htdocs:\n$ docker volume create httpd_htdocs httpd_htdocs $ Voer vervolgens onze docker run-opdracht opnieuw uit en geef de -v mount-vlag op.\n$ docker run --rm -d --name apache -p 80:80 -v httpd_htdocs:/usr/local/apache2/htdocs/ httpd:2.4 c21dd93fea83d710b4d4c954911862760030723df6a5b42650e462e388fe6049 $ En kopieer opnieuw in ons aangepaste HTML-bestand.\n$ docker cp index.html apache:/usr/local/apache2/htdocs/ $ En voer curl uit om te verifiëren of het werkte.\n$ curl localhost \u0026lt;html\u0026gt;\u0026lt;body\u0026gt;\u0026lt;h1\u0026gt;Het werkt in Docker!\u0026lt;/h1\u0026gt;\u0026lt;/body\u0026gt;\u0026lt;/html\u0026gt; $ Om het volume in actie te zien, stoppen we de container. Door de \u0026ndash;rm-vlag tijdens de run op te geven, zou de container bij het stoppen moeten worden verwijderd.\n$ docker stop apache apache $ Start httpd dan nogmaals met dezelfde run-opdracht als de vorige keer. Deze keer kunnen we curl gebruiken en zien dat onze bestandswijzigingen er nog steeds zijn.\n$ docker run --rm -d --name apache -p 80:80 -v httpd_htdocs:/usr/local/apache2/htdocs/ httpd:2.4 c21dd93fea83d710b4d4c954911862760030723df6a5b42650e462e388fe6049 $ curl localhost \u0026lt;html\u0026gt;\u0026lt;body\u0026gt;\u0026lt;h1\u0026gt;Het werkt in Docker!\u0026lt;/h1\u0026gt;\u0026lt;/body\u0026gt;\u0026lt;/html\u0026gt; $ We kunnen dit volume nu op elke HTTPD-container mounten, wat ons de flexibiliteit geeft om onze container te verwisselen voor nieuwere versies zonder onze gegevens te verliezen, als we dat willen.\nGa door en voer docker stop apache uit om de container te stoppen en te verwijderen, en vervolgens docker volume rm httpd_htdocs om het volume te verwijderen.\nHostdirectory\u0026rsquo;s op containers mounten # Als alternatief voor het gebruik van volumes, als u een directory op uw hostmachine hebt die u wilt gebruiken als een volume, kunt u die ook mounten. Deze techniek is handig in ontwikkelomgevingen, waar u uw lokale repo op een Docker-image wilt mounten en de inhoud van een Docker-container actief wilt wijzigen zonder bestanden opnieuw te bouwen of te kopiëren.\nDe -v-vlag om dit te bereiken is bijna identiek aan de vorige. Geef in plaats daarvan gewoon een absoluut pad op naar een lokale directory. In ons geval geven we . door om de directory met 5 volumes in deze repo op te geven, die handig genoeg een aangepaste versie van het HTML-bestand bevat.\n$ pwd /home/david/src/docker-training/exercises/basic/5-volumes/ $ docker run --rm -d --name apache -p 80:80 -v /home/david/src/docker-training/exercises/basic/5-volumes/:/usr/local/apache2/htdocs/ httpd:2.4 0d91516b20ea6113b5dcca08ada6465095dc68663b3d2201dc0490165764f842 $ curl localhost \u0026lt;html\u0026gt;\u0026lt;body\u0026gt;\u0026lt;h1\u0026gt;Het werkt in Docker!\u0026lt;/h1\u0026gt;\u0026lt;/body\u0026gt;\u0026lt;/html\u0026gt; $ Met de host directory mount op zijn plaats, wijzig het bestand index.html in deze directory met een bericht naar keuze, sla het bestand op en voer curl opnieuw uit.\n$ curl localhost \u0026lt;html\u0026gt;\u0026lt;body\u0026gt;\u0026lt;h1\u0026gt;Het werkt vrij goed in Docker!\u0026lt;/h1\u0026gt;\u0026lt;/body\u0026gt;\u0026lt;/html\u0026gt; $ U kunt zien dat bestandswijzigingen direct plaatsvinden in de Docker-container zonder dat u docker cp hoeft uit te voeren.\nGa door en voer docker stop apache uit om de container te stoppen en te verwijderen.\nNetwerken # In deze oefening leren we werken met Docker-netwerken en containers met elkaar verbinden.\nOm dit te bereiken, stellen we twee Postgres-databases in en voeren we query\u0026rsquo;s tussen deze databases uit.\nNetwerken weergeven\nDocker definieert netwerken, die containers groeperen voor interoperabiliteit en DNS-functies.\nOm netwerken weer te geven, voert u docker network ls uit:\n$ docker network ls NETWERK-ID NAAM DRIVER-BEREIK 99cbf6b3d074 bridge bridge local 4a2071abf006 host host local 3789e459bd9c none null local $ Er zijn 3 standaardnetwerken: bridge, host en none die hier worden vermeld. Alle andere aangepaste netwerken worden hier ook vermeld. De host- en none-netwerken zijn niet belangrijk voor deze oefening, maar bridge is wel interessant.\nHet standaard bridgenetwerk\nAlle nieuwe containers worden, als er geen andere configuratie is opgegeven, automatisch toegevoegd aan het bridgenetwerk. Dit netwerk fungeert als een doorvoer naar het ethernet van uw host, zodat uw Docker-containers toegang hebben tot internet.\nWe kunnen het bridgenetwerk inspecteren door docker network inspect bridge uit te voeren:\n$ docker network inspect bridge [ { \u0026#34;Name\u0026#34;: \u0026#34;bridge\u0026#34;, \u0026#34;Id\u0026#34;: \u0026#34;99cbf6b3d07476bca2aaca71413b1a7609338d7d8deae9d4af77b062a98672de\u0026#34;, \u0026#34;Created\u0026#34;: \u0026#34;2017-04-17T20:27:36.319424753-04:00\u0026#34;, \u0026#34;Scope\u0026#34;: \u0026#34;local\u0026#34;, \u0026#34;Driver\u0026#34;: \u0026#34;bridge\u0026#34;, \u0026#34;EnableIPv6\u0026#34;: false, \u0026#34;IPAM\u0026#34;: { \u0026#34;Driver\u0026#34;: \u0026#34;default\u0026#34;, \u0026#34;Options\u0026#34;: null, \u0026#34;Config\u0026#34;: [ { \u0026#34;Subnet\u0026#34;: \u0026#34;172.17.0.0/16\u0026#34;, \u0026#34;Gateway\u0026#34;: \u0026#34;172.17.0.1\u0026#34; } ] }, \u0026#34;Intern\u0026#34;: false, \u0026#34;Attachable\u0026#34;: false, \u0026#34;Containers\u0026#34;: {}, \u0026#34;Opties\u0026#34;: { \u0026#34;com.docker.network.bridge.default_bridge\u0026#34;: \u0026#34;true\u0026#34;, \u0026#34;com.docker.network.bridge.enable_icc\u0026#34;: \u0026#34;true\u0026#34;, \u0026#34;com.docker.network.bridge.enable_ip_masquerade\u0026#34;: \u0026#34;true\u0026#34;, \u0026#34;com.docker.network.bridge.host_binding_ipv4\u0026#34;: \u0026#34;0.0.0.0\u0026#34;, \u0026#34;com.docker.network.bridge.name\u0026#34;: \u0026#34;docker0\u0026#34;, \u0026#34;com.docker.network.driver.mtu\u0026#34;: \u0026#34;1500\u0026#34; }, \u0026#34;Labels\u0026#34;: {} } ] $ Er is wat overige informatie over het netwerk, maar let op de \u0026ldquo;Containers\u0026rdquo;: {} entry. U kunt hier alle containers zien die momenteel met het netwerk zijn verbonden.\nLaten we een pingcontainer starten en deze opnieuw inspecteren:\n$ docker run --rm -d --name dummy delner/ping:1.0 104633917dbfe00843722336838f163b800dde46e632e47470b204c21fc44f21 $ docker network inspect bridge ... \u0026#34;Containers\u0026#34;: { \u0026#34;104633917dbfe00843722336838f163b800dde46e632e47470b204c21fc44f21\u0026#34;: { \u0026#34;Name\u0026#34;: \u0026#34;dummy\u0026#34;, \u0026#34;EndpointID\u0026#34;: \u0026#34;38f01d182b8d55de5f8ed3221f12086dd2eac3426b159cc8e6bda0075dbd0f47\u0026#34;, \u0026#34;MacAddress\u0026#34;: \u0026#34;02:42:ac:11:00:02\u0026#34;, \u0026#34;IPv4Address\u0026#34;: \u0026#34;172.17.0.2/16\u0026#34;, \u0026#34;IPv6Address\u0026#34;: \u0026#34;\u0026#34; } }, ... $ Je ziet dat de container is toegevoegd aan het standaardnetwerk. Laten we nu een andere pingcontainer toevoegen en deze instellen om onze eerste te pingen.\n$ docker run --rm -d -e PING_TARGET=172.17.0.2 --name pinger delner/ping:1.0 3a79f28b8ac36c0e7aae523c4831c9405c110d593c15a30639606250595b245b $ docker ps CONTAINER-ID AFBEELDING OPDRACHT GEMAAKT STATUS POORTEN NAMEN 3a79f28b8ac3 delner/ping:1.0 \u0026#34;sh -c \u0026#39;ping $PING...\u0026#34; 4 seconden geleden Omhoog 3 seconden pinger 104633917dbf delner/ping:1.0 \u0026#34;sh -c \u0026#39;ping $PING...\u0026#34; Ongeveer een minuut geleden Omhoog Ongeveer een minuut dummy $ docker logt pinger PING 172.17.0.2 (172.17.0.2) 56(84) bytes aan data. 64 bytes van 172.17.0.2: icmp_seq=1 ttl=64 time=0.171 ms 64 bytes van 172.17.0.2: icmp_seq=2 ttl=64 time=0.100 ms 64 bytes van 172.17.0.2: icmp_seq=3 ttl=64 time=0.098 ms 64 bytes van 172.17.0.2: icmp_seq=4 ttl=64 time=0.098 ms $ Als we de logs voor pinger inspecteren, zien we dat het de andere container in het netwerk succesvol kon pingen. Hoewel het IP-adres werkt, is het erg omslachtig en foutgevoelig als adressen veranderen. Het zou beter zijn om een ​​hostnaam te gebruiken, specifiek de containernaam dummy, om altijd naar de juiste container te verwijzen.\nPing uitvoeren met de dummy als doel:\n$ docker run --rm -d -e PING_TARGET=dummy --name pinger delner/ping:1.0 3a79f28b8ac36c0e7aae523c4831c9405c110d593c15a30639606250595b245b $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 104633917dbf delner/ping:1.0 \u0026#34;sh -c \u0026#39;ping $PING...\u0026#34; Ongeveer een minuut geleden Up Ongeveer een minuut dummy $ \u0026hellip; resulteert in een fout. De hostnaam kon niet worden opgelost, waardoor de opdracht een fout veroorzaakte en de container werd afgesloten en automatisch werd verwijderd.\nHet standaardbrugnetwerk staat niet automatisch toe dat u containers op containernaam netwerkt. We kunnen echter eenvoudig hostresolutie bereiken met behulp van een aangepast netwerk.\nStop en verwijder de dummycontainer door docker stop dummy uit te voeren.\nAangepaste netwerken beheren # Om een ​​nieuw netwerk te maken, gebruikt u de opdracht docker network create en geeft u deze een netwerknaam.\n$ docker network create skynet c234438e88ab579be943859dbc0a89788563226c3a9a13b4f1a2c78d1d8000c9 $ docker network ls NETWERK-ID NAAM DRIVER BEREIK 99cbf6b3d074 bridge bridge lokaal 4a2071abf006 host host lokaal 3789e459bd9c none null lokaal c234438e88ab skynet bridge lokaal $ docker network inspect skynet [ { \u0026#34;Naam\u0026#34;: \u0026#34;skynet\u0026#34;, \u0026#34;Id\u0026#34;: \u0026#34;c234438e88ab579be943859dbc0a89788563226c3a9a13b4f1a2c78d1d8000c9\u0026#34;, \u0026#34;Created\u0026#34;: \u0026#34;2017-04-18T01:28:56.982335289-04:00\u0026#34;, \u0026#34;Scope\u0026#34;: \u0026#34;local\u0026#34;, \u0026#34;Driver\u0026#34;: \u0026#34;bridge\u0026#34;, \u0026#34;EnableIPv6\u0026#34;: false, \u0026#34;IPAM\u0026#34;: { \u0026#34;Driver\u0026#34;: \u0026#34;default\u0026#34;, \u0026#34;Options\u0026#34;: {}, \u0026#34;Config\u0026#34;: [ { \u0026#34;Subnet\u0026#34;: \u0026#34;172.26.0.0/16\u0026#34;, \u0026#34;Gateway\u0026#34;: \u0026#34;172.26.0.1\u0026#34; } ] }, \u0026#34;Internal\u0026#34;: false, \u0026#34;Attachable\u0026#34;: false, \u0026#34;Containers\u0026#34;: {}, \u0026#34;Options\u0026#34;: {}, \u0026#34;Labels\u0026#34;: {} } ] $ Om netwerken te verwijderen, voer docker network rm uit en geef het de netwerknaam.\nContainers toevoegen aan een netwerk # Laten we de pingcontainer opnieuw uitvoeren, dit keer door deze toe te wijzen aan een netwerk:\n$ docker run --rm -d --network skynet --name dummy delner/ping:1.0 Dan de pinger, gericht op de dummy pingcontainer:\n$ docker run --rm -d --network skynet -e PING_TARGET=dummy --name pinger delner/ping:1.0 28e68fed9fe28a4346951fa8b6f4147a16f2afec8671357f1ed5f27425914b0a $ docker logs pinger PING dummy (172.26.0.2) 56(84) bytes aan data. 64 bytes van dummy.skynet (172.26.0.2): icmp_seq=1 ttl=64 time=0.101 ms 64 bytes van dummy.skynet (172.26.0.2): icmp_seq=2 ttl=64 time=0.102 ms 64 bytes van dummy.skynet (172.26.0.2): icmp_seq=3 ttl=64 time=0.116 ms $ Let op dat de hostnaam deze keer succesvol wordt opgelost. Dit is Docker\u0026rsquo;s Embedded DNS in actie. Het is het meest nuttig bij het orkestreren van meerdere containers in één enkele applicatie, zoals een webserver, database en cache. In plaats van IP-adressen te gebruiken, kunt u elk van de respectieve verbindingsreeksen definiëren met behulp van containernamen om DNS-resolutie te benutten.\nStop en verwijder de containers door docker stop pinger en docker stop dummy uit te voeren.\nVerbinding maken tussen containers in een netwerk # We kunnen hostnamen en ping oplossen, maar dit is niet hetzelfde als verbinding maken met TCP/UDP tussen containers.\nLaten we twee postgres-databases instellen om verbinding met elkaar te maken: een widget-database en een gadget-database.\nStart elke database en voeg ze toe aan het netwerk:\n$ docker run --rm -d --name widgetdb --network skynet -p 5432 postgres 7f0248e3c0f4f03159ef966fd9767a4c7e3412801f8b0445cebb933d1e84e020 $ docker run --rm -d --name gadgetdb --network skynet -p 5432 postgres 8dc66701837c695728abb9046db71924112a9b8f2f1e096094ab5b5d631e2f73 $ docker ps CONTAINER-ID AFBEELDING OPDRACHT GEMAAKT STATUS POORTEN NAMEN 8dc66701837c postgres \u0026#34;docker-entrypoint...\u0026#34; 11 seconden geleden Up 10 seconden 0.0.0.0:32769-\u0026gt;5432/tcp gadgetdb 7f0248e3c0f4 postgres \u0026#34;docker-entrypoint...\u0026#34; 40 seconden geleden Up 39 seconden 0.0.0.0:32768-\u0026gt;5432/tcp widgetdb $ Standaard is poort 5432 geblokkeerd en ontoegankelijk. Door echter -p 5432 toe te voegen, staan ​​we andere containers toe om er toegang toe te krijgen via poort 5432, de standaard Postgres-poort.\nNu ze draaien, start u een shell-sessie in de widgetdb met docker exec:\n$ docker exec -it widgetdb /bin/bash root@7f0248e3c0f4:/# U kunt vervolgens verbinding maken met de lokale database met behulp van psql. (Beëindig de psql-sessie door \\q in te voeren.)\nroot@7f0248e3c0f4:/# psql -U postgres psql (9.6.2) Typ \u0026#34;help\u0026#34; voor hulp. postgres=# \\q root@7f0248e3c0f4:/# Of naar de gadgetdatabase door ernaar te verwijzen met de naam:\nroot@7f0248e3c0f4:/# psql -U postgres -h gadgetdb psql (9.6.2) Typ \u0026#34;help\u0026#34; voor hulp. postgres=# \\q root@7f0248e3c0f4:/# Typ exit om de sessie te beëindigen, en vervolgens docker stop widgetdb gadgetdb om de containers te stoppen en te verwijderen.\nPoorten binden aan de host # Soms is het handig om rechtstreeks toegang te krijgen tot een applicatie die in een Docker-container draait, alsof deze op uw hostmachine draait.\nHiervoor kunt u poorten van een container binden aan een poort op uw hostmachine. Om dit te doen, zou de aangepaste opdracht uit ons vorige Postgres-voorbeeld er als volgt uitzien:\n$ docker run --rm -d --name widgetdb --network skynet -p 5432:5432 postgres De -p-vlag die is gegeven \u0026lt;hostpoort\u0026gt;:\u0026lt;containerpoort\u0026gt; doet deze toewijzing, waardoor de server beschikbaar wordt als localhost:5432:\nU kunt vervolgens psql (als het hulpprogramma is geïnstalleerd) op uw hostmachine uitvoeren om toegang te krijgen tot de Postgres-database\n$ psql -U postgres -h localhost psql (9.6.2) Typ \u0026#34;help\u0026#34; voor hulp. postgres=# \\q $ Het is belangrijk om in gedachten te houden dat u slechts één applicatie tegelijk aan een hostpoort kunt binden. Als u probeert om applicaties op uw hostmachine te starten, of andere Docker-containers die willen binden aan een poort die al in gebruik is, zal dit niet lukken.\nTyp docker stop widgetdb om de container te stoppen en te verwijderen.\n","date":"26 Januarie 2026","externalUrl":null,"permalink":"/docker/oefeningen/","section":"Dockers","summary":"","title":"Docker Oefeningen","type":"docker"},{"content":" Point of note: Ubuntu targets # Ansible target hsots need to have either SSH (Linux / network equipment) or WinRM (Windows) enabled. Ubuntu does not have a SSH daemon running by default. You could install one on the target system using the following command:\nsudo apt update sudo apt install openssh-server Verify ansible inventory consistency # To check if your Ansible inventory file is valid, you can use the ansible-inventory command with the \u0026ndash;list option. This command will attempt to load and parse your inventory file, and display the resulting inventory in JSON format.\nHere\u0026rsquo;s an example of how to use the ansible-inventory command to check if your inventory file is valid:\nansible-inventory -i inventory.ini --list In this example, the inventory.ini file is the path to your inventory file. If the inventory file is valid, the \u0026ndash;list option will display the inventory in JSON format. If the inventory file contains errors, you will see an error message indicating what the problem is.\nVisualise ansible inventory # In addition to the \u0026ndash;list option, you can also use the \u0026ndash;graph option to display a visual representation of the inventory graph, which can be helpful for understanding the relationships between hosts and groups.\nHere\u0026rsquo;s an example of how to use the ansible-inventory command with the \u0026ndash;graph option:\nansible-inventory -i inventory.ini --graph This command will display a tree-like graph of the inventory, with hosts and groups represented as nodes and edges connecting them. This can be especially helpful for visualizing the structure of your inventory and identifying any issues with the inventory file.\nVerify presence of a machine in the inventory file # You can also query to the ansible inventory file to check if a host is present:\nansible \u0026lt;hostname\u0026gt; --list-hosts SSH to older network devices # Older network typically support only legacy encryption suites. Typical examples are switches and routers.\nTo allow ansible to connect to these hosts, you can use the following procedure:\nEdit SSH config\nsudo nano /etc/ssh/ssh_config In this inventory file, unquote the following entry:\nCiphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc Afterwards, add the following line at the bottom of the file:\nKexAlgorithms +diffie-hellman-group1-sha1 HostKeyAlgorithms +ssh-rsa PubkeyAcceptedKeyTypes +ssh-rsa Specifically for RHEL, it might also be required to add the SHA1 hashing algorithm in the crypto policies. This can be done with the following command:\nsudo update-crypto-policies --set DEFAULT:SHA1 On Rhel8, you might also need the following command:\nsudo update-crypto-policies --set LEGACY For very old switches # Some very old switches only support diffiehellman1-group1 negotiations. This is blocked by default on RHEL 8 and RHEL 9 versions.\nTo enable it, perform the following actions\nCreate a file in the SSH client config directory sudo nano /etc/ssh/ssh_config.d/40-sha1.conf Enter the following string KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1 Reboot your RHEL VM reboot Verify connectivity with SSH using the following command structure: \u0026ldquo;ssh \u0026lt;username\u0026gt;@\u0026lt;IP address of switch\u0026gt;\u0026rdquo;. An example is the following ssh ansible@192.168.100.5 Help! I can\u0026rsquo;t connect to switches and routers with my Ansible controller # As mentioned before, ansible uses various modules. Additional modules are maintained and centralized in the Ansible Galaxy.\nHowever, many modules are community driven and can contain different SSH packages as their dependancies.\nCheck if the following Python modules are installed:\nparamiko ansible-pylibssh\nThey can be installed using the following commands: pip install paramiko pip install ansible-pylibssh Install network modules in Ansible # The following modules are used for cisco switches\nansible-galaxy collection install ansible.network ansible-galaxy collection install cisco.ios This will install the latest version of the ansible.network collection, which includes the ios_command, ios_hostname, ios_interface, ios_interface_vlan, ios_static_route, and ios_vlan modules.\nThe following module set can also be used for other vendors.\nCommunity network edition\nRHEL8: SSH connection to devices that have a RSA key generated with less than 1024 bits # On a RHEL7 system, download the packages that are necessary to execute ssh\n``` mkdir /tmp/miniroot /tmp/packages yum install --downloadonly --installroot=/tmp/miniroot --releasever=/ --downloaddir=/tmp/packages openssh-clients ``` In the example above, the packages will be available in /tmp/packages directory.\nCopy the packages to the RHEL8 system\nscp -r /tmp/packages RHEL8:/root/ On the RHEL8 system, create the miniroot\n# mkdir /rhel7_miniroot # semanage fcontext -a -e / /rhel7_miniroot # yum install --installroot /rhel7_miniroot ./packages/*.rpm In the example above, the miniroot for the container will be installed as /rhel7_miniroot.\nOn the RHEL8 system, enter the miniroot to access your legacy device\nsystemd-nspawn -D /rhel7_miniroot https://access.redhat.com/solutions/6187741\n","date":"26 Januarie 2026","externalUrl":null,"permalink":"/ansible/tips-tricks/","section":"Ansibles","summary":"","title":"Tips \u0026 Tricks","type":"ansible"},{"content":" Werken met Git in Visual Studio Code op een Ubuntu Desktop # ","date":"25 Januarie 2026","externalUrl":null,"permalink":"/git/video-git/","section":"Gits","summary":"","title":"Video's Git","type":"git"},{"content":"","externalUrl":"https://pmnxis.github.io","permalink":"/users/5-5bf94b5c1e0c4a40d81816df85e1444f/","section":"Users","summary":"","title":"pmnxis.github.io","type":"users"},{"content":" Wat is portainer # Portainer is een open-source beheerinterface (UI) voor Docker-omgevingen. Het biedt een grafische, webgebaseerde interface waarmee gebruikers eenvoudig Docker-containers, -images, -netwerken en -volumes kunnen beheren zonder de opdrachtregel te hoeven gebruiken. Portainer kan zowel lokale als externe Docker-omgevingen beheren, waaronder Docker Swarm- en Kubernetes-clusters.\nToepassingen # Vereenvoudigd Docker-beheer: Portainer maakt het voor gebruikers van elk vaardigheidsniveau eenvoudig om Docker-resources te beheren. Dit gebeurt via een grafische interface voor veelvoorkomende taken, zoals het aanmaken, starten, stoppen en verwijderen van containers, evenals het beheren van images, netwerken en volumes. Monitoring en probleemoplossing: Portainer biedt realtime monitoring en visualisatie van uw Docker-omgeving, zodat u het resourcegebruik kunt bijhouden en mogelijke problemen kunt opsporen. Ook biedt het de mogelijkheid om logs te bekijken en toegang te krijgen tot de containerconsole, wat het oplossen van problemen vereenvoudigt. Toegangsbeheer voor gebruikers: Portainer beschikt over een systeem voor op rollen gebaseerd toegangsbeheer (RBAC). Hiermee kunnen beheerders gebruikersrollen en rechten definiëren voor het beheer van Docker-resources. Deze functie is vooral nuttig voor organisaties met meerdere gebruikers die uiteenlopende toegangsniveaus tot de Docker-omgeving nodig hebben. Beheer van Docker Swarm en Kubernetes: Portainer breidt zijn beheermogelijkheden uit naar Docker Swarm- en Kubernetes-clusters. Hierdoor kunnen gebruikers hun container-orchestratieplatforms via dezelfde interface beheren en bewaken. Versies # Portainer is beschikbaar in zowel een betaalde Business Edition (Portainer BE) als een Community Edition (Portainer CE). In deze cursus maken we gebruik van de Community Edition.\nInstallatie # 1 volume aanmaken Maak eerst het volume aan dat Portainer Server zal gebruiken om de database op te slaan:\ndocker volume create portainer_data 2 Installeer Download en installeer vervolgens de Portainer Server-container:\ndocker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest Daarna is Portainer klaar voor gebruik! Laten we dat laatste commando eens nader bekijken. Dit commando start een nieuwe Docker-container op basis van de Portainer Community Edition (CE)-image.\ndocker run: Het commando dat wordt gebruikt om een ​​nieuwe Docker-container aan te maken en te starten vanuit een image.\n-d: Start de container in \u0026lsquo;detached\u0026rsquo;-modus; dit betekent dat de container op de achtergrond draait zonder logs in de terminal weer te geven.\n-p 8000:8000 -p 9443:9443: Koppelt poort 8000 en 9443 van de host aan respectievelijk poort 8000 en 9443 van de container. Hierdoor zijn de services die op deze poorten in de container draaien, van buitenaf toegankelijk.\n\u0026ndash;name portainer: Geeft de container de naam \u0026ldquo;portainer\u0026rdquo;. Dit maakt het eenvoudiger om naar de container te verwijzen bij het gebruik van andere Docker-commando\u0026rsquo;s.\n\u0026ndash;restart=always: Configureert de container zo dat deze automatisch opnieuw opstart als hij stopt of als de Docker-daemon opnieuw wordt opgestart. Dit zorgt ervoor dat de container altijd blijft draaien.\n-v /var/run/docker.sock:/var/run/docker.sock: Koppelt de Docker-socket van de host aan de Docker-socket van de container. Hierdoor kan Portainer communiceren met de Docker-daemon en de Docker-omgeving beheren. -v portainer_data:/data: Koppelt het \u0026ldquo;portainer_data\u0026rdquo;-volume aan de map \u0026ldquo;/data\u0026rdquo; in de container. Dit maakt persistente opslag van Portainer-gegevens (zoals configuraties en instellingen) mogelijk; deze blijven behouden, zelfs als de container wordt verwijderd en opnieuw wordt aangemaakt.\nportainer/portainer-ce:latest: Geeft de image aan die moet worden gebruikt bij het aanmaken van de container. In dit geval betreft het de nieuwste versie van de Portainer Community Edition (CE)-image. Standaard wordt er op DockerHub naar de image gezocht. Ò\nPortainer starten # Je kunt Portainer gebruiken door naar het publieke IP-adres van je host te navigeren via poort 9443:\nhttps://\u0026lt;IP-VAN-JE-VM\u0026gt;:9443/ ","date":"26 Januarie 2026","externalUrl":null,"permalink":"/docker/portainer/","section":"Dockers","summary":"","title":"Portainer","type":"docker"},{"content":"Als je je kennis van Git wilt opfrissen, kun je de volgende links gebruiken. Elke link heeft een specifiek doel, dus lees eerst de toelichting bij de link.\nhttps://www.atlassian.com/git/tutorials/setting-up-a-repository\nDit is de \u0026lsquo;getting started\u0026rsquo;-tutorial voor Git van Atlassian (een van de toonaangevende aanbieders van samenwerkingstools). Hiermee leer je de basisbeginselen van het gebruik van Git.\nhttps://learngitbranching.js.org/\nDit is een handige tool om op interactieve wijze te leren werken met Git-branches; het helpt je begrijpen hoe branching werkt en welke commando\u0026rsquo;s je in welke situatie gebruikt. Begin op het niveau dat voor jou geschikt is.\nhttps://semver.org/\nSemVer is een zeer bekende methode voor versiebeheer van projecten en wordt vaak gebruikt om belangrijke wijzigingen in softwarepakketten aan te duiden. - De volgende cheat sheet kan je helpen als je vastloopt en een specifiek commando nodig hebt:\nhttps://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet\nGIT-FAQ # Hier vind je vragen die vaak door je collega\u0026rsquo;s zijn gesteld.\nCursus Git # Cursus Git\nOefeningen Git\ngitignore\nGit in VS Code\nBoek\n","date":"25 Januarie 2026","externalUrl":null,"permalink":"/git/tips-tricks/","section":"Gits","summary":"","title":"Tips \u0026 Tricks","type":"git"},{"content":"","externalUrl":"https://ciicadalab.github.io","permalink":"/users/6-ef51c7b9654a4f2d13525eb80ee46cdf/","section":"Users","summary":"","title":"ciicadalab.github.io","type":"users"},{"content":"","externalUrl":"https://georgiancodeclub.github.io","permalink":"/users/7-25036bf87aa99ef82e09089a1ddbb9eb/","section":"Users","summary":"","title":"georgiancodeclub.github.io","type":"users"},{"content":"","externalUrl":"https://loisvelasco.is-a.dev","permalink":"/users/8-6c20c1af90023ed60919801cfba0f08f/","section":"Users","summary":"","title":"loisvelasco.is-a.dev","type":"users"},{"content":" Cursus # You need to laern Ansible RIGHT NOW !! (Linus Automation) # ","date":"25 Januarie 2026","externalUrl":null,"permalink":"/ansible/video-ansible/","section":"Ansibles","summary":"","title":"Ansible Video","type":"ansible"},{"content":"","externalUrl":"https://insidemordecai.com","permalink":"/users/9-7ee8520d5e9eadae8557be82f46ff18d/","section":"Users","summary":"","title":"insidemordecai.com","type":"users"},{"content":"","externalUrl":"https://blastomussa.dev","permalink":"/users/10-4ea7eb30d575afb5183b02f31a661c42/","section":"Users","summary":"","title":"blastomussa.dev","type":"users"},{"content":"","externalUrl":"https://jam.dsg.li","permalink":"/users/11-ee5d5eca13c3742f7a454a52424f9d73/","section":"Users","summary":"","title":"jam.dsg.li","type":"users"},{"content":"","externalUrl":"https://priyakdey.com","permalink":"/users/12-72d71e304faaa40b3d547d5357edc450/","section":"Users","summary":"","title":"priyakdey.com","type":"users"},{"content":"","externalUrl":"https://sdehm.dev","permalink":"/users/13-1a882ded73613252bb07c2c13f40b9e3/","section":"Users","summary":"","title":"sdehm.dev","type":"users"},{"content":"","externalUrl":"https://dizzytech.de","permalink":"/users/14-039ca94b0aeeb9ab4c95226615bfb840/","section":"Users","summary":"","title":"dizzytech.de","type":"users"},{"content":"","externalUrl":"https://alejandro-ao.com/","permalink":"/users/15-620af4c12a7ee8932fadb45ae52bba7e/","section":"Users","summary":"","title":"alejandro-ao.com","type":"users"},{"content":"","externalUrl":"https://adir1.com/","permalink":"/users/16-64faf41f22317a170125dd7b2cd642e2/","section":"Users","summary":"","title":"adir1.com","type":"users"},{"content":"","externalUrl":"https://blog.muffn.io/","permalink":"/users/17-e07582d573aa187c3c15bb042872ca4a/","section":"Users","summary":"","title":"blog.muffn.io","type":"users"},{"content":"","externalUrl":"https://vividscc.com/","permalink":"/users/18-3bfa5ccb77cf79199527df4c0259d0dc/","section":"Users","summary":"","title":"vividscc.com","type":"users"},{"content":" Docker deel 1: Commando\u0026rsquo;s # Docker Deel 2: Docker en Visual Studio Code # Docker Deel 3: Docker Hub en Portainer # ","date":"25 Januarie 2026","externalUrl":null,"permalink":"/docker/video-docker/","section":"Dockers","summary":"","title":"Docker Video's","type":"docker"},{"content":"","externalUrl":"https://technicat.com/","permalink":"/users/19-6ed0dcb17b6e24c166f7da0bdfb0c1f5/","section":"Users","summary":"","title":"technicat.com","type":"users"},{"content":"","externalUrl":"https://fugugames.com/","permalink":"/users/20-e2ca3d6494c32151235beabe7567b23d/","section":"Users","summary":"","title":"fugugames.com","type":"users"},{"content":"","externalUrl":"https://hyperbowl3d.com/","permalink":"/users/21-129162dc71b9d40ee7948e51910d415a/","section":"Users","summary":"","title":"hyperbowl3d.com","type":"users"},{"content":"","externalUrl":"https://talkdimsum.com/","permalink":"/users/22-80d4420e686d5a055bab647fa03d281b/","section":"Users","summary":"","title":"talkdimsum.com","type":"users"},{"content":"","externalUrl":"https://alanctanner.com/","permalink":"/users/23-8168c3eeb157c9c9b1ca287393393f9c/","section":"Users","summary":"","title":"alanctanner.com","type":"users"},{"content":"","externalUrl":"https://rdgo.dev/","permalink":"/users/24-98f15180691d43fbfcbaf685e1b9ab06/","section":"Users","summary":"","title":"rdgo.dev","type":"users"},{"content":"","externalUrl":"https://clemsau.com/","permalink":"/users/25-66a61706d45b77b559869cd1247fe8fc/","section":"Users","summary":"","title":"clemsau.com","type":"users"},{"content":"","externalUrl":"https://weaxsey.org/","permalink":"/users/26-5801e67070cd59e592c82693a1bda773/","section":"Users","summary":"","title":"weaxsey.org","type":"users"},{"content":"","externalUrl":"https://nikarashihatsu.github.io/","permalink":"/users/27-c7116358255c4f5ccb306f7012306e22/","section":"Users","summary":"","title":"nikarashihatsu.github.io","type":"users"},{"content":"","externalUrl":"https://www.halcyonstraits.com/","permalink":"/users/28-d8ebb1396d8c7d2233b33a6b3ca0adc4/","section":"Users","summary":"","title":"halcyonstraits.com","type":"users"},{"content":"","externalUrl":"https://www.50-nuances-octets.fr/","permalink":"/users/29-24577d47b9474b6bc72eba9a6009dba4/","section":"Users","summary":"","title":"50-nuances-octets.fr","type":"users"},{"content":"","externalUrl":"https://marupanda.art/marucomics/","permalink":"/users/30-6e0c28f8b70015dd35f332d927960d06/","section":"Users","summary":"","title":"marupanda.art/marucomics","type":"users"},{"content":"","externalUrl":"https://m3upt.com","permalink":"/users/31-4d4fb24dca11a144122fa0bb831d9d03/","section":"Users","summary":"","title":"m3upt.com","type":"users"},{"content":"","externalUrl":"https://pacochan.net","permalink":"/users/32-c8eb3ba4d0e565e041ead9aabe6fc770/","section":"Users","summary":"","title":"pacochan.net","type":"users"},{"content":"","externalUrl":"https://vkmki001.github.io/","permalink":"/users/33-069e8f01e7ef48830ebea5239e2189b4/","section":"Users","summary":"","title":"vkmki001.github.io","type":"users"},{"content":"","externalUrl":"https://bbagwang.com","permalink":"/users/34-43d57d92cc54037519270a0cb07dbb83/","section":"Users","summary":"","title":"bbagwang.com","type":"users"},{"content":"","externalUrl":"https://jamiemoxon.tech","permalink":"/users/35-d9e559aaa0c3488012725cc4699ff9c4/","section":"Users","summary":"","title":"jamiemoxon.tech","type":"users"},{"content":"","externalUrl":"https://theindiecoder.cloud","permalink":"/users/36-9eed597b03512bc7b7b4b3cf81814a37/","section":"Users","summary":"","title":"theindiecoder.cloud","type":"users"},{"content":"","externalUrl":"https://gma.name","permalink":"/users/37-48ff442c7de299911eab10b72b02cc84/","section":"Users","summary":"","title":"gma.name","type":"users"},{"content":"","externalUrl":"https://mayer.life","permalink":"/users/38-1b3c507d9cd618565898e6d099c0427d/","section":"Users","summary":"","title":"mayer.life","type":"users"},{"content":"","externalUrl":"https://ohdmire.github.io","permalink":"/users/39-fec44f5dd2be29e37c305696d018f99f/","section":"Users","summary":"","title":"ohdmire.github.io","type":"users"},{"content":"","externalUrl":"https://ricklan.photography","permalink":"/users/40-954584ca9b811d77ac600cf7c426be45/","section":"Users","summary":"","title":"ricklan.photography","type":"users"},{"content":"","externalUrl":"https://deepumohan.com/tech/","permalink":"/users/41-8032d46bf9c96ae4b59c419032c7ad89/","section":"Users","summary":"","title":"deepumohan.com/tech","type":"users"},{"content":"","externalUrl":"https://joush007.github.io","permalink":"/users/42-b66472425d53d4e270e85ba4f160e7a1/","section":"Users","summary":"","title":"joush007.github.io","type":"users"},{"content":"","externalUrl":"https://blog.stonegarden.dev/","permalink":"/users/43-3ec093539269bc4ce9498fe9c36a2b7d/","section":"Users","summary":"","title":"blog.stonegarden.dev","type":"users"},{"content":"","externalUrl":"https://renaud.warnotte.be","permalink":"/users/44-4f0c88168fb7a348b4393a56ede2e799/","section":"Users","summary":"","title":"renaud.warnotte.be","type":"users"},{"content":"","externalUrl":"https://boringtech.net/","permalink":"/users/45-82b432ad2bfc873ec725001f0b3ac495/","section":"Users","summary":"","title":"BoringTech.net","type":"users"},{"content":"","externalUrl":"https://alxhslm.github.io/","permalink":"/users/46-427cec3309be77abe6f19b006b2a3dc0/","section":"Users","summary":"","title":"alxhslm.github.io","type":"users"},{"content":"","externalUrl":"https://www.the-maze.net/","permalink":"/users/47-e518dc969af1ea65a3d0b55630705047/","section":"Users","summary":"","title":"the-maze.net","type":"users"},{"content":"","externalUrl":"https://www.dxpetti.com/","permalink":"/users/48-0327ac1993f378aa2fc5bbb8a840c9cb/","section":"Users","summary":"","title":"DXPetti.com","type":"users"},{"content":"","externalUrl":"https://asterisk.lol","permalink":"/users/49-6e57b74d392f64f3698aee7046cc2606/","section":"Users","summary":"","title":"asterisk.lol","type":"users"},{"content":"","externalUrl":"https://ekwska.com","permalink":"/users/50-1314bf3d7ce70ad90f1fc7666032e147/","section":"Users","summary":"","title":"ekwska.com","type":"users"},{"content":"","externalUrl":"https://aakashnand.com/","permalink":"/users/51-a322d57671bf49fe0f2539096f9ed57f/","section":"Users","summary":"","title":"aakashnand.com","type":"users"},{"content":"","externalUrl":"https://karlukle.site","permalink":"/users/52-7d028665dc1cf54485e6e82a7083ce69/","section":"Users","summary":"","title":"karlukle.site","type":"users"},{"content":"","externalUrl":"http://www.adammadej.com/","permalink":"/users/53-15cf92fba36f0319bd4b176da554fdb9/","section":"Users","summary":"","title":"Adam Madej - Gameplay Animator","type":"users"},{"content":"","externalUrl":"http://www.eallion.com/","permalink":"/users/54-1f94add7b0ba58983ff507632b822401/","section":"Users","summary":"","title":"eallion.com","type":"users"},{"content":"","externalUrl":"https://synapticsugar.games","permalink":"/users/55-c0d9928ff3857960ec230178bdec1b8d/","section":"Users","summary":"","title":"Synaptic Sugar","type":"users"},{"content":"","externalUrl":"https://www.michaeldorner.de","permalink":"/users/56-d965f981aa39336ef7be5efac83c96b2/","section":"Users","summary":"","title":"michaeldorner.de","type":"users"},{"content":"","externalUrl":"http://www.ignaciomconde.com/","permalink":"/users/57-4de384e83ae8af3834cad28f6dfc6966/","section":"Users","summary":"","title":"Ignacio Conde","type":"users"},{"content":"","externalUrl":"https://blog.ummit.dev/","permalink":"/users/58-c506ded8078df151fc8ce943e7ac1c8a/","section":"Users","summary":"","title":"UmmIt - Blog","type":"users"},{"content":"","externalUrl":"https://nveshaan.github.io/","permalink":"/users/59-02c452502ee9a03866c720c14bf86f9e/","section":"Users","summary":"","title":"nveshaan","type":"users"},{"content":"","externalUrl":"https://kumacat.pages.dev","permalink":"/users/60-d52c3523ad809eb1d9ddbcbe32e92661/","section":"Users","summary":"","title":"kumacat.pages.dev","type":"users"},{"content":"","externalUrl":"https://andrealucchini.com","permalink":"/users/61-bdd6b2db27fb40b3fa79a37659b2f285/","section":"Users","summary":"","title":"andrealucchini.com","type":"users"},{"content":"","externalUrl":"https://luizglomyer.github.io/","permalink":"/users/62-af89464ac25ab9445658a3541e623778/","section":"Users","summary":"","title":"glomyer.dev","type":"users"},{"content":"","externalUrl":"https://lazarusoverlook.com","permalink":"/users/63-033c87b7e950b82ea500c552c9523367/","section":"Users","summary":"","title":"lazarusoverlook.com","type":"users"},{"content":"","externalUrl":"https://p3rception.github.io/","permalink":"/users/64-7596a225b244e0859da338621e680481/","section":"Users","summary":"","title":"p3rception.github.io","type":"users"},{"content":"","externalUrl":"https://www.emse.education","permalink":"/users/65-54b73306674ec7e6778b54a0a8b18b36/","section":"Users","summary":"","title":"Handbook on Teaching Empirical Software Engineering: Online Materials","type":"users"},{"content":"","externalUrl":"https://blog.lofibean.cc","permalink":"/users/66-ad989702a19d1fd8add147d6771c6c02/","section":"Users","summary":"","title":"blog.lofibean.cc","type":"users"},{"content":"","externalUrl":"https://acamize.com/","permalink":"/users/67-e263f9bb6dcec27003a8f5f947ba5abb/","section":"Users","summary":"","title":"Academy Customize","type":"users"},{"content":"","externalUrl":"https://mrtruongvu.com","permalink":"/users/68-837b47128639b5359ade845eae461c3a/","section":"Users","summary":"","title":"mrtruongvu.com","type":"users"},{"content":"","externalUrl":"https://stepaniah.me","permalink":"/users/69-1b3da762734b4fb503e49822ed506dbb/","section":"Users","summary":"","title":"StepaniaH","type":"users"},{"content":"","externalUrl":"https://laterre.dev/","permalink":"/users/70-447e2f0f6f439b915e0b57f93e49b7d6/","section":"Users","summary":"","title":"Laterre Dev","type":"users"},{"content":"","externalUrl":"https://lazyproductreviews.com/","permalink":"/users/71-3fa4eb553f5d984050d2ee4954960034/","section":"Users","summary":"","title":"Lazy Product Reviews","type":"users"},{"content":"","externalUrl":"https://zzzhome.cc/","permalink":"/users/72-46ea5d4b3698fa18fc0b79faa3d89bef/","section":"Users","summary":"","title":"zzzhome","type":"users"},{"content":"","externalUrl":"https://bootlegcoal.com","permalink":"/users/73-915a897f2ea3ba018728d7dce3540b1b/","section":"Users","summary":"","title":"Bootleg Coal Rebellion","type":"users"},{"content":"","externalUrl":"https://ctry.tech/","permalink":"/users/74-0805e986c2f7265e3bbbfc7bc647ed92/","section":"Users","summary":"","title":"Chill-Try","type":"users"},{"content":"","externalUrl":"https://hudsonmcnamara.com","permalink":"/users/75-2d29fadfaf8ddfaee0b69b563bae8d2d/","section":"Users","summary":"","title":"Hudson McNamara","type":"users"},{"content":"","externalUrl":"https://www.wegumweg.de","permalink":"/users/76-eb23ebd26738c98db323eff207dc7c0e/","section":"Users","summary":"","title":"Weg um Weg","type":"users"},{"content":"","externalUrl":"https://panoskorovesis.github.io/","permalink":"/users/77-706590b7d6a58b77f0eadb22b1dc6cd5/","section":"Users","summary":"","title":"The Space 🌍","type":"users"},{"content":"","externalUrl":"https://blog.francescopapini.com","permalink":"/users/78-a615163aad4c6bb5746a697a9450d563/","section":"Users","summary":"","title":"blog.francescopapini.com","type":"users"},{"content":"","externalUrl":"https://adriantunez.cloud","permalink":"/users/79-6057b72b4986ae88640d46262a4be0a0/","section":"Users","summary":"","title":"Adri Antunez's Cloud Site","type":"users"},{"content":"","externalUrl":"https://irusukan.com","permalink":"/users/80-e3f304eacd2f79e31f294cae0ff8162e/","section":"Users","summary":"","title":"irusukan","type":"users"},{"content":"","externalUrl":"https://feec-seminar-comp-eng.github.io/","permalink":"/users/81-405727a6fae1350173ef8915b4c9eb7d/","section":"Users","summary":"","title":"FEEC/UNICAMP IA382 - Seminar in Computer Engineering","type":"users"},{"content":"","externalUrl":"https://blog.francescopapini.com","permalink":"/users/82-a615163aad4c6bb5746a697a9450d563/","section":"Users","summary":"","title":"blog.francescopapini.com","type":"users"},{"content":"","externalUrl":"https://heykyo.com","permalink":"/users/83-9d162f4046cb83c367d8d8ab57240711/","section":"Users","summary":"","title":"Kyo's Garden","type":"users"},{"content":"","externalUrl":"https://abantikabhuti.github.io","permalink":"/users/84-7c98d8b7ba531e032abcd675d4f49c17/","section":"Users","summary":"","title":"abantikabhuti.github.io","type":"users"},{"content":"","externalUrl":"https://yag0x1.github.io","permalink":"/users/85-e4f1c9a4c352ea63707824576d889c8f/","section":"Users","summary":"","title":"yag0x1.github.io","type":"users"},{"content":"","externalUrl":"https://mitri.lol","permalink":"/users/86-8cb20b5823049623e2b7214c967a2efc/","section":"Users","summary":"","title":"mitri.lol","type":"users"},{"content":"","externalUrl":"https://kieranlowe.io","permalink":"/users/87-b94f03ec7b2e6d8dbac26fa6cd1cd5d4/","section":"Users","summary":"","title":"kieranlowe.io","type":"users"},{"content":"","externalUrl":"https://eike.in","permalink":"/users/88-c3df142090b1a28ef311312eb82f1e51/","section":"Users","summary":"","title":"eike.in","type":"users"},{"content":"","externalUrl":"https://metalhearf.fr","permalink":"/users/89-16a262b9921c2d90b4bc072bbb3c1d56/","section":"Users","summary":"","title":"metalhearf.fr","type":"users"},{"content":"","externalUrl":"https://encelo.github.io/","permalink":"/users/90-a8ae3ddde64e0cd053837877522e2373/","section":"Users","summary":"","title":"encelo.github.io","type":"users"},{"content":"","externalUrl":"https://ncine.github.io/","permalink":"/users/91-8f0822721042bca88707da31b1c241e3/","section":"Users","summary":"","title":"ncine.github.io","type":"users"},{"content":"","externalUrl":"https://www.merza.is/","permalink":"/users/92-f430dff82b8fbb8334091953bfe58598/","section":"Users","summary":"","title":"István Merza","type":"users"},{"content":"","externalUrl":"https://daytaur.com/","permalink":"/users/93-a8326fb0e2d1670165af1c6547b239dd/","section":"Users","summary":"","title":"daytaur.com","type":"users"},{"content":"","externalUrl":"https://zzamboni.org/","permalink":"/users/94-e2d4a1e205128436961ad3e1f2d0de5e/","section":"Users","summary":"","title":"zzamboni.org","type":"users"},{"content":"","externalUrl":"https://www.towerofkubes.com/","permalink":"/users/95-43b666016e50920826ef05ae95486724/","section":"Users","summary":"","title":"Tower of Kubes","type":"users"},{"content":"","externalUrl":"https://monpetitdev.fr/","permalink":"/users/96-d168a95bef76f9306c5f0d645168f8e6/","section":"Users","summary":"","title":"monpetitdev.fr","type":"users"},{"content":"","externalUrl":"https://noorkhafidzin.com/","permalink":"/users/97-e7ef7b552aa65b10f3e26de21d81f702/","section":"Users","summary":"","title":"Noor Khafidzin","type":"users"},{"content":"","externalUrl":"https://reyneese.com/","permalink":"/users/98-834393216bdba408631c891ee45d379c/","section":"Users","summary":"","title":"Reyneese on WoW","type":"users"},{"content":"","externalUrl":"https://goodjinc.com/","permalink":"/users/99-850f485eb8e81e2873f1a285e3eb0b1d/","section":"Users","summary":"","title":"GOODJINC","type":"users"},{"content":"","externalUrl":"https://tyloch.biz/","permalink":"/users/100-2496d52e0aa601cbba3ad6572e007d26/","section":"Users","summary":"","title":"Artur Tyloch","type":"users"},{"content":"","externalUrl":"https://blog.rewse.jp/","permalink":"/users/101-860d9db7030d829b0f0128400c2ab5d4/","section":"Users","summary":"","title":"Tats Shibata","type":"users"},{"content":"","externalUrl":"https://prusa.net/","permalink":"/users/102-118f0958fbab30b68d5bb3359548a40f/","section":"Users","summary":"","title":"Radek Průša","type":"users"},{"content":"","externalUrl":"https://jbetzen.net/","permalink":"/users/103-bbc5b87f25e67eb50f9308ddb2e30fb3/","section":"Users","summary":"","title":"jbetzen.net","type":"users"},{"content":"","externalUrl":"https://alst.ovh/","permalink":"/users/104-578198405817d000a9b09d08fe594b1f/","section":"Users","summary":"","title":"alst.ovh","type":"users"},{"content":"","externalUrl":"https://blog.zynji.my.id/","permalink":"/users/105-853c2c3c85eecb5148db16a8f005a529/","section":"Users","summary":"","title":"Zarvelion Zynji","type":"users"},{"content":"","externalUrl":"https://www.airikatrading.com","permalink":"/users/106-2e8cdaa29760febdf1d75307255aafe9/","section":"Users","summary":"","title":"Airika","type":"users"},{"content":"","externalUrl":"https://cooklikeanerd.com/","permalink":"/users/107-ae148b43ea1a0101066984d0d6d321c0/","section":"Users","summary":"","title":"Cook Like A Nerd","type":"users"},{"content":"","externalUrl":"https://cintiaching.com/","permalink":"/users/108-577a9817320654ddbf1030cbf1c9ca7f/","section":"Users","summary":"","title":"Cintia Ching","type":"users"},{"content":"","externalUrl":"https://luizcarloscf.github.io/","permalink":"/users/109-704dd03d684dfd9eef53eb6072fef261/","section":"Users","summary":"","title":"luizcarloscf.github.io","type":"users"},{"content":"","externalUrl":"https://fairchild26.github.io/","permalink":"/users/110-92babc5577690a161170943a87ae816d/","section":"Users","summary":"","title":"Robin Fairchild","type":"users"},{"content":"","externalUrl":"https://paraguay4life.com/","permalink":"/users/111-9a4fa7947ad8e197f14bc3d89c98a755/","section":"Users","summary":"","title":"Paraguay4Life","type":"users"},{"content":"","externalUrl":"https://www.gsking.co.uk","permalink":"/users/112-fb2885fb36e97b3799ab7bc03bd9e08a/","section":"Users","summary":"","title":"www.gsking.co.uk","type":"users"},{"content":"","externalUrl":"https://storySeedLibrary.org/","permalink":"/users/113-c7fe2437cad52bb0686e75dd3a087db7/","section":"Users","summary":"","title":"Story Seed Library","type":"users"},{"content":"","externalUrl":"https://www.azriel.id/","permalink":"/users/114-4e4190a01d423f152e7f6cbe8eb856cd/","section":"Users","summary":"","title":"www.azriel.id","type":"users"},{"content":"","externalUrl":"https://douwez.dev","permalink":"/users/115-e87e841623f5c97464db030fe1369ad5/","section":"Users","summary":"","title":"Douwe Zumker","type":"users"},{"content":"","externalUrl":"https://fionnlinux.com","permalink":"/users/116-4ff91a53ea73c604f10d70eac8cb3f9a/","section":"Users","summary":"","title":"fionnlinux.com","type":"users"},{"content":"","externalUrl":"https://techtrailpulse.com","permalink":"/users/117-0f9795e2737d936e7cb966b67bf406d5/","section":"Users","summary":"","title":"Tech Trail Pulse","type":"users"},{"content":"","externalUrl":"https://clmbooks.org","permalink":"/users/118-0eeb7aad8a5b43eefbace7d1671f4173/","section":"Users","summary":"","title":"Christian Living Ministries Books","type":"users"},{"content":"","externalUrl":"https://blog.nordbye.it/","permalink":"/users/119-cdbb83b9de2176ac468416802e61d6df/","section":"Users","summary":"","title":"blog.nordbye.it","type":"users"},{"content":"","externalUrl":"https://sebastianzehner.com","permalink":"/users/120-4a642690daddb956e55559033a05169a/","section":"Users","summary":"","title":"Sebastian Zehner","type":"users"},{"content":"","externalUrl":"https://tobydevlin.com","permalink":"/users/121-0b031dfc872b30be5424e3e0a97ceb5a/","section":"Users","summary":"","title":"tobydevlin.com","type":"users"},{"content":"","externalUrl":"https://chandlerthompson.dev","permalink":"/users/122-78c3c80b618b24c7a4b4858a4bd5bba1/","section":"Users","summary":"","title":"chandlerthompson.dev","type":"users"},{"content":"","externalUrl":"https://scottkuperus.com","permalink":"/users/123-8055e20f8513c7ab07eea07f78da3fdc/","section":"Users","summary":"","title":"scottkuperus.com","type":"users"},{"content":"","externalUrl":"https://libreleo.com","permalink":"/users/124-113e14a4e9726eca5f662b836716d547/","section":"Users","summary":"","title":"LibreLeo","type":"users"},{"content":"","externalUrl":"https://chius.cc/","permalink":"/users/125-d64c08db0db65bafca08cb3158926cb8/","section":"Users","summary":"","title":"chius.cc","type":"users"},{"content":"","externalUrl":"https://russellchubb.com","permalink":"/users/126-1b82e9707d95718be8cc0a9e7f745fe9/","section":"Users","summary":"","title":"RussellChubb.com","type":"users"},{"content":"","externalUrl":"https://or1k.net","permalink":"/users/127-0d9fac078a5be287478b949c021738a8/","section":"Users","summary":"","title":"or1k.net","type":"users"},{"content":"","externalUrl":"https://yannick.services","permalink":"/users/128-235c06b122aca1f524cdce15e8d6434a/","section":"Users","summary":"","title":"yannick.services","type":"users"},{"content":"","externalUrl":"https://brunowollmann.com","permalink":"/users/129-3df98ce1335e5fa19060fab48b73e371/","section":"Users","summary":"","title":"Bruno Wollmann on Networking","type":"users"},{"content":"","externalUrl":"https://usttaraf.com","permalink":"/users/130-fae623b5364eeb533cf5045d83a19821/","section":"Users","summary":"","title":"Üst Taraf","type":"users"},{"content":"","externalUrl":"https://blog.siyalight.com","permalink":"/users/131-819b5e408825ddaa2c9be60b33544c05/","section":"Users","summary":"","title":"Siya's Blog","type":"users"},{"content":"","date":"26 Januarie 2026","externalUrl":null,"permalink":"/ansible/","section":"Ansibles","summary":"","title":"Ansibles","type":"ansible"},{"content":"","date":"26 Januarie 2026","externalUrl":null,"permalink":"/tags/appendix/","section":"Tags","summary":"","title":"Appendix","type":"tags"},{"content":"","date":"26 Januarie 2026","externalUrl":null,"permalink":"/tags/commando/","section":"Tags","summary":"","title":"Commando","type":"tags"},{"content":"","date":"26 Januarie 2026","externalUrl":null,"permalink":"/tags/containers/","section":"Tags","summary":"","title":"Containers","type":"tags"},{"content":"","date":"26 Januarie 2026","externalUrl":null,"permalink":"/tags/docker/","section":"Tags","summary":"","title":"Docker","type":"tags"},{"content":"","date":"26 Januarie 2026","externalUrl":null,"permalink":"/docker/","section":"Dockers","summary":"","title":"Dockers","type":"docker"},{"content":"","date":"26 Januarie 2026","externalUrl":null,"permalink":"/tags/git/","section":"Tags","summary":"","title":"Git","type":"tags"},{"content":"","date":"26 Januarie 2026","externalUrl":null,"permalink":"/tags/github/","section":"Tags","summary":"","title":"GitHub","type":"tags"},{"content":"","date":"26 Januarie 2026","externalUrl":null,"permalink":"/git/","section":"Gits","summary":"","title":"Gits","type":"git"},{"content":"","date":"26 Januarie 2026","externalUrl":null,"permalink":"/tags/installatie/","section":"Tags","summary":"","title":"Installatie","type":"tags"},{"content":"","date":"26 Januarie 2026","externalUrl":null,"permalink":"/tags/introductie/","section":"Tags","summary":"","title":"Introductie","type":"tags"},{"content":"","date":"26 Januarie 2026","externalUrl":null,"permalink":"/tags/oefeningen/","section":"Tags","summary":"","title":"Oefeningen","type":"tags"},{"content":"","date":"26 Januarie 2026","externalUrl":null,"permalink":"/tags/portainer/","section":"Tags","summary":"","title":"Portainer","type":"tags"},{"content":"Blowfish has full support for Hugo taxonomies and will adapt to any taxonomy set up. Taxonomy listings like this one also support custom content to be displayed above the list of terms.\nThis area could be used to add some extra descriptive text to each taxonomy. Check out the advanced tag below to see how to take this concept even further.\n","date":"26 Januarie 2026","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"26 Januarie 2026","externalUrl":null,"permalink":"/tags/versiebeheer/","section":"Tags","summary":"","title":"Versiebeheer","type":"tags"},{"content":"","date":"26 Januarie 2026","externalUrl":null,"permalink":"/tags/voorbeelden/","section":"Tags","summary":"","title":"Voorbeelden","type":"tags"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/agile/","section":"Agiles","summary":"","title":"Agiles","type":"agile"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/tags/anders/","section":"Tags","summary":"","title":"Anders","type":"tags"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/ci-cd/","section":"Ci-Cds","summary":"","title":"Ci-Cds","type":"ci-cd"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/tags/cloud/","section":"Tags","summary":"","title":"Cloud","type":"tags"},{"content":" Details over het project # De evaluatie van het praktijkexamen/project bestaat uit 3 onderdelen.\nPresentatie # Jij (en je team) maken een PowerPoint-presentatie om je project verder te verduidelijken. Deze zal in ieder geval de volgende onderwerpen bevatten:\nLeg de usecase van het project uit: Waarom heb je voor dit specifieke project gekozen? Leg uit welke bouwstenen binnen je project worden gebruikt (bijv. Terraform/Ansible voor implementatie, LibreNMS voor monitoring,\u0026hellip;) en welke pakketten je hebt gebruikt (bijv. heb je Docker of Apache gebruikt voor de webserver,\u0026hellip;). Rollen en verantwoordelijkheden: Als je ervoor hebt gekozen om het project in teamverband uit te voeren, hoe was het werk dan binnen je team verdeeld? Wie was verantwoordelijk voor welk deel van het project? Pro tip: Je kunt bijvoorbeeld het kanbanbord gebruiken dat je tijdens het project hebt gebruikt. Leerpunten: Welke kennis heb je opgedaan tijdens het project? Ben je tijdens de implementatie van je project tegen problemen en/of uitdagingen aangelopen? Hoe heb je die aangepakt? Vat ze samen in 1 of 2 dia\u0026rsquo;s. Live demo # Jij en je team laten zien hoe de applicatie werkt tijdens een live demo. Je implementeert je applicatie volledig opnieuw om aan te tonen dat je de juiste tools en technieken hebt gebruikt die je hebt geleerd.\nDit betekent dat je je moet concentreren op het DevOps/implementatiegedeelte en minder op de applicatie/tool ​​zelf. Je hoeft alleen aan te tonen dat de geïmplementeerde applicatie werkt (bijvoorbeeld door een inlogscherm te tonen en in te loggen op de applicatie, in te loggen op de gameserver,\u0026hellip;).\nDe volgende componenten moeten verplicht getoond worden:\nAutomatisering: Automatiseer de implementatie en configuratie van je gekozen applicatie. Monitoring: Laat zien dat de assets die je hebt geïmplementeerd correct worden gemonitord. De monitoringhost zelf hoeft niet opnieuw te worden geïmplementeerd. Je moet je applicatiehosts automatisch aan je monitoringoplossing kunnen toevoegen. (Dit kan bijvoorbeeld via een API.) Documentatie # Documentatie is een integraal onderdeel van elk project. Het documentatiebestand kan worden geüpload naar de DevOps-map in de Canvas-cursus (link naar de Canvas-omgeving van Thomas More).\nDe documentatie bevat de volgende elementen:\nData flow design: Dit diagram toont alle componenten die u in uw projecten hebt gebruikt en welke protocollen er tussen de verschillende componenten worden gebruikt.\nVervolgens leg je de technische componenten en code van jouw project uit.\nLeg alle code (Ansible/Terraform) uit die binnen het project wordt gebruikt. Leg uit welke monitoring er wordt uitgevoerd en welke statistieken er worden gemonitord. Leg uit welke API-query\u0026rsquo;s er worden uitgevoerd. \u0026hellip; ","date":"25 Januarie 2026","externalUrl":null,"permalink":"/inleiding/evaluatie/","section":"Inleidings","summary":"","title":"Evaluatie","type":"inleiding"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/tags/examens/","section":"Tags","summary":"","title":"Examens","type":"tags"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/tags/grafana/","section":"Tags","summary":"","title":"Grafana","type":"tags"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/tags/inleiding/","section":"Tags","summary":"","title":"Inleiding","type":"tags"},{"content":" In deze sectie maak je kennis met de basisprincipes van Agile werken en de belangrijkste begrippen binnen Scrum en Kanban. Agile fundamenten # **Term****Definitie****Agile manifesto**Een reeks uitspraken met **vier waarden** en **twaalf principes** die bedoeld zijn om u te helpen een Agile mindset te omarmen**Kanban**een **planningssysteem** dat wordt gebruikt in lean manufacturing; past lean thinking toe op softwareontwikkeling**Producteigenaar**persoon die verantwoordelijk is voor het bepalen van de richting en het prioriteren van het werk**Scrum**het meest populaire Agile-framework**Scrum Master**Scrum master zorgt ervoor dat de voortgang wordt bijgehouden en voor iedereen zichtbaar is en moedigt het team aan om meer verantwoordelijkheid te nemen. **Takenbord**een eenvoudig zwembanen-diagram dat kleine hoeveelheden werk weergeeft.**Watervalbenadering**stapsgewijze aanpak met specifieke richtlijnen. Agile Manifest : Principes # Het Agile Manifesto kent zijn oorsprong in 2001. Toen afvaardiging van tal van Agile software development methodologies en sympathisanten van een alternatief voor de klassieke, documentatie gerichte, zware software development processen, kwamen samen om hierover van gedachten te wisselen. Resultaat: [het Agile Manifesto (opens new window)](http://agilemanifesto.org/)! Wat stond er in dit manifesto? 12 punten over hoe we software moeten ontwikkelen.\nWe volgen de volgende principes: # #### 1 ##### **Onze hoogste prioriteit is het tevredenstellen van de klant door het vroegtijdig en voortdurend opleveren van waardevolle software.** #### 2 ##### **Verwelkom veranderende behoeftes, zelfs laat in het ontwikkelproces.** **Agile processen benutten verandering tot concurrentievoordeel van de klant.** #### 3 ##### **Lever regelmatig werkende software op. Liefst iedere paar weken, hooguit iedere paar maanden.** #### 4 ##### **Mensen uit de business en ontwikkelaars moeten dagelijks samenwerken gedurende het gehele project.** #### 5 ##### **Bouw projecten rond gemotiveerde individuen. Geef hen de omgeving en ondersteuning die ze nodig hebben en vertrouw erop dat ze de klus klaren.** #### 6 ##### **De meest efficiënte en effectieve manier om informatie te delen in en met een ontwikkelteam is door met elkaar te praten. ** #### 7 ##### **Werkende software is de belangrijkste maat voor voortgang.** #### 8 ##### **Agile processen bevorderen constante ontwikkeling. De opdrachtgevers, ontwikkelaars en gebruikers moeten een constant tempo eeuwig kunnen volhouden.** #### 9 ##### **Voortdurende aandacht voor een hoge technische kwaliteit en voor een goed ontwerp versterken agility.** #### 10 ##### **Eenvoud, de kunst van het maximaliseren van het werk dat niet gedaan wordt, is essentieel.** #### 11 ##### **De beste architecturen, eisen en ontwerpen komen voort uit zelfsturende teams.** #### 12 ##### **Op vaste tijden, onderzoekt het team hoe het effectiever kan worden en past vervolgens zijn gedrag daarop aan.** Deze methodes legden de grondslag van een nieuwe werkwijze voor software development op. We merken enkele gelijkenissen met LEAN maar ook grote verschillen. Agile focust echter niet op grote schaal werken maar ik kleine teams snel kunnen opleveren en aanpassen.\nHoe dit de bereiken in de praktijk? Dat zien we verder in SCRUM en Kanban.\nRelatie Tussen DevOps en Agile # DevOps bouwt voort op Agile-principes en -praktijken. Agile richt zich op iteratieve ontwikkeling en snelle feedback, terwijl DevOps zich uitbreidt naar de implementatie en operationele aspecten van softwarelevering.\n** Uitgebreide uitleg: **\nAgile en DevOps zijn nauw verwant, maar ze zijn niet hetzelfde. Agile is een softwareontwikkelingsmethodiek die zich richt op iteratieve ontwikkeling, snelle feedback en klantgerichtheid. DevOps breidt Agile-principes uit naar de gehele software delivery lifecycle, inclusief implementatie en beheer. DevOps kan worden gezien als een uitbreiding van Agile, die zich richt op het automatiseren en optimaliseren van de processen die nodig zijn om software te releasen en te beheren.\nAnalogie:\nStel je voor dat je een huis bouwt. Agile is als het bouwen van de fundering en de muren van het huis. DevOps is als het installeren van de elektriciteit, het sanitair en de afwerkingen, en het zorgen dat het huis bewoonbaar is.\nVoorbeeld:\nEen team dat Agile toepast, werkt in sprints van twee weken om nieuwe features te ontwikkelen. Aan het einde van elke sprint wordt een werkende versie van de software opgeleverd. Een team dat DevOps toepast, automatiseert het build-, test- en implementatieproces, zodat de software na elke sprint automatisch kan worden geïmplementeerd in een testomgeving.\nKey Takeaways:\nDevOps bouwt voort op Agile-principes en -praktijken. DevOps breidt Agile uit naar de implementatie en operationele aspecten van softwarelevering. ","date":"25 Januarie 2026","externalUrl":null,"permalink":"/agile/agile/","section":"Agiles","summary":"","title":"Inleiding: Agile","type":"agile"},{"content":" Admonition # Admonitions allow you to insert eye-catching callout boxes in your content.\nAdmonitions serve a similar purpose as the alert shortcode but are implemented via Hugo render hooks. The key difference is syntax: admonitions use Markdown syntax, making them more portable across different platforms, whereas shortcodes are specific to Hugo. The syntax resembles GitHub alerts:\n\u0026gt; [!TIP] \u0026gt; A Tip type admonition. Custom Title + Custom Icon A collapsible admonition with custom title.\nThe alert sign (+ or -) is optional to control whether the admonition is folded or not. Note that alert sign is only compatible in Obsidian.\nSupported types Valid admonition types include GitHub alert types and Obsidian callout types. The types are case-insensitive.\nThis is an error! Call to action Make it yours Start from a thoughtful default, then adjust every meaningful detail. Learn more Publish faster Compose rich content with small, reusable building blocks. Browse shortcodes Built for people Accessible defaults, responsive layouts, and dark mode included. 40+\nShortcodes\nCompose pages without bespoke templates. 100%\nPortable\nKeep your content in Markdown. 0\nRequired plugins\nStart with Hugo and Blowfish. 1 Configure the theme Choose a colour scheme and homepage layout. 2 Write your content Use standard Markdown and shortcodes. Details What is included? Responsive behaviour Accessible markup JavaScript Python Go console.log(\u0026#34;Hello\u0026#34;); print(\u0026#34;Hello\u0026#34;) fmt.Println(\u0026#34;Hello\u0026#34;) JavaScript Python Go const add = (a, b) =\u0026gt; a + b; def add(a, b): return a + b func add(a, b int) int { return a + b } header badge test subheader Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus non magna ex. Donec sollicitudin ut lorem quis lobortis. Nam ac ipsum libero. Sed a ex eget ipsum tincidunt venenatis quis sed nisl. Pellentesque sed urna vel odio consequat tincidunt id ut purus. Nam sollicitudin est sed dui interdum rhoncus. Another Awesome Header date - present Awesome Subheader With html code Coffee Tea Milk Shortcodes AWESOME With other shortcodes Example #1:\n{{\u0026lt; list limit=2 \u0026gt;}} Example #2:\n{{\u0026lt; list title=\u0026#34;Samples\u0026#34; cardView=true limit=6 where=\u0026#34;Type\u0026#34; value=\u0026#34;sample\u0026#34; \u0026gt;}} LTR/RTL # ltr and rtl allows you to mix your contents. Many RTL language users want to include parts of the content in LTR. Using this shortcode will let you do so, and by leveraging % as the outer-most dilemeter in the shortcode Hugo shortcodes, any markdown inside will be rendered normally.\nExample:\n- This is an markdown list. - Its per default a LTR direction {{% rtl %}} - هذه القائمة باللغة العربية - من اليمين الى اليسار {{% /rtl %}} This is an markdown list. Its per default a LTR direction هذه القائمة باللغة العربية من اليمين الى اليسار Mermaid # mermaid allows you to draw detailed diagrams and visualisations using text. It uses Mermaid under the hood and supports a wide variety of diagrams, charts and other output formats.\nSimply write your Mermaid syntax within the mermaid shortcode and let the plugin do the rest.\nRefer to the official Mermaid docs for details on syntax and supported diagram types.\nExample:\n{{\u0026lt; mermaid \u0026gt;}} graph LR; A[Lemons]--\u0026gt;B[Lemonade]; B--\u0026gt;C[Profit] {{\u0026lt; /mermaid \u0026gt;}} graph LR; A[Lemons]--\u003eB[Lemonade]; B--\u003eC[Profit] Stats # Use stats and stat to present concise, high-signal metrics in a responsive grid. The grid uses three columns on large screens by default, or four with columns=\u0026quot;4\u0026quot;.\n{{\u0026lt; stats \u0026gt;}} {{\u0026lt; stat value=\u0026#34;40+\u0026#34; label=\u0026#34;Shortcodes\u0026#34; \u0026gt;}}Compose pages without bespoke templates.{{\u0026lt; /stat \u0026gt;}} {{\u0026lt; stat value=\u0026#34;100%\u0026#34; label=\u0026#34;Portable\u0026#34; \u0026gt;}}Keep your content in Markdown.{{\u0026lt; /stat \u0026gt;}} {{\u0026lt; stat value=\u0026#34;0\u0026#34; label=\u0026#34;Required plugins\u0026#34; \u0026gt;}}Start with Hugo and Blowfish.{{\u0026lt; /stat \u0026gt;}} {{\u0026lt; /stats \u0026gt;}} 40+\nShortcodes\nCompose pages without bespoke templates. 100%\nPortable\nKeep your content in Markdown. 0\nRequired plugins\nStart with Hugo and Blowfish. Steps # Use steps and step for onboarding, processes, roadmaps, and tutorials.\n{{\u0026lt; steps \u0026gt;}} {{\u0026lt; step number=\u0026#34;1\u0026#34; title=\u0026#34;Configure the theme\u0026#34; \u0026gt;}}Choose a colour scheme and homepage layout.{{\u0026lt; /step \u0026gt;}} {{\u0026lt; step number=\u0026#34;2\u0026#34; title=\u0026#34;Write your content\u0026#34; \u0026gt;}}Use standard Markdown and shortcodes.{{\u0026lt; /step \u0026gt;}} {{\u0026lt; /steps \u0026gt;}} 1 Configure the theme Choose a colour scheme and homepage layout. 2 Write your content Use standard Markdown and shortcodes. Swatches # swatches outputs a set of up to three different colors to showcase color elements like a color palette. This shortcode takes the HEX codes of each color and creates the visual elements for each.\nExample\n{{\u0026lt; swatches \u0026#34;#64748b\u0026#34; \u0026#34;#3b82f6\u0026#34; \u0026#34;#06b6d4\u0026#34; \u0026gt;}} Output Tabs # The tabs shortcode is commonly used to present different variants of a particular step. For example, it can be used to show how to install VS Code on different platforms.\nParameter Description group Optional. Group name for synchronized tab switching. All tabs with the same group name will switch together. default Optional. Label of the tab to be active by default. If not set, the first tab will be active. label Required. The text label displayed on the tab button. icon Optional. Icon name to display before the label. md Optional. Render tab content as Markdown (default true). Use md=false when the content is already HTML. Example 1: Basic Usage\n{{\u0026lt; tabs \u0026gt;}} {{\u0026lt; tab label=\u0026#34;Windows\u0026#34; \u0026gt;}} Install using Chocolatey: ```pwsh choco install vscode.install ``` or install using WinGet ```pwsh winget install -e --id Microsoft.VisualStudioCode ``` {{\u0026lt; /tab \u0026gt;}} {{\u0026lt; tab label=\u0026#34;macOS\u0026#34; \u0026gt;}} ```bash brew install --cask visual-studio-code ``` {{\u0026lt; /tab \u0026gt;}} {{\u0026lt; tab label=\u0026#34;Linux\u0026#34; \u0026gt;}} {{\u0026lt; alert \u0026gt;}}See [documentation](https://code.visualstudio.com/docs/setup/linux#_install-vs-code-on-linux).{{\u0026lt; /alert \u0026gt;}} {{\u0026lt; /tab \u0026gt;}} {{\u0026lt; /tabs \u0026gt;}} Output\nWindows macOS Linux Install using Chocolatey:\nchoco install vscode.install or install using WinGet\nwinget install -e --id Microsoft.VisualStudioCode brew install --cask visual-studio-code See documentation. Nested shortcodes are supported with the default Markdown behaviour. For example, an accordion can live inside a tab without its generated HTML being rendered as Markdown a second time:\n{{\u0026lt; tabs \u0026gt;}} {{\u0026lt; tab label=\u0026#34;Details\u0026#34; \u0026gt;}} {{\u0026lt; accordion mode=\u0026#34;open\u0026#34; \u0026gt;}} {{\u0026lt; accordionItem title=\u0026#34;What is included?\u0026#34; \u0026gt;}} - Responsive behaviour - Accessible markup {{\u0026lt; /accordionItem \u0026gt;}} {{\u0026lt; /accordion \u0026gt;}} {{\u0026lt; /tab \u0026gt;}} {{\u0026lt; /tabs \u0026gt;}} Details What is included? Responsive behaviour Accessible markup Example 2: With Group, Default, and Icon\n{{\u0026lt; tabs group=\u0026#34;lang\u0026#34; default=\u0026#34;Python\u0026#34; \u0026gt;}} {{\u0026lt; tab label=\u0026#34;JavaScript\u0026#34; icon=\u0026#34;code\u0026#34; \u0026gt;}} ```javascript console.log(\u0026#34;Hello\u0026#34;); ``` {{\u0026lt; /tab \u0026gt;}} {{\u0026lt; tab label=\u0026#34;Python\u0026#34; icon=\u0026#34;sun\u0026#34; \u0026gt;}} ```python print(\u0026#34;Hello\u0026#34;) ``` {{\u0026lt; /tab \u0026gt;}} {{\u0026lt; tab label=\u0026#34;Go\u0026#34; icon=\u0026#34;moon\u0026#34; \u0026gt;}} ```go fmt.Println(\u0026#34;Hello\u0026#34;) ``` {{\u0026lt; /tab \u0026gt;}} {{\u0026lt; /tabs \u0026gt;}} {{\u0026lt; tabs group=\u0026#34;lang\u0026#34; default=\u0026#34;Python\u0026#34; \u0026gt;}} {{\u0026lt; tab label=\u0026#34;JavaScript\u0026#34; icon=\u0026#34;code\u0026#34; \u0026gt;}} ```javascript const add = (a, b) =\u0026gt; a + b; ``` {{\u0026lt; /tab \u0026gt;}} {{\u0026lt; tab label=\u0026#34;Python\u0026#34; icon=\u0026#34;sun\u0026#34; \u0026gt;}} ```python def add(a, b): return a + b ``` {{\u0026lt; /tab \u0026gt;}} {{\u0026lt; tab label=\u0026#34;Go\u0026#34; icon=\u0026#34;moon\u0026#34; \u0026gt;}} ```go func add(a, b int) int { return a + b } ``` {{\u0026lt; /tab \u0026gt;}} {{\u0026lt; /tabs \u0026gt;}} Output\nJavaScript Python Go console.log(\u0026#34;Hello\u0026#34;); print(\u0026#34;Hello\u0026#34;) fmt.Println(\u0026#34;Hello\u0026#34;) JavaScript Python Go const add = (a, b) =\u0026gt; a + b; def add(a, b): return a + b func add(a, b int) int { return a + b } In this example, both tab groups share the same group=\u0026quot;lang\u0026quot; parameter, so clicking any tab will synchronize both groups. The default=\u0026quot;Python\u0026quot; parameter makes Python the initially active tab, and icon=\u0026quot;code\u0026quot; adds an icon before each label.\n40+\nShortcodes\nCompose pages without bespoke templates. 100%\nPortable\nKeep your content in Markdown. 0\nRequired plugins\nStart with Hugo and Blowfish. 1 Configure the theme Choose a colour scheme and homepage layout. 2 Write your content Use standard Markdown and shortcodes. In this example, both tab groups share the same group=\u0026quot;lang\u0026quot; parameter, so clicking any tab will synchronize both groups. The default=\u0026quot;Python\u0026quot; parameter makes Python the initially active tab, and icon=\u0026quot;code\u0026quot; adds an icon before each label.\nTimeline # The timeline creates a visual timeline that can be used in different use-cases, e.g. professional experience, a project\u0026rsquo;s achievements, etc. The timeline shortcode relies on the timelineItem sub-shortcode to define each item within the main timeline. Each item can have the following properties.\nParameter Description md render the content as Markdown (true/false) icon the icon to be used in the timeline visuals header header for each entry badge text to place within the top right badge subheader entry\u0026rsquo;s subheader Example:\n{{\u0026lt; timeline \u0026gt;}} {{\u0026lt; timelineItem icon=\u0026#34;github\u0026#34; header=\u0026#34;header\u0026#34; badge=\u0026#34;badge test\u0026#34; subheader=\u0026#34;subheader\u0026#34; \u0026gt;}} Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus non magna ex. Donec sollicitudin ut lorem quis lobortis. Nam ac ipsum libero. Sed a ex eget ipsum tincidunt venenatis quis sed nisl. Pellentesque sed urna vel odio consequat tincidunt id ut purus. Nam sollicitudin est sed dui interdum rhoncus. {{\u0026lt; /timelineItem \u0026gt;}} {{\u0026lt; timelineItem icon=\u0026#34;code\u0026#34; header=\u0026#34;Another Awesome Header\u0026#34; badge=\u0026#34;date - present\u0026#34; subheader=\u0026#34;Awesome Subheader\u0026#34; \u0026gt;}} With html code \u0026lt;ul\u0026gt; \u0026lt;li\u0026gt;Coffee\u0026lt;/li\u0026gt; \u0026lt;li\u0026gt;Tea\u0026lt;/li\u0026gt; \u0026lt;li\u0026gt;Milk\u0026lt;/li\u0026gt; \u0026lt;/ul\u0026gt; {{\u0026lt; /timelineItem \u0026gt;}} {{\u0026lt; timelineItem icon=\u0026#34;star\u0026#34; header=\u0026#34;Shortcodes\u0026#34; badge=\u0026#34;AWESOME\u0026#34; \u0026gt;}} With other shortcodes {{\u0026lt; gallery \u0026gt;}} \u0026lt;img src=\u0026#34;gallery/01.jpg\u0026#34; class=\u0026#34;grid-w33\u0026#34; /\u0026gt; \u0026lt;img src=\u0026#34;gallery/02.jpg\u0026#34; class=\u0026#34;grid-w33\u0026#34; /\u0026gt; \u0026lt;img src=\u0026#34;gallery/03.jpg\u0026#34; class=\u0026#34;grid-w33\u0026#34; /\u0026gt; \u0026lt;img src=\u0026#34;gallery/04.jpg\u0026#34; class=\u0026#34;grid-w33\u0026#34; /\u0026gt; \u0026lt;img src=\u0026#34;gallery/05.jpg\u0026#34; class=\u0026#34;grid-w33\u0026#34; /\u0026gt; \u0026lt;img src=\u0026#34;gallery/06.jpg\u0026#34; class=\u0026#34;grid-w33\u0026#34; /\u0026gt; \u0026lt;img src=\u0026#34;gallery/07.jpg\u0026#34; class=\u0026#34;grid-w33\u0026#34; /\u0026gt; {{\u0026lt; /gallery \u0026gt;}} {{\u0026lt; /timelineItem \u0026gt;}} {{\u0026lt; timelineItem icon=\u0026#34;code\u0026#34; header=\u0026#34;Another Awesome Header\u0026#34;\u0026gt;}} {{\u0026lt; github repo=\u0026#34;nunocoracao/blowfish\u0026#34; \u0026gt;}} {{\u0026lt; /timelineItem \u0026gt;}} {{\u0026lt; /timeline \u0026gt;}} header badge test subheader Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus non magna ex. Donec sollicitudin ut lorem quis lobortis. Nam ac ipsum libero. Sed a ex eget ipsum tincidunt venenatis quis sed nisl. Pellentesque sed urna vel odio consequat tincidunt id ut purus. Nam sollicitudin est sed dui interdum rhoncus. Another Awesome Header date - present Awesome Subheader With html code Coffee Tea Milk Shortcodes AWESOME With other shortcodes TypeIt # TypeIt is the most versatile JavaScript tool for creating typewriter effects on the planet. With a straightforward configuration, it allows you to type single or multiple strings that break lines, delete \u0026amp; replace each other, and it even handles strings that contain complex HTML.\nBlowfish implements a sub-set of TypeIt features using a shortcode. Write your text within the typeit shortcode and use the following parameters to configure the behavior you want.\nParameter Description tag [String] html tag that will be used to render the strings. classList [String] List of css classes to apply to the html element. initialString [String] Initial string that will appear written and will be replaced. speed [number] Typing speed, measured in milliseconds between each step. lifeLike [boolean] Makes the typing pace irregular, as if a real person is doing it. startDelay [number] The amount of time before the plugin begins typing after being initialized. breakLines [boolean] Whether multiple strings are printed on top of each other (true), or if they\u0026rsquo;re deleted and replaced by each other (false). waitUntilVisible [boolean] Determines if the instance will begin when loaded or only when the target element becomes visible in the viewport. The default is true loop [boolean] Whether your strings will continuously loop after completing Example 1:\n{{\u0026lt; typeit \u0026gt;}} Lorem ipsum dolor sit amet {{\u0026lt; /typeit \u0026gt;}} Example 2:\n{{\u0026lt; typeit tag=h1 lifeLike=true \u0026gt;}} Lorem ipsum dolor sit amet, consectetur adipiscing elit. {{\u0026lt; /typeit \u0026gt;}} Example 3:\n{{\u0026lt; typeit tag=h3 speed=50 breakLines=false loop=true \u0026gt;}} \u0026#34;Frankly, my dear, I don\u0026#39;t give a damn.\u0026#34; Gone with the Wind (1939) \u0026#34;I\u0026#39;m gonna make him an offer he can\u0026#39;t refuse.\u0026#34; The Godfather (1972) \u0026#34;Toto, I\u0026#39;ve a feeling we\u0026#39;re not in Kansas anymore.\u0026#34; The Wizard of Oz (1939) {{\u0026lt; /typeit \u0026gt;}} Video # Blowfish includes a video shortcode for embedding local or external videos in content. The shortcode renders a \u0026lt;figure\u0026gt; wrapper with a responsive video player and an optional caption.\nThe video shortcode accepts the following parameters:\nParameter Description src Required. Video URL or local path. Local lookup order: page resource → assets/ → static/. poster Optional poster image URL or local path. If omitted, the shortcode attempts a same-name image in the page bundle. caption Optional Markdown caption shown below the video. autoplay true/false. Enables autoplay when true. Default: false. loop true/false. Loops when true. Default: false. muted true/false. Mutes when true. Default: false. controls true/false. Shows the browser’s default playback controls when true. Default: true. playsinline true/false. Inline playback on mobile when true. Default: true. preload metadata (load info), none (save bandwidth), or auto (preload more). Default: metadata. start Optional start time in seconds. end Optional end time in seconds. ratio Reserved aspect ratio for the player. Supports 16/9, 4/3, 1/1, or custom W/H. Default: 16/9. fit How the video fits the ratio: contain (no crop), cover (crop to fill), fill (stretch). Default: contain. If the browser cannot play the video, the player will show a minimal English fallback message with a download link.\nExample:\n{{\u0026lt; video src=\u0026#34;https://upload.wikimedia.org/wikipedia/commons/5/5a/CC0_-_Public_Domain_Dedication_video_bumper.webm\u0026#34; poster=\u0026#34;https://upload.wikimedia.org/wikipedia/commons/e/e0/CC0.jpg\u0026#34; caption=\u0026#34;**Public domain demo** — CC0 video and poster.\u0026#34; loop=true muted=true \u0026gt;}} Your browser cannot play this video. Download video.\nPublic domain demo — CC0 video and poster. Youtube Lite # A shortcut to embed youtube videos using the lite-youtube-embed library. This library is a lightweight alternative to the standard youtube embeds, and it\u0026rsquo;s designed to be faster and more efficient.\nParameter Description id [String] Youtube video id to embed. label [String] Label for the video params [String] Extras parameters for video playing Example 1:\n{{\u0026lt; youtubeLite id=\u0026#34;SgXhGb-7QbU\u0026#34; label=\u0026#34;Blowfish-tools demo\u0026#34; \u0026gt;}} Example 2:\nYou can use all of Youtube\u0026rsquo;s player parameters for the params variable, as demonstrated below:\nThis video will start after 130 seconds (2m10)\n{{\u0026lt; youtubeLite id=\u0026#34;SgXhGb-7QbU\u0026#34; label=\u0026#34;Blowfish-tools demo\u0026#34; params=\u0026#34;start=130\u0026#34; \u0026gt;}} This video will not have UI controls, will start playing at 130 seconds and will stop 10 seconds later.\nTo concatenate multiple options as shown below, you need to add the \u0026amp; character between them.\n{{\u0026lt; youtubeLite id=\u0026#34;SgXhGb-7QbU\u0026#34; label=\u0026#34;Blowfish-tools demo\u0026#34; params=\u0026#34;start=130\u0026amp;end=10\u0026amp;controls=0\u0026#34; \u0026gt;}} More informations can be found on the youtubeLite GitHub repo and Youtube\u0026rsquo;s player parameters page.\nÒ\n","date":"25 Januarie 2026","externalUrl":null,"permalink":"/agile/kanban/","section":"Agiles","summary":"","title":"Inleiding: Kanban","type":"agile"},{"content":" GitHub Repo In de opslagplaats (repositorry) kan je alle voorbeelden en demo\u0026rsquo;s terug vinden. Bezoek github Agile Video\u0026rsquo;s met les inhoud. Bekijk de video\u0026rsquo;s Git Video\u0026rsquo;s met les inhoud. Bekijk de video\u0026rsquo;s Ansible Video\u0026rsquo;s met les inhoud. Bekijk de video\u0026rsquo;s Docker Video\u0026rsquo;s met les inhoud. Bekijk de video\u0026rsquo;s CI/CD Video\u0026rsquo;s met les inhoud. Bekijk de video\u0026rsquo;s monitoring Video\u0026rsquo;s met les inhoud. Bekijk de video\u0026rsquo;s ","date":"25 Januarie 2026","externalUrl":null,"permalink":"/media/","section":"Cursus DevOps.","summary":"","title":"Inleiding: Kanban","type":"page"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/inleiding/","section":"Inleidings","summary":"","title":"Inleidings","type":"inleiding"},{"content":"DevOps is een set van werkwijzen, principes en tools die de samenwerking en communicatie tussen softwareontwikkeling (Dev) en IT-operations (Ops) teams verbeteren. Het doel is om de snelheid en frequentie van softwareleveringen te verhogen, terwijl de kwaliteit en stabiliteit gewaarborgd blijven.\nUitgebreide uitleg: # DevOps is ontstaan vanuit de noodzaak om de traditionele “silo” aanpak in software ontwikkeling te doorbreken, waarbij ontwikkelingsteams en operationele teams vaak gescheiden werkten met verschillende doelstellingen. Deze scheiding leidde tot vertragingen, miscommunicatie en problemen bij het in productie nemen van software. DevOps lost dit op door een cultuur van samenwerking, automatisering en gedeelde verantwoordelijkheid te bevorderen.\nAnalogie: # Stel je voor dat je een auto bouwt. In een traditioneel model zou het ontwerpteam het chassis ontwerpen, het motorteam de motor bouwen, en het assemblageteam de auto in elkaar zetten. Elk team werkt onafhankelijk en communiceert minimaal. Dit kan leiden tot problemen wanneer de motor niet in het chassis past of wanneer de assemblage instructies onduidelijk zijn. In een DevOps model zouden alle teams vanaf het begin nauw samenwerken, hun werk integreren en continu feedback uitwisselen. Dit zorgt voor een soepeler proces en een beter eindproduct.\nPotentiële toepassingen: # DevOps kan worden toegepast in elke organisatie die software ontwikkelt en levert, ongeacht de grootte of de branche. Voorbeelden zijn:\nWeb applicaties: DevOps kan worden gebruikt om web applicaties sneller te ontwikkelen, te testen en te implementeren. Mobiele applicaties: DevOps kan worden gebruikt om mobiele applicaties te ontwikkelen en te releasen met een hogere frequentie. Enterprise software: DevOps kan worden gebruikt om enterprise software te ontwikkelen en te implementeren met een hogere kwaliteit en stabiliteit. Key Takeaways: # DevOps is een cultuurverschuiving die samenwerking en automatisering bevordert. DevOps streeft naar het elimineren van de barrières tussen ontwikkelings- en operationele teams. DevOps kan worden toegepast in elke organisatie die software ontwikkelt en levert. Wat leren we in deze cursus ? # Volgende topics komen aan bod:\nAnsible: Voor het automatiseren van verschillende taken, o.a. package installations,\u0026hellip; Cloud infrastructuur opzetten: We maken een virtuele machine aan op Amazon cloud en ook een share. API: Leer over machine-tot-machinecommunicatie en de kracht van API\u0026rsquo;s Terraform: Infrastructuur als codeoplossing om serverimplementatie te stroomlijnen Monitoring: Overzicht van monitoringtypen en praktische voorbeelden met behulp van SNMP Containerbeheer: Samenvatting van docker-containers en monitoring van docker-logs en -prestaties ","date":"25 Januarie 2026","externalUrl":null,"permalink":"/inleiding/introductie/","section":"Inleidings","summary":"","title":"Introductie tot DevOps","type":"inleiding"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/tags/monitoring/","section":"Tags","summary":"","title":"Monitoring","type":"tags"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/monitoring/","section":"Monitorings","summary":"","title":"Monitorings","type":"monitoring"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/tags/node-exporter/","section":"Tags","summary":"","title":"Node Exporter","type":"tags"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/tags/principes/","section":"Tags","summary":"","title":"Principes","type":"tags"},{"content":" Collaboration: Ontwikkelings- en operationele teams werken nauw samen. Automation: Automatisering van repetitieve taken zoals bouwen, testen en implementeren. Continuous Feedback: Feedbacklussen tussen teams en stakeholders om snel te leren en te verbeteren. Continuous Improvement: Streven naar continue verbetering van processen en tools. Infrastructure as Code: Infrastructuur wordt beheerd als code, waardoor het reproduceerbaar en schaalbaar is. Uitgebreide uitleg: # Collaboration: # DevOps benadrukt de samenwerking tussen ontwikkelingsteams, operationele teams en andere stakeholders, zoals testers, security engineers en business analisten. Door nauw samen te werken, kunnen teams sneller feedback krijgen, problemen sneller oplossen en software efficiënter leveren.\nAutomation: # Automatisering is een essentieel onderdeel van DevOps. Door repetitieve taken te automatiseren, zoals bouwen, testen en implementeren, kunnen teams tijd besparen, fouten verminderen en de software delivery lifecycle versnellen.\nContinuous Feedback: # DevOps bevordert continue feedbacklussen tussen teams en stakeholders. Door feedback vroeg en vaak te verzamelen, kunnen teams snel leren van hun fouten en de software continu verbeteren.\nContinuous Improvement: # DevOps is een iteratief proces dat gericht is op continue verbetering. Teams streven ernaar om hun processen, tools en technologieën continu te verbeteren om de efficiëntie en kwaliteit van softwareontwikkeling en -levering te verhogen.\nInfrastructure as Code: # Infrastructure as Code (IaC) is een DevOps-praktijk waarbij infrastructuur wordt beheerd als code. Dit betekent dat infrastructuur kan worden gedefinieerd, geïmplementeerd en beheerd met behulp van code, net als software. IaC maakt infrastructuur reproduceerbaar, schaalbaar en geautomatiseerd.\nVoorbeelden: # Collaboration: Een ontwikkelingsteam en een operationeel team werken samen aan het ontwerpen en implementeren van een nieuwe feature. Automation: Een team automatiseert het build- en testproces van hun software met behulp van Jenkins. Continuous Feedback: Een team gebruikt een tool zoals Slack om feedback te verzamelen van stakeholders over een nieuwe release. Continuous Improvement: Een team analyseert hun software delivery lifecycle en identificeert knelpunten die kunnen worden verbeterd. Infrastructure as Code: Een team gebruikt Terraform om hun cloud infrastructuur te definiëren en te implementeren. Key Takeaways: # DevOps is gebaseerd op een aantal belangrijke principes, waaronder samenwerking, automatisering, continue feedback en continue verbetering. Infrastructure as Code is een DevOps-praktijk waarbij infrastructuur wordt beheerd als code. ","date":"25 Januarie 2026","externalUrl":null,"permalink":"/inleiding/principes/","section":"Inleidings","summary":"","title":"Principes van DevOps","type":"inleiding"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/tags/prometheus/","section":"Tags","summary":"","title":"Prometheus","type":"tags"},{"content":" Scrum # Scrum is an agile project management framework that is widely used in software development. It is an iterative and incremental approach to managing complex projects that emphasizes collaboration, flexibility, and adaptability.\nIn Scrum, a project is divided into a series of iterations, called sprints, which typically last 2-4 weeks. Each sprint begins with a planning meeting, where the team decides on the work to be done and sets goals for the sprint. The team then works on the tasks during the sprint and meets regularly to discuss progress, identify and solve issues, and plan for the next sprint. At the end of the sprint, the team reviews the work and demonstrates the completed tasks to the stakeholders. This process repeats until the project is completed.\nScrum roles # Scrum uses a number of roles, events, and artifacts to support the project management process. The main roles in Scrum are:\nProduct Owner: responsible for defining and prioritizing the product backlog, which is a list of user stories and requirements for the project. Scrum Master: responsible for facilitating the Scrum process and ensuring that the team is following the Scrum framework and principles. Development Team: responsible for designing, developing, and testing the product increment during the sprints. Artifacts # In the context of project management, an artifact is any tangible or intangible item that is created, used, or modified during the course of a project. Artifacts serve as evidence of project progress, decisions made, and information collected, and they provide a means for project stakeholders to communicate, collaborate, and make informed decisions.\nSome common examples of project artifacts include:\nProject Charter: a document that outlines the project scope, objectives, stakeholders, timelines, and resources. Requirements Document: a document that specifies the functional and non-functional requirements for the project. Project Plan: a document that outlines the overall approach, activities, resources, timelines, and milestones for the project. Risk Management Plan: a document that identifies, assesses, and mitigates potential risks that could impact the project. Status Report: a regular update on the project\u0026rsquo;s progress, including completed tasks, upcoming milestones, and any issues or risks that need to be addressed. Test Plan: a document that outlines the testing approach, scenarios, and criteria for the project. Design Documents: a set of documents that describe the design of the product or system being developed, including architecture, components, and interfaces. Artifacts are important because they provide a record of the project\u0026rsquo;s activities and decisions, and they help to ensure that everyone involved in the project is on the same page. They also serve as a reference for future projects or for making decisions about changes to the current project. Finally, they can be used to evaluate the success of the project and to identify areas for improvement in future projects.\nSome of the common artifacts used in Scrum are:\nProduct Backlog: a prioritized list of user stories and requirements for the project, maintained by the Product Owner. Sprint Backlog: a list of user stories and tasks that the Development Team commits to completing during the sprint. Burn-Down Chart: a visual representation of the work remaining in the sprint, which is updated daily and shows progress toward the sprint goal. User stories # User stories are a key part of the Scrum framework. A user story is a short, simple description of a feature or requirement, written from the perspective of the user or customer. It describes the user\u0026rsquo;s need and the value that the feature will provide. User stories are typically written in the following format:\n\u0026ldquo;As a \\[user\\], I want \\[feature\\], so that \\[value\\].\u0026rdquo;\nFor example, a user story for a website could be:\n\u0026ldquo;As a user, I want to be able to search for products by category, so that I can quickly find what I\u0026rsquo;m looking for.\u0026rdquo;\nOr a user story for a mobile app could be:\n\u0026ldquo;As a traveler, I want to be able to see the location of nearby restaurants on a map, so that I can easily find a place to eat.\u0026rdquo;\nUser stories are used to define the requirements of the project and to prioritize the product backlog. They are also used to help the team understand the needs of the users and to design and test the product increment during the sprints.\nOverview # User Stories # Visie: we zijn de eerste bezetters van Mars, er zijn al meerdere vluchten onderweg vol met mensen die op Mars komen wonen. We moeten een stad bouwen die iedereen kan opvangen, levensbehoeften kan voorzien en als laatste ook mensen gelukkig kan maken in hun nieuwe leven. Een hele missie waar we constant moeten bijsturen en verbeteren.\nElk team werkt individueel aan een habitat maar deze moet wel kunnen samenwerken met de andere habitats.\nSprint 1 # Als piloot wil ik een landingsplaats zodat ik veilig kan landen Als bewoner wil ik een een naam voor mijn nieuwe woonplaats zodat ik me thuis voel als op aarde Als bewoner wil ik een eigen slaapplaats zodat ik kan slapen/eten/… Als bewoner wil ik naar andere mensen kunnen reizen zodat ik kan communiceren met andere bewoners Sprint 2 # Als ouder van kinderen wil ik dat ze een leeromgeving hebben zodat ze kunnen leren Als bezetter van deze habitat wil ik een werkplek zodat iedereen mij kan vinden Als bewoner wil ik voedsel dat niet uit zakjes komt zodat ik gezond en lekker kan eten Als bewoner wil ik andere habitats kunnen bezoeken zodat ik mijn oude vrienden kan zien Sprint 3 # Als bewoner wil ik dat ongelijkeid tussen de habitats verdwijnt zodat iedereen gelijk is! (alle gebouwen blauw wit!) Als bezetter wil ik geerd worden door mijn bewoners, ik heb hun leven gered! Als bewoner wil ik eel luxe sportcomplex zodat ik geen rondjes rond het huis hoef te lopen Als bewoner wil ik meer groen zodat deze plek meer op de aarde lijkt Als 3 schepen toekomstige vluchtelingen willen we een landingsplaats een een leefbare slaapplaats. Als bewoner wil ik voedsel dat niet uit zakjes komt zodat ik gezond en lekker kan eten Sprint 4 # Als bezetter wil ik betere voedsel voorziening zodat het hongertekort verdwijnt en er geen opstanden komen Als Elon Musk wil ik een sociaal netwerk op Mars om iedereen te verbinden (en Teslas te verkopen) Als bewoner wil ik beter transport omdat elke dag 2 uur file te veel is Als bewoners willen we een solide democratie zodat er een einde komt aan de dictatuur Meetings # Sprint Planning # Bij begin van een sprint – 60 min per sprint week WAT Analyse fase = WAT “Wat” moet er gebeuren tijdens volgende sprint Product Owner legt de stories uit en beantwoord vragen HOE Ontwerpfase = HOE Het team bespreekt de manier waarop ze de user stories gaan oplossen Deelt user story op in taken Sprint Daily Scrum # Kort – time boxed meeting (max 15 minutes niet langer!) daily, same time, same place! 3 vragen voor elk team lid Wat heb ik sinds gisteren gedaan Wat ben ik van plan vandaag te doen Wat verhindert mij om dit te doen Sprint Review # ~60 minuten per sprint voorstelling van voltooid en onvoltooid werk demo van toegevoegde werkende functionaliteit samen met stakeholders Sprint Retrospective # ~45 min per sprint week Continue verbetering 2 belangrijke vragen Wat ging er goed gedurende de voorbije sprint Wat kan er beter tijdens volgende sprint ","date":"25 Januarie 2026","externalUrl":null,"permalink":"/agile/scrum/","section":"Agiles","summary":"","title":"Scrum \u0026 User Stories","type":"agile"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/tags/teraform/","section":"Tags","summary":"","title":"Teraform","type":"tags"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/terraform/","section":"Terraforms","summary":"","title":"Terraforms","type":"terraform"},{"content":" Wat is Agile ? # Scrum Framework # Kanban bord maken op GitHub # ","date":"25 Januarie 2026","externalUrl":null,"permalink":"/agile/video-agile/","section":"Agiles","summary":"","title":"Video's","type":"agile"},{"content":" Installatie Node Exporter, Prometheus en Grafana # ","date":"25 Januarie 2026","externalUrl":null,"permalink":"/monitoring/video-monitoring/","section":"Monitorings","summary":"","title":"Video's : Grafana, Prometheus, Node Exporter","type":"monitoring"},{"content":"Jenkins, Proxmox, Ansible en Terraform\nJenkins # Terraform, Ansible en Proxmox # ","date":"25 Januarie 2026","externalUrl":null,"permalink":"/ci-cd/video-ci-cd/","section":"Ci-Cds","summary":"","title":"Video's Automatisering","type":"ci-cd"},{"content":" Terraform Deel 1: Docker Containers maken # Terraform # Providers # Terraform Deel 2 : AWS Cloud en EC2 # Terraform # Providers # Labs # Terraform Deel 3 : AWS Cloud en Buckets # # Terraform # Providers # Terraform Deel 4: Proxmox Cloudinit VM Clonen # Terraform Deel 5: Proxmox LXC # ","date":"25 Januarie 2026","externalUrl":null,"permalink":"/terraform/video-terraform/","section":"Terraforms","summary":"","title":"Video's Terraform \u0026 Cloud","type":"terraform"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/tags/voordelen/","section":"Tags","summary":"","title":"Voordelen","type":"tags"},{"content":" Voordelen van het werken volgens het DevOps principe: Snellere softwareleveringen Verbeterde kwaliteit en stabiliteit Verhoogde efficiëntie en productiviteit Betere samenwerking en communicatie Snellere time-to-market Uitgebreide uitleg # Snellere softwareleveringen: DevOps stelt teams in staat om software sneller te leveren door automatisering, continue integratie en continue levering. Dit betekent dat nieuwe features en bugfixes sneller bij de klant terechtkomen.\nVerbeterde kwaliteit en stabiliteit: DevOps bevordert geautomatiseerd testen en continue monitoring, wat leidt tot een hogere kwaliteit en stabiliteit van software. Fouten worden sneller opgespoord en opgelost, waardoor de kans op problemen in productie wordt verminderd.\nVerhoogde efficiëntie en productiviteit: DevOps automatiseert repetitieve taken en stroomlijnt processen, wat leidt tot een hogere efficiëntie en productiviteit van ontwikkelings- en operationele teams. Teams kunnen zich meer richten op innovatie en het leveren van waarde aan de klant.\nBetere samenwerking en communicatie: DevOps bevordert een cultuur van samenwerking en communicatie tussen ontwikkelings- en operationele teams. Dit leidt tot een beter begrip van elkaars werk en een snellere oplossing van problemen.\nSnellere time-to-market: DevOps stelt bedrijven in staat om sneller nieuwe producten en diensten op de markt te brengen. Door de software delivery lifecycle te versnellen, kunnen bedrijven sneller inspelen op veranderingen in de markt en concurrentievoordeel behalen.\nVoorbeelden # Snellere softwareleveringen: Een bedrijf dat DevOps implementeert, kan nieuwe features wekelijks releasen in plaats van maandelijks. Verbeterde kwaliteit en stabiliteit: Een bedrijf dat DevOps implementeert, ziet een afname in het aantal bugs in productie. Verhoogde efficiëntie en productiviteit: Een bedrijf dat DevOps implementeert, kan meer features leveren met hetzelfde aantal ontwikkelaars. Betere samenwerking en communicatie: Een bedrijf dat DevOps implementeert, ziet een verbetering in de communicatie tussen ontwikkelings- en operationele teams. Snellere time-to-market: Een bedrijf dat DevOps implementeert, kan een nieuw product sneller lanceren dan zijn concurrenten. **Key Takeaways:** - DevOps biedt tal van voordelen, waaronder snellere softwareleveringen, verbeterde kwaliteit en stabiliteit, verhoogde efficiëntie en productiviteit, betere samenwerking en communicatie, en snellere time-to-market. ","date":"25 Januarie 2026","externalUrl":null,"permalink":"/inleiding/voordelen/","section":"Inleidings","summary":"","title":"Voordelen van DevOps","type":"inleiding"},{"content":"Als we kijken naar het hedendaagse IT landschap zien we mooie vooruitgangen in onze leefwereld maar ook heel wat problemen. We kunnen al eeuwen projecten afwerken, maar al deze methodes falen in software? We zien in het nieuws stuk voor stuk gefaalde grote software projecten gebeuren, en dit is maar het tipje van de ijsberg. Terwijl we dit in niet-IT veel minder zien. We zijn al bezig met dit fenomeen sinds 1950!\nIn de IT hebben we te maken met een constante evolutie van onze technologie, veel sneller dan andere sectoren. Daarboven kennen we een constante evolutie van eisen, de wereld rondom ons veranderd bijna op een even snel tempo.\nSoftware is als de antwerpse ring, je bouwt jaren aan een tunnel \u0026lt;br\u0026gt;\u0026lt;/br\u0026gt; die veel te groot is en in 5 jaar tijd is ze al te klein. \u0026lt;br\u0026gt;\u0026lt;/br\u0026gt;(\u0026lt;a href=\u0026#34;https://www.vrt.be/vrtnws/nl/2019/05/29/50-jaar-kennedytunnel/\u0026#34; rel=\u0026#34;noopener noreferrer\u0026#34; target=\u0026#34;_blank\u0026#34;\u0026gt;Lees 50 jaar Kennedytunnel (opens new window)\u0026lt;/a\u0026gt;) Maar we hebben een geluk: software is flexibel!\n","date":"25 Januarie 2026","externalUrl":null,"permalink":"/inleiding/anders/","section":"Inleidings","summary":"","title":"Wat is er nu zo anders?","type":"inleiding"},{"content":"","date":"25 Januarie 2026","externalUrl":null,"permalink":"/tags/workflow/","section":"Tags","summary":"","title":"Workflow","type":"tags"},{"content":"","date":"23 Januarie 2026","externalUrl":null,"permalink":"/","section":"Cursus DevOps.","summary":"","title":"Cursus DevOps.","type":"page"},{"content":"","date":"14 Januarie 2020","externalUrl":null,"permalink":"/tags/sample/","section":"Tags","summary":"","title":"Sample","type":"tags"},{"content":"","date":"14 Januarie 2020","externalUrl":null,"permalink":"/tags/users/","section":"Tags","summary":"","title":"Users","type":"tags"},{"content":"Real websites that are built with Blowfish. Check the full list in JSON format.\nBlowfish user? To add your site to this list, submit a pull request. ","date":"14 Januarie 2020","externalUrl":null,"permalink":"/users/users/","section":"Users","summary":"","title":"Users","type":"users"},{"content":"Real websites that are built with Blowfish. Check the full list in JSON format.\nBlowfish user? To add your site to this list, submit a pull request. ","date":"14 Januarie 2020","externalUrl":null,"permalink":"/users/","section":"Users","summary":"","title":"Users","type":"users"},{"content":"Blowfish で構築された実際のウェブサイトです。すべてのウェブサイト一覧は JSON 形式 で閲覧可能です。\nBlowfish ユーザーですか? この一覧にあなたのサイトを加える際は、 pull request を送信 してください。 ","date":"14 Januarie 2020","externalUrl":null,"permalink":"/users/users/","section":"Users","summary":"","title":"ユーザー","type":"users"},{"content":"","date":"14 Januarie 2020","externalUrl":null,"permalink":"/tags/%E5%8F%8B%E9%93%BE/","section":"Tags","summary":"","title":"友链","type":"tags"},{"content":"这里有使用 Blowfish 构建的网站实例。点击这里以 JSON 形式查看完整列表。\n您也是 Blowfish 用户？ 提交 PR来把你的网站加入此列表。 ","date":"14 Januarie 2020","externalUrl":null,"permalink":"/users/users/","section":"Users","summary":"","title":"用户列表","type":"users"},{"content":"","date":"14 Januarie 2020","externalUrl":null,"permalink":"/tags/%E7%A4%BA%E4%BE%8B/","section":"Tags","summary":"","title":"示例","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/academia/","section":"Tags","summary":"","title":"Academia","type":"tags"},{"content":"This is the advanced tag. Just like other listing pages in Blowfish, you can add custom content to individual taxonomy terms and it will be displayed at the top of the term listing. \u0026#x1f680;\nYou can also use these content pages to define Hugo metadata like titles and descriptions that will be used for SEO and other purposes.\n","externalUrl":null,"permalink":"/tags/advanced/","section":"Tags","summary":"","title":"Advanced","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/ai/","section":"Tags","summary":"","title":"AI","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/app-site/","section":"Tags","summary":"","title":"App Site","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/astronomy/","section":"Tags","summary":"","title":"Astronomy","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/author-site/","section":"Tags","summary":"","title":"Author Site","type":"tags"},{"content":"A quick example of how to start using author taxonomies in your articles.\n","externalUrl":null,"permalink":"/authors/","section":"Authors Taxonomy Listing Example","summary":"","title":"Authors Taxonomy Listing Example","type":"authors"},{"content":"Bart Thonissen bio.\nDocent bij Thomas More.\nSysteem en netwerkbeheer Internet of Things (IoT) Certificaten\nOracle : Certified teacher in Database Design and Programming with SQL NetAcad : Netwerk fundamentals Certified Teacher Linux Certified teacher ","externalUrl":null,"permalink":"/authors/nunocoracao/","section":"Authors Taxonomy Listing Example","summary":"","title":"Bart Thonissen","type":"authors"},{"content":"","externalUrl":null,"permalink":"/tags/beispiel/","section":"Tags","summary":"","title":"Beispiel","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/benutzer/","section":"Tags","summary":"","title":"Benutzer","type":"tags"},{"content":"Echte Websites, die mit Blowfish erstellt wurden. Die vollständige Liste im JSON-Format anzeigen.\nBlowfish-Benutzer? Um Ihre Website zu dieser Liste hinzuzufügen, reichen Sie einen Pull Request ein. ","externalUrl":null,"permalink":"/users/users/","section":"Users","summary":"","title":"Benutzer","type":"users"},{"content":"","externalUrl":null,"permalink":"/tags/blog/","section":"Tags","summary":"","title":"Blog","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/book/","section":"Tags","summary":"","title":"Book","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/books/","section":"Tags","summary":"","title":"Books","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/business-site/","section":"Tags","summary":"","title":"Business Site","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/cad/","section":"Tags","summary":"","title":"CAD","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/calculators/","section":"Tags","summary":"","title":"Calculators","type":"tags"},{"content":"","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","externalUrl":null,"permalink":"/tags/christian-devotionals/","section":"Tags","summary":"","title":"Christian Devotionals","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/class/","section":"Tags","summary":"","title":"Class","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/college-club-site/","section":"Tags","summary":"","title":"College Club Site","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/comics-site/","section":"Tags","summary":"","title":"Comics Site","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/community-project/","section":"Tags","summary":"","title":"Community Project","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/company-site/","section":"Tags","summary":"","title":"Company Site","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/dawel/","section":"Tags","summary":"","title":"Dawel","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/devops/","section":"Tags","summary":"","title":"DevOps","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/diy/","section":"Tags","summary":"","title":"DIY","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/doll-photography/","section":"Tags","summary":"","title":"Doll Photography","type":"tags"},{"content":"Dummy Second Author\u0026rsquo;s awesome dummy bio.\n","externalUrl":null,"permalink":"/authors/secondauthor/","section":"Authors Taxonomy Listing Example","summary":"","title":"Dummy Second Author","type":"authors"},{"content":"","externalUrl":null,"permalink":"/tags/dwkde/","section":"Tags","summary":"","title":"DwKDE","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/dwos/","section":"Tags","summary":"","title":"DwOS","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/e-commerce/","section":"Tags","summary":"","title":"E-Commerce","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/ejemplo/","section":"Tags","summary":"","title":"Ejemplo","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/environment-design/","section":"Tags","summary":"","title":"Environment Design","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/exemple/","section":"Tags","summary":"","title":"Exemple","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/exemplo/","section":"Tags","summary":"","title":"Exemplo","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/full-stack-developer/","section":"Tags","summary":"","title":"Full Stack Developer","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/fun-project/","section":"Tags","summary":"","title":"Fun Project","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/gallery/","section":"Tags","summary":"","title":"Gallery","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/game-site/","section":"Tags","summary":"","title":"Game Site","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/games-site/","section":"Tags","summary":"","title":"Games Site","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/home-automation/","section":"Tags","summary":"","title":"Home Automation","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/it/","section":"Tags","summary":"","title":"IT","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/learning/","section":"Tags","summary":"","title":"Learning","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/linux/","section":"Tags","summary":"","title":"Linux","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/mechanical-engineering/","section":"Tags","summary":"","title":"Mechanical Engineering","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/network-architecture/","section":"Tags","summary":"","title":"Network Architecture","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/networking/","section":"Tags","summary":"","title":"Networking","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/open-source/","section":"Tags","summary":"","title":"Open Source","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/organization-site/","section":"Tags","summary":"","title":"Organization Site","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/outdoor-blog/","section":"Tags","summary":"","title":"Outdoor Blog","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/paraguay/","section":"Tags","summary":"","title":"Paraguay","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/pdfs/","section":"Tags","summary":"","title":"PDF's","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/personal-blog/","section":"Tags","summary":"","title":"Personal Blog","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/personal-finance/","section":"Tags","summary":"","title":"Personal Finance","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/personal-site/","section":"Tags","summary":"","title":"Personal Site","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/personal-website/","section":"Tags","summary":"","title":"Personal Website","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/photography/","section":"Tags","summary":"","title":"Photography","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/portfolio/","section":"Tags","summary":"","title":"Portfolio","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/portfolio-site/","section":"Tags","summary":"","title":"Portfolio Site","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/project-site/","section":"Tags","summary":"","title":"Project Site","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/recipe-blog/","section":"Tags","summary":"","title":"Recipe Blog","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/seminars/","section":"Tags","summary":"","title":"Seminars","type":"tags"},{"content":"","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"},{"content":"","externalUrl":null,"permalink":"/tags/software-developer/","section":"Tags","summary":"","title":"Software Developer","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/solarpunk/","section":"Tags","summary":"","title":"Solarpunk","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/tech/","section":"Tags","summary":"","title":"Tech","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/tech-blog/","section":"Tags","summary":"","title":"Tech Blog","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/techlab/","section":"Tags","summary":"","title":"Techlab","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/technology-blog/","section":"Tags","summary":"","title":"Technology Blog","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/theme-author/","section":"Tags","summary":"","title":"Theme Author","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/travel/","section":"Tags","summary":"","title":"Travel","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/usuarios/","section":"Tags","summary":"","title":"Usuarios","type":"tags"},{"content":"Sitios web reales construidos con Blowfish. Consulta la lista completa en formato JSON.\n¿Usuario de Blowfish? Para agregar tu sitio a esta lista, envía un pull request. ","externalUrl":null,"permalink":"/users/users/","section":"Users","summary":"","title":"Usuarios","type":"users"},{"content":"","externalUrl":null,"permalink":"/tags/usu%C3%A1rios/","section":"Tags","summary":"","title":"Usuários","type":"tags"},{"content":"Sites reais construídos com Blowfish. Confira a lista completa em formato JSON.\nUsuário do Blowfish? Para adicionar seu site a esta lista, envie um pull request. ","externalUrl":null,"permalink":"/users/users/","section":"Users","summary":"","title":"Usuários","type":"users"},{"content":"","externalUrl":null,"permalink":"/tags/utilisateurs/","section":"Tags","summary":"","title":"Utilisateurs","type":"tags"},{"content":"De vrais sites web construits avec Blowfish. Consultez la liste complète en format JSON.\nUtilisateur de Blowfish ? Pour ajouter votre site à cette liste, soumettez une pull request. ","externalUrl":null,"permalink":"/users/users/","section":"Users","summary":"","title":"Utilisateurs","type":"users"},{"content":"","externalUrl":null,"permalink":"/tags/utilizadores/","section":"Tags","summary":"","title":"Utilizadores","type":"tags"},{"content":"Sites reais construídos com Blowfish. Consulte a lista completa em formato JSON.\nUtilizador do Blowfish? Para adicionar o seu site a esta lista, submeta um pull request. ","externalUrl":null,"permalink":"/users/users/","section":"Users","summary":"","title":"Utilizadores","type":"users"},{"content":"","externalUrl":null,"permalink":"/tags/videogame-developer/","section":"Tags","summary":"","title":"Videogame Developer","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/world-of-warcraft/","section":"Tags","summary":"","title":"World of Warcraft","type":"tags"},{"content":"","externalUrl":null,"permalink":"/tags/wow/","section":"Tags","summary":"","title":"WoW","type":"tags"}]