[Docker] [alle OS] Het grote Docker ervaringen en tips topic

Pagina: 1 ... 17 18 Laatste
Acties:

  • DjoeC
  • Registratie: November 2018
  • Laatst online: 23:51
CH4OS schreef op maandag 5 januari 2026 @ 16:26:
@DjoeC De Joomla installaties zet je dan toch achter Traefik / Caddy / Nginx Proxy Manager?

Met Traefik hoef je dan niet eens de poorten te openen / forwarden, zolang de Traefik container ze maar bereiken kan. Ik zie echt niet waarom de containers op het netwerk buiten Docker zouden moeten zitten, dat laat ik liever Docker regelen icm Traefik (ook via Docker). De back-end(s) voor Joomla kun je dan evenetueel op een intern netwerk (docker network create --insternal <naam>) zetten waardoor buitenaf er niet eens bij kan. De Joomla instanties zet je dan dus op 2 netwerken, zodat ze enerzijds intern de database kunnen bereiken en het andere netwerk is extern, zodat bepaalde resources die je remote ophaalt (afbeeldingen via een CDN bijvoorbeeld, of metadata van een film of serie) dan opgehaald kan worden. Als dat niet eens nodig is voor de Joomla instanties, kan je dus gewoon met 1 intern netwerk af, Traefik gaat dan voor je naar buiten.

Ik denk echt dat je een en ander onnodig complex hebt voor jezelf, als ik jouw bovenstaande reactie zo lees :$ Ook Pi-Hole draai ik zonder macvlan (draait op een simpele Pi 3B in Docker, tezamen met DSMR reader om mijn slimme meter uit te lezen, verder doet de Pi niks), maar dan dus met portforward, voor Ad Guard Home (die ik op mijn homelab draai) idem dito. Voor het draaien van containers op een andere host zonder aanpassingen te hoeven doen, gebruik je dan toch gewoon Docker Swarm?
Dank je. Ik ga me er echt nog eens goed in verdiepen want ik wil dit eenvoudiger krijgen. Gaat me wat tijd kosten maar goed ;)

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

DjoeC schreef op maandag 5 januari 2026 @ 17:39:
Dank je. Ik ga me er echt nog eens goed in verdiepen want ik wil dit eenvoudiger krijgen. Gaat me wat tijd kosten maar goed ;)
Graag gedaan! :) Ik zou toch eens overwegen om meer met stacks (en elimineren van afhankelijkheden zoals een enkele database instance) te gaan werken. In combinatie met docker compose bijvoorbeeld werkt dat echt goed anno nu.

[ Voor 8% gewijzigd door CH4OS op 05-01-2026 19:24 ]


  • synoniem
  • Registratie: April 2009
  • Niet online
CH4OS schreef op maandag 5 januari 2026 @ 19:24:
[...]
Graag gedaan! :) Ik zou toch eens overwegen om meer met stacks (en elimineren van afhankelijkheden zoals een enkele database instance) te gaan werken. In combinatie met docker compose bijvoorbeeld werkt dat echt goed anno nu.
Het aantal mogelijkheden is wat dat betreft best groot. Omdat ik toch een webserver moet draaien en aan Apache2 gewend ben, heb ik een aantal docker compose scripts waarin Traefik alle services verbindt en de Let's Encrypt certificaten regelt. De Apache2 server stelt een aantal webservices beschikbaar maar is tegelijkertijd ook een proxy voor services die hun eigen webserver draaien.

Uiteraard kan Traefik ook het proxy werk doen maar de webserver met proxy had ik al dus het is min of meer zo organisch gegroeid. Het voordeel is wel dat er een service gewoon kan uitvallen. Zolang de webserver maar blijft draaien blijven de andere services bereikbaar. De volgende stap is het redundant maken met k3s en Longhorn.

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

@synoniem Traefik kan ook prima het Let's Encrypt deel doen, dus dat hoeft niet per se in aparte scripts gedaan te worden. :) Ook ververst het een certificaat dan automatisch voor je. Om daar dan nog een Apache2 als proxy achter te hangen voelt een beetje dubbel als ik jouw verhaal zo lees. Of ik begrijp het verhaal nu een beetje verkeerd.

  • synoniem
  • Registratie: April 2009
  • Niet online
CH4OS schreef op maandag 5 januari 2026 @ 19:59:
@synoniem Traefik kan ook prima het Let's Encrypt deel doen, dus dat hoeft niet per se in aparte scripts gedaan te worden. :) Ook ververst het een certificaat dan automatisch voor je. Om daar dan nog een Apache2 als proxy achter te hangen voelt een beetje dubbel als ik jouw verhaal zo lees. Of ik begrijp het verhaal nu een beetje verkeerd.
Ja ik ben misschien niet duidelijk genoeg. Traefik regelt inderdaad de certificaten, om precies te zijn een wildcard certificaat dat ook mjin mailserver (in een container) gebruikt. De webserver zit in hetzelfde script om alle subdomeinen af te laten vangen door Traefik proxy. Ik heb gewoon mijn webservice maar ook een subdomein voor icecast/mpd, webmail, postfixadmin terwijl git+docker registry en Navidrome etc. ge-proxied worden.

  • DjoeC
  • Registratie: November 2018
  • Laatst online: 23:51
CH4OS schreef op maandag 5 januari 2026 @ 19:24:
[...]
Graag gedaan! :) Ik zou toch eens overwegen om meer met stacks (en elimineren van afhankelijkheden zoals een enkele database instance) te gaan werken. In combinatie met docker compose bijvoorbeeld werkt dat echt goed anno nu.
Alles zit al in docker compose/yaml en dat werkt inderdaad prima!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

DjoeC schreef op maandag 5 januari 2026 @ 22:11:
Alles zit al in docker compose/yaml en dat werkt inderdaad prima!
Ah, dat is althans wat ik bedoelde met stacks :$

Toch even een vraag: Hoe beheren jullie deze files/stacks? Ik doe dat 'simpel' met VS Code (al twijfel ik ook om over te stappen op een andere fork, maar weet nog niet welke, hoor ook veel goede verhalen over Google's Antigravity bijvoorbeeld) en docker doe ik gewoon old-school via de commandline. Maar hoe doen jullie dat? :) Gebruiken jullie bijvoorbeeld Portainer, Dockge, Arcane of een van de vele andere (webbased) beheertools? Lazydocker wellicht?

[ Voor 58% gewijzigd door CH4OS op 05-01-2026 22:20 ]


  • DjoeC
  • Registratie: November 2018
  • Laatst online: 23:51
CH4OS schreef op maandag 5 januari 2026 @ 22:16:
[...]
Ah, dat is althans wat ik bedoelde met stacks :$
Yes, maar dan wel vzv mogelijk 1 service/1 container per yaml/compose/ok, stack ;) Alleen immich wordt uitgebreider maar wel zonder de database, die wil ik echt centraal houden......

Aanvulljng: Ik heb Raspi lite met daaroverheen Openmediavault. Onderdeel daarvan is een steeds meer uitgebreid Docker nanagement, grofweg Portainer kloon maar werkt veel soepeler. Portainer gebruik ik alleen nog voor snel een container stoppen/starten en das alleen omdat omv geen multiselects kent. Daarbij zijn de omv ontwikkelaars ontzettend responsief bij vragen of issues.

[ Voor 35% gewijzigd door DjoeC op 05-01-2026 22:28 ]


  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Ah, ik heb een onderverdeling gemaakt in wat het doeleinde is. Mijn 'Arr stack' bijvoorbeeld heeft 20 services in totaal, waarvan 2 services dubbel draaien ivm limitaties en/of betere filtering en sorteringsopties voor anime. :$ Dat is dan wel gelijk mijn grootste stack, andere stacks die ik heb, zijn dan weer kleiner, zoals mijn networking stack (waarin ik dus Traefik heb zitten en die ik vervolgens op bijna elk Docker netwerk heb zitten). immich is hier ook een aparte stack, net als OpenCloud zijn eigen stack heeft.

[ Voor 8% gewijzigd door CH4OS op 05-01-2026 22:29 ]


  • synoniem
  • Registratie: April 2009
  • Niet online
CH4OS schreef op maandag 5 januari 2026 @ 22:16:
[...]
Ah, dat is althans wat ik bedoelde met stacks :$

Toch even een vraag: Hoe beheren jullie deze files/stacks? Ik doe dat 'simpel' met VS Code (al twijfel ik ook om over te stappen op een andere fork, maar weet nog niet welke, hoor ook veel goede verhalen over Google's Antigravity bijvoorbeeld) en docker doe ik gewoon old-school via de commandline. Maar hoe doen jullie dat? :) Gebruiken jullie bijvoorbeeld Portainer, Dockge, Arcane of een van de vele andere (webbased) beheertools? Lazydocker wellicht?
Ik gebruik gewoon de commandline en heb mijn yaml in git repos staan. Mijn servers zijn headless dus een mooie tool met grafische interface heeft weinig nut.

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

@synoniem Eigenlijk hebben alle genoemde tools een webinterface, een gui draaien is dus niet nodig... :) Enige die dat niet heeft is Lazydocker, dat is een commandline tool. :)

[ Voor 44% gewijzigd door CH4OS op 05-01-2026 22:48 ]


  • blackd
  • Registratie: Februari 2001
  • Niet online
Voor de mensen die Uptime-Kuma gebruiken, ik las gisteren deze blogpost en leerde toen AutoKuma kennen.

Voorheen had ik een Ansible Task gemaakt die via deze Python library en deze ansible collection een web request deed naar Uptime Kuma om monitors aan te maken. Echter kreeg ik hier steeds meer problemen mee. Ik vermoed het gebruik van de SQLite database icm veel monitors en veel historische data, dus wil graag upgraden naar 2.x met MariaDB.

In plaats van bovenstaande aanpak kan ik met AutoKuma nu labels aanmaken in de Compose file zelf om AutoKuma te voeden met de juiste info om de monitors aan te maken.

Ik beheer op deze manier al mijn Traefik configuratie via labels, mijn Homepage configuratie via labels dus dit past mooi in dat straatje.

Ik ben nu bezig alle config als labels in te richten, daarna kan ik eenvoudig upgraden van 1.x naar 2.x in een nieuwe stack en met een schone lei beginnen.

YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
services:
  autokuma:
    image: ghcr.io/bigboot/autokuma:uptime-kuma-v1-2.0.0
    restart: unless-stopped
    environment:
      AUTOKUMA__KUMA__URL: http://uptime-kuma:3001
      AUTOKUMA__KUMA__USERNAME: ${KUMA_USERNAME}
      AUTOKUMA__KUMA__PASSWORD: ${KUMA_PASSWORD}
      AUTOKUMA__DOCKER__EXCLUDE_CONTAINER_PATTERNS: "^temp_;^[a-f0-9]{12}_.*_" # Excludes test containers and temporary stack containers.
      AUTOKUMA__DEFAULT_SETTINGS: |-
        docker.docker_container: {{ container_name }}
        http.max_redirects: 10
        *.max_retries: 3
      AUTOKUMA__DOCKER__LABEL_PREFIX: kuma
      AUTOKUMA__SNIPPETS__DOCKER: |-
         {{container_name}}_docker.docker.docker_container: {{container_name}}
         {{container_name}}_docker.docker.docker_host_name: local
         {{container_name}}_docker.docker.name: docker_{{container_name}}
         {{container_name}}_docker.docker.notification_name_list: ["pushbullet"]
      AUTOKUMA__SNIPPETS__WEB: |-
         {{container_name}}_http.http.name: web_{{container_name}}
         {{container_name}}_http.http.url: https://{{container_name}}.domain.tld
         {{container_name}}_http.http.notification_name_list: ["pushbullet"]
    labels:
      kuma.local.docker_host.name: 'Local Docker Socket'
      kuma.local.docker_host.connection_type: 'socket'
      kuma.local.docker_host.path: '/var/run/docker.sock'
      kuma.pushbullet.notification.name: 'Pushbullet'
      kuma.pushbullet.notification.active: 'true'
      kuma.pushbullet.notification.config: |
        {   [ .. config in JSON ..]
        }
     [..]
   [ ook een uptime-kuma container gedefinieerd op poort 3001]


En dan als voorbeeld:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
name: sabnzbd
services:
  sabnzbd:
    image: ghcr.io/home-operations/sabnzbd:4.5.5@sha256:da57e01cdebc547852b6df85c8df8c0e4d87792742c7608c5590dc653b184e8c
    container_name: sabnzbd
   [..]
    labels:
      - traefik.enable=true
      - traefik.docker.network=traefik-net
      - traefik.http.routers.sabnzbd.rule=Host(`sabnzbd.domain.tld`)
      - traefik.http.routers.sabnzbd.entrypoints=websecure
      - traefik.http.routers.sabnzbd.tls.certresolver=cfdns
      - traefik.http.services.sabnzbd.loadbalancer.server.port=8080
      - kuma.__web
      - kuma.__docker
 [..]

De labels kuma.__web en kuma.__docker zijn snippets die via de labels AUTOKUMA__SNIPPETS__* geconfigureerd worden.
CH4OS schreef op maandag 5 januari 2026 @ 22:16:
[...]
Ah, dat is althans wat ik bedoelde met stacks :$

Toch even een vraag: Hoe beheren jullie deze files/stacks? Ik doe dat 'simpel' met VS Code (al twijfel ik ook om over te stappen op een andere fork, maar weet nog niet welke, hoor ook veel goede verhalen over Google's Antigravity bijvoorbeeld) en docker doe ik gewoon old-school via de commandline. Maar hoe doen jullie dat? :) Gebruiken jullie bijvoorbeeld Portainer, Dockge, Arcane of een van de vele andere (webbased) beheertools? Lazydocker wellicht?
Zoveel mogelijk geautomatiseerd met Ansible, elke stack als Ansible Role in een Github project. Ik doe het beheer met VSCode lokaal en het deployen doe ik via Ansible met een Github self hosted runner.

Als het nodig is containers restarten via Dockge of debuggen via Portainer en worst-case via de CLI via SSH.

[ Voor 33% gewijzigd door blackd op 06-01-2026 09:30 ]

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • synoniem
  • Registratie: April 2009
  • Niet online
CH4OS schreef op maandag 5 januari 2026 @ 22:45:
@synoniem Eigenlijk hebben alle genoemde tools een webinterface, een gui draaien is dus niet nodig... :) Enige die dat niet heeft is Lazydocker, dat is een commandline tool. :)
Tja, ik ben old skool wat dat betreft dus geen beheerinterface aan het net hangen. Een headless server (vps) is bij mij alleen bereikbaar op port 443 en 22 (en eventueel imap en smtp). Ik zou eventueel een beheerinterface aan localhost kunnen hangen en dan via ssh forwarden maar dat is net zoveel werk als met ssh inloggen en het zelf doen.

  • ThinkPad
  • Registratie: Juni 2005
  • Laatst online: 20:53
Ik meen ooit eens een container te hebben gezien voor het bijhouden van verzekeringspolissen, energiecontracten e.d. Kan het alleen niet vinden, ik kom dan uit bij document management systemen zoals Paperless, of warranty trackers waarin ik kan registreren dat de garantie van m'n TV verloopt op 5 nov. 2027 bijv. Of inventarissystemen, om bij te houden hoeveel boodschappen ik nog in huis heb, of hoeveel dozen schroefjes. Niet wat ik zoek :P

Ik zoek meer een Excel-achtig overzicht waarin ik kan invoeren dat ik m'n auto verzekerd heb bij BedrijfX, dat ik een energiecontract heb bij LeverancierXYZ wat loopt tot dd-mm-yyyy en een internetcontract heb wat loopt tot dd-mm-yyyy

Iemand een idee?

[ Voor 9% gewijzigd door ThinkPad op 06-01-2026 09:21 ]


  • synoniem
  • Registratie: April 2009
  • Niet online
ThinkPad schreef op dinsdag 6 januari 2026 @ 09:19:
Ik meen ooit eens een container te hebben gezien voor het bijhouden van verzekeringspolissen, energiecontracten e.d. Kan het alleen niet vinden, ik kom dan uit bij document management systemen zoals Paperless, of warranty trackers waarin ik kan registreren dat de garantie van m'n TV verloopt op 5 nov. 2027 bijv. Of inventarissystemen, om bij te houden hoeveel boodschappen ik nog in huis heb, of hoeveel dozen schroefjes. Niet wat ik zoek :P

Ik zoek meer een Excel-achtig overzicht waarin ik kan invoeren dat ik m'n auto verzekerd heb bij BedrijfX, dat ik een energiecontract heb bij LeverancierXYZ wat loopt tot dd-mm-yyyy en een internetcontract heb wat loopt tot dd-mm-yyyy

Iemand een idee?
Zoiets als Wallos?

  • ThinkPad
  • Registratie: Juni 2005
  • Laatst online: 20:53
Yes perfect!

Ik zat al te kijken naar een Excel-template zoals deze, maar die Wallos is precies wat ik zoek zo te zien. Kan ook notificaties sturen als iets bijna verloopt zo te zien.

  • Ben.Hahlen
  • Registratie: December 2003
  • Laatst online: 19-03 12:19
@DjoeC (en anderen):
Interessante discussie over "de inrichting" :)
Mijn 2 centen:

Ik heb een hele tijd MACVLan gedraaid en was daar best tevreden over, maar het management is wel "ingewikkeld", want je moet goed bijhouden wat waar draait, in PiHole regeltjes bijhouden voor routing etc.

Ondertussen ben ik al een hele tijd over naar "normale" netwerken, maar ik draai ook nog "generieke" services, dus geen stack per applicatie.
Mijn folder structuur ziet er nu zo uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
.
├── 01-critical
├── 02-databases
├── 03-middleware
├── 04-management
├── 05-home
├── 06-personal
├── 07-finance
├── 08-travel
├── 09-tools
├── 10-media
├── 11-games
├── 12-websites
├── 13-ai

In the eerste stack zitten bijvoorbeeld Authentik, Traefik, PiHole en Postgres (speciaal voor die stack). Dat is de enige die volledig zelf-contained is.

Voor het managen van de files gebruik ik VSCode en de Compose Stacks starten/stoppen doe ik met dc, een tooltje dat ik voor mezelf geschreven heb.

Blog


  • DjoeC
  • Registratie: November 2018
  • Laatst online: 23:51
Ben.Hahlen schreef op dinsdag 6 januari 2026 @ 14:30:
@DjoeC (en anderen):
Interessante discussie over "de inrichting" :)
Mijn 2 centen:

Ik heb een hele tijd MACVLan gedraaid en was daar best tevreden over, maar het management is wel "ingewikkeld", want je moet goed bijhouden wat waar draait, in PiHole regeltjes bijhouden voor routing etc.

Ondertussen ben ik al een hele tijd over naar "normale" netwerken, maar ik draai ook nog "generieke" services, dus geen stack per applicatie.
Mijn folder structuur ziet er nu zo uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
.
├── 01-critical
├── 02-databases
├── 03-middleware
├── 04-management
├── 05-home
├── 06-personal
├── 07-finance
├── 08-travel
├── 09-tools
├── 10-media
├── 11-games
├── 12-websites
├── 13-ai

In the eerste stack zitten bijvoorbeeld Authentik, Traefik, PiHole en Postgres (speciaal voor die stack). Dat is de enige die volledig zelf-contained is.

Voor het managen van de files gebruik ik VSCode en de Compose Stacks starten/stoppen doe ik met dc, een tooltje dat ik voor mezelf geschreven heb.
Interessant..... Voor mij is het voordeel van MACVLAN nou juist dat ik na de eerste keer geen routering meer hoef aan te passen. Pihole krijgt ip 10.1.1.2 en houd dat, ongeacht op welke docker instantie die draait.... Ben dus wel benieuwd waarom jij routering zou moeten aanpassen. Gewoon elke service z'n eigen hostname in de pihole locale DNS - die ik trouwens op de Fritzbox router ook als overall DNS heb ingesteld.

  • Ben.Hahlen
  • Registratie: December 2003
  • Laatst online: 19-03 12:19
DjoeC schreef op dinsdag 6 januari 2026 @ 16:41:
[...]
Interessant..... Voor mij is het voordeel van MACVLAN nou juist dat ik na de eerste keer geen routering meer hoef aan te passen. Pihole krijgt ip 10.1.1.2 en houd dat, ongeacht op welke docker instantie die draait.... Ben dus wel benieuwd waarom jij routering zou moeten aanpassen. Gewoon elke service z'n eigen hostname in de pihole locale DNS - die ik trouwens op de Fritzbox router ook als overall DNS heb ingesteld.
Ik zat in die tijd nogal in de "speelfase", dus heel vaak containers weg en nieuwe er voor in de plaats.
Dan gaat het hard met de administratie :)

PiHole heeft een WildCard verwijzing naar mijn Traefik, zodat intern alles ook op hostname resolved kan worden.

Mijn USG en PiHole wlke ook samen.

Blog


  • Greatsword
  • Registratie: Februari 2010
  • Niet online
Ik heb docker op mijn (Ugreen) NAS draaien, voornamelijk voor zaken als Plex, Sonarr, Radarr etc.

Deze applicaties maken netjes wekelijks geautomatiseerde backups in Zip bestanden, maar hoe maak ik nu eigenlijk het beste een backup van Docker? Stel de NAS houdt er mee op dan wil ik dus zo snel mogelijk alles weer terug kunnen zetten.

Is het dan voldoende om de zip bestanden (backups) ergens anders op te slaan of moet ik dan echt de hele Docker / appdata map overzetten.

De NAS staat 24/7 aan en in deze applicaties worden ook continue logs geschreven, dus ben benieuwd of dat nog conflicten met zich kan meebrengen.

  • DjoeC
  • Registratie: November 2018
  • Laatst online: 23:51
Ben.Hahlen schreef op woensdag 7 januari 2026 @ 10:16:
[...]

Ik zat in die tijd nogal in de "speelfase", dus heel vaak containers weg en nieuwe er voor in de plaats.
Dan gaat het hard met de administratie :)

PiHole heeft een WildCard verwijzing naar mijn Traefik, zodat intern alles ook op hostname resolved kan worden.

Mijn USG en PiHole wlke ook samen.
Ik heb me alvast een beetje verder ingelezen. In de revrvse proxy opties is voorlopig Caddy afgevallen. Traefik moet ik me nog meer in verdiepen dus nog geen uiteindelijke selectie gemaakt voor de nieuwe omgeving.

Daarnaast me nog eens opnieuw ingelezen over macvlan in de docker docs. Daar lijken wat nadelen aan te zitten die door gebruik van ipvlan kunnen worden ondervangen. Dan is er nog het onderscheid in ipvlan L2 en L3, daar moet ik eerst ook wat meer van gaan snappen (en wat mee experimenteren)..... Leuk!

  • DjoeC
  • Registratie: November 2018
  • Laatst online: 23:51
Greatsword schreef op donderdag 8 januari 2026 @ 15:24:
Ik heb docker op mijn (Ugreen) NAS draaien, voornamelijk voor zaken als Plex, Sonarr, Radarr etc.

Deze applicaties maken netjes wekelijks geautomatiseerde backups in Zip bestanden, maar hoe maak ik nu eigenlijk het beste een backup van Docker? Stel de NAS houdt er mee op dan wil ik dus zo snel mogelijk alles weer terug kunnen zetten.

Is het dan voldoende om de zip bestanden (backups) ergens anders op te slaan of moet ik dan echt de hele Docker / appdata map overzetten.

De NAS staat 24/7 aan en in deze applicaties worden ook continue logs geschreven, dus ben benieuwd of dat nog conflicten met zich kan meebrengen.
Ik maak 2 soorten "backup's" van docker spul. Databases dagelijks middels https://github.com/tiredofit/docker-db-backup , die komen in een shared backup folder die "zodra ze er staan" en Windows beschikbaar is naar Windows worden overgehaald en daar in de Windows backup cyclus meelopen. Daarnaast wordt alle "permanente" docker data (docker-config en docker-data) middels een simpel script naar die backup folder gekopieerd en loopt op dezelfde manier mee. Al het andere is een herstel kwestie van: configatie, datafolders terug zetten, containers opnieuw uitrollen mbv de bewaarde yml's en gaan met die banaan. De databases (mariadb): Eerst kale Mariadb starten en dan alles (behalve system) restoren.

En ja, er zijn meer en veel meer sophisticated manieren, dit werkt voor mij zonder omkijken. O ja, en van pihole draai ik elke nacht een automatische teleporter job. Dan heeft ie ook mijn lokale DNS altijd compleet. 1 dag verlies kan ik mij veroorloven. Als je dat niet kunt: andere maatregelen treffen ;)

Verwijderd

Greatsword schreef op donderdag 8 januari 2026 @ 15:24:
Ik heb docker op mijn (Ugreen) NAS draaien, voornamelijk voor zaken als Plex, Sonarr, Radarr etc.

Deze applicaties maken netjes wekelijks geautomatiseerde backups in Zip bestanden, maar hoe maak ik nu eigenlijk het beste een backup van Docker? Stel de NAS houdt er mee op dan wil ik dus zo snel mogelijk alles weer terug kunnen zetten.

Is het dan voldoende om de zip bestanden (backups) ergens anders op te slaan of moet ik dan echt de hele Docker / appdata map overzetten.

De NAS staat 24/7 aan en in deze applicaties worden ook continue logs geschreven, dus ben benieuwd of dat nog conflicten met zich kan meebrengen.
Toen ik nog gebruik maakte van een Intel NUC, gebruikte ik een script + rsync om elke nacht alle docker-compose projecten te stoppen, te kopiëren naar een specifieke te back-uppen map en daarna een-voor-een de docker-compose projecten weer op te starten. De te back-uppen map werd dan op een later tijdstip (geloof een uur later) door Duplicati verwerkt naar de cloud. De downtime die het met zich mee bracht, maakte mij niets uit. Het gehele proces liep als ik lag te slapen.

Op dit moment draai ik een Raspberry Pi 3B+, daarvan hanteer ik bijna dezelfde werkwijze, behalve het kopiëren. Middels scripting worden de docker-compose projecten gestopt, vervolgens gaat Duplicati de boel uploaden naar de cloud, om uiteindelijk de projecten weer te starten. De downtime is hier iets langer, maar ook nu heb ik er geen last van (het proces loopt diep in de nacht).

Zolang als ik self-host (10+ jaar), heb ik altijd downtime verkozen boven, mogelijk, incomplete backups, omdat het spul nog draaiende is. Ik geloof wel dat de tooling tegenwoordig beter is geworden, maar goed :P

  • DjoeC
  • Registratie: November 2018
  • Laatst online: 23:51
Verwijderd schreef op donderdag 8 januari 2026 @ 15:59:
[...]
De downtime is hier iets langer, maar ook nu heb ik er geen last van (het proces loopt diep in de nacht).
Hmm, ik zou toch liever doordraaien, zeker als zoiets hier 1 alle DNS verzorgd wordt (pihole, unbound) en er ook (beschermd via Cloudflare) een paar publieke websites draaien. Ik kan niet voorspellen wie wanneer wel of niet slaapt. Daarnaast vind ik (maar goed, wie ben ik) unattended stops en starts onwenselijk. Maar goed, YMMV.

  • DjoeC
  • Registratie: November 2018
  • Laatst online: 23:51
Vraag: ik gebruik momenteel Mosquitto als MQTT broker (bron voor HA en eigen proggies), gevoed vanuit sensoren en ESP's (eigen proggies). Ik gebruik zoveel mogelijk MQTT V5 maar V3 wordt ook nog wel gebruikt.

Nu mis ik een grafische (management) interface waar statistieken, timestamp laatste bericht in een queue, oid te zien zijn. Ik denk NIET aan prometheus achtige oplossingen. Blijkbaar is er een commercieele versie van Mosquitto die dit heeft maar ik zoek eigenlijk gewoon open-source.

Is er een betere MQTT broker met iets meer opties (docker gebaseerd). Ik kom HiveMQ, RabbitMQ, emqx tegen. Heeft iemand ervaring met 1 van die alternatieven?

  • Ben.Hahlen
  • Registratie: December 2003
  • Laatst online: 19-03 12:19
DjoeC schreef op zaterdag 17 januari 2026 @ 15:21:
Vraag: ik gebruik momenteel Mosquitto als MQTT broker (bron voor HA en eigen proggies), gevoed vanuit sensoren en ESP's (eigen proggies). Ik gebruik zoveel mogelijk MQTT V5 maar V3 wordt ook nog wel gebruikt.

Nu mis ik een grafische (management) interface waar statistieken, timestamp laatste bericht in een queue, oid te zien zijn. Ik denk NIET aan prometheus achtige oplossingen. Blijkbaar is er een commercieele versie van Mosquitto die dit heeft maar ik zoek eigenlijk gewoon open-source.

Is er een betere MQTT broker met iets meer opties (docker gebaseerd). Ik kom HiveMQ, RabbitMQ, emqx tegen. Heeft iemand ervaring met 1 van die alternatieven?
Ik gebruik MQTT Explorer.
Deze connect naar Mosquitto, misschien is dat wat?

Blog


  • DjoeC
  • Registratie: November 2018
  • Laatst online: 23:51
Ben.Hahlen schreef op maandag 19 januari 2026 @ 15:28:
[...]

Ik gebruik MQTT Explorer.
Deze connect naar Mosquitto, misschien is dat wat?
Ja, die gebruik ik al op Windows maar liefst zou ik iets hebben dat direct onder docker draait - of zou dit zo in een container te "verpakken" kunnen zijn?

Vanochtend heb ik EMQX uitgeprobeerd, dat leip eigenlijk best wel als alternatief voor Mosquitto. Het grote verschil: Mosquitto kan maar 100.000 connecties aan en EMQX wel 1.000.000. Duhhh....

Daar zit een "soort van" combinatie in van MQTT Explorer en https://github.com/sanjeshpathak/Mosquitto-Dashboard maar ik vraag me af of dat pakket niet veel te zwaar is voor een Raspi. Daarbij moet je met EMQX bij een "cluster" al meteen een betaalde licentie aanschaffen, ik neem aan dat dat bij bridgen ook geldt - terwijl bringen van mosquitto gewoon een paar config regels zijn....

Maar goed, als er echt niks is maak ik misschien wel een Python containertje dat statistics naar Home Assistant kan sturen en maak ik daar wel een dashboardje. Werk waar ik niet op zit te wachten - maar dat kan natuurlijk wel.....

  • Mars Warrior
  • Registratie: Oktober 2003
  • Laatst online: 19-03 12:41

Mars Warrior

Earth, the final frontier

DjoeC schreef op maandag 19 januari 2026 @ 15:37:
[...]

Ja, die gebruik ik al op Windows maar liefst zou ik iets hebben dat direct onder docker draait - of zou dit zo in een container te "verpakken" kunnen zijn?

Vanochtend heb ik EMQX uitgeprobeerd, dat leip eigenlijk best wel als alternatief voor Mosquitto. Het grote verschil: Mosquitto kan maar 100.000 connecties aan en EMQX wel 1.000.000. Duhhh....

Daar zit een "soort van" combinatie in van MQTT Explorer en https://github.com/sanjeshpathak/Mosquitto-Dashboard maar ik vraag me af of dat pakket niet veel te zwaar is voor een Raspi. Daarbij moet je met EMQX bij een "cluster" al meteen een betaalde licentie aanschaffen, ik neem aan dat dat bij bridgen ook geldt - terwijl bringen van mosquitto gewoon een paar config regels zijn....

Maar goed, als er echt niks is maak ik misschien wel een Python containertje dat statistics naar Home Assistant kan sturen en maak ik daar wel een dashboardje. Werk waar ik niet op zit te wachten - maar dat kan natuurlijk wel.....
Dat clusteren van EMQS geld kost wist ik niet. Voorheen draaide ik dat namelijk op een netwerk van RPIs...

Maar EMQX is mooi en informatief als optie voor een GUI.

Daarnaast heb je nog RabbitMQ. Kan wat bewerkelijker zijn omdat je een MQTT plugin moet gebruiken, immers RabbitMQ doet standaard AMQP.

En wat dacht je van deze, MQTTUI?
Dit is een aparte GUI voor een willekeurige broker en draait vanzelfsprekend in Docker.

Afbeeldingslocatie: https://github.com/terdia/mqttui/raw/main/static/screenshot_1.png

Material 3 Thema's voor HA | Swiss Army Knife custom card voor HA | AmoebeLabs


  • Ben.Hahlen
  • Registratie: December 2003
  • Laatst online: 19-03 12:19
DjoeC schreef op maandag 19 januari 2026 @ 15:37:
[...]

Ja, die gebruik ik al op Windows maar liefst zou ik iets hebben dat direct onder docker draait - of zou dit zo in een container te "verpakken" kunnen zijn?
Jazeker, dat is de enige manier dat ik hem heb:
YAML:
1
2
3
4
5
6
7
8
9
10
11
  mqtt-explorer:
    extends:
      file: ../shared.yml
      service: pubnet-shared
    image: smeagolworms4/mqtt-explorer:latest
    container_name: mqtt-explorer
    hostname: mqtt-explorer
    env_file: mqtt-explorer.env
    volumes:
      - ./mqtt-explorer/config:/mqtt-explorer/config
 

Blog


  • DjoeC
  • Registratie: November 2018
  • Laatst online: 23:51
Mars Warrior schreef op maandag 19 januari 2026 @ 16:06:
[...]

Dat clusteren van EMQS geld kost wist ik niet. Voorheen draaide ik dat namelijk op een netwerk van RPIs...

Maar EMQX is mooi en informatief als optie voor een GUI.

Daarnaast heb je nog RabbitMQ. Kan wat bewerkelijker zijn omdat je een MQTT plugin moet gebruiken, immers RabbitMQ doet standaard AMQP.

En wat dacht je van deze, MQTTUI?
Dit is een aparte GUI voor een willekeurige broker en draait vanzelfsprekend in Docker.

[Afbeelding]
EMQX heeft de licentie afgelopen jaar aangepast. Multi-node kan nog wel voor eigen gebruik/hobby maar je moet wel een (en daar zat ik waarschijnlijk fout) vzv ik kan zien gratis licentie voor aanvragen. Daar houdt ik niet zo van ;)

RabbitMQ heb ik in het verleden al eens naar gekeken maar toen was hun MQTT ondersteuning er niet/in een pril statium. Misschien ook maar weer eens proberen.

Met Terdia MQTUI ben ik gosteren aan t kloten geweest. Ik kreeg t niet leek aan de gang. Maar als chatgpt t aanbeveelt zal het toch wel goed moeten zijn ;)

En anders wordt t toch weer het vertrouwde Mosquitto, dan maar geen interface - in de huidige "produktie"omgeving doet die ook gewoon wat ie doen moet. Alleen, een mens wil soms wat extra franje..

  • DjoeC
  • Registratie: November 2018
  • Laatst online: 23:51
Ben.Hahlen schreef op maandag 19 januari 2026 @ 16:15:
[...]

Jazeker, dat is de enige manier dat ik hem heb:
YAML:
1
2
3
4
5
6
7
8
9
10
11
  mqtt-explorer:
    extends:
      file: ../shared.yml
      service: pubnet-shared
    image: smeagolworms4/mqtt-explorer:latest
    container_name: mqtt-explorer
    hostname: mqtt-explorer
    env_file: mqtt-explorer.env
    volumes:
      - ./mqtt-explorer/config:/mqtt-explorer/config
 
Ik ga die zometeen eens uitrollen, die heb ik over t hoofd gezien - zal vast wel verkeerd gezocht hebben. Nou dat dashboard nog, om de stats snel in beeld te hebben, dan ben ik klaar en kan ik gewoon op Mosquitto blijven.

<aanvulling>
MQTT-explorer draait al en net zoals lokaal ;) Top!

[ Voor 4% gewijzigd door DjoeC op 19-01-2026 16:48 ]


  • DjoeC
  • Registratie: November 2018
  • Laatst online: 23:51
Is er een "goede" reden om Python scripts via een Dockerfile uit te rollen naar een "eigen" image ipv een script vanuit de (een) standaard Pyhton image via command vanuit de compose te starten? Als vrijwel iedereen eigen images bakt zal daar best een (door mij niet kunnen vinden) hele goede onderbouwing voor zijn...

Nee, ik gebruik voor eigen images (nog) geen repository en heb dus ook geen automatische bewaking (zoals Watchtower) of er voor een onderdeel van het image updates uitgekomen zijn....

  • Arunia
  • Registratie: Februari 2003
  • Laatst online: 00:31
Ik probeer alles ondertussen steeds beter te stroomlijnen en wat meer in Docker te gooien. Ja, ik gebruik nog steeds Docker Desktop onder Windows met Linux containers en voor mijn taken eigenlijk niet echt problemen. Enige is dat ik aan 16GB ram de laatste tijd op 99 procent zat en nu gelukkig omlaag naar 85 procent. De opslag op mijn bootschijf is ook redelijk vol met nog 20GB over. Wel een clean actie gedaan op de virtuele disk en dat heeft wel wat geholpen.
Alleen waar ik nu naar kijk omdat ik toch nog niet van Windows af durf te stappen voor andere zaken, is om af te stappen van Docker Desktop, maar ben bang dat ik dan alsnog alles opnieuw moet installeren qua containers. Ik krijg het nog niet qua logica in mijn hoofd en wil er toch meer mee doen.
Dus backups maken, alles verwijderen en los in WSL2 verder gaan met Portainer omdat ik dat toch al gebruik.

Qua backups maken zoek ik al best een tijd en kom uit op alles uploaden naar github of docker nog iets. Maar liefste zou ik het gewoon lokaal regelen, maar ben bang dat dat zo makkelijk niet is.
Of de hele container naar een volume zetten en dan weer terug verwijzen na het schoon beginnen.

  • Ghoulli
  • Registratie: Juli 2021
  • Laatst online: 16:58

Ghoulli

Snapt er niks van.

Je kunt er natuurlijk voor kiezen om de Docker Compose files te migreren naar een directory binnen Windows. Met WSL kan je gewoon de Windows directories aanspreken om daar data vanaf te halen. Je kunt dit hetzelfde aanpakken met enige data die echt niet verloren mag raken wanneer de containers migraten. Je kan altijd een private repository opzetten voor jezelf, maar voor nu alles op een directory zetten en dan kopieeren in WSL is niet zo'n grote moeite.

Als je echt een clean install wil, dan zou ik gewoon belangrijke data naar een externe schijf zetten en de compose files op een private Github repo knallen.

  • Arunia
  • Registratie: Februari 2003
  • Laatst online: 00:31
Ghoulli schreef op vrijdag 27 februari 2026 @ 10:51:
Je kunt er natuurlijk voor kiezen om de Docker Compose files te migreren naar een directory binnen Windows. Met WSL kan je gewoon de Windows directories aanspreken om daar data vanaf te halen. Je kunt dit hetzelfde aanpakken met enige data die echt niet verloren mag raken wanneer de containers migraten. Je kan altijd een private repository opzetten voor jezelf, maar voor nu alles op een directory zetten en dan kopieeren in WSL is niet zo'n grote moeite.

Als je echt een clean install wil, dan zou ik gewoon belangrijke data naar een externe schijf zetten en de compose files op een private Github repo knallen.
Ok, thanks. In principe is alles schoon eigenlijk Docker Desktop verwijderen en WSL2 opnieuw inrichten (DD gebruikt nu ook WSL2 btw).
Qua backup gaat het me om wat er aan data in de containers zit.
Maar buiten FireFlyIII en Mealie zal dat ook niet zo heel boeiend zijn. Mealie kan ik gelukkig los backuppen en FireFlyIII op een laag pitje.
Nu ik er zo over nadenk valt het wel mee eigenlijk. De rest lijkt ook niet zo veel om het met de hand te doen. Dacht dat het veel meer was eigenlijk.

Verder heb ik van alles op een Portainer Stack na, gewoon docker compose bestanden.

Dingen die ik nu als applicatie draai, zou ik straks richting Docker willen pushen, maar dan ook met de juiste backups.

[ Voor 3% gewijzigd door Arunia op 27-02-2026 11:04 ]


  • DjoeC
  • Registratie: November 2018
  • Laatst online: 23:51
@Arunia Ik ben begonnen met een Raspberry, Openmediavault bovenop Debian, Docker en Portainer. Inmiddels gebruik ik een Pi5, 16GB intern, 2TB SSD waar ik alles regel binnen de GUI van Openmediavault (versie 8 inmiddels). Alles via de compose optoes die daar inzitten. Ik heb flink wat dingen moeten leren de laatste 4 jaar of zo maar ik ben dik tevreden met hoe OMV de zaken heeft geregeld. Ook backup mogelijkheden zitten daar in.... OMV draait overigens ZONDER desktop, dus op de kale Linux met een GUI. Portainer draai ik nog wel, maar alleen om containers te stoppen en te starten omdat ik daar alle containers/stacks/compose files op 1 scherm kan krijgen, OMV kent maximaal 20 per pagina ;)

Wat je zou kunnen doen is een Debian VM maken op je windows machine en wat experimenteren. Het zou zomaar kunnen dat het iets is dat je bevalt....

  • Airw0lf
  • Registratie: Mei 2005
  • Laatst online: 22:35
Voor de goede orde: volgens mij doet Portainer niks met compose/yaml bestanden. Dus als je iets wijzigt via de gui van Portainer wordt dat niet meegenomen in de compose/yaml bestanden.

makes it run like clockwork


  • ed1703
  • Registratie: Januari 2010
  • Niet online
Airw0lf schreef op vrijdag 27 februari 2026 @ 12:40:
Voor de goede orde: volgens mij doet Portainer niks met compose/yaml bestanden. Dus als je iets wijzigt via de gui van Portainer wordt dat niet meegenomen in de compose/yaml bestanden.
De bedoeling van portainer is dat je de stack aanpast, wat dan weer gewoon een compose is.
compose-file's buiten de stacks kan inderdaad niet. Zo is portainer en ik dacht ook dockge niet gemaakt.

  • Arunia
  • Registratie: Februari 2003
  • Laatst online: 00:31
DjoeC schreef op vrijdag 27 februari 2026 @ 12:37:
@Arunia Ik ben begonnen met een Raspberry, Openmediavault bovenop Debian, Docker en Portainer. Inmiddels gebruik ik een Pi5, 16GB intern, 2TB SSD waar ik alles regel binnen de GUI van Openmediavault (versie 8 inmiddels). Alles via de compose optoes die daar inzitten. Ik heb flink wat dingen moeten leren de laatste 4 jaar of zo maar ik ben dik tevreden met hoe OMV de zaken heeft geregeld. Ook backup mogelijkheden zitten daar in.... OMV draait overigens ZONDER desktop, dus op de kale Linux met een GUI. Portainer draai ik nog wel, maar alleen om containers te stoppen en te starten omdat ik daar alle containers/stacks/compose files op 1 scherm kan krijgen, OMV kent maximaal 20 per pagina ;)

Wat je zou kunnen doen is een Debian VM maken op je windows machine en wat experimenteren. Het zou zomaar kunnen dat het iets is dat je bevalt....
Ik ben jarengeleden ook met kleine servertjes en klooien met een Pi bezig geweest. Op dit moment een server draaien, wel op Windows 11, maar ik heb daar op een bepaalde manier alles ingeregeld wat ik belangrijk vind. Backup, cloud backup, etc. Daar ook software voor aangeschaf, maar dat terzijde. Vandaar dat ik niet zo even over stap op Linux. Uiteraard ken ik Linux ook gewoon. Deels vanwege de Pi en kan ik daar redelijk mee overweg. Voor nu zal dat hem gewoon niet worden en op zich denk ik zonder DD en met WSL2 prima weg te kunnen komen.

  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
Ik loop regelmatig tegen de beperkingen van WSL2 op ten opzichte van een echt Linux systeem. Het geheugen dynamisch alloceren is niet ideaal en met NAT networking werken bepaalde dingen niet zoals verwacht zoals ZeroConf. En IPv6 is ook niet voordehand liggend om aan de praat te krijgen. Ik heb het vooralsnog daarom nog maar gelaten. Laatst had ik nog wel getest met Mirrored networking mode, maar dat had weer andere nadelen. Ik dacht performance, maar ik weet het niet meer zeker.

Op mijn workstation werkt het dus aardig, maar ik zou er niet aan moeten denken omdat als '''server''' te draaien. Idem voor Docker Desktop. Dat is Docker Desktop, niet Docker Server.

  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
Recent ben ik overigens bezig geweest met het security hardenen van mijn containers in Compose. Enerzijds door het inperken van rechten, anderzijds door het inperken van resources. Dat laatste had nog wel een leuk bij effect dat het stroomgebruik van mijn server wat minder piekerig was en dus gemiddeld gezien wat afnam. Tegelijkertijd ben ik me ook wat bewuster geworden van de gebruikte resources en rechten van containers en dat heb ik ook kunnen gebruiken voor o.a. IPv6 Router Advertisements in containers.

Hoe ik het nu in ingeregeld is als volgt. Allereerst de basis:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
services:
  my-service:
    stop_grace_period: 30s
    tty: false
    stdin_open: false
    security_opt:
      - no-new-privileges:true
    tmpfs:
      - /tmp:rw,noexec,nosuid,nodev,size=64m
    logging:
      driver: json-file
      options:
        max-size: "8m"
        max-file: "4"
    pids_limit: 256
Sowieso perk ik de rechten in van tty en stdin. Dat hebben server containers nagenoeg nooit nodig. Ik zet een security_opt dat er ook niet zomaar nieuwe permissies mogen toegewezen. Eigenlijk heeft dat geen zin omdat de container toch alle SELinux capabilities heeft, maar dat doe ik afhankelijk van de applicatie wel met cap_add en cap_drop. Ik zorg dat een container niet zomaar tmpfs kan gebruiken voor evt. executables. Mocht er dus een 'probleemapplicatie' bij zitten dan kan in ieder geval /tmp niet zomaar misbruikt worden. Tot slot zet ik een logging limit om logging bombing te voorkomen en een (hier ruime) pids_limit.

Daar bovenop kan ik dan ook nog de read_only optie plaatsen zodat containers niet zomaar nieuwe bestanden of mappen mogen aanmaken buiten de volume mounts. En een aangepaste user toevoegen, dus niet root. Alhoewel beide opties soms lastig zijn bij sommige containers. Dan krijg je dit soort constructies:
YAML:
1
2
3
4
5
6
7
8
services:
  postgresql:
    user: {{ immich_user }}:{{ immich_group }}
    read_only: true
    tmpfs:
      - /tmp:rw,noexec,nosuid,nodev,size=16m
      - /etc/postgresql:rw,exec,suid,nodev,size=64m
      - /run/postgresql:rw,exec,suid,nodev,size=64m
Daarna perk ik ook resources in met:
YAML:
1
2
3
4
5
6
7
8
9
services:
  my-service:
    pids_limit: 512
    mem_reservation: 512m
    mem_limit: 2048m
    cpus: 2
    cpu_shares: 1024
    cpuset: "12-19"
    oom_score_adj: 0
De meeste opties spreken hier vermoedelijk voor zich, maar hier laat ik dus eigenlijk de Linux scheduler zelf bepalen waar de applicatie draait op de E-cores van mijn processor. Eerder deed ik dit handmatig, maar dit lijkt wat meer rust te geven op het systeem. Ook hebben sommige applicaties wat meer ademruimte omdat ze zichzelf over meerdere cores kunnen verdelen.

Ik wil ook nog kijken hoe ik evt. io kan inperken, maar daar ben ik nog niet helemaal aan toe gekomen. De documentatie is hier op sommige punten wat Spartaans :X.

  • ElCondor
  • Registratie: Juni 2001
  • Laatst online: 20:51

ElCondor

Geluk is Onmisbaar

alex3305 schreef op vrijdag 27 februari 2026 @ 17:27:
Recent ben ik overigens bezig geweest met het security hardenen van mijn containers in Compose. Enerzijds door het inperken van rechten, anderzijds door het inperken van resources. Dat laatste had nog wel een leuk bij effect dat het stroomgebruik van mijn server wat minder piekerig was en dus gemiddeld gezien wat afnam. Tegelijkertijd ben ik me ook wat bewuster geworden van de gebruikte resources en rechten van containers en dat heb ik ook kunnen gebruiken voor o.a. IPv6 Router Advertisements in containers.

Hoe ik het nu in ingeregeld is als volgt. Allereerst de basis:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
services:
  my-service:
    stop_grace_period: 30s
    tty: false
    stdin_open: false
    security_opt:
      - no-new-privileges:true
    tmpfs:
      - /tmp:rw,noexec,nosuid,nodev,size=64m
    logging:
      driver: json-file
      options:
        max-size: "8m"
        max-file: "4"
    pids_limit: 256
Sowieso perk ik de rechten in van tty en stdin. Dat hebben server containers nagenoeg nooit nodig. Ik zet een security_opt dat er ook niet zomaar nieuwe permissies mogen toegewezen. Eigenlijk heeft dat geen zin omdat de container toch alle SELinux capabilities heeft, maar dat doe ik afhankelijk van de applicatie wel met cap_add en cap_drop. Ik zorg dat een container niet zomaar tmpfs kan gebruiken voor evt. executables. Mocht er dus een 'probleemapplicatie' bij zitten dan kan in ieder geval /tmp niet zomaar misbruikt worden. Tot slot zet ik een logging limit om logging bombing te voorkomen en een (hier ruime) pids_limit.

Daar bovenop kan ik dan ook nog de read_only optie plaatsen zodat containers niet zomaar nieuwe bestanden of mappen mogen aanmaken buiten de volume mounts. En een aangepaste user toevoegen, dus niet root. Alhoewel beide opties soms lastig zijn bij sommige containers. Dan krijg je dit soort constructies:
YAML:
1
2
3
4
5
6
7
8
services:
  postgresql:
    user: {{ immich_user }}:{{ immich_group }}
    read_only: true
    tmpfs:
      - /tmp:rw,noexec,nosuid,nodev,size=16m
      - /etc/postgresql:rw,exec,suid,nodev,size=64m
      - /run/postgresql:rw,exec,suid,nodev,size=64m
Daarna perk ik ook resources in met:
YAML:
1
2
3
4
5
6
7
8
9
services:
  my-service:
    pids_limit: 512
    mem_reservation: 512m
    mem_limit: 2048m
    cpus: 2
    cpu_shares: 1024
    cpuset: "12-19"
    oom_score_adj: 0
De meeste opties spreken hier vermoedelijk voor zich, maar hier laat ik dus eigenlijk de Linux scheduler zelf bepalen waar de applicatie draait op de E-cores van mijn processor. Eerder deed ik dit handmatig, maar dit lijkt wat meer rust te geven op het systeem. Ook hebben sommige applicaties wat meer ademruimte omdat ze zichzelf over meerdere cores kunnen verdelen.

Ik wil ook nog kijken hoe ik evt. io kan inperken, maar daar ben ik nog niet helemaal aan toe gekomen. De documentatie is hier op sommige punten wat Spartaans :X.
Nice work! Ik heb nog veel te leren, merk ik wel en ik was zo al tevreden zoals ik het nu ingericht heb.
Maar goed, net pas een beetje de boel aan het stroomlijnen wat beheersbaarheid.
Zal hier binnenkort eens een verhaal neerzetten over mijn infra, zoals ik het nu heb draaien.
Wel alles zoveel mogelijk op Linux, daar draai ik mijn hand niet meer voor om, sinds een paar jaar.
Heb nog wat windows draaien om de kennis op pijl te houden maar Linux is tegenwoordig al wel mijn daily-driver.
Vooral die resource allocation en security measures zijn wel interessant. Niet per s'e voor thuis, want ik publiceer weinig openbaar, maar zeker goed om kennis van te nemen. Op werk gaan we meer en meer met docker en kubernetes doen, dus daar kan het zeker van pas komen.

[ Voor 3% gewijzigd door ElCondor op 05-03-2026 10:11 ]

Hay 365 dias en un año y 366 occasiones para festejar (Boliviaans spreekwoord)


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
ElCondor schreef op dinsdag 3 maart 2026 @ 10:56:
[...]

Nice work! Ik heb nog veel te leren, merk ik wel en ik was zo al tevreden zoals ik het nu ingericht heb.
Maar goed, net pas een beetje de boel aan het stroomlijnen wat beheersbaarheid.
Het is geen wedstrijd hè. Ik ben ook niet gisteren begonnen.

Afbeeldingslocatie: https://tweakers.net/i/U9iw9S0Wo9W8sPyjtQfJCF6Fn1M=/fit-in/4000x4000/filters:no_upscale():strip_exif()/f/image/sXrN32qInRfSBsXfposh7YkG.png?f=user_large

De eerste commit in deze repository dateert alweer uit 2019

Afbeeldingslocatie: https://tweakers.net/i/hYSgqDyRRbTlHcAO67ZN9UXNDY4=/fit-in/4000x4000/filters:no_upscale():strip_exif()/f/image/4wEWWi4rxHogLKOCv1sRL3wU.png?f=user_large
Vooral die resource allocation en security measures zijn wel interessant. Niet per s'e voor thuis, want ik publiceer weinig openbaar, maar zeker goed om kennis van te nemen. Op werk gaan we meer en meer met docker en kubernetes doen, dus daar kna het zeker van pas komen.
Waarom niet voor thuis? Volgens mij is het dan juist interessant. Helemaal met de huidige prijzen van hardware en elektriciteit.

Ik heb nu namelijk de controle over hoeveel geheugen en cpu resources applicaties krijgen in plaats van dat ze geheugen nemen en dit geheugen misschien niet teruggeven zoals gebruikelijk op een Linux systeem. Immers draaien de containers afgesloten. Tegelijkertijd zorgen tmpfs mounts ervoor dat de SSD minder belast wordt door tijdelijke data, zoals transocdering van Plex of Jellyfin. En tot slot zorgt cpuset ervoor dat ik mijn processen primair op de E-cores van de Intel processor kan draaien.

Het verschil in stroomverbruik tussen de P-cores en E-cores is gigantisch. Alhoewel ik de power limits beperkt heb, boosten de P-cores eenvoudig naar 65W als het nodig is. Met out of the box hogere power limits gaat dat naar 95W of 120W. Echter levert dit geen extreme snelheidswinst op. Tegelijkertijd zou een proces zoals Traefik bij load ervoor zorgen dat de processor constant boost, wat het stroomverbruik enorm laat toenemen.

Ik heb niet de meest zuinige setup, maar ik probeer mijn primaire server rond de 20W in idle te houden. De secundaire machine zit zo rond de 3-5W. En dat lukt op deze manier vrij aardig.

  • ElCondor
  • Registratie: Juni 2001
  • Laatst online: 20:51

ElCondor

Geluk is Onmisbaar

alex3305 schreef op dinsdag 3 maart 2026 @ 11:09:
[...]

Het is geen wedstrijd hè. Ik ben ook niet gisteren begonnen.

[Afbeelding]

De eerste commit in deze repository dateert alweer uit 2019

[Afbeelding]


[...]

Waarom niet voor thuis? Volgens mij is het dan juist interessant. Helemaal met de huidige prijzen van hardware en elektriciteit.

Ik heb nu namelijk de controle over hoeveel geheugen en cpu resources applicaties krijgen in plaats van dat ze geheugen nemen en dit geheugen misschien niet teruggeven zoals gebruikelijk op een Linux systeem. Immers draaien de containers afgesloten. Tegelijkertijd zorgen tmpfs mounts ervoor dat de SSD minder belast wordt door tijdelijke data, zoals transocdering van Plex of Jellyfin. En tot slot zorgt cpuset ervoor dat ik mijn processen primair op de E-cores van de Intel processor kan draaien.

Het verschil in stroomverbruik tussen de P-cores en E-cores is gigantisch. Alhoewel ik de power limits beperkt heb, boosten de P-cores eenvoudig naar 65W als het nodig is. Met out of the box hogere power limits gaat dat naar 95W of 120W. Echter levert dit geen extreme snelheidswinst op. Tegelijkertijd zou een proces zoals Traefik bij load ervoor zorgen dat de processor constant boost, wat het stroomverbruik enorm laat toenemen.

Ik heb niet de meest zuinige setup, maar ik probeer mijn primaire server rond de 20W in idle te houden. De secundaire machine zit zo rond de 3-5W. En dat lukt op deze manier vrij aardig.
LOL :D
code:
1
2
PS ❯ git rev-list --count --all
63
Ben net een maandje geleden pas begonnen met git en het structureren van mijn docker omgeving omdat ik tegen allerlei issues aan begon te lopen bij de toenmalige implementatie.
Ik was toen ook nog vanalles aan het uitproberen en had al wel een aantal containers in 'productie' draaien.

Omdat ik vanalles met default settings geinstalleerd had, wilde het nog wel eens voorkomen dat bij update of het opnieuw deployen van een container de data niet persistent bleek te zijn en ik alles kwijt was.
Ik had het toen ook nog op een combinatie van fysieke en virtuele machines draaien waarvan een deel Windows en een deel Linux. En dan voor Linux ook nog op ijzer en een docker instance op een LXC.
Toen ik wat meer begrip van ProxMox begon te krijgen (zie mijn posts in dat draadje) ben ik radicaal gaan schonen in mijn infra. Windows teruggebracht van 6 naar 3 fysieke machines, Hyper-V de deur uit en op 4 machines (2 NUC's en 2 grotere servers) een ProxMox cluster ingericht. Dat tegelijk gedaan met de inrichting van NFS backed storage voor de guests op ProxMox.

Omdat een aantal van die VM's verschillende implementaties van docker draaiden, eens gaan kijken hoe ik NFS storage kon gaan inzetten voor docker. Ik moest voor het toepassen van configuratie wijzigingen op de containers altijd inloggen op de docker host en dan met nano de wijzigingen aanbrengen :F Dan loop je er ook nog tegenaan dat docker op een LXC container niet ideaal is als je een unprivileged container gebruikt. En de containers migreren is een hel als je niet precies weet waar docker data en volumes terecht zijn gekomen.
Met behulp van wat kunst en vliegwerk uiteindelijk alles kunnen consolideren op 3 docker hosts die exact hetzelfde zijn ingericht, zodat ik me niet een slag in de rondte hoef te zoeken naar de data.
  • docker01: essentiele stacks zoals reverse proxy en dashboard
  • docker02: media presentatie stacks zoals audiobookshelf, calibre-web, kavita en binnenkort immich
  • docker03: non-essentiele stacks zoals mktxp, unpoller, guacamole en paperless
Alle stacks maken, waar mogelijk gebruik van volumes op een NFS export op een van mijn NAS-en en alles wordt beheerd vanuit VSCode en Dockhand. :9

Het beheer van docker doe ik vanuit een sysops folder waar ik per docker instance de compose files in bijhoudt en een representatie van de verschillende config volumes voor specifieke containers, zodat ik lokaal de config kan aanpassen en dan vanuit VSCode kan deployen naar de binds op de NAS. Als het meezit, dan pikken de containers ze dan direct op. Dat is helaas niet in alle gevallen zo, omdat containers vaak gebruik maken van inode-monitoring op Linux, en dit werkt niet over NFS. :(

Daarnaast blijkt dat er ook containers zijn die specifiek een config file mounten in de container en het is weer niet mogelijk om zo een file via NFS te provisionen, want dit kan alleen met volledige folders.
Ook zijn er containers die het niet leuk vinden dat hun database draait op NFS (Kavita). Deze kan alleen op local storage draaien anders ondervindt je allerhande database lock exceptions omdat draaien op NFS eenvoudigweg niet ondersteund wordt door SQLite en MEF |:(

Zoals je ziet ben ik nog helemaal niet bezig met het implementeren van security of resource management.
Omdat het om een home-labje gaat vind ik security niet de grootste prio, maar resource management is wel interessant om naar te kijken, dat ben ik wel met je eens.
De hardware die ik gebruik is volgens mij niet zo recent dat er E en P cores in zitten, dus dat zou me niet heel veel helpen, maar wellicht zijn er andere optimalisaties te maken. Vooral geheugen gebruik vindt ik wel interessant, want die Kavita container, staat zelfs in de documentatie, reserveert al het geheugen op de betreffende docker instance (die staat ook altijd in het oranje). Als je dan een htop draait op de host, dan is er niks aan het handje. Dus een beetje vreemd gedrag. :?
Maar prachtige techniek en materie om mee aan het prutselen te zijn. :)

Hay 365 dias en un año y 366 occasiones para festejar (Boliviaans spreekwoord)


  • synoniem
  • Registratie: April 2009
  • Niet online
ElCondor schreef op donderdag 5 maart 2026 @ 10:04:
[...]


LOL :D
code:
1
2
PS ❯ git rev-list --count --all
63
Ben net een maandje geleden pas begonnen met git en het structureren van mijn docker omgeving omdat ik tegen allerlei issues aan begon te lopen bij de toenmalige implementatie.
Ik was toen ook nog vanalles aan het uitproberen en had al wel een aantal containers in 'productie' draaien.

Omdat ik vanalles met default settings geinstalleerd had, wilde het nog wel eens voorkomen dat bij update of het opnieuw deployen van een container de data niet persistent bleek te zijn en ik alles kwijt was.
Ik had het toen ook nog op een combinatie van fysieke en virtuele machines draaien waarvan een deel Windows en een deel Linux. En dan voor Linux ook nog op ijzer en een docker instance op een LXC.
Toen ik wat meer begrip van ProxMox begon te krijgen (zie mijn posts in dat draadje) ben ik radicaal gaan schonen in mijn infra. Windows teruggebracht van 6 naar 3 fysieke machines, Hyper-V de deur uit en op 4 machines (2 NUC's en 2 grotere servers) een ProxMox cluster ingericht. Dat tegelijk gedaan met de inrichting van NFS backed storage voor de guests op ProxMox.

Omdat een aantal van die VM's verschillende implementaties van docker draaiden, eens gaan kijken hoe ik NFS storage kon gaan inzetten voor docker. Ik moest voor het toepassen van configuratie wijzigingen op de containers altijd inloggen op de docker host en dan met nano de wijzigingen aanbrengen :F Dan loop je er ook nog tegenaan dat docker op een LXC container niet ideaal is als je een unprivileged container gebruikt. En de containers migreren is een hel als je niet precies weet waar docker data en volumes terecht zijn gekomen.
Met behulp van wat kunst en vliegwerk uiteindelijk alles kunnen consolideren op 3 docker hosts die exact hetzelfde zijn ingericht, zodat ik me niet een slag in de rondte hoef te zoeken naar de data.
  • docker01: essentiele stacks zoals reverse proxy en dashboard
  • docker02: media presentatie stacks zoals audiobookshelf, calibre-web, kavita en binnenkort immich
  • docker03: non-essentiele stacks zoals mktxp, unpoller, guacamole en paperless
Alle stacks maken, waar mogelijk gebruik van volumes op een NFS export op een van mijn NAS-en en alles wordt beheerd vanuit VSCode en Dockhand. :9

Het beheer van docker doe ik vanuit een sysops folder waar ik per docker instance de compose files in bijhoudt en een representatie van de verschillende config volumes voor specifieke containers, zodat ik lokaal de config kan aanpassen en dan vanuit VSCode kan deployen naar de binds op de NAS. Als het meezit, dan pikken de containers ze dan direct op. Dat is helaas niet in alle gevallen zo, omdat containers vaak gebruik maken van inode-monitoring op Linux, en dit werkt niet over NFS. :(

Daarnaast blijkt dat er ook containers zijn die specifiek een config file mounten in de container en het is weer niet mogelijk om zo een file via NFS te provisionen, want dit kan alleen met volledige folders.
Ook zijn er containers die het niet leuk vinden dat hun database draait op NFS (Kavita). Deze kan alleen op local storage draaien anders ondervindt je allerhande database lock exceptions omdat draaien op NFS eenvoudigweg niet ondersteund wordt door SQLite en MEF |:(

Zoals je ziet ben ik nog helemaal niet bezig met het implementeren van security of resource management.
Omdat het om een home-labje gaat vind ik security niet de grootste prio, maar resource management is wel interessant om naar te kijken, dat ben ik wel met je eens.
De hardware die ik gebruik is volgens mij niet zo recent dat er E en P cores in zitten, dus dat zou me niet heel veel helpen, maar wellicht zijn er andere optimalisaties te maken. Vooral geheugen gebruik vindt ik wel interessant, want die Kavita container, staat zelfs in de documentatie, reserveert al het geheugen op de betreffende docker instance (die staat ook altijd in het oranje). Als je dan een htop draait op de host, dan is er niks aan het handje. Dus een beetje vreemd gedrag. :?
Maar prachtige techniek en materie om mee aan het prutselen te zijn. :)
De problemen met Docker en NFS herken ik wel. De storagedriver die geschikt was voor gebruik met NFS is uitgefaseerd (weet nu uit mijn hoofd het versienummer van Docker niet meer). Sindsdien gebruik ik iscsi voor mijn Pi cluster. Wat nog wel werkt is NFS in de container mounten maar vraagt ook wat extra werk. Wil je echt shared storage voor containers dan is Rancher is een goede optie.

  • ElCondor
  • Registratie: Juni 2001
  • Laatst online: 20:51

ElCondor

Geluk is Onmisbaar

Maar, met iSCSI heb ik op mijn nas dan weer geen toegang tot de inhoud van de LUN, omdat block-based. En het gaat me er juist om dat ik bij de bestanden kan anders dan te moeten inloggen op mijn docker host en daar moet gaan wijzigen. Ik ZOU de iSCSI lun 'loop-back' kunnen mounten op mijn NAS en dan de bestanden ontsluiten, maar ja...

Ik maak dus wél gebruik van NFS mounting dmv de volume definitie in de docker compose. Echt een hele verbetering, want ik kan de compose dan gewoon down gooien op docker 1 en up gooien op docker 2 en het draait daar gewoon verder. Ik zit te denken om een swarm te gaan gebruiken of alles om te bouwen naar Kubernetes, maar ja, zo kan ik nog wel even bezig blijven :)

Rancher heb ik nog niet van gehoord, dus daar ga ik me ook maar eens in verdiepen.

Wat is je ervaring met docker op Pi's. Ik had een stack van 4 Pi 4's waar ik Kubernetes op deployed had, maar bij iedere update klapte de sd-kaartjes er onderuit, om de een of andere reden en ik kreeg het nooit stabiel. Vandaar dat ik op dit moment docker nog draai in VM-s en een test Kubernetes clustertje ook op basis van VM's heb draaien.

Hay 365 dias en un año y 366 occasiones para festejar (Boliviaans spreekwoord)


  • synoniem
  • Registratie: April 2009
  • Niet online
ElCondor schreef op donderdag 5 maart 2026 @ 11:31:
Maar, met iSCSI heb ik op mijn nas dan weer geen toegang tot de inhoud van de LUN, omdat block-based. En het gaat me er juist om dat ik bij de bestanden kan anders dan te moeten inloggen op mijn docker host en daar moet gaan wijzigen. Ik ZOU de iSCSI lun 'loop-back' kunnen mounten op mijn NAS en dan de bestanden ontsluiten, maar ja...

Ik maak dus wél gebruik van NFS mounting dmv de volume definitie in de docker compose. Echt een hele verbetering, want ik kan de compose dan gewoon down gooien op docker 1 en up gooien op docker 2 en het draait daar gewoon verder. Ik zit te denken om een swarm te gaan gebruiken of alles om te bouwen naar Kubernetes, maar ja, zo kan ik nog wel even bezig blijven :)

Rancher heb ik nog niet van gehoord, dus daar ga ik me ook maar eens in verdiepen.

Wat is je ervaring met docker op Pi's. Ik had een stack van 4 Pi 4's waar ik Kubernetes op deployed had, maar bij iedere update klapte de sd-kaartjes er onderuit, om de een of andere reden en ik kreeg het nooit stabiel. Vandaar dat ik op dit moment docker nog draai in VM-s en een test Kubernetes clustertje ook op basis van VM's heb draaien.
Ik heb 12 Pi's die geen sd-kaarten gebruiken maar netwerk booten vanaf TFTP en vervolgens hun eigen specifieke iSCSI image mounten. Voor Raspi OS ziet die mount eruit als een gewone fysieke harde schijf en docker kan zijn standaard storage driver gebruiken. Zolang je een 64 bit versie gebruikt kun je k0s of k3s of minik8s gebruiken maar vind ik wat overkill voor een Pi en ik gebruik daarom gewoon docker swarm/stack. Voor testdoeleinden gebruik ik 4 NUC's als Kubernetes clustertje maar dan de k3s versie (alleen een beetje weinig tijd voor op het moment).

  • ElCondor
  • Registratie: Juni 2001
  • Laatst online: 20:51

ElCondor

Geluk is Onmisbaar

synoniem schreef op donderdag 5 maart 2026 @ 11:50:
[...]

Ik heb 12 Pi's die geen sd-kaarten gebruiken maar netwerk booten vanaf TFTP en vervolgens hun eigen specifieke iSCSI image mounten. Voor Raspi OS ziet die mount eruit als een gewone fysieke harde schijf en docker kan zijn standaard storage driver gebruiken. Zolang je een 64 bit versie gebruikt kun je k0s of k3s of minik8s gebruiken maar vind ik wat overkill voor een Pi en ik gebruik daarom gewoon docker swarm/stack. Voor testdoeleinden gebruik ik 4 NUC's als Kubernetes clustertje maar dan de k3s versie (alleen een beetje weinig tijd voor op het moment).
Maar, als jij dus voor een specifieke containerized app configuratie aanpassingen wilt doen, dan doe je dat door in te loggen op een van de Pi's of het cluster en dan op het 'lokale' file system je ding te doen?

Ik wil juist niet hoeven in te loggen op de docker host en mijn applicatie config binds op één centrale plek beschikbaar hebben. Vandaar de NFS volume mounts. Alle docker instances maken dus gebruik van dezelfde volume mount waarop alle binds te vinden zijn.

Hay 365 dias en un año y 366 occasiones para festejar (Boliviaans spreekwoord)


  • synoniem
  • Registratie: April 2009
  • Niet online
ElCondor schreef op donderdag 5 maart 2026 @ 12:26:
[...]

Maar, als jij dus voor een specifieke containerized app configuratie aanpassingen wilt doen, dan doe je dat dor in te loggen op een van de Pi's of het cluster en dan op het 'lokale' file system je ding te doen?

Ik wil juist niet hoeven in te loggen op de docker host en mijn applicatie config binds op één centrale plek beschikbaar hebben. Vandaar de NFS volume mounts. Alle docker instances maken dus gebruik van dezelfde volume mount waarop alle binds te vinden zijn.
Ik heb zowel de Dockerfile als de container image in Forgejo (voorheen Gitea) staan (git en container registry ineen). Als ik wat wil wijzigen doe ik dat in de Dockerfile en push een nieuwe image naar de container registry en doe een swarm update. Als ik een shared volume nodig heb voor de containers in de swarm/kubernetes gebruik ik Rancher maar voor de kleine dingen die ik met die Pi's doe heb ik dat niet nodig die gebruiken een centrale database(container) of een REST-api.

  • ElCondor
  • Registratie: Juni 2001
  • Laatst online: 20:51

ElCondor

Geluk is Onmisbaar

Ik snap hem, dan heb je dus nog een build straat voor de docker deployment zelf staan.
Ik gebruik alleen maar prefab containers en build geen images zelf. Dat is nog wel het overwegen waard inderdaad.
Dus van docker image naar een nieuwe lokale build en dan deployment naar een nieuwe versie van de stack op basis van het lokaal gebuilde image.
Daar zal ik me ook eens in gaan verdiepen. :D

Hay 365 dias en un año y 366 occasiones para festejar (Boliviaans spreekwoord)


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
@ElCondor Goed dat je het aan het opzetten / structureren bent toch? Het is geen wedstrijd hè :).

NFS en Docker heb ik ook nog een tijdje meegewerkt, maar dat was om meerdere redenen niet ideaal. Het direct mounten van NFS volumes in een Compose stack vond ik niet echt handig. Vooral wanneer een NFS server niet werkte was het niet heel erg transparant waar het dan misging. En inmiddels wordt die storage driver, zoals @synoniem terecht opmerkt, niet meer ondersteund.

Daarnaast geeft de netwerklatency op momenten soms onverwachte resultaten. Dat zal met Proxmox als host wat minder een probleem zijn, maar probeer ik altijd wel in het achterhoofd te houden.

Tot slot zijn permissies ook niet altijd ideaal of handig in te stellen. Vooral als je niet met root-achtige users werkt. Hef liefste wil je dan of de Docker conatiner als root of de mount als root, maar dat voelt dan ook niet heel erg lekker. Of de NFS mount zonder permissies gebruiken, maar dat geeft mij hetzelfde gevoel.

Ik heb ook nog wel gekeken naar Ceph, maar dat vond ik nogal overkill voor mijn use-case; en GlusterFS maar dat is ook niet ideaal in het onderhoud en staat op een laag pitje. Andere, kleinere projecten heb ik ook nog bekeken, maar het is/was me de moeite in ieder geval nu niet waard. Ik gebruik dus nu geen shared volumes.

Tegelijkertijd zit ik ook bijna nooit op systemen te werken. Ik heb het hier al eerder genoemd, maar vanuit mijn werkervaring doe ik mijn deployment volledig met Ansible. Grotendeels of eigenlijk bijna alleen maar vanuit Forgejo. Dit combineer ik dan met Renovate voor versiebeheer. En ben ik enorm over te spreken.

In principe heb ik 4 nodes die ik hiermee beheer: primaire, secundaire, een 'support' en een remote. De primaire node heeft aardige specs met een Intel 13500. Op deze node draaien eigenlijk alle applicaties. Die zijn zo'n 35 Compose projecten.

De secundaire node was vroeger mijn primaire machine en heeft maar een Intel J4105 :+. Op deze node staan momenteel applicaties die interfacen met hardware, zoals Zigbee2MQTT, OTBR en Z-WaveJS. Er zit namelijk een bug in de Intel 600-series chipset van de primaire machine die ervoor zorgt dat bij USB2.0 apparaten het energieverbruik toeneemt met minimaal 5W en C-States niet meer correct werken. Tja, dan kan ik net zo goed deze machine inzetten als backup en extra :). Die verbruikt in idle namelijk minder 8)7...

De support node is een oude Pi 3B, eigenlijk de ex-ex-primair :+. Die doet al jaren dienst als boiler thermometer en sinds een paar maanden ook als uptime monitor. Hiervoor gebruik ik gatus die ik configureer via Ansible. Eerder gebruikte ik altijd Uptime Kuma, maar die werd bij mij na een relatief korte periode altijd heel traag. Ook vond ik het inregelen via de UI niet bijzonder geslaagd. Alhoewel deze machine gekoppeld zit via een trage wifi chip met meerdere muren ertussen werkt dat verrassend goed.

Tot slot heb ik nog een remote machine. Dit is een trage VPS met 1TB aan opslag. Die gebruik ik als remote backup. Ik wil deze machine binnenkort eveneens gaan uitbreiden met een uptime monitor. Hoe of wat, moet ik nog bezien.

Doordat ik dus vier compleet verschillende machines heb, heb ik dus ook wat minder behoefte aan gedeelde volumes. Toegegeven, het zou soms handig zijn. Bijvoorbeeld met het HA draaien van Traefik. Anderzijds heb ik het ook niet echt nodig... Ik kan overigens ook niet zomaar Swarm deployments gebruiken omdat daarin cpuset ontbreekt. Kubernetes heb ik niet verder meer naar gekeken. Daar had ik weinig behoefte meer aan als ik thuis kwam van werk :+.

Resource monitoring doe ik overigens met Beszel en kan ik iedereen van harte aanraden. Dat is enorm snel en licht. Sinds kort zit er ook ondersteuning in voor Docker containers en Docker logs. Dat komt soms enorm van pas.

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op donderdag 5 maart 2026 @ 15:11:
De support node is een oude Pi 3B, eigenlijk de ex-ex-primair :+. Die doet al jaren dienst als boiler thermometer en sinds een paar maanden ook als uptime monitor. Hiervoor gebruik ik gatus die ik configureer via Ansible. ]
Ik ken gatus niet, maar zie dat je die configureert met een configfile, die zul je via Ansible beheren neem ik aan? Zo ja, template je die?
Of gebruik je docker labels?
Eerder gebruikte ik altijd Uptime Kuma, maar die werd bij mij na een relatief korte periode altijd heel traag. Ook vond ik het inregelen via de UI niet bijzonder geslaagd.
Uptime Kuma v2 met MariaDb doet het hier wel een stuk beter (tot nu toe).En over AutoKuma (met docker labels, had ik eerder al over gepost in dit topic) ben ik wel te spreken.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
blackd schreef op donderdag 5 maart 2026 @ 19:33:
[...]

Ik ken gatus niet, maar zie dat je die configureert met een configfile, die zul je via Ansible beheren neem ik aan? Zo ja, template je die?
Yes en yes. Nu nog gewoon uit configuratie. Het staat nog op mijn lijstje om er een aparte Ansible task van te maken. Dus containers ophalen van host A en templaten naar Gatus.
Of gebruik je docker labels?
Nee. Leuk idee, maar met meerdere hosts niet bijster handig. Dan zou ik de configuratiefiles moeten genereren en kopiëren. Dat vind ik onhandig. Nu is het misschien niet zo strak of automatisch, maar sinds de inrichting heb ik eigenlijk nog niets aangepast.
Uptime Kuma v2 met MariaDb doet het hier wel een stuk beter (tot nu toe).En over AutoKuma (met docker labels, had ik eerder al over gepost in dit topic) ben ik wel te spreken.
Nice. Versie 2 heb ik nog niet geprobeerd. Ik heb Uptime Kuma een aantal keer geprobeerd, maar Gatus doet nu voor mij wat het moet doen.

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op donderdag 5 maart 2026 @ 22:41:
Nee. Leuk idee, maar met meerdere hosts niet bijster handig. Dan zou ik de configuratiefiles moeten genereren en kopiëren. Dat vind ik onhandig. Nu is het misschien niet zo strak of automatisch, maar sinds de inrichting heb ik eigenlijk nog niets aangepast.
Wat dat betreft past AutoKuma & Uptime Kuma wel weer beter bij jouw use case, je zou meerdere AutoKuma's kunnen opzetten (één per host, uitlezen lokale Docker socket) en die allemaal laten verwijzen naar één Uptime Kuma instantie.

Ik ben wel blij met de labels op mijn Compose projects. Houdt alles bij elkaar.
Een valkuil van monitoring configuratie met labels is wel: zodra je docker compose project niet meer bestaat op de host, wat gebeurt er dan met de monitor in Uptime Kuma? Dat kun je gelukkig configureren met AUTOKUMA__ON_DELETE.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
blackd schreef op zondag 8 maart 2026 @ 08:51:
[...]

Wat dat betreft past AutoKuma & Uptime Kuma wel weer beter bij jouw use case, je zou meerdere AutoKuma's kunnen opzetten (één per host, uitlezen lokale Docker socket) en die allemaal laten verwijzen naar één Uptime Kuma instantie.
Ja wellicht wel.

Ik vond het destijds een prachtig product, maar v1 werd bij mij altijd na een paar weken rete langzaam :|. Ook is op een gegeven moment de ontwikkeling redelijk gestagneerd. Niet zo erg, maar vind ik altijd een beetje spannend bij een dergelijk eenpitter-project :X.

Toen kwam die dev met Dockge als alternatief voor Portainer. Prachtig en gebruik ik nog steeds. Maar toen dat een beetje begon te lopen ging de dev weer terug naar Uptime Kuma om Dockge zowat te laten varen :|. De laatste release van Dockge is bijna 1 jaar oud, en de laatste nieuwe functie is alweer 2 jaar geleden geïntroduceerd.

Voor mij is een dergelijk open source project geen verplichting, maar daar staat tegenover dat Uptime Kuma en Dockge bij mij in het hoekje infrastructuur vallen. En dat moet wel een beetje betrouwbaar zijn. Een dev die komt en gaat is dat wat mij betreft niet echt.

Dit is mijn persoonlijke overweging. En ik ben bijna zeker dat Uptima Kuma een beter en mooier product is, maar ik vind de simpelheid van Gatus momenteel perfect voor mijn use-case op een Pi 3B. Het zou vast kunnen dat ik over een paar maanden of een jaar weer iets anders uitprobeer. Zo blijf ik ook nog een beetje bezig :P

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op zondag 8 maart 2026 @ 14:26:
Zo blijf ik ook nog een beetje bezig :P
Zo is het. Het is daarnaast leuk om op deze manier ervaringen met verschillende tools uit te wisselen.

Zo heb ik een aantal maanden geleden een complete molecule test set ontwikkeld op mijn docker compose stacks.

Bij een aanpassing van een docker compose role waarvoor een test scenario aanwezig is, wordt die test case uitgevoerd. Werkt perfect.

Die heeft daarna al vrij snel een probleem weten te voorkomen met het updaten van Plex (ze hadden het hele release gebeuren omgegooid en mijn renovate config was niet strikt genoeg en renovate proveerde te upgraden naar een armhf image).

Daarnaast heb ik nu ook een template role opgezet die een docker compose project genereert, door het opgeven van aantal parameters. Die heb ik daarnaast uitgebreid met een test scenario in molecule.

Met een task roep ik ansible galaxy init role aan (met template) en daarna verplaats ik het scenario naar de juiste folder.

Als iemand daar meer over wil weten, laat maar weten.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
@blackd Altijd interessant. Molecule staat ook nog steeds ergens op een lijstje. Tegelijkertijd heb ik er nog geen noodzaak voor gehad :|. Dus ben wel benieuwd hoe jij dat doet :).

Ik gebruik nu alweer een tijdje een Ansible anti-patroon om mijn Docker Compose applicaties uit te rollen. Namelijk een 'common' role. Ik ben er zelf ook geen fan van, maar de alternatieven zijn een git submodule. Dat werkt wel, maar vind ik niet transparant. En daarmee dus onhandig. Of op 40+ plekken dezelfde checks. Die bij een aanpassing op alle plekken aangepast moeten worden. Nou, dat doe ik dus niet. Of ik vergaat er eentje, en dan zijn de resultaten soms onverwacht :F.

Ik had de stap gemaakt omdat ik dacht deze rol - en uiteindelijk al mijn andere rollen - in een Ansible Collection. Helemaal (y). Totdat ik erachter kwam dat dependencies niet echt dependencies zijn. En dat je deze dependencies alleen mag includen vanuit Ansible Galaxy. Niet super bezwaarlijk, maar eerlijk gezegd heb ik tijdens het testen daar weinig trek in. Ik heb dat dus nu even overgeslagen...

Waarschijnlijk dat ik t.z.t. wat rollen los in eigen Git repo's zet. Maar ja, dat vind ik weer lelijk met zo'n common role die geen echte afhankelijkheid is. Je ziet waarschijnlijk al waar dit heengaat, een mooi, mentaal cirkeltje :+.

Een ander alternatief zou zijn om een Docker Compose Jinja template op te bouwen vanuit Jinja includes of macro's. Dan zou het e.e.a. meer configuratie worden dan volledige yaml files. Hier heb ik vanuit mijn vorige baan redelijk wat nachtmerries van overgehouden O-). En dan krijg je ook weer van dit soort 'gare' constructies:
Django/Jinja:
1
{{ lookup('ansible.builtin.template', './docker_resources.yaml.j2', template_vars={'cpuset': '12-18', 'memory_limit': '2048'}) }}
En dan heb ik het nog niet over relatieve pad referenties :X...

Zoiets zou mijn leven makkelijker moeten maken, niet moeilijker. Ik hou het dus nog even bij mijn mono-repo denk ik :9

  • blackd
  • Registratie: Februari 2001
  • Niet online
@alex3305 ik heb ook een mono repo én een docker_compose_base role met veelgebruikte tasks.
Ik gebruik de collection testing van molecule om per role een scenario te hebben, met een default scenario voor prepare en destroy.

De prepare en destroy tuigen een docker container op, dat is de test resource.
In de converge stap pas ik de role toe (plaatsen compose files, docker compose up) en in de verify check ik of de container (van het compose project) draait.

Aangezien ik dit zowel lokaal op een devcontainer draai, als in GitHub actions, zit er wat DinD logica in wat het uitdagend maakt. Ik zal binnenkort wel eens wat posten.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op zondag 8 maart 2026 @ 21:42:
@blackd Altijd interessant. Molecule staat ook nog steeds ergens op een lijstje. Tegelijkertijd heb ik er nog geen noodzaak voor gehad :|. Dus ben wel benieuwd hoe jij dat doet :).

Ik gebruik nu alweer een tijdje een Ansible anti-patroon om mijn Docker Compose applicaties uit te rollen. Namelijk een 'common' role. Ik ben er zelf ook geen fan van, maar de alternatieven zijn een git submodule.
Dit heb ik dus ook:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
docker_compose_base
├── defaults
│   └── main.yml
├── tasks
│   ├── build.yml
│   ├── chown_dataset.yml
│   ├── copy.yml
│   ├── create_dataset.yml
│   ├── delete.yml
│   ├── delete_app.yml
│   ├── delete_dataset.yml
│   ├── down.yml
│   └── up.yml
└── vars
    └── main.yml
en die gebruik ik in mijn docker compose roles als volgt (dockge als voorbeeld):
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
---
- name: Copy tasks
  ansible.builtin.import_role:
    name: docker_compose_base
    tasks_from: copy
  vars:
    docker_compose_base__stack_base_dir: "{{ dockge__stack_base_dir }}"

# place custom docker compose project setup here

- name: Docker Compose Up
  ansible.builtin.import_role:
    name: docker_compose_base
    tasks_from: up
  vars:
    docker_compose_base__stack_base_dir: "{{ dockge__stack_base_dir }}"
De copy.yml gebruikt ansible.builtin.template om templates/compose.yml en templates/.env.j2 te plaatsen in de project directory.
De up.yml doet een docker compose up in de project directory.

Ik had al verklapt dat ik molecule collections tests had gebruikt. Qua structuur ziet dat er zo uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
extensions
└── molecule
    ├── config.yml
    ├── default
    │   ├── create.yml
    │   ├── destroy.yml
    │   ├── molecule.yml
    │   └── tasks
    │       ├── assert-container.yml
    │       ├── create-fail.yml
    │       └── set-permissions.yml
    ├── dockge
    │   ├── cleanup.yml
    │   ├── converge.yml
    │   ├── molecule.yml
    │   └── verify.yml
    [snip]
    └── uptime_kuma_v2
        [snip]
Het staat ook uitgelegd in de docs maar eerst wordt het scenario default/create.yml playbook uitgevoerd, daarna per scenario de converge, verify en cleanup, vervolgens scenario default/destroy.yml.

De belangrijkste config hiervoor is extensions/molecule/config.yml.

Hier is dus het test_sequence scenario expliciet gemaakt. Zelf gebruik ik alleen converge, verify, cleanup.
De shared_state=true zorgt ervoor dat default/create.yml als eerste (voor alle andere scenario's) wordt uitgevoerd, en default/destroy.yml als laatste (na alle andere scenario's) wordt uitgevoerd.

Om dit te laten werken, moest ik wel een galaxy.yml in mijn root project folder aanmaken (via ansible-creator
init collection <namespace>.<collection>). Zie deze documentatie.

Dan heb ik het default scenario als volgt:
default/create.yml:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
---
- name: Create
  hosts: localhost
  connection: local
  gather_facts: false

  tasks:
    - name: Create dind-network
      community.docker.docker_network:
        name: dind-network
        state: present

    - name: Create dind-daemon container
      community.docker.docker_container:
        name: my-dind-daemon
        image: docker:dind
        docker_host: unix:///var/run/docker.sock
        state: started
        command: ["--data-root", "/var/lib/docker"]
        privileged: true
        env:
          DOCKER_TLS_CERTDIR: ""
        networks:
          - name: dind-network
            aliases:
              - docker

    - name: Create a container
      community.docker.docker_container:
        name: "{{ item }}"
        image: "{{ hostvars[item].image }}"
        docker_host: unix:///var/run/docker.sock
        state: started
        command: sleep 1d
        log_driver: json-file
        networks:
          - name: dind-network
        env:
          DOCKER_HOST: "tcp://docker:2375"
      register: result
      loop: "{{ groups['molecule'] }}"

    - name: Fail if container is not running
      when: >
        item.container.State.ExitCode != 0 or
        not item.container.State.Running
      ansible.builtin.include_tasks:
        file: tasks/create-fail.yml
      loop: "{{ result.results }}"
      loop_control:
        label: "{{ item.container.Name }}"

- name: Prepare
  hosts: molecule
  gather_facts: true

  pre_tasks:
     [ hier alle voorwaarden waaraan de test-resource moet voldoen,
      in mijn geval een bepaalde uid/gid ]
  roles:
     [ hier alle voorwaarden van roles (in mijn geval galaxy roles) 
      die geinstalleerd moeten staan, vóór testuitvoer ]
  post_tasks:
     [ hier alle voorwaarden die afhankelijk zijn van de roles, 
       in mijn geval een shared docker netwerk voor traefik ]
default/destroy.yml:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
---
- name: Destroy molecule containers
  hosts: molecule
  gather_facts: false
  tasks:
    - name: Stop and remove molecule container
      delegate_to: localhost
      community.docker.docker_container:
        name: "{{ inventory_hostname }}"
        state: absent
        auto_remove: true
        docker_host: unix:///var/run/docker.sock

    - name: Stop and remove dind container
      delegate_to: localhost
      community.docker.docker_container:
        name: my-dind-daemon
        state: absent
        auto_remove: true
        docker_host: unix:///var/run/docker.sock

    - name: Destroy networks
      delegate_to: localhost
      community.docker.docker_network:
        name: "{{ item }}"
        state: absent
        docker_host: unix:///var/run/docker.sock
      loop:
        - [ mijn traefik netwerk ] 
        - dind-network
Je ziet dat ik een inventory heb met een molecule test resource, deze wordt in config.yml geconfigureerd en ziet er als volgt uit:
extensions/molecule/inventory.yml:
YAML:
1
2
3
4
5
6
7
8
9
10
---
all:
  children:
    molecule:
      hosts:
        molecule-debian12:
          image: geerlingguy/docker-debian12-ansible
          ansible_connection: community.docker.docker
      vars:
        [ evt noodzakelijke host vars ]
Tot zover alle 'scaffolding' en je moet een beetje door de DinD heen kijken om het te begrijpen.

Dan duiken we nu in één scenario, van dockge, daar doe ik eerst de converge (role toepassen), daarna verify (controleren op gewenste resultaat), cleanup (opruimen).
Om dat uberhaupt te laten werken, moet er een molecule.yml aanwezig zijn, die leeg is:

extensions/molecule/dockge/molecule.yml:
YAML:
1
Molecule zoekt gewoon naar de glob extensions/molecule/*/molecule.yml

Dan de converge stap, het toepassen van de role op de test resource:

extensions/molecule/dockge/converge.yml:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---
# Purpose: bring the instance to the desired state by running the role under test.
# Molecule calls this playbook with `molecule converge`.
- name: Converge
  hosts: molecule
  gather_facts: false # Disable if your role does not rely on facts

  # Set Docker host to communicate with the Docker daemon inside the DinD container
  environment:
    DOCKER_HOST: tcp://docker:2375/

  tasks:
    - name: Apply role under test
      ansible.builtin.include_role:
        name: <namespace>.<collection>.dockge
Je ziet dat DOCKER_HOST verwijst naar de DinD container (my-dind-container heeft een alias docker op het dind-network).

Onderwater worden de roles in mijn collection als dependency geinstalleerd bij het uitvoeren van Molecule, vandaar de include_role met volledige galaxy namespace (uit galaxy.yml). Hierdoor zijn ingewikkelde relatieve paden niet nodig.

Dan de verify stap om te controleren of alles goed is gegaan:

extensions/molecule/dockge/verify.yml:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
---
# Purpose: assert that the instance really ended up in the expected state.
# Molecule calls this playbook with `molecule verify`.
- name: Verify
  hosts: molecule
  gather_facts: false # Quicker, if you do not need facts

  tasks:

    - name: Assert container running
      ansible.builtin.include_tasks:
        file: ../default/tasks/assert-container.yml
      loop:
        - dockge-dockge-1
Ik heb hier een reusable task van gemaakt die ik in alle scenario's hergebruik.

extensions/molecule/default/tasks/assert-container.yml:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
---
- name: Exit if item not provided
  ansible.builtin.assert:
    that:
      - item is defined
    fail_msg: >
       Error running assert container task
       Variable {{ item }} should be provided in a loop, but is not present.

- name: Obtain container info
  community.docker.docker_container_info:
    name: "{{ item }}"
  register: container_info

- name: Assert container exists
  ansible.builtin.assert:
    that:
      - container_info.container is not none
    fail_msg: Container {{ item }} is not running

- name: Assert container is running correctly
  ansible.builtin.assert:
    that:
      - container_info.container.State.Running == true
      - container_info.container.State.ExitCode == 0
      - container_info.container.State.Restarting == false
    fail_msg: "The container {{ item }} is not running as expected."
    success_msg: "The container {{ item }} is running as expected."
Je ziet dat ik controleer of de state van de container juist is, maar je kan natuurlijk ook andere zaken controleren.
Alleen al voor het testen van templates zou molecule best een goede tool zijn.

Dan de cleanup playbook, die haalt de container down en gooit de files weer weg.
Heb weer DOCKER_HOST laten verwijzen naar DinD container.

extensions/molecule/dockge/cleanup.yml:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
---
- name: Cleanup
  hosts: molecule
  gather_facts: false
  vars:
    compose_project_dir: "{{ dockge__stack_base_dir | default('/opt/stacks/dockge') }}"

  # Set Docker host to communicate with the Docker daemon inside the DinD container
  environment:
    DOCKER_HOST: tcp://docker:2375/

  tasks:
    - name: Check if compose_project_dir exists
      ansible.builtin.stat:
        path: "{{ compose_project_dir }}"
      register: compose_dir_stat

    - name: Docker compose down
      become: true
      community.docker.docker_compose_v2:
        project_src: "{{ compose_project_dir }}"
        state: absent
      when: compose_dir_stat.stat.exists

    - name: Remove folder
      ansible.builtin.file:
        path: "{{ compose_project_dir }}"
        state: absent
      become: true
Als ik nu molecule test uitvoer in mijn project root, worden alle tests uitgevoerd.
Met -s kan ik één (of meerdere) scenario's uitvoeren.

In mijn CI check ik met een script welke files in /roles/ worden gewijzigd en als er een overeenkomstige folder in extensions/molecule is, trap ik die met molecule -s af.
Ik heb nog niet voor alle roles een scenario, maar wel voor alle docker compose projects op mijn TrueNAS machine.

Wat nog wel lastig was is omgaan met volumes (gemount op docker host), deze komen ook in de DinD container terecht.

Mijn docker compose projects draaien op TrueNAS en per applicatie maak ik een dataset aan. Ik heb dus een reusable task in docker_compose_base om deze datasets aan te maken. Deze stap sla ik over bij het uitvoeren van Molecule tests (met de tag "notest") maar om de permissies wel goed te hebben tijdens de tests, voer ik pre_tasks uit in de converge playbook om permissies goed te zetten. Hieronder de reusable task die met docker_container_exec wat magic uitvoert in de DinD container.

extensions/molecule/default/tasks/set-permissions.yml:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
---
- name: Exit if item not provided
  ansible.builtin.assert:
    that:
      - item is defined
      - item_uid is defined
      - item_gid is defined
    fail_msg: >
       Error running set permissions task.
       Check if all required variables are set correctly.
       Variable {{ item }} should be provided in a loop.
       Variables {{ item_uid }} and {{ item_gid }} should be defined.


- name: Set permissions inside my-dind-daemon container
  delegate_to: localhost
  community.docker.docker_container_exec:
    container: my-dind-daemon
    command: >
      sh -c "mkdir -p {{ item }} &&
              chown -R {{ item_uid }}:{{ item_gid }} {{ item }} &&
              chmod -R 775 {{ item }}"
    docker_host: unix:///var/run/docker.sock
Al met al was het best een klus om dit allemaal werkend te krijgen, maar als je één simpel scenario op een gegeven moment werkend hebt, volgt de rest daarna vrij snel. Ik ben begonnen met simpele compose projecten zonder docker volume mounts, daarna de complexere projecten met volume mounts opgepakt.

Voor Traefik heb ik nog op het lijstje om met Let's Encrypt staging te gaan werken of met een stub wat betreft de certificaten. Ook zou ik daar de Cloudflare tunnel willen 'stubben' o.i.d.
Zo is er altijd ruimte voor verbetering :).

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • Arunia
  • Registratie: Februari 2003
  • Laatst online: 00:31
Ik vind het echt fantastisch dat mijn topic prima loopt en als ik zo jullie dingen zie, duizelt het me echt zo nu en dan. Maar, dat vind ik alleen maar leuk!

Ga binnenkort Docker Desktop verwijderen en via WSL-2 en denk Portainer, Docker draaien in een VM onder Windows. Als dat werkt en ik heb de huidige onderdelen daar weer in staan, dan ga ik verder met Plex, Rustdesk, Nextcloud, Immich en nog legio andere dingen in Docker onderbrengen.
Wil nog reverse nat/proxy (even de correcte naam vergeten om met namen verschillende onderdelen aan te spreken in plaats van IP en poort.

Voornamelijk de reden om van DD af te stappen is, omdat ik het idee heb dat deze aardig zwaar is. Zit nu constant op 98 procent en er overheen van het RAM geheugen welke 16GB is.
Als ik nu RDP richting mijn server, duurt het een aardige tijd voor deze weer online is. Terwijl het RAM geheugen niet vol beschikbaar zou moeten zijn. Wellicht nog wat WSL-2 instellingen die ik aan kan passen, maar dat moet ik verder onderzoeken.

Ik ben het eens dat het niet ideaal is omdat Docker onder Windows te draaien, maar kan nog geen afscheid nemen van Windows zelf. Wellicht ooit bij een volgende pc, maar voor nu niet en over het algemeen loopt het ook gewoon prima.

  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
@blackd Thanks voor de enorm uitgebreide post _/-\o_ Ik heb er nu even doorheen gelezen, maar dit zet ik zeker op mijn lijstje om op een later moment op te gaan pakken :D.

Ik vind het wel enorm leuk om te zien dat onze Docker + Ansible aanpak enorm veel overeenkomsten heeft :D.

Ik heb momenteel mijn structuur zo opgezet, met als voorbeeld mijn 'common' role.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
group_vars/
host_vars/
playbooks/
roles/
  └── common/
      ├── defaults/
      │   └── main.yml 
      ├── tasks/
      │   ├── assert/
      │   │   ├── devices.yml
      │   │   ├── docker.networks.yml
      │   │   ├── docker.proxy.yml
      │   │   ├── docker.resources.yml
      │   │   ├── docker.volumes.yml
      │   │   └── storage.yml
      │   └── compose/
      │       ├── up.yml
      │       ├── down.yml
      │       └── remove.yml
      └── vars/
          └── main.yml
De defaults zijn wat defaults voor o.a. Docker, de vars hebben voornamelijk 'interne' variabelen en statische strings die ik hergebruik, bijvoorbeeld:
YAML:
1
2
3
4
5
6
7
8
_parent_role: "{{ ansible_parent_role_names | last }}"

_compose_filename: 'compose.yaml'
_compose_env_filename: ".env"

_is_unraid: >-
  {{ 'slackware' in (ansible_facts['distribution'] | lower) and
      'unraid' in (ansible_facts['kernel'] | lower) }}
En tot slot heb ik mijn tasks opgesplitst in momenteel twee categorieën: assertions en Compose.

Elke set met tasks begint bij mij overigens hetzelfde:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- name: Assert role isn't invoked directly
  ansible.builtin.assert:
    that:
      - ansible_parent_role_names is defined
      - ansible_parent_role_names is iterable and
        ansible_parent_role_names is not string
      - ansible_parent_role_names | default([]) | length > 0
      - _parent_role is defined
      - _parent_role is string
      - _parent_role | length > 0
    fail_msg: >-
      The 'common' role is an internal utility role and should not be
      invoked directly.
  tags:
    - always
Het is namelijk niet de bedoeling dat deze tasks op zichzelf gebruikt worden.

De assertions gebruik ik puur en alleen om geen oneindige herhaling van code / configuratie te hebben. Een paar voorbeelden:

assert/docker.networks.yml
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
- name: "{{ _parent_role }} : Assert Docker networks are provided"
  ansible.builtin.assert:
    that:
      - docker_networks is defined
      - docker_networks is iterable and docker_networks is not string
      - docker_networks | length > 0
    fail_msg: No, an invalid or an empty `docker_networks` list was provided.

- name: "{{ _parent_role }} : Assert Docker volumes have the correct format"
  ansible.builtin.assert:
    that:
      - item is defined
      - item is mapping
      - item.name is defined
      - item.name is string
      - item.name | length > 0 and item.name | length <= 64
      - (item.ipv4_address | default()) is defined
      - (item.ipv4_address | default(none)) is none or
        item.ipv4_address is ansible.utils.ipv4_address
      - (item.ipv6_address | default()) is defined
      - (item.ipv6_address | default(none)) is none or
        item.ipv6_address is ansible.utils.ipv6_address
      - (item.driver_opts | default()) is defined
      - (item.driver_opts | default(none)) is none or
        item.driver_opts is mapping
    fail_msg: >-
      The provided Docker networks mapping has an incorrect format. A `name`
      attribute is required per network. An optional IPv4 address and/or an
      optional IPv6 address can be provided. As well as a `driver_opts`
      mapping.
  loop: "{{ docker_networks }}"

- name: "{{ _parent_role }} : Test if provided Docker network exists"
  community.docker.docker_network_info:
    name: "{{ item.name }}"
  register: _docker_network_info_output
  failed_when: not _docker_network_info_output.exists
  loop: "{{ docker_networks }}"
assert/docker.resources.yml
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- name: "{{ _parent_role }} : Assert Docker resource constraints are provided"
  ansible.builtin.assert:
    that:
      - docker_services is defined
      - docker_services is iterable and docker_services is not string
    fail_msg: No or an invalid `docker_services` list was provided.

- name: "{{ _parent_role }} : Assert Docker resource constraints"
  ansible.builtin.assert:
    that:
      - item.cpu_limit is defined
      - item.cpu_limit is number
      - item.cpu_limit <= (ansible_facts['processor_vcpus'] | int)
      - item.cpuset is defined
      - item.cpuset is none or item.cpuset is string
      - item.mem_limit is defined
      - item.mem_limit is number
      - item.mem_limit <= (ansible_facts['memtotal_mb'] | int)
      - item.mem_reservation is defined
      - item.mem_reservation is number
      - item.mem_reservation <= item.mem_limit
    fail_msg: One or more provided resource constraints has errors
  loop: "{{ docker_services }}"
  when: docker_services | length > 0
Niet bepaald rocket science voor mensen bekend met Ansible, maar het zorgt er bij mij voor dat ik in rollen deze controles op een wat bondigere manier kan afwikkelen. Een voorbeeld uit mijn Home Assistant role.
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
- name: Assert storage configuration
  ansible.builtin.include_role:
    name: common
    tasks_from: assert/storage.yml
  vars:
    application_dir: "{{ home_assistant_dir }}"
    application_user: "{{ home_assistant_user }}"
    application_group: "{{ home_assistant_group }}"

- name: Assert Docker configuration
  ansible.builtin.include_role:
    name: common
    tasks_from: assert/docker.resources.yml
  vars:
    docker_services:
      - cpu_limit: "{{ home_assistant_cpu_limit }}"
        cpuset: "{{ home_assistant_cpuset }}"
        mem_limit: "{{ home_assistant_mem_limit }}"
        mem_reservation: "{{ home_assistant_mem_reservation }}"

- name: Assert Reverse proxy configuration
  ansible.builtin.include_role:
    name: common
    tasks_from: assert/docker.proxy.yml
  vars:
    docker_ingress_network: "{{ home_assistant_ingress_network }}"
    traefik_domain: "{{ home_assistant_domain }}"

- name: Assert Docker networks
  ansible.builtin.include_role:
    name: common
    tasks_from: assert/docker.networks.yml
  vars:
    docker_networks: "{{ home_assistant_networks }}"
  when: home_assistant_networks | length > 0
En hierna kan ik dan (eventueel) nog specifieke role-configuratie controleren. Bijvoorbeeld de juiste waardes van configuratie variabelen.
blackd schreef op vrijdag 13 maart 2026 @ 08:51:
[...]

De copy.yml gebruikt ansible.builtin.template om templates/compose.yml en templates/.env.j2 te plaatsen in de project directory.
De up.yml doet een docker compose up in de project directory.
Doe jij dat dus dynamisch? Want nu geef ik bij elke role de bestanden mee...
YAML:
1
2
3
4
5
6
7
- name: Docker Compose Up
  ansible.builtin.include_role:
    name: common
    tasks_from: compose/up.yml
  vars:
    compose_template: "templates/compose.yaml.j2"
    compose_env_template: "templates/.env.j2"
Is niets mis mee, maar ik zou dat eigenlijk dynamisch willen... Als ik er nu, zo diep in mijn hoofd hè, over nadenk is dat waarschijnlijk ook triviaal :+.

Verder doe ik in de compose/up.yml nog wel een verwijdering van niet-Compose bestanden afhankelijk van wat er is gedeployed. En een validatie van Compose voor de Compose up:
YAML:
1
2
3
4
5
6
7
8
- name: "{{ _parent_role }} : Validate Docker Compose"
  ansible.builtin.command:
    cmd: docker compose config
    chdir: "{{ _compose_directory.path }}"
  register: _docker_compose_config_output
  ignore_errors: "{{ ansible_check_mode }}"
  failed_when: _docker_compose_config_output.rc != 0
  changed_when: false
Die validate zou je eigenlijk bij een template willen, maar dat heb ik niet werkend gekregen. Ik weet niet helemaal meer waarom, omdat dit alweer een tijdje geleden is.

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op vrijdag 13 maart 2026 @ 10:17:
@blackd Thanks voor de enorm uitgebreide post _/-\o_ Ik heb er nu even doorheen gelezen, maar dit zet ik zeker op mijn lijstje om op een later moment op te gaan pakken :D.

Ik vind het wel enorm leuk om te zien dat onze Docker + Ansible aanpak enorm veel overeenkomsten heeft :D.
Goed om te horen, zeker leuk dat we veel overeenkomsten hebben en van de verschillen kunnen we denk ik alleen maar leren :).
Doe jij dat dus dynamisch? Want nu geef ik bij elke role de bestanden mee...
YAML:
1
2
3
4
5
6
7
- name: Docker Compose Up
  ansible.builtin.include_role:
    name: common
    tasks_from: compose/up.yml
  vars:
    compose_template: "templates/compose.yaml.j2"
    compose_env_template: "templates/.env.j2"
Wat bedoel je met dynamisch? Mijn compose.yml is geen Jinja template als je dat bedoelt. Mijn compose file is gewoon uitgeschreven en bevat hooguit variabelen die gevoed worden uit de .env file.
Ik gebruik wel de template module van Ansible zodat de bestanden bij elkaar staan, maar eigenlijk is het onnodige overhead. Maar het maakt wel dat ik dclint over mijn compose files halen, wat ik dus ook doe in pre-commit en CI. Jij had al eerder aangegeven dat je op verschillende hosts wat configuratie en templating nodig had dus dat is bij jou wellicht wel wat lastiger.

De compose up task gaat er vanuit dat de role die hem aanroept een templates/compose.yml en templates/.env.j2 heeft. Netter zou zijn om de bestandsnamen door te geven zoals jij doet.
Mocht ik een keer een andere naam hanteren, dan gaat het fout. Aan de andere kant, ik heb hiervoor een role_template die de compose file genereert, dus daarmee is het risico op verkeerde bestandsnamen kleiner.

Wat dat betreft heb jij je tasks veel beter afgekaderd en ingeperkt dat ze niet misbruikt kunnen worden en fail-fast zijn. Daar kan ik nog wat van leren :). Bedankt voor jouw tips en voorbeelden hiervoor _/-\o_.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
blackd schreef op vrijdag 13 maart 2026 @ 10:58:
[...]

Goed om te horen, zeker leuk dat we veel overeenkomsten hebben en van de verschillen kunnen we denk ik alleen maar leren :).
Precies. Dat vind ik echt heel waardevol :). Alhoewel ik misschien veel zend, neem ik alle informatie tegelijkertijd ook in me op :).
Wat bedoel je met dynamisch? Mijn compose.yml is geen Jinja template als je dat bedoelt. Mijn compose file is gewoon uitgeschreven en bevat hooguit variabelen die gevoed worden uit de .env file.
Ah juist. Dan valt bij mij het spreekwoordelijke kwartje :).

Ik gebruik inderdaad veel templating. In mijn vorige post sprak ik bijvoorbeeld over home_assistant_networks en die template ik dan ook in mijn Compose (snippet):
Django/Jinja:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
services:
  home-assistant:
    container_name: ${COMPOSE_PROJECT_NAME}
    image: ghcr.io/home-assistant/home-assistant:2026.3.1@sha256:0e091dfce3068339c3e1d14382e6c34141e05cd589a1972ebd4d9a8e6b5d8969
    restart: on-failure:10
    networks:
      ingress:
        priority: 10
      {% if home_assistant_networks | length > 0 %}
      {%    for network in home_assistant_networks %}
      {{ network.name }}:
        {%     if network.ipv4_address is defined %}
        ipv4_address: {{ network.ipv4_address }}
        {%     endif %}
        {%     if network.ipv6_address is defined %}
        ipv6_address: {{ network.ipv6_address }}
        {%     endif %}
        {% if network.driver_opts is defined and network.driver_opts is not none %}
        driver_opts:
          {{ network.driver_opts | to_nice_yaml | indent(10) }}
        {% endif %}
      {%    endfor %}
      {% endif %}

networks:
  ingress:
    name: {{ swarm_overlay_network }}
    external: true

  {% for network in home_assistant_networks %}
  {{ network.name }}:
    name: {{ network.name }}
    external: true
  {% endfor %}
In de host configuratie geef ik het volgende mee:
YAML:
1
2
3
4
5
6
home_assistant_networks:
  - name: "{{ iot_network }}"
    ipv4_address: "192.168.24.100"
    ipv6_address: "{{ ipv6_prefix }}:24:100::100"
    driver_opts:
      com.docker.network.endpoint.sysctls: net.ipv6.conf.IFNAME.accept_ra=1,net.ipv6.conf.IFNAME.accept_ra_rt_info_max_plen=64,net.ipv6.conf.IFNAME.forwarding=0
Ik noem dit specifieke voorbeeld omdat dit een coole Docker constructie is die ik (nog) niet veel ben tegengekomen. In dit geval configureer ik namelijk specifieke IPv6 configuratie in de service in Compose zodat Thread vanuit de Home Assistant container werkt zonder dat host networking nodig is :D. Eenzelfde constructie heb ik ook voor ESPHome.

Dit zou je natuurlijk ook vast kunnen zetten in Compose en daar is niets mis mee. Tegelijkertijd is dit niet de enige plek of situatie waar ik zoiets doe. Ik doe dit ook bij ESPHome om dezelfde reden. Maar bij Plex kan ik op deze manier tamelijk eenvoudig een netwerk toevoegen voor een HDHomerun apparaat, bijvoorbeeld voor xTeve of vergelijkbare software.

Ook template ik bijv. Traefik labels met de naam van de Compose stack, dus:
code:
1
2
3
4
5
6
7
8
9
10
11
{{ ansible_managed | comment }}

name: {{ compose_stack_name }}

services:
  home-assistant:
    container_name: ${COMPOSE_PROJECT_NAME}
    labels:
      traefik.enable: true
      traefik.http.routers.{{ compose_stack_name }}.rule: "Host(`{{ home_assistant_domain }}`)"
      traefik.http.services.{{ compose_stack_name }}.loadbalancer.server.port: 8123
Waarmee ik dus wederom tamelijk eenvoudig een secundaire instantie van dezelfde software kan deployen zonder dat deze elkaar in de weg zitten :).

Bij mij is het templaten dus ook organisch gegroeid, maar inmiddels een groot onderdeel van mijn Compose setup.
Maar het maakt wel dat ik dclint over mijn compose files halen, wat ik dus ook doe in pre-commit en CI. Jij had al eerder aangegeven dat je op verschillende hosts wat configuratie en templating nodig had dus dat is bij jou wellicht wel wat lastiger.
Goed dat je me hier nogmaals aan herinnerd :). dclint staat ook nog steeds ergens op een lijstje.
De compose up task gaat er vanuit dat de role die hem aanroept een templates/compose.yml en templates/.env.j2 heeft. Netter zou zijn om de bestandsnamen door te geven zoals jij doet.
Mja, ik wilde met 'defaults' werken, maar dat was niet heel erg evident. Daar wil ik ook nog een keer naar kijken maar heeft geen prio.
Wat dat betreft heb jij je tasks veel beter afgekaderd en ingeperkt dat ze niet misbruikt kunnen worden en fail-fast zijn. Daar kan ik nog wat van leren :). Bedankt voor jouw tips en voorbeelden hiervoor _/-\o_.
Geen probleem :), jij ook bedankt. Fail fast vind ik enorm belangrijk. Dat is misschien ook wel een van de kernwaarde van hoe ik werk. Op die manier zit ik namelijk nog in de materie en kan ik direct zien hoe, wat en waar het eventueel misgaat. In plaats van dat het al gedeployed is of bij een update kapot vliegt :X.

Het testen van bijv. storage of devices doe ik wel al langer en is inmiddels automatisme. Fails komen weinig voor, maar als ze voortkomen is het vaak enorm belangrijk. Bijvoorbeeld als er een Zigbee / Z-Wave / Thread dongle mist. Dat wil ik liever op voorhand weten en het controleren kost niets.

In sommige gevallen - maar lang nog niet overal O-) - test ik ook op de bereikbaarheid van diensten. Bij mijn Frigate role ben ik daar enorm blij mee :)
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- name: Assert Frigate MQTT configuration
  ansible.builtin.assert:
    that:
      - frigate_mqtt is defined
      - frigate_mqtt is mapping
      - frigate_mqtt.enabled is defined
      - frigate_mqtt.enabled is boolean
      - frigate_mqtt.enabled and frigate_mqtt.host is defined
      - frigate_mqtt.enabled and frigate_mqtt.host is string
      - (frigate_mqtt.port | default(1883)) is defined
      - (frigate_mqtt.port | default(1883)) is number
      - (frigate_mqtt.user is defined and frigate_mqtt.password is not none)
        or (frigate_mqtt.user is not defined)
    fail_msg: The provided Frigate MQTT configuration has errors

- name: Ensure that the provided MQTT server is reachable
  ansible.builtin.wait_for:
    host: "{{ frigate_mqtt.host }}"
    port: "{{ frigate_mqtt.port | default(1883) }}"
    timeout: 60
    msg: Could not reach the provided MQTT server
  when: frigate_mqtt.enabled
Of de controle dat de reverse proxy na het deployen ook echt online komt
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
post_tasks:
    - name: Ensure Traefik is reachable from localhost
      ansible.builtin.uri:
        url: "https://{{ traefik_dashboard_domain }}/ping"
        return_content: false
        validate_certs: true
        status_code: [200]
      register: traefik_output
      until: traefik_output is defined and traefik_output.status == 200
      delay: 5
      retries: 24
      delegate_to: localhost
      tags: [always]

    - name: Ensure Traefik is reachable through reverse proxy from target node
      ansible.builtin.uri:
        url: "https://{{ traefik_dashboard_domain }}/ping"
        return_content: true
        validate_certs: true
        status_code: [200]
      register: traefik_output
      until: traefik_output is defined and traefik_output.status == 200
      delay: 5
      retries: 24
      tags: [always]
Dat heeft me al de nodige hoofdpijn bespaard :D.

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op vrijdag 13 maart 2026 @ 13:13:
Ik gebruik inderdaad veel templating.
Hier stip je een belangrijk verschil aan tussen onze setups: jij deployt de roles naar meerdere hosts of zelfs meerdere keren per host, waardoor je bepaalde verschillen kwijt wil kunnen in je roles, dan is templating een prima oplossing.

In mijn setup heb ik alleen traefik dubbel uitgevoerd (voor intern en extern verkeer) en dat zijn (nog) twee aparte compose projecten. Bij de externe variant deploy ik ook cloudflared, bij de interne niet.
Ook template ik bijv. Traefik labels met de naam van de Compose stack, dus:

Bij mij is het templaten dus ook organisch gegroeid, maar inmiddels een groot onderdeel van mijn Compose setup.
Hier ben ik dus een andere weg in geslagen en heb ik een template compose role gemaakt:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
role_template
├── _templates  [1]
│   ├── .env.j2.j2  [3]
│   └── compose.yaml.j2
├── defaults
│   └── main.yml
├── molecule_scenario [2]
│   ├── cleanup.yml.j2
│   ├── converge.yml.j2
│   ├── molecule.yml.j2
│   └── verify.yml.j2
├── tasks
│   └── main.yml.j2
└── vars
    └── main.yml.j2
Ietswat uitleg bij deze structuur:
[1] deze folder heb ik bewust _templates genoemd omdat de ansible-galaxy role init --role-skeleton deze anders niet meepakt. In de Taskfile.yml hernoem ik deze folder naar templates
[2] deze molecule_scenario hoort niet binnen de role maar binnen extensions/molecule/ en deze verplaats ik ook in mijn Taskfile.yml.
[3] Ja ja, ik template een template ;).

Hier heb ik dus ook variabelen als compose project name, maar ik pas ze niet runtime toe zoals jij.
compose.yaml.j2:
Django/Jinja:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
name: {{ init_docker_compose_project_name }}
services:
  service-1:
    image: hub/image:version
    container_name: {{ init_docker_compose_project_name }}
    volumes:  
    [... snip ...]
    labels:
      traefik.enable: true
      traefik.docker.network: traefik-net
      traefik.http.routers.{{ init_docker_compose_project_name }}.rule: Host(`{{ init_docker_compose_project_name }}.domain.tld`)
      traefik.http.routers.{{ init_docker_compose_project_name }}.entrypoints: websecure
      traefik.http.routers.{{ init_docker_compose_project_name }}.tls.certresolver: cfdns
      traefik.http.services.{{ init_docker_compose_project_name }}.loadbalancer.server.port: 8080
Geen probleem :), jij ook bedankt. Fail fast vind ik enorm belangrijk. Dat is misschien ook wel een van de kernwaarde van hoe ik werk. Op die manier zit ik namelijk nog in de materie en kan ik direct zien hoe, wat en waar het eventueel misgaat. In plaats van dat het al gedeployed is of bij een update kapot vliegt :X.
Ik hou daar ook van maar ik heb dat principe nog niet overal toegepast. Door deze discussie leer ik dat ik daar nog e.e.a. kan verbeteren.
In sommige gevallen - maar lang nog niet overal O-) - test ik ook op de bereikbaarheid van diensten. Bij mijn Frigate role ben ik daar enorm blij mee :)
Of de controle dat de reverse proxy na het deployen ook echt online komt
Dat heeft me al de nodige hoofdpijn bespaard :D.
Dat kan ik me heel goed voorstellen.
Momenteel monitor ik mijn docker containers en web services met Uptime Kuma en als iets omvalt wordt ik daar binnen een paar minuten van op de hoogte gebracht.
Mijn Renovate PR's merge ik (o.b.v. release notes) en deze zijn dan al in Molecule getest.
Nightly wordt mijn omgeving geupgrade met een playbook, die voer ik eerst uit in check mode, daarna apply ik de configuratie.

Maar het is helemaal tof als je de state van de service in het playbook al kan controleren.
Je kan zelfs zover gaan dat je een automatische rollback implementeert. Dat heb ik voor mijn twee RPI's gedaan met PiHole. Ik heb een playbook hiervoor met serial: 1 dus de hosts worden om de beurt geupgraded. Eerst haal ik keepalived down zodat de andere master wordt, daarna update ik de software.
Ik maak eerst een backup van de 'running config', plaats de nieuwe compose file, kijk of deze 'up' komt en lukt dat niet, plaats ik de 'running config' terug en breng die up. Dit werkt met een block en rescue sectie in de tasks.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
blackd schreef op vrijdag 13 maart 2026 @ 20:42:
Hier stip je een belangrijk verschil aan tussen onze setups: jij deployt de roles naar meerdere hosts of zelfs meerdere keren per host, waardoor je bepaalde verschillen kwijt wil kunnen in je roles, dan is templating een prima oplossing.
Mja. Maar beperkt. Traefik of eigenlijk traefik-kop staat op al mijn hosts en hetzelfde geldt voor Beszel (agent). En AdGuard Home staat ook op meerdere hosts.

Waar ik het vooral handig voor vindt is het kunnen schuiven van applicaties. Wederom geen dagelijkse kost. Laatst heb ik bijvoorbeeld Beszel Hub van mijn hoofdmachine verplaatst naar mijn Pi. Die Pi had eigenlijk alleen de verantwoordelijkheid over een DS18B20 sensor waarmee ik mijn boiler aanstuur. Beszel Hub verplaatsten was zo gepiept en de data had ik met het handje even overgezet. Immers ga ik geen Ansible spullen inrichten voor een eenmalige scp.

Achteraf gezien bleek de Pi net teveel latency en te weinig pk's te hebben om Beszel naar tevredenheid te draaien. Vervolgens heb ik daarom besloten om Beszel Hub van de Pi naar mijn secundaire machine te verplaatsen. Niet meer naar mijn primaire host omdat ik niet wil dat dergelijke monitoring omvalt bij problemen daar. Wederom was dit zo gepiept met ~5 minuten downtime.

Dan vind ik het templating toch wel lekker, aangezien dit voor een groot gedeelte in de Compose yaml wordt geconfigureerd.

Ik bedoel daarmee vooral te zeggen dat ik jouw setup niet afkeur of slecht vind, maar dat ik uiteindelijk echt wel voordelen zie in het templaten. Ook met betrekking tot resource constraints.
Hier ben ik dus een andere weg in geslagen en heb ik een template compose role gemaakt:
Yes. Dit snap ik. Dit had ik eerst ook zo :). Alleen gebeurde het me regelmatig dat ik nieuwe functies of bugfixes in role implementaties doorvoerde maar niet meer 'backportte' naar de template. Ik heb daar de discipline niet voor.
Nightly wordt mijn omgeving geupgrade met een playbook, die voer ik eerst uit in check mode, daarna apply ik de configuratie.
Interessant :). Ik wil dus niets nightly doen :D. Alle updates gaan bij mij op tijden dat ik wakker ben of kan reageren om maar niet wakker te hoeven worden met een kapotte omgeving.

Bij het aanmaken van de PR door Renovate worden automatisch de geraakte role(s) in check mode gerunt door Forgejo runner. Wanneer deze checks slagen en de PR gemerged wordt, wordt er direct gedeployed. Wel met uitzonderingen. Home Assistant en verwante applicaties deploy ik bijvoorbeeld handmatig. Wederom heb ik geen zin in een spontaan kapotte Zigbee2MQTT. Hetzelfde geldt voor major's of sommige minor's.
Dat heb ik voor mijn twee RPI's gedaan met PiHole. Ik heb een playbook hiervoor met serial: 1 dus de hosts worden om de beurt geupgraded. Eerst haal ik keepalived down zodat de andere master wordt, daarna update ik de software.
Zoiets wil ik nog doen met Traefik en/of Mosquitto. Alleen vind ik het de investering vooralsnog niet waard. Daarmee bedoel ik vooral dat ik er al meermaals aan begonnen ben, maar uiteindelijk nooit afmaak omdat er voor mijn thuissituatie te weinig voordelen zijn. Behalve het 'baller'-effect :+.

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op vrijdag 13 maart 2026 @ 21:22:
Bij het aanmaken van de PR door Renovate worden automatisch de geraakte role(s) in check mode gerunt door Forgejo runner. Wanneer deze checks slagen en de PR gemerged wordt, wordt er direct gedeployed.
Hoe doe je dit?
Ik heb één main playbook die weer andere playbooks include, de enige manier om daar selectief mee om te gaan die ik had gevonden is met tags. Maar dat vereist discipline.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
Ik citeer je even andersom om eerst mijn opzet hierin wat meer toe te lichten :).
blackd schreef op vrijdag 13 maart 2026 @ 22:05:
Ik heb één main playbook die weer andere playbooks include, de enige manier om daar selectief mee om te gaan die ik had gevonden is met tags. Maar dat vereist discipline.
Ik gebruik ook tags, maar ik heb aparte playbooks en meta-playbooks.

Neem ik bijvoorbeeld AdGuard home, dan heb ik dus het playbook playbooks/apps/adguard_home.yml.
YAML:
1
2
3
4
5
6
- name: Deploy AdGuard Home
  hosts: dns

  roles:
    - role: adguard_home
      tags: [app, dns, infra, adguard, adguard_home]
De 'dns' hosts zijn dus mijn primaire en secundaire nodes zoals ik in mijn eerdere post aangaf. Deze playbook gebruik ik ook bij het 'meta-playbook' playbooks/apps/infra.yml:
YAML:
1
2
3
4
5
6
7
8
9
10
11
- name: Deploy AdGuard Home
  ansible.builtin.import_playbook: adguard_home.yml

- name: Deploy ddclient
  ansible.builtin.import_playbook: ddclient.yml

- name: Deploy Beszel
  ansible.builtin.import_playbook: beszel.yml

- name: Deploy Gatus
  ansible.builtin.import_playbook: gatus.yml
En dit 'meta-playbook' neem ik toevallig ook weer mee in een ander 'meta-playbook' playbooks/apps/all.yml:
YAML:
1
2
3
4
5
6
7
- name: Deploy Infra
  ansible.builtin.import_playbook: infra.yml

- name: Deploy Traefik
  ansible.builtin.import_playbook: traefik.yml

# de rest van het playbook is hier niet relevant...
Om tot slot dit 'meta-playbook' nog eenmaal mee te nemen in een ander playbook: playbooks/all.yml om de meta-ception te maximaliseren :+
YAML:
1
2
3
4
5
6
7
8
- name: Setup Hosts
  ansible.builtin.import_playbook: hosts/all.yml

- name: Setup Docker
  ansible.builtin.import_playbook: docker.yml

- name: Install apps
  ansible.builtin.import_playbook: apps/all.yml
Daarmee heeft elk playbook een eigen functie:
  • playbooks/apps/adguard_home.yml gebruik ik wanneer ik alleen AdGuard Home deploy
  • playbooks/apps/infra.yml gebruik ik bij het deployen van de basis infra
  • playbooks/apps/all.yml gebruik ik bij het deployen van alle apps (eventueel met een host list) bijvoorbeeld wanneer ik een 'bulk' aan aanpassingen heb gedaan zoals CPU of mem toewijzingen
  • playbooks/all.yml gebruik ik bij een verse install
AdGuard Home is daarin een beetje flauw, maar mijn Home Assistant playbook include op deze manier ook vele andere playbooks (en rollen) voordat Home Assistant daadwerkelijk deployed wordt. Een selectie uit dat playbook:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
- name: Deploy Mosquitto
  ansible.builtin.import_playbook: mosquitto.yml

- name: Deploy Zigbee2MQTT
  ansible.builtin.import_playbook: zigbee2mqtt.yml

- name: Deploy Home Assistant
  hosts: home_assistant

  roles:
    - role: home_assistant
      tags: [app, infra, home-assistant, home_assistant]
Het zou dan ook zomaar kunnen zijn dat de Zigbee2MQTT playbook in dit geval ook Moquitto deployed. Zou kunnen, want dat heb ik momenteel nog niet O-). Dit werkt niet helemaal zoals ik zou verwachten met import_playbook omdat dan toch de role twee keer wordt uitgevoerd. Mja, 'verwacht' dus, want uiteraard is een playbook altijd afzonderlijk.

Doordat Ansible idempotent is zou ik uiteraard ook altijd all.yml of apps/all.yml kunnen gebruiken. Dit doe ik voornamelijk vanwege het af kunnen kaderen (kom ik zo op) en performance bij het ontwikkelen. Ik wil niet altijd alles of grote gedeeltes deployen. Ik besef me ook dat dit een kwestie van smaak is.
Hoe doe je dit?
Met bovenstaande dus in het achterhoofd heb ik mijn Forgejo workflow een path-mapping toegewezen. Om dus met AdGuard Home verder te gaan, .forgejo/workflows/adguard_home.yaml:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
name: Deploy AdGuard Home

# yamllint disable-line rule:truthy
on:
  push:
    branches:
      - main
    paths:
      - roles/adguard_home/**
  pull_request:
    types:
      - opened
      - reopened
      - synchronize
    paths:
      - roles/adguard_home/**
  workflow_dispatch:
    inputs:
      check_mode:
        description: "Check mode (dry-run)"
        default: false
        required: false
        type: boolean

concurrency:
  group: ${{ github.repository }}

jobs:
  deploy:
    name: Deploy AdGuard Home
    runs-on: ubuntu-latest
    timeout-minutes: 5

    steps:
      - name: ⤵️ Checkout repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - name: 🏗️ Setup Python
        id: setup-python
        uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
        with:
          cache: 'pip'
          cache-dependency-path: 'requirements.txt'

      - name: 👷 Install Python dependencies
        if: steps.setup-python.outputs.cache-hit != 'true'
        shell: bash
        run: pip install -r requirements.txt

      - name: 📦 Setup Ansible Galaxy Cache
        id: ansible-galaxy-cache
        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
        with:
          path: |
            .ansible
            ~/.ansible
          key: ${{ runner.os }}-ansible-${{ hashFiles('**/requirements.yml') }}
          restore-keys: |
            ${{ runner.os }}-ansible-

      - name: 🌌 Install Ansible Galaxy dependencies
        if: steps.ansible-galaxy-cache.outputs.cache-hit != 'true'
        shell: bash
        run: ansible-galaxy install -r requirements.yml

      - name: 🚧 Setup known hosts
        id: setup-known-hosts
        shell: bash
        run: |
          if [ -z "${KNOWN_HOSTS}" ]; then
            echo "No known hosts provided, skipping setup."
            exit 0
          fi

          KNOWN_HOSTS_FILE="/etc/ssh/known_hosts"

          mkdir -p /etc/ssh/
          echo ${KNOWN_HOSTS} > ${KNOWN_HOSTS_FILE}
          echo "known-hosts-file=$KNOWN_HOSTS_FILE" >> $GITHUB_OUTPUT
          echo "SSH known hosts setup at: $KNOWN_HOSTS_FILE"
        env:
          KNOWN_HOSTS: ${{ vars.KNOWN_HOSTS }}

      - name: 🔑 Setup Vault password
        id: setup-vault-pass
        shell: bash
        run: |
          if [ -z "${VAULT_PASS}" ]; then
            echo "No vault password provided, skipping setup."
            exit 0
          fi

          echo "::add-mask::${VAULT_PASS}"

          if [ -z "$VAULT_PASS_DIRECTORY" ]; then
            VAULT_PASS_FILE="${{ github.workspace }}/.vault_pass"
          else
            mkdir -p "$VAULT_PASS_DIRECTORY"
            VAULT_PASS_FILE="$VAULT_PASS_DIRECTORY/.vault_pass"
          fi

          echo "$VAULT_PASS" > $VAULT_PASS_FILE
          echo "vault-pass-file=$VAULT_PASS_FILE" >> $GITHUB_OUTPUT
          echo "Vault password file setup at: $VAULT_PASS_FILE"
        env:
          VAULT_PASS: ${{ inputs.vault-pass }}
          VAULT_PASS_DIRECTORY: ${{ inputs.vault-pass-directory }}

      - name: 🚀 Run Ansible Playbook
        uses: dawidd6/action-ansible-playbook@v9
        with:
          playbook: playbooks/apps/adguard_home.yml
          requirements: requirements.yml
          key: ${{ secrets.DEPLOY_KEY }}
          vault_password: ${{ secrets.ANSIBLE_VAULT_KEY }}
          check_mode: >-
            ${{ inputs.check_mode == true ||
                github.event_name == 'pull_request' }}
Bij een PR wordt er dus altijd een check_mode uitgevoerd. Je zou uiteraard ook nog een Molecule test kunnen doen. Wanneer het PR uiteindelijk geaccepteerd wordt door Renovate wordt de deploy gedaan.

Ik gebruik voor het deployen een eigen fork van deze GitHub action. Die kerel had namelijk check_mode vernaggeld. Dit is alweer een tijdje geleden, dus de action zou wellicht weer kunnen werken.

De hele Ansible setup heb ik in een workflow zitten zodat ik geen oneindige herhaling van code heb. Tegenwoordig is het ook mogelijk om hiervoor workflow_call te gebruiken.

Tot slot heb ik in Renovate een tijdslot gezet voor auto-merges van Docker applicaties.
JSON:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
  "packageRules": [
      "description": "Update Docker dependencies",
      "matchFileNames": [
        "roles/common/**",
        "roles/docker/**",
        "roles/dockge/**",
        "**/compose.yml",
        "**/compose.yaml",
        "**/compose.yml.j2",
        "**/compose.yaml.j2"
      ],
      "automergeSchedule": ["* 10-19 * * 1-6"]
    }
}
Vandaar dat ik dit de roles dus eigenlijk in een aparte repo zou willen. Dan is het een en ander van nature namelijk afgekaderd in plaats van dat ik dit nog moet configureren. De merges zouden dan ook continue kunnen plaatsvinden met een afgekaderde / tijdstlot merge naar mijn infra-repo

Nu heb ik namelijk regelmatig 3 - 5 Renovate PR's openstaan, terwijl ik voor digests zelfs al alleen branches gebruik 8)7 :X. Dat houdt elkaar ook nog eens op, want elke keer moeten PR's gesynct worden én wordt er dus opnieuw een Ansible-playbook met check mode uitgevoerd om te testen of het geheel nog werkt.

  • blackd
  • Registratie: Februari 2001
  • Niet online
@alex3305 interessante aanpak, zo had ik er nog niet over nagedacht. Feitelijk maak je voor alle laagste niveau apps een playbook en installeer je daar ook je dependencies.

Ik neem aan dat je deze opzet ook kent?
Als je de dependencies op role niveau definieert, zouden ze maar 1x uitgevoerd moeten worden.

En mag ik concluderen uit je post dat je hiermee eigenlijk voor elke app een eigen workflow hebt?
Klinkt als een mooie feature voor mijn role template :*) .

Ik heb nu maar 1 workflow die altijd het grote playbook uitvoert. Dat duurt 15 min, dat was ik zat, vandaar dat ik naar een nightly release ben overgestapt.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
blackd schreef op zaterdag 14 maart 2026 @ 17:02:
@alex3305 interessante aanpak, zo had ik er nog niet over nagedacht. Feitelijk maak je voor alle laagste niveau apps een playbook en installeer je daar ook je dependencies.
Ja, heel kort door de bocht wel ja :).
Ik neem aan dat je deze opzet ook kent?
Als je de dependencies op role niveau definieert, zouden ze maar 1x uitgevoerd moeten worden.
Zeker. Sterker nog, die pagina had ik open toen ik mijn post schreef :9. Maar een role dependency is wederom per playbook, omdat ik meerdere playbooks uitvoer werkt dat dus niet zoals ik hoop dat dat werkt. Ik moet daarbij wel opmerken dat ik het niet heb getest :$. Wel om meerdere roles uit te voeren in twee playbooks en die worden dan dus ook twee keer uitgevoerd. Verder las ik wat online discussies en documentaties waarbij aangegeven wordt dat role deduplication alleen per play plaatsvindt.

Daarnaast vind ik dat bijvoorbeeld Mosquitto of Zigbee2MQTT geen echte dependency is van Home Assistant. En misschien is dat niet helemaal waar voor een tool zoals Zigbee2MQTT, maar wel voor Mosquitto. De MQTT broker gebruik ik immers ook op andere plekken. En ook krijg je dan een beetje 'vreemde' afhankelijkheden. Is DNS (AdGuard Home) bijvoorbeeld ergens afhankelijk van? Of monitoring en logging? Maar ja, als ik ze niet heb dan werkt het ook niet. Of in een extremer geval is Traefik met Crowdsec bij mij afhankelijk van het Vaultwarden (logging) pad. Is dan Vaultwarden een afhankelijkheid van Traefik? Eigenlijk wel... Maar dat voelt niet zo goed :/.

Collecties zouden hier de uitkomst bieden, maar daarbij zijn afhankelijkheden op andere rollen of collecties alleen mogelijk als deze in de centrale Ansible Galaxy repository staan. En dat wil ik niet :|.

Ik zit hier dus een beetje tussen wal en schip :-(.
En mag ik concluderen uit je post dat je hiermee eigenlijk voor elke app een eigen workflow hebt?
Klinkt als een mooie feature voor mijn role template :*) .
Kort door de bocht wel. Er zijn uiteraard uitzonderingen. Home Assistant is zo'n uitzondering waarbij die wel alle afhankelijkheden include, maar geen op zichzelf staand playbook heeft.
Ik heb nu maar 1 workflow die altijd het grote playbook uitvoert. Dat duurt 15 min, dat was ik zat, vandaar dat ik naar een nightly release ben overgestapt.
Ik haal het volgens mij niet in 15 minuten :P. Misschien is dat wel de noodzaak voor het opsplitsen geweest B-) oOo

Nee, dat was mijn vorige werk. Daar deden we volledige cloud inrichtingen met Ansible. Daar zaten we ook ruim over de 100 rollen heen. Dan is een volledige play - ook per host - niet meer praktisch. Ik heb het dan ook over een Ansible setup van ruim 12 jaar oud.

Dit patroon zie je overigens ook al bij de grotere setups van bijv. Red Hat zelf. Dus heel vreemd is het niet.

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op zaterdag 14 maart 2026 @ 17:51:
Zeker. Sterker nog, die pagina had ik open toen ik mijn post schreef :9. Maar een role dependency is wederom per playbook, omdat ik meerdere playbooks uitvoer werkt dat dus niet zoals ik hoop dat dat werkt. Ik moet daarbij wel opmerken dat ik het niet heb getest :$. Wel om meerdere roles uit te voeren in twee playbooks en die worden dan dus ook twee keer uitgevoerd. Verder las ik wat online discussies en documentaties waarbij aangegeven wordt dat role deduplication alleen per play plaatsvindt.
Ik heb wel op die manier dependencies opgegeven, zo heb ik een dockerproxy role toegevoegd aan mijn setup en alles wat iets met het docker socket nodig heeft, heeft als dependency de dockerproxy role.
Dat werkt inderdaad binnen een playbook prima, want dat is hoe ik het nu heb ingericht.
Op mijn TrueNAS machine heb ik een jailmaker jail, waar ik alle docker compose projecten naar deploy.
Daarvoor heb ik één playbook truenas_apps.yml waarin alle docker compose projecten als roles staan, ieder met een eigen tag.
Daarnaast vind ik dat bijvoorbeeld Mosquitto of Zigbee2MQTT geen echte dependency is van Home Assistant. En misschien is dat niet helemaal waar voor een tool zoals Zigbee2MQTT, maar wel voor Mosquitto. De MQTT broker gebruik ik immers ook op andere plekken. En ook krijg je dan een beetje 'vreemde' afhankelijkheden. Is DNS (AdGuard Home) bijvoorbeeld ergens afhankelijk van? Of monitoring en logging? Maar ja, als ik ze niet heb dan werkt het ook niet. Of in een extremer geval is Traefik met Crowdsec bij mij afhankelijk van het Vaultwarden (logging) pad. Is dan Vaultwarden een afhankelijkheid van Traefik? Eigenlijk wel... Maar dat voelt niet zo goed :/.
Dat HomeAssistant een dependency heeft op Zigbee2MQTT vind ik wel wat voor te zeggen, ook dat Zigbee2MQTT een broker nodig heeft, vind ik een goede dependency. Maar het maakt ook wel uit wanneer je de dependency nodig hebt, al bij het opstarten of pas bij het configureren van de applicaties.

Een DNS server heb je nodig, dat klopt. Maar dat kun je ook op een andere manier afdwingen, nl: volgorde in je playbooks, zoals je dat bij Docker ook gedaan hebt.

Ik heb een vergelijkbaar playbook voor docker met een groep in mijn inventory en daar kan ik opgeven op welke hosts ik docker geïnstalleerd wil hebben.

Maar hoe pas jij jouw patroon toe bij apps die je op meerdere machines deployed?

Want ik kan me voorstellen dat als je Traefik op meerdere hosts deployed, dat je workflow file triggert op roles/traefik/* maar als je dan meerdere playbooks (aanname) moet aanroepen heb je eigenlijk de link tussen host en app op twee plekken liggen: in je playbooks én je workflow.
Of heb je één playbook per app en dan in die playbooks geconfigureerd op welke host (of groep) je de zaken deployed?

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
blackd schreef op zaterdag 14 maart 2026 @ 19:56:
[...]

Dat HomeAssistant een dependency heeft op Zigbee2MQTT vind ik wel wat voor te zeggen, ook dat Zigbee2MQTT een broker nodig heeft, vind ik een goede dependency. Maar het maakt ook wel uit wanneer je de dependency nodig hebt, al bij het opstarten of pas bij het configureren van de applicaties.
Fair enough. Alleen was ik 1 detail nog vergeten O-). Zigbee2MQTT draait mijn niet op mijn primaire machine. En Mosquitto niet op mijn secundaire machine :*). Dit is in dit geval wel nodig, althans zo lees ik de documentatie.
Ik heb een vergelijkbaar playbook voor docker met een groep in mijn inventory en daar kan ik opgeven op welke hosts ik docker geïnstalleerd wil hebben.

Maar hoe pas jij jouw patroon toe bij apps die je op meerdere machines deployed?

Want ik kan me voorstellen dat als je Traefik op meerdere hosts deployed, dat je workflow file triggert op roles/traefik/* maar als je dan meerdere playbooks (aanname) moet aanroepen heb je eigenlijk de link tussen host en app op twee plekken liggen: in je playbooks én je workflow.
Of heb je één playbook per app en dan in die playbooks geconfigureerd op welke host (of groep) je de zaken deployed?
In principe is er één 'hoofd' playbook per gedeployde dienst. Dus voor Traefik, die op al mijn Docker hosts draait, wordt dus gedeployed naar de groep docker vanuit hetzelfde playbook. Idem voor Docker en Docker Compose. Beszel draait op alle hosts, maar daarbij configureer ik in de host_vars welke variant ik deploy.

Om nog even bij Home Assistant terug te komen, deze wordt gedeployed op meerdere hosts vanuit één hoofd playbook, namelijk:
  • home_assistant
  • mqtt
  • thread
  • zigbee
  • zwave
Daarbij deploy ik nog meer diensten maar heb ik dus geen 1-op-1 koppeling tussen playbook en role, maar een 1-op-n koppeling. Eigenlijk een n-op-n koppeling, maar mijn (1) Home Assistant playbook deployed dus o.a. de roles Mosquitto, Frigate, Zigbee2MQTT, Matter, ESPHome en Home Assistant. Alleen Mosquitto, Frigate en Zigbee2MQTT komen uit een ander playbook.

  • DjoeC
  • Registratie: November 2018
  • Laatst online: 23:51
alex3305 schreef op zaterdag 14 maart 2026 @ 21:01:
[...]
Fair enough. Alleen was ik 1 detail nog vergeten O-). Zigbee2MQTT draait mijn niet op mijn primaire machine. En Mosquitto niet op mijn secundaire machine :*). Dit is in dit geval wel nodig, althans zo lees ik de documentatie.
Volgens mij zijn er geen machine/container afhankelijkheden als je ze als losse containers draait. Mogelijk wel als je de HA integratie gebruikt. Bij mij gaat het prima over machines/servers heen.

HA praat met mosquitto op server/poort niveau, Z2M idem.

  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
DjoeC schreef op zaterdag 14 maart 2026 @ 21:31:
[...]

Volgens mij zijn er geen machine/container afhankelijkheden als je ze als losse containers draait. Mogelijk wel als je de HA integratie gebruikt. Bij mij gaat het prima over machines/servers heen.

HA praat met mosquitto op server/poort niveau, Z2M idem.
Ja :F... Dat was niet de context van mijn post hè.

Het gaat erover als je als dependency markeert in een meta/main.yml in Ansible zoals @blackd bedoelde en zoals hier beschreven in de Ansible documentatie dat deze niet over meerdere target hosts uit de inventory heengaat.

Ik wil dus de Mosquitto container via mijn Mosquitto role op mijn mqtt host uit de inventory parkeren, maar Zigbee2MQTT moet op de zigbee host én tot slot moet Home Assistant op de home_assistant host. Ansible heeft in principe geen kennis of context of deze hosts daadwerkelijk verschillend of gelijk zijn. Maar volgens mij gaat dat niet met role dependencies, wat volgens de documentatie ook semenatisch meer prerequisites zijn.

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op zaterdag 14 maart 2026 @ 21:37:
Het gaat erover als je als dependency markeert in een meta/main.yml in Ansible zoals @blackd bedoelde en zoals hier beschreven in de Ansible documentatie dat deze niet over meerdere target hosts uit de inventory heengaat.
Volgens mij is er wel een uitzondering mogelijk hierop met delegate_to.

In mijn base role kan ik een directory maken op mijn TrueNAS machine. Dat doe ik in principe eerst op de TrueNAS host als zfs dataset, daarna in de TrueNAS jail.
De zfs dataset task draai ik met delegate to op de nas host, de role zelf gaat in de jail.
Oh ja en de jail mag niet met de nas praten dus ik gebruik een jump host.

Maar met een playbook is veel netter imho want met delegate to fixeer je de host in de role zelf.
alex3305 schreef op zaterdag 14 maart 2026 @ 21:01:
Fair enough. Alleen was ik 1 detail nog vergeten O-). Zigbee2MQTT draait mijn niet op mijn primaire machine. En Mosquitto niet op mijn secundaire machine :*).
Ik had al zo'n vermoeden ;).
Ik ga deze aanpak ook een keer proberen en kijken of het mij bevalt.

De templates in compose files ontkom ik denk ik ook niet aan. Ik heb meer duplicatie dan ik dacht (*Arr stack in uhd en 4k).
De gescheiden paden voor config e.d lukt nog wel, maar de traefik labels wordt lastig zonder templates vrees ik.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
blackd schreef op zaterdag 14 maart 2026 @ 22:29:
[...]

Volgens mij is er wel een uitzondering mogelijk hierop met delegate_to.
Yes. Daar had ik ook nog aan gedacht, maar een delegate_to zonder eerst een setup / gather_facts vind ik niet transparant en onverwacht. Daar blijf ik als het even kan dus ook van weg. Tijdens het opzetten van bijv. Swarm werkt een dergelijke constructie wel goed. Dan wil je bijv. alleen tasks uitvoeren op (de eerste) Swarm manager(s).
Maar met een playbook is veel netter imho want met delegate to fixeer je de host in de role zelf.
Ook dat nog. Nu zijn mijn rollen juist op zichzelf staand van de inventory en plays.
De templates in compose files ontkom ik denk ik ook niet aan.
Ik heb er uiteindelijk echt geen enkele moeite meer mee, omdat het dus gemeengoed is. Het was ook al iets waar ik eerder al genoeg ervaring mee had.

Zoals ik eerder in deze post al aangaf wil ik ook nog een keer gaan kijken naar includes / lookups van templates om vaste stukken uit de compose te templaten. Ik heb bijvoorbeeld Unraid labels die overal hetzelfde zijn met wat kleine verschillen. Aan de andere kant werkt dit voor mij en is het duidelijk en transparant. Daarmee bedoel ik dat ik na een half jaar ook nog weet wat er staat. Soms is meer dus beter en de noodzaak nu niet zo hoog ;).

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op zaterdag 14 maart 2026 @ 22:44:
Ik heb er uiteindelijk echt geen enkele moeite meer mee, omdat het dus gemeengoed is. Het was ook al iets waar ik eerder al genoeg ervaring mee had.
Ik kan (nog) niet leunen op jaren ervaring Jinja2 templates dus voor mij is het nieuw.
Wel heb ik in het verleden wat ervaring opgedaan met genereren van bijv. config files met Jinja2 templates.
Maar zo uitgebreid is voor mij nieuw, wat het dan lastiger maakt is dat ik snel feedback wil hebben of het eindresultaat (na templating) qua syntax klopt. Daarvoor heb ik nu dclint maar dat gaat niet werken op een .j2 variant van compose.yml. Hoe had jij bedacht dat aan te gaan pakken? Wat je zou kunnen doen is in Molecule een stap toevoegen die de syntax van compose.yml valideert, zodat je snel feedback hebt. Of je voert een template uit op de lokale machine en valideert dan met dclint. Of had je een andere aanpak bedacht?
Zoals ik eerder in deze post al aangaf wil ik ook nog een keer gaan kijken naar includes / lookups van templates om vaste stukken uit de compose te templaten. Ik heb bijvoorbeeld Unraid labels die overal hetzelfde zijn met wat kleine verschillen.
Dat zou een mooie use case zijn voor een herbruikbare role om bepaalde docker labels te templaten en deze logica maar op één plek te leggen. Want ik neem aan dat je met includes de docker compose includes bedoelt? Met standaard docker compose merging zou je ook je compose file modulair kunnen opzetten:
code:
1
2
3
4
- compose.yml [base]
- compose.labels.yml [docker labels]
- compose.networks.yml [docker networks] 
- .. enzovoorts
alex3305 schreef op zaterdag 14 maart 2026 @ 14:48:
Ik gebruik ook tags, maar ik heb aparte playbooks en meta-playbooks.
Neem ik bijvoorbeeld AdGuard home, dan heb ik dus het playbook playbooks/apps/adguard_home.yml.
Ik ben (met de power van AI) begonnen om voor elke role in mijn TrueNAS playbook een apart playbook aan te maken en deze in het TrueNAS playbook te importeren.

Stiekem gebruikte ik namelijk best vaak de -l limit en -t tags om of alle apps of één app te deployen. Een playbook per app is dus een logische keuze.

Mijn plan van aanpak is als volgt:
  • Playbook per app, import in de 'main' playbooks zodat ik ze altijd raak.
  • Workflow per app, waarbij ik trigger op de betreffende role(s), ik configureer hier het molecule scenario wat bij de role hoort én welk playbook erbij hoort, dan roep ik een herbruikbare workflow aan (zie hieronder).
  • Herbruikbare workflow maken, hier zit alle logica in voor CI, zoals Molecule test uitvoeren, Ansible Playbook in Check mode en Deployment.
Later kan ik dit uitbreiden naar de generieke playbooks, ik heb playbooks voor het configureren van unattended upgrades op alle machines en docker upgrades op alle machines (docker-ce).

Ik heb ook jouw tips voor asserts en naamgeving van de tasks in de common role al doorgevoerd.

[ Voor 26% gewijzigd door blackd op 15-03-2026 10:21 ]

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
blackd schreef op zondag 15 maart 2026 @ 09:40:
Ik kan (nog) niet leunen op jaren ervaring Jinja2 templates dus voor mij is het nieuw.
Wel heb ik in het verleden wat ervaring opgedaan met genereren van bijv. config files met Jinja2 templates.
Maar zo uitgebreid is voor mij nieuw, wat het dan lastiger maakt is dat ik snel feedback wil hebben of het eindresultaat (na templating) qua syntax klopt. [...] Hoe had jij bedacht dat aan te gaan pakken?
Dat is gewoon een skill issue :*) O-)... Nee hoor, dat is een flauwe grap :> :+. Wat ik al zei, ik ben al meer dan een decennium bezig met Ansible en Jinja. En zelfs Jinja in Jinja of Go templates in Jinja. Dan wordt zoiets na al die jaren ook vanzelfsprekend. Ik zeg ook altijd dat Ansible een leercurve heeft van minimaal 6 maanden tot 1 jaar. Waarbij ik al zeer regelmatig na 1 maand de feedback terug heb gekregen dat ik uit mijn nek klets en Ansible veel makkelijker is. Ja, totdat je tegen een 'vaag' probleem aanloopt en een oplossing uit zich lijkt. Wat dat betreft is het dan "easy to learn, hard to master". En dan leer ik ook nog wekelijks bij.

Maar om jouw vraag te beantwoorden; waarom template je het niet gewoon? Bij Jinja2 syntax fouten krijg je toch een foutmelding van Ansible, ook in check mode. Daarna valideer ik de uitgeschreven template met Compose zoals ik in mijn eerdere post liet zien.

Ik zou nog wat extra stappen kunnen toevoegen door bijvoorbeeld met een lookup plugin de yaml terug in te laden in Ansible en wat simpele assertions te doen. Bijvoorbeeld dat er services zijn. Alleen vind ik dat veel extra moeite en tijd met waarschijnlijk weinig concreet resultaat.
Wat je zou kunnen doen is in Molecule een stap toevoegen die de syntax van compose.yml valideert, zodat je snel feedback hebt. Of je voert een template uit op de lokale machine en valideert dan met dclint. Of had je een andere aanpak bedacht?
Dat zou ook nog kunnen, maar aangezien ik (nog) geen Molecule heb is dat bij mij niet van toepassing.

Tijdens mijn vorige werk werd voor Docker applicaties de template weggeschreven naar een /tmp/, gevalideerd en daarna gekopieerd naar de juiste directory. Dat werkt in tegenstelling tot mijn aanpak ook in check mode.
Dat zou een mooie use case zijn voor een herbruikbare role om bepaalde docker labels te templaten en deze logica maar op één plek te leggen. Want ik neem aan dat je met includes de docker compose includes bedoelt? Met standaard docker compose merging zou je ook je compose file modulair kunnen opzetten:
code:
1
2
3
4
- compose.yml [base]
- compose.labels.yml [docker labels]
- compose.networks.yml [docker networks] 
- .. enzovoorts
Nee, ik bedoel lookup templates.

Ik wil geen gesplitste Compose configuratie, daar heb ik immers Ansible voor. Die moet de juiste puzzelstukjes als geheel naar de target host zetten. En of dat dan lokaal in 1 stukje of 200 stukjes zit kan me een spreekwoordelijke worst wezen. Ik vind gesplitste Compose namelijk ondoorzichtig. Daarbij komt nog dat software zoals Dockge of Portainer daar niet of niet goed mee om kan gaan.
Ik ben (met de power van AI) begonnen om voor elke role in mijn TrueNAS playbook een apart playbook aan te maken en deze in het TrueNAS playbook te importeren.

Stiekem gebruikte ik namelijk best vaak de -l limit en -t tags om of alle apps of één app te deployen. Een playbook per app is dus een logische keuze.

Mijn plan van aanpak is als volgt:
  • Playbook per app, import in de 'main' playbooks zodat ik ze altijd raak.
  • Workflow per app, waarbij ik trigger op de betreffende role(s), ik configureer hier het molecule scenario wat bij de role hoort én welk playbook erbij hoort, dan roep ik een herbruikbare workflow aan (zie hieronder).
  • Herbruikbare workflow maken, hier zit alle logica in voor CI, zoals Molecule test uitvoeren, Ansible Playbook in Check mode en Deployment.
Later kan ik dit uitbreiden naar de generieke playbooks, ik heb playbooks voor het configureren van unattended upgrades op alle machines en docker upgrades op alle machines (docker-ce).

Ik heb ook jouw tips voor asserts en naamgeving van de tasks in de common role al doorgevoerd.
Klinkt als een mooie stap :). Zoiets doe ik dan vaak in een PR / feature branch om even te kijken hoe het mij bevalt. Het kan dan ook best zijn dat ik alles nog maar eens terugbouw omdat het dus niet bevalt :9.

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op zondag 15 maart 2026 @ 14:06:
Maar om jouw vraag te beantwoorden; waarom template je het niet gewoon? Bij Jinja2 syntax fouten krijg je toch een foutmelding van Ansible, ook in check mode. Daarna valideer ik de uitgeschreven template met Compose zoals ik in mijn eerdere post liet zien.
Daar ga ik ook wel naar toe bewegen vermoed ik, eerst de apps als losse playbooks apart deploybaar maken en dan kan ik daarna de duplicatie in rollen wegwerken door de compose files dynamischer te maken met templating en d.m.v. variabelen sturen hoe de role meerdere keren gedeployed kan worden.

Het gaat mij om de controle niet alleen om de Jinja2 syntax van het template, maar ook om het resultaat van de compose file na templating.

Ik zie nu dat ansible.builtin.template ook een validate parameter heeft en dat deze een tmp locatie gebruikt. Je zou daar ook docker compose config in kunnen doen, toch?
Heb jij die bewust niet gebruikt en 'm als aparte stap opgenomen?
Nee, ik bedoel lookup templates.

Ik wil geen gesplitste Compose configuratie, daar heb ik immers Ansible voor. Die moet de juiste puzzelstukjes als geheel naar de target host zetten. En of dat dan lokaal in 1 stukje of 200 stukjes zit kan me een spreekwoordelijke worst wezen. Ik vind gesplitste Compose namelijk ondoorzichtig. Daarbij komt nog dat software zoals Dockge of Portainer daar niet of niet goed mee om kan gaan.
Het leek mij ook onoverzichtelijk maar al speurende door de docs kwam ik deze opties tegen. Het ging toen met name om hoe ik in de test-uitvoer bepaalde zaken anders moest doen of over moest slaan. Denk aan een stub CA voor Let's encrypt + Traefik bij het uitvoeren van Molecule.

Ik vind persoonlijk één compose file ook veel overzichtelijker dan allemaal losse stukjes, dus daarover zijn we het eens :).
Klinkt als een mooie stap :). Zoiets doe ik dan vaak in een PR / feature branch om even te kijken hoe het mij bevalt. Het kan dan ook best zijn dat ik alles nog maar eens terugbouw omdat het dus niet bevalt :9.
Ja, dat is ook mijn aanpak.

[ Voor 3% gewijzigd door blackd op 15-03-2026 15:06 ]

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
blackd schreef op zondag 15 maart 2026 @ 15:02:
Daar ga ik ook wel naar toe bewegen vermoed ik, eerst de apps als losse playbooks apart deploybaar maken en dan kan ik daarna de duplicatie in rollen wegwerken door de compose files dynamischer te maken met templating en d.m.v. variabelen sturen hoe de role meerdere keren gedeployed kan worden.
Zo heb ik het ook gedaan :). Ik wil ook nog blijven benadrukken dat mijn eigen setup ook al ruim 6 jaar oud is :X. Rome is ook niet in één dag gebouwd.
Het gaat mij om de controle niet alleen om de Jinja2 syntax van het template, maar ook om het resultaat van de compose file na templating.
Mij ook :D. De Jinja2 syntax geloof ik wel.
Ik zie nu dat ansible.builtin.template ook een validate parameter heeft en dat deze een tmp locatie gebruikt. Je zou daar ook docker compose config in kunnen doen, toch?
Heb jij die bewust niet gebruikt en 'm als aparte stap opgenomen?
Zeker zou dat kunnen en het is dus inderdaad een bewuste keuze om daar een aparte stap van te maken. Althans 'bewuste' keuze. Want als je de documentatie leest kom je er direct achter waarom dat niet gaat:
quote: Ansible
Parameters
ParameterComments
validate
string
The validation command to run before copying the updated file into the final destination.

A temporary file path is used to validate, passed in through %s which must be present as in the examples below.

Also, the command is passed securely so shell features such as expansion and pipes will not work.
Examples
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- name: Copy a new sudoers file into place, after passing validation with visudo
  ansible.builtin.template:
    src: /mine/sudoers
    dest: /etc/sudoers
    validate: /usr/sbin/visudo -cf %s

- name: Update sshd configuration safely, avoid locking yourself out
  ansible.builtin.template:
    src: etc/ssh/sshd_config.j2
    dest: /etc/ssh/sshd_config
    owner: root
    group: root
    mode: '0600'
    validate: /usr/sbin/sshd -t -f %s
    backup: yes
En het docker compose config commando accepteert geen input path.

Volgens de docs moet je dan kijken naar handling complex validation. Dat lijkt op hoe ik het doe muv de rescue en always blokken. Dat heb ik door luiheid simpelweg niet geïmplementeerd. Wederom weer iets voor op het lijstje ;).
Ik vind persoonlijk één compose file ook veel overzichtelijker dan allemaal losse stukjes, dus daarover zijn we het eens :).
Ik denk dat we het over heel veel zaken eens zijn :). Alleen hebben we op sommige punten een smaakverschil. Ik vind het ook super interessant om te lezen hoe jij (en anderen hier) hun Docker en bijbehorende CI omgevingen aanpakken. Ik vind het ook echt leuk om te zien dat je zoveel balletjes opgooit. Het nadeel is alleen dat ik die balletjes voor een groot deel zelf ook al had gevonden :+. Gelukkig veranderd er nog weleens wat en vind ik het periodiek heroverwegen een goed idee :)

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op zondag 15 maart 2026 @ 15:34:
En het docker compose config commando accepteert geen input path.
YAML:
1
2
3
4
5
6
7
ansible.builtin.template:
    src: "compose.yaml"
    dest: ".."
    owner: ".."
    group: ".."
    mode: ".."
    validate: "docker compose -f %s config"
werkt hier perfect :*)

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
blackd schreef op zondag 15 maart 2026 @ 15:52:
[...]
YAML:
1
2
3
4
5
6
7
ansible.builtin.template:
    src: "compose.yaml"
    dest: ".."
    owner: ".."
    group: ".."
    mode: ".."
    validate: "docker compose -f %s config"
werkt hier perfect :*)
👀 Hier inmiddels ook :*) . Thanks :D

@blackd Toch niet helemaal. Dit werkt niet lekker met verplichte .env bestanden. Ik ga er een combinatie van maken :).

[ Voor 14% gewijzigd door alex3305 op 15-03-2026 16:26 ]


  • blackd
  • Registratie: Februari 2001
  • Niet online
@alex3305 Helaas, liep ik er ook tegenaan, gelukkig wezen mijn Molecule tests me hier ook op :*).

Het lukte mij niet om met de --env-file de reeds geplaatste .env file mee te nemen in de validatie.
Daarnaast wil je beide files rollbacken wanneer er iets mis gaat.

Dan maar een extra stap opnemen zoals jij, dit wordt vaker toegepast zo te zien.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op zaterdag 14 maart 2026 @ 14:48:
Met bovenstaande dus in het achterhoofd heb ik mijn Forgejo workflow een path-mapping toegewezen. Om dus met AdGuard Home verder te gaan, .forgejo/workflows/adguard_home.yaml:
YAML:
1
2
3
4
name: Deploy AdGuard Home

concurrency:
  group: ${{ github.repository }}
Ik ben bezig geweest met de aanpassingen om de deployment op een vergelijkbare manier te doen als jij, met het verschil dat ik per app een deploy-appname.yaml workflow heb, deze meerdere reusable workflows aanroept (test, check, deploy) maar ik loop vast met concurrency groups. Ik gebruik GitHub actions, de syntax is vergelijikbaar en volgens mij de werking van concurrency groups ook.

Als ik bovenstaande zo lees, zou je bij een PR wat meerdere deployment workflows triggert, ervoor zorgen dat andere workflows (binnen of buiten dezelfde PR) gecancelled worden (de default van cancel-in-progress is true waardoor er één winnaar overblijft). Klopt dat of heb ik dat verkeerd begrepen?

Ik heb e.e.a. op meerdere manieren geprobeerd:
In de composite workflow op workflow niveau, concurrency group [repo], cancel false
In de composite workflow op job niveau, concurrency group [repo], cancel false bij alleen de deploy
In de reusable workflow op job niveau, concurrency group [repo], cancel false bij alleen de deploy
Daarnaast nog geprobeerd om voor de andere jobs een concurrency group met workflow+github ref toe te voegen en cancel op true te zetten.

Wat ik wil bereiken is dat de Test en Check (playbook --check) gecancelled mogen worden in de context van de PR als er een nieuwe push op de featurebranch is, maar dat de Deploy nadat de PR gemerged is, altijd blijft doorlopen en niet onderbroken wordt.

Voor elke deploy workflow moet eerst de Test en dan de Check worden uitgevoerd. Dat lukt op zich met needs: in de workflow. Elke workflow op zich moet gewoon door blijven lopen, ook parallel.

Daarnaast wil ik ook dat er maar één deploy mogelijk is per keer. Al is dat min of meer afgedwongen doordat ik de Ansible Playbook job altijd op mijn self-hosted runner draai, de rest op GitHub Actions runners.

Ik heb het vermoeden dat ik een ander niveau van concurrency group nodig heb en het voldoende is om maar één local runner te hebben zodat alle playbook workflows sequentieel worden uitgevoerd.

Edit: het probleem opschrijven lost het halve probleem op, ik heb nu een concurrency group gemaakt deploy-$(appname)-to-production en met een 5 tal workflows ben ik dat nu aan het testen.

[ Voor 3% gewijzigd door blackd op 16-03-2026 09:16 ]

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
@blackd Ik zie dat ik hier een 'copy-paste' fout had gemaakt :o. Excuses daarvoor. Ik hergebruik workflows met een interne action, dus ik kan niet zomaar een hele workflow hier neerzetten, want dan mist er een groot stuk context.

Het linten gebeurd bij mij per commit, dus:
YAML:
1
2
3
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
maar de deploys gaan per workflow:
YAML:
1
2
concurrency:
  group: ${{ github.workflow }}
Ik zag net toevallig in de documentatie ook wel een andere leuke constructie die ik eens ga uitproberen:
YAML:
1
2
3
concurrency:
  group: ${{ github.workflow }}
  cancel-in-progress: ${{ !contains(github.ref, 'main')}}
Omdat mijn 'niet'-main deploys namelijk altijd een check mode zijn, zou dit dus een mooie toevoeging zijn.

Bij mij werkt dit volgens mij wel zoals ik verwacht. Althans ik kan mij zo niet herinneren dat ik gek gedrag heb opgemerkt...

  • blackd
  • Registratie: Februari 2001
  • Niet online
@alex3305 ik zou idd cancel-in-progress expliciet maken bij de deployment en bij check mode mag die op true maar de daadwerkelijke deploy op false.

Mijn aanpak geschetst in de edit lijkt goed te werken en komt globaal overeen met jouw oplossing.

Ik heb nu alleen aparte steps voor check en deploy, misschien voeg ik dat nog samen.
De check is afhankelijk van test, de deploy hoeft dat niet te zijn.

Ik heb een aparte workflow voor linting, ik gebruikt reviewdog en die doet ansible lint en dclint.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
@blackd Ja precies.

Je zou ook nog workflow_call kunnen gebruiken om workflows te hergebruiken.

Mijn check / deploy is wel dezelfde workflow want immers is dat hetzelfde met uitzondering van een 'check_mode' parameter.

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op maandag 16 maart 2026 @ 13:19:
Je zou ook nog workflow_call kunnen gebruiken om workflows te hergebruiken.
Zoiets?
.github/workflows/deploy-authentik.yml:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
name: Authentik
on:
  push:
    branches:
      - main
    paths:
      - 'roles/authentik/**'
  pull_request:
    types:
      - opened
      - synchronize
      - reopened
    paths:
      - 'roles/authentik/**'
  workflow_dispatch:
    inputs:
      check_mode:
        description: "Check mode (dry-run)"
        default: false
        required: false
        type: boolean

jobs:
  deploy:
    name: Deploy
    uses: ./.github/workflows/deploy-generic.yml
    with:
      ansible_playbook_path: playbooks/apps/authentik.yml
      molecule_scenario: "authentik"
      check_mode: ${{ inputs.check_mode == true || github.event_name == 'pull_request' }}
    secrets: inherit
.github/workflows/deploy-generic.yml:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
on:
  workflow_call:
    inputs:
      molecule_scenario:
        description: "Molecule (test) scenario to run"
        required: true
        type: string
      ansible_playbook_path:
        description: "Ansible Playbook path (relative to project root)"
        required: true
        type: string
      check_mode:
        description: "Check mode (dry-run)"
        default: false
        required: false
        type: boolean

jobs:
  test:
    name: Molecule
    if: inputs.check_mode == true
    uses: ./.github/workflows/molecule.yml
    with:
      scenario: ${{ inputs.molecule_scenario }}
    secrets: inherit
    concurrency:
      group: "${{ github.workflow }}-${{ github.head_ref }}"
      cancel-in-progress: true

  check:
    name: Deploy (dry run)
    if: inputs.check_mode == true
    uses: ./.github/workflows/ansible-playbook.yml
    needs: [test]
    with:
      ansible-playbook-check-mode: true
      playbook-file: ${{ inputs.ansible_playbook_path }}
    secrets: inherit
    concurrency:
      group: "${{ github.workflow }}-${{ github.head_ref }}"
      cancel-in-progress: true

  deploy:
    name: Deploy
    if: inputs.check_mode == false
    uses: ./.github/workflows/ansible-playbook.yml
    with:
      ansible-playbook-check-mode: false
      playbook-file: ${{ inputs.ansible_playbook_path }}
    secrets: inherit
    concurrency:
      group: ${{ github.workflow }}
      cancel-in-progress: false
Inmiddels heb ik van bovenstaande .github/workflows/deploy-generic.yml twee versies gemaakt: 1 met test en 1 zonder test (stap molecule overslaan en check & deploy teruggebracht naar 1 job.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
@blackd Ja precies :). Dan zou je zelfs nog de test als conditional kunnen opnemen, bijvoorbeeld:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
on:
  workflow_call:
    inputs:
      run_test:
        description: "Run Molecule Test(s)"
        default: true
        required: false
        type: boolean

jobs:
  test:
    name: Molecule
    if: inputs.run_test == true || inputs.check_mode == true
Dan hoef je dat ook niet elke keer als parameter mee te geven, maar wordt het standaard toch gedaan.

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op maandag 16 maart 2026 @ 19:17:
@blackd Ja precies :). Dan zou je zelfs nog de test als conditional kunnen opnemen, bijvoorbeeld:
Dan hoef je dat ook niet elke keer als parameter mee te geven, maar wordt het standaard toch gedaan.
Volgens mij kom ik dan in de knoei met mijn job > check, die needs: [test] ?
alex3305 schreef op zaterdag 14 maart 2026 @ 14:48:
.forgejo/workflows/adguard_home.yaml:
YAML:
1
2
3
4
5
6
7
name: Deploy AdGuard Home

# yamllint disable-line rule:truthy
on:
  push:
    paths:
      - roles/adguard_home/**
Let op dat die /** glob geen dotfiles matched, dus een change in je .env wordt niet opgepakt.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op zaterdag 14 maart 2026 @ 14:48:
.forgejo/workflows/adguard_home.yaml:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
name: Deploy AdGuard Home

# yamllint disable-line rule:truthy
on:
  push:
    branches:
      - main
    paths:
      - roles/adguard_home/**
  pull_request:
    types:
      - opened
      - reopened
      - synchronize
    paths:
      - roles/adguard_home/**
  workflow_dispatch:
    inputs:
      check_mode:
        description: "Check mode (dry-run)"
        default: false
        required: false
        type: boolean
Deze deployment workflow werkt goed wanneer een role wordt aangepast (bijv. door renovate die een versie upgrade uitvoert) of omdat je een refactoring doet aan tasks binnen een role.

Maar het roept bij mij de vraag op hoe je omgaat met wijzigingen van configuratie?
Denk aan inventory group variabelen of .env files. Want ik neem aan dat je bij een wijziging van configuratie van een app het bijbehorende playbook óók wilt kunnen runnen in een PR.
Een van de best practices in Ansible is om variabelen per group vast te leggen in je inventory, maar daar triggert deze workflow niet op.

Daarnaast de vraag, hoe ga je om met (controleren van) wijzigingen van de playbooks zelf? Heb je hier een aparte workflow voor of is dat onderdeel van de deploy workflow?
Want een ansible-playbook check mode dient meerdere doelen, waaronder het controleren of het playbook nog correct werkt.

Zou je dus bij de path mapping per deployment van een app niet ten minste ook willen toevoegen:
  • Het playbook waarmee de deployment plaatsvindt
En hoe ver ga je daarin, want moet je dan ook alle dependencies in je playbook meenemen?
Bijv. in het voorbeeld van MQTT broker, Z2M, HA. Bij deploy HA, neem je dan ook changes in de playbooks van MQTT, Z2M mee? Ergens wel logisch, maar tegelijkertijd leg je die logica dan twee keer vast.
  • De inventory files waarmee de role variabelen gevoed worden
Hoe richt je dat goed in? De kennis van op welke groep (of host) de applicatie gedeployed wordt, ligt in het playbook. Je kan een glob maken met inventory/*/<rolename>.yml, waarmee je tevens alle role variabelen in de group bij elkaar houdt.

Of heb je een andere aanpak hiervoor?

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
@blackd Goede vragen :)

Alhoewel ik best het e.e.a. strak heb ingericht is er bij mij ook nog ruimte voor verbetering. Met andere woorden, ik heb dat nu niet. Ik heb dat eigenlijk ook niet helemaal nodig. In ieder geval niet met mijn workflow. In principe doe ik na het wijzigen van mijn group_vars of host_vars sowieso een deploy vanaf mijn lokale workstation. Enerzijds om het te testen en direct problemen op te lossen, anderzijds omdat ik snel resultaat wil O-). Wijzigingen in de vars worden dus door middel van het fail fast principe snel getest.

Tegelijkertijd heb ik ook mijn vars voor een heel groot gedeelte opgesplitst per role. Simpelweg omdat ik veel liever met veel kleine bestanden werk dan met 1 grote. Want...

Ik heb het hier vaker op Tweakers verteld, maar ik ben slechtziend en heb een zichtvermogen van circa 20%. Mijn letters zijn dus ietsjes groter dan ehh gemiddeld :9. Om een indicatie te geven hierbij een screenshot van een gemiddeld VS Code window waarbij ik de 80 karakterlimiet heb aangewezen met een rode pijl

Afbeeldingslocatie: https://tweakers.net/i/tm_0n8gexi_teL1ya2fqbMR79y8=/800x/filters:strip_exif()/f/image/fiJ0JVklSNU8OrkNoGmzQZGk.png?f=fotoalbum_large

Dit venster neemt 75% van mijn 32" display in beslag. Een display waar ik een 25-30 centimeter vanaf zit O-). Verticaal passen er zo'n 40 regels op mijn scherm voordat het ophoudt. Mijn truc is overigens om code aan de structuur te herkennen en simpelweg te onthouden waar alles staat. Ik kan daardoor bijna blind (hurdur) door code heen navigeren.

Ik ben dus bijna verplicht om veel kleine bestanden te gebruiken. Sterker nog, van Traefik heb ik zelfs twee vars bestanden in mijn group_vars, één met de configuratie en de andere met de dynamische reverse proxy configuratie. In mijn group_vars heb ik daarbij de variabelen die nodig zijn voor het geheel, dus domeinnaam, middleware configuratie, ingress netwerk, etc. En in de host_vars staan alleen variabelen die nodig zijn voor die host.

Bij een check (en deployment, want dat is bij mij hetzelfde) doe ik sowieso een deploy van het playbook. In sommige gevallen de applicatie zelf, maar in andere gevallen de complete stack. Dat is een beetje afhankelijk van de applicatie en wat ik prettig vind. Ik heb dan wat Shields in mijn README die ik kan checken wat de status is en eventueel Gatus voor status. Het feest gaat sowieso niet door bij een probleem in het playbook, inclusief validatie problemen.

Ook Renovate rolt het hele playbook uit bij een versie upgrade, maar altijd in check mode in de PR. Als een check mode niet slaagt wordt het PR niet gemerged. Klaar, uit. Ik vind dat veilig genoeg.

Eigenlijk heb ik de afgelopen jaar of jaren nog geen een echte probleem deployment gehad. Behalve dan door mijn eigen gepruts. Vaak door haastigheid :+. Ik voel dus niet de noodzaak om dit proces nog strakker in te richten. En al helemaal niet als ik zie hoeveel runs ik heb gedaan in de afgelopen ~2 jaar:

Afbeeldingslocatie: https://tweakers.net/i/-KbSZl-YUJ2AD50EIutS2jSfUyQ=/800x/filters:strip_exif()/f/image/8KlmEVfgKNTd5n50eKzV2ymK.png?f=fotoalbum_large

Niet om te pochen, maar dit gaat dus om ~1000 runs per maand of gemiddeld zo'n 30 per dag. Als er dan niet echt iets misgaat vind ik het wel best.

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op dinsdag 17 maart 2026 @ 21:18:
@blackd Goede vragen :)

Alhoewel ik best het e.e.a. strak heb ingericht is er bij mij ook nog ruimte voor verbetering. Met andere woorden, ik heb dat nu niet. Ik heb dat eigenlijk ook niet helemaal nodig. In ieder geval niet met mijn workflow. In principe doe ik na het wijzigen van mijn group_vars of host_vars sowieso een deploy vanaf mijn lokale workstation. Enerzijds om het te testen en direct problemen op te lossen, anderzijds omdat ik snel resultaat wil O-). Wijzigingen in de vars worden dus door middel van het fail fast principe snel getest.
Met mijn vragen probeer ik te ondekken hoe jouw workflow is ingericht :).
We hebben weer een overeenkomst te pakken, mijn workflow voor grote wijzigingen of nieuwe roles is ook dat ik dit op mijn laptop ontwikkel en (uiteindelijk) ga uittesten op de omgeving. Met molecule heb ik daar nog een test resource bij die ik eerder kan gebruiken. De --diff parameter is daarbij heel handig om direct bij converge te zien wat je output is (bijv. de output van een template task).
extensions/molecule/config.yml
YAML:
1
2
3
4
5
6
7
8
9
10
---
ansible:
  executor:
    args:
      ansible_playbook:
        - --diff
        - --force-handlers
        - --inventory=${MOLECULE_SCENARIO_DIRECTORY}/../inventory.yml
  env:
[.snip.]
Conclusie is volgens mij dat jij jouw deploy-<app>.yml workflows primair hebt bedoeld voor gebruik van Renovate. Check jij hier dan nog op in de workflow, bijv. met een label in de PR? Ik laat Renovate een label plaatsen, daarmee zijn die PR's herkenbaar.
Tegelijkertijd heb ik ook mijn vars voor een heel groot gedeelte opgesplitst per role. Simpelweg omdat ik veel liever met veel kleine bestanden werk dan met 1 grote. Want...

Ik ben dus bijna verplicht om veel kleine bestanden te gebruiken. Sterker nog, van Traefik heb ik zelfs twee vars bestanden in mijn group_vars, één met de configuratie en de andere met de dynamische reverse proxy configuratie. In mijn group_vars heb ik daarbij de variabelen die nodig zijn voor het geheel, dus domeinnaam, middleware configuratie, ingress netwerk, etc. En in de host_vars staan alleen variabelen die nodig zijn voor die host.
Los van jouw beperking in zichtvermogen vind ik het zelf ook prettig om met kleine overzichtelijke eenheden te werken. Dus ik wil ook toewerken naar een config file per role.

Ik zou daar wat meer op willen in zoomen, want in jouw screenshot staan variabelen die bedoeld zijn voor de role beszel en in de tree explorer staat er een voor de role adguard_home.
Ik had die op group_vars niveau verwacht.

Ik heb het nu zo ingericht:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
production
├── group_vars
│   ├── all
│   │   ├── main.yml
│   │   ├── secrets.yml
│   │   └── vault.yml
│   ├── truenas_apps
│   │   ├── authentik.yml
[..snip..]
│   │   └── uptime_kuma.yml
│   └── truenas_host
│       └── jailmaker.yml
├── host_vars
│   ├── docker.yml
│   ├── localhost.yml
│   └── nas.yml
└── inventory.yml
waarbij ik de inventory.yml file heb:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
truenas_host:
  hosts:
    nas:

truenas_apps:
  hosts:
    docker:

truenas_shared:
  children:
    truenas_hosts:
    truenas_apps:
Op mijn 'docker' host draai ik alle docker compose roles.
Ik heb dus een indirectie via een group:
docker (=host, met een IP adres, dit is een jail op de TrueNAS machine) > truenas_apps (=group)
Alle playbooks apply ik op de group, niet op de host.
Als gevolg hiervan heb ik alle role variabelen in de truenas_apps group een eigen file gegeven met de role variabelen.

In host_vars staan echt alleen host specifieke variabelen:
inventory/production/host_vars/nas.yml:
YAML:
1
2
3
4
5
ansible_host: [..]
ansible_user: [..]
ansible_password: "{{ secrets.truenas_admin_password }}"
ansible_become_password: "{{ secrets.truenas_admin_password }}"
ansible_ssh_common_args: '[ jump host ]'
Ik vraag me af of mijn indirectie zin heeft of dat het ook simpeler kan. Want zo te zien heb jij alle role variabelen op host_var niveau geplaatst. Klopt dat of heb ik het mis?

Daarnaast vraag ik me af, ik heb compose stacks die ik 2x uitrol, dat zijn nu twee roles, maar die wil/kan ik generaliseren naar één role. Bijv. traefik en traefik_external. Die hebben allebei een aparte folder voor het compose project. Ik ontkom er niet aan om de variabele die de folder naam stuurt, in het playbook te specificeren:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
---
- name: Deploy traefik
  hosts: truenas_apps

  roles:
     - role: traefik
       vars:
          traefik__stack_name: traefik
          traefik__external: false
     - role: traefik
       vars:
          traefik__stack_name: traefik-external
          traefik__external: true
          [ andere variabelen die anders zijn, zoals poorten, labels ... ]
Bij een check (en deployment, want dat is bij mij hetzelfde) doe ik sowieso een deploy van het playbook. In sommige gevallen de applicatie zelf, maar in andere gevallen de complete stack. Dat is een beetje afhankelijk van de applicatie en wat ik prettig vind. Ik heb dan wat Shields in mijn README die ik kan checken wat de status is en eventueel Gatus voor status. Het feest gaat sowieso niet door bij een probleem in het playbook, inclusief validatie problemen.
Met 'het playbook' bedoel je jouw meta playbooks/all.yml en dat gebruik je op jouw lokale machine?
Of heb je hier ook een check/deploy workflow voor in CI?

Want wanneer je klaar bent met lokaal ontwikkelen wil je wel de lint, test, check en deploy ook uitvoeren en testen of je checkin compleet is. Hoe maak je dan het onderscheid tussen de overige deploy workflows die voor Renovate gebruikt worden?
Ook Renovate rolt het hele playbook uit bij een versie upgrade, maar altijd in check mode in de PR. Als een check mode niet slaagt wordt het PR niet gemerged. Klaar, uit. Ik vind dat veilig genoeg.
Wat bedoel je met een versie upgrade? Bedoel je hiermee dependencies zoals ansible-core, python, collections en external-roles?

Ik zie de volgende stromen aan changes in mijn repo voorbij komen:
  1. Docker image upgrades, getriggerd door Renovate, onderdeel van een role.
  2. Package updates (docker-ce, apt packages, dat soort dingen), getriggerd door Renovate, onderdeel van een (externe) role.
  3. Core updates (ansible-core, python, roles, collections), onderdeel van mijn execution environment, getriggerd door Renovate vanuit mijn andere repo.
  4. Development updates (pre-commit, ansible-lint, renovate-cli, ...), getriggerd door Renovate, onderdeel van andere files in mijn repo (pre-commit-config.yml, etc.).
  5. Renovate reconfigure
  6. Workflow aanpassingen
  7. Feature/Fix PR's, getriggerd door mijzelf, aanpassingen in al het bovenstaande mogelijk.
Eigenlijk wil je per flow van werk een goede CI inrichten om het te testen en waar nodig deployen.
Flow 1 heb ik nu met de deploy-<role>.yml workflows wel goed ingericht, maar de overige flows wil ik nog kijken of ik dat wat strakker kan inrichten.
Eigenlijk heb ik de afgelopen jaar of jaren nog geen een echte probleem deployment gehad.
Ik de laatste tijd eigenlijk ook niet, maar ik kom van Semaphore UI, daarna Woodpecker CI en nu Github Actions. Ik heb de afgelopen tijd wel e.e.a. aan wijzigingen doorgevoerd om sneller feedback te krijgen door meer te linten en testen. Ik ben afgestapt van Semaphore UI vanwege de inflexibiliteit van de run omgeving (de container waar je playbook draait) en de keuzes die ik toen had gemaakt (bitwarden integratie) wat heel lastig op te zetten was. Woodpecker CI was daar al wat beter in, maar toen ging ik ook Github Actions gebruiken en dan is de wisselwerking niet te doen (bijv. check mode afhankelijk van een job test). Daarom helemaal over naar Github Actions. Tot nu toe gaat dat goed, maar de job moet niet te groot zijn. Ik heb de eerste 'out of disk space' al gehad bij een Molecule test met alle scenario's.

Ik gebruik nu dus Github Actions, deels de Github runners en deels lokaal. Als ik een grote refactoring doe, kom ik makkelijk aan de 2000 minuten/maand (=limiet). Ik heb vorige maand ook 900 jobs gedraaid, 1600min en dan doe ik niks geks.

Mijn initial commit van deze repo was Dec 2024. Ik ben ergens in Jun 2024 met Ansible gestart, dat was om Pi-Hole in een HA cluster te draaien. Mijn job is wel in de IT maar als software engineer, dus ik doe dit puur voor de hobby.

Is het al tijd voor een 'Ansible Automation' topic :+.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
blackd schreef op woensdag 18 maart 2026 @ 10:29:
Met mijn vragen probeer ik te ondekken hoe jouw workflow is ingericht :).
Yes. En ik krijg inzicht in hoe jij het doet :). Tegelijkertijd is het ook niet verkeerd om hier kritisch over te blijven denken. Dank daarvoor.
Conclusie is volgens mij dat jij jouw deploy-<app>.yml workflows primair hebt bedoeld voor gebruik van Renovate. Check jij hier dan nog op in de workflow, bijv. met een label in de PR? Ik laat Renovate een label plaatsen, daarmee zijn die PR's herkenbaar.
Primair is misschien niet het juiste woord. Primair is het voor alle deployment, maar als ik iets in mijn vars verander dan test ik dat wel eerst met een deployment vanuit mijn lokale host voordat ik dat vanuit CI uitrol. Aangezien een CI deploy bij mij altijd wordt uitgevoerd bij een commit naar main, wordt dus de deployment dus altijd idempotent herhaald.

Ik plaats zeker labels :). Ik heb een eigen label sync action gebouwd zodat ik labels in een yaml bestand kan managen. Op het moment dat ik deze yaml wijzig, worden de labels geüpdatet. Vanuit Renovate voeg ik dan de juiste labels bij PR's toe:

Afbeeldingslocatie: https://tweakers.net/i/JkqsweVUeKJy2pewYU4Fp04BG9U=/800x/filters:strip_exif()/f/image/8t1hhHfCXP6MTJrY7Jg9RBsL.png?f=fotoalbum_large

In principe krijgen Renovate PR's altijd de labels CI en maintenance.
Ik vraag me af of mijn indirectie zin heeft of dat het ook simpeler kan. Want zo te zien heb jij alle role variabelen op host_var niveau geplaatst. Klopt dat of heb ik het mis?
Dat heb je mis :).

De connection parameters zoals ansible_user, ansible_host, etc. heb ik in mijn inventory opgenomen.

In mijn group_vars staan variabelen die voor heel de groep gelden. De meeste van mijn applicaties zijn Docker applicaties dus de meeste van mijn group_vars bevinden zich bij mij in de docker group. Wellicht dat ik dat nog een keer splits. Pak ik dan home_assistant.yml in mijn docker group_vars, dan heb ik daarin bijvoorbeeld het domein en netwerk staan waarin de Home Assistant applicatie zich bevindt.

In de host_vars van mijn primaire host heb ik ook een home_assistant.yml waarin ik o.a. de cpuset configureer Dit is namelijk host afhankelijk. Op de secundaire host heb ik ook een home_assistant.yml waar ik mijn Zigbee en Z-Wave adapter heb ingesteld. Wederom is dit host afhankelijk. Dit zou je ook in een eigen yml kunnen doen.
Daarnaast vraag ik me af, ik heb compose stacks die ik 2x uitrol, dat zijn nu twee roles, maar die wil/kan ik generaliseren naar één role. Bijv. traefik en traefik_external. Die hebben allebei een aparte folder voor het compose project. Ik ontkom er niet aan om de variabele die de folder naam stuurt, in het playbook te specificeren.
Ik heb geen rollen die ik twee keer naar dezelfde host uitrol. Als ik dat wel heb, pas ik inderdaad de variabelen van 1 role aan.
Met 'het playbook' bedoel je jouw meta playbooks/all.yml en dat gebruik je op jouw lokale machine?
Of heb je hier ook een check/deploy workflow voor in CI?
Nee, het playbook van de applicatie die ik aan heb gepast. Het all playbook gebruik ik nauwelijks.
Want wanneer je klaar bent met lokaal ontwikkelen wil je wel de lint, test, check en deploy ook uitvoeren en testen of je checkin compleet is. Hoe maak je dan het onderscheid tussen de overige deploy workflows die voor Renovate gebruikt worden?
Niet? Dat is gewoon dezelfde workflow. Ik gebruik wel een pre-commit hook voordat ik alles commit.
Wat bedoel je met een versie upgrade? Bedoel je hiermee dependencies zoals ansible-core, python, collections en external-roles?
Ook. Maar ik bedoel hiermee de applicatie uit Docker Compose.
Eigenlijk wil je per flow van werk een goede CI inrichten om het te testen en waar nodig deployen.
Ik zie dat toch net anders. Ik heb 1 flow per Compose applicatie of stack. Op het moment dat er een stack aangepast wordt, wordt deze in check mode uitgevoerd en uiteindelijk deployed. Alle andere tooling die daaronder zit komt automatisch mee en wil ik dus niet apart testen. Met andere woorden: dat geloof ik wel. Omdat ik toch fail fast gebruik zie ik problemen snel genoeg.

En mocht er toch een onderdeel problemen geven, dan wordt de applicatie niet deployed. Enerzijds omdat waarschijnlijk eerder in het proces het probleem al ontstaat, anderzijds omdat de check mode dan sowieso faalt en het PR niet wordt gemerged.

Ook wil ik alles zsm deployen, wederom vanwege4 fail fast, maar ook omdat Ansible idempotent hoort te zijn. Zijn er dus constant changes, dan gaat er waarschijnlijk iets anders mis.
Is het al tijd voor een 'Ansible Automation' topic :+.
Eerder iets over CI / homelab / selfhosting :).

  • blackd
  • Registratie: Februari 2001
  • Niet online
@alex3305 Thanks voor je reactie, je zet me aan het denken m.b.t. de workflow strategie.
Ik denk dat ik dit alles even moet laten bezinken en verder moet gaan met de playbooks gaan opknippen met de juiste path mapping en de juiste roles applyen.

Want het risico wat ik zie met opknippen en niet het main.yml playbook te gebruiken is dat je iets mist met je checkins en niet uitrolt, zodat je omgeving niet (compleet) in de desired state is. Maar misschien is dat een gevoel wat nu ontstaat door dit opknippen en dat er straks niks meer aan de hand is.

Daarnaast zit ik nog te puzzelen (in mijn hoofd) hoe ik bepaalde generieke (externe) rollen goed moet organiseren en laten triggeren door Renovate. Bijv. voor docker gebruik ik geerlingguy.docker en daarmee kan ik de docker-ce version configureren. Dat is nu een group variable, dus dan moet het docker-ce playbook daarop triggeren. Vandaar mijn vragen over host_vars en group_vars.
alex3305 schreef op zaterdag 14 maart 2026 @ 14:48:
Nu heb ik namelijk regelmatig 3 - 5 Renovate PR's openstaan, terwijl ik voor digests zelfs al alleen branches gebruik 8)7 :X. Dat houdt elkaar ook nog eens op, want elke keer moeten PR's gesynct worden én wordt er dus opnieuw een Ansible-playbook met check mode uitgevoerd om te testen of het geheel nog werkt.
Al eens naar een merge-queue gekeken? Ik zag dat Github het wel ondersteunt, maar alleen voor betalende klanten of openbare repo's. Voor Forejo staat een feature request open zag ik.

[ Voor 30% gewijzigd door blackd op 18-03-2026 12:49 ]

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
@blackd Je hebt gelijk dat het gebruik van opgeknipte playbooks risico's met zich meebrengt. Wat mij betreft is dat een trade-off tussen snelheid (development velocity) en mogelijke instabiliteit of eigenlijk beter gezegd een 'incomplete' omgeving. Ik besef me op dat moment ook dat mijn meta-playbooks uiteindelijk allemaal gebruik maken van de applicatie playbooks. De kans dat ik dus iets mis bij het uitrollen acht ik daarmee dus minimaal, immers vinden die vaak genoeg plaats.

Toen ik Ansible gebruikte op grotere omgevingen en met klanten rolde we ook vaak alleen specifieke veranderingen en/of klantapplicaties uit. En dan periodiek alles. Wat mij betreft is dat een prima verhouding, maar dat is natuurlijk een kwestie van smaak. Net zoals met veel aspecten die ik hier neerpen. Het is bijvoorbeeld ook niet verkeerd om klein te beginnen en uit te bouwen. Of een andere opzet dan de mijne te hebben. Ik vind dit fijn, jij misschien niet. Prima, toch? Ik vind het vooral belangrijk om een open blik te houden naar de opzet en mening van anderen. Daar kun je alleen maar van leren :).
Daarnaast zit ik nog te puzzelen (in mijn hoofd) hoe ik bepaalde generieke (externe) rollen goed moet organiseren en laten triggeren door Renovate. Bijv. voor docker gebruik ik geerlingguy.docker en daarmee kan ik de docker-ce version configureren. Dat is nu een group variable, dus dan moet het docker-ce playbook daarop triggeren. Vandaar mijn vragen over host_vars en group_vars.
Oh ja. Grappig genoeg heb ik die role dus zelf gebouwd en is die vrijwel gelijk aan die van geerlingguy O-). Dat soort dingen zou ik in een 'group_vars/docker/all.yml' zetten en daarop laten triggeren. Of wellicht 'group_vars/docker/version.yml'. Die kun je dan direct door Renovate met een yaml comment laten bijhouden. Zo'n extra file voelt misschien gaar, maar tegelijkertijd is het wel heel erg duidelijk. Immers heb ik ook een python-version bestand in mijn repo.
Al eens naar een merge-queue gekeken? Ik zag dat Github het wel ondersteunt, maar alleen voor betalende klanten of openbare repo's. Voor Forejo staat een feature request open zag ik.
Goed idee, maar ik gebruik bijna geen GitHub. En aangezien het dus nog niet in Forgejo zit, gebruik ik het sowieso niet :>. Ik heb er enorm veel schik in om alles zelf te hosten. Dat probeer ik dus zover als het kan. GitHub is prima, maar ik vind bijv. Copilot enorm ruk. Ook omdat ik niet alles in de cloud wil hebben...

Wat dat betreft is zo ongeveer het enige wat ik nog echt mis is een mailserver. Laatst wel naar Docker mailserver gekeken, maar ik wilde het eigenlijk achter Traefik hebben en dat ging niet. Misschien dat ik binnenkort nog eens een poging waag.

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op woensdag 18 maart 2026 @ 16:44:
Toen ik Ansible gebruikte op grotere omgevingen en met klanten rolde we ook vaak alleen specifieke veranderingen en/of klantapplicaties uit. En dan periodiek alles. Wat mij betreft is dat een prima verhouding, maar dat is natuurlijk een kwestie van smaak. Net zoals met veel aspecten die ik hier neerpen. Het is bijvoorbeeld ook niet verkeerd om klein te beginnen en uit te bouwen. Of een andere opzet dan de mijne te hebben.
Periodiek het hele playbook runnen zou een goed compromis zijn.
Ik zag ergens anders dat jij periodiek een release doet van je codebase.
Op dit moment doe ik een nightly release en dan apply ik de gehele omgeving. Dat zou ik nog steeds kunnen doen, maar misschien wat minder vaak (wekelijks bijv.).
Ik vind dit fijn, jij misschien niet. Prima, toch? Ik vind het vooral belangrijk om een open blik te houden naar de opzet en mening van anderen. Daar kun je alleen maar van leren :).
Helemaal eens, daarom geef ik ook aan dat het misschien bij mij nog een kwestie van gewenning is.
Mijn repo is aan het groeien, ik loop al langer met de gedachtes om e.e.a. sneller te maken. Maar hoe, dat wist ik niet. Jouw aanpak met deploy per role lijkt tot nu toe een mooie oplossing en ik heb de grootste wijzigingen in mijn playbook al doorgevoerd.

Daarnaast heb ik tot nu toe bijna alles zelf geleerd wat betreft Ansible, deze discussies voeren versnelt het leerproces, dus dat vind ik erg tof! :).
Oh ja. Grappig genoeg heb ik die role dus zelf gebouwd en is die vrijwel gelijk aan die van geerlingguy O-). Dat soort dingen zou ik in een 'group_vars/docker/all.yml' zetten en daarop laten triggeren. Of wellicht 'group_vars/docker/version.yml'. Die kun je dan direct door Renovate met een yaml comment laten bijhouden. Zo'n extra file voelt misschien gaar, maar tegelijkertijd is het wel heel erg duidelijk. Immers heb ik ook een python-version bestand in mijn repo.
Hele goede suggestie, ik was al die richting op aan het bewegen. Ik heb al een group 'pkg_docker' met de hosts waarop docker draait dus een group_vars/pkg_docker/docker_version.yml vind ik een mooie, ik moet nog e.e.a. centraliseren maar de workflow voelt zo heel logisch:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
name: Docker-ce
on:
  push:
    branches:
      - main
    paths:
      - 'inventories/production/group_vars/*/docker_version.yml'
  pull_request:
    types:
      - opened
      - synchronize
      - reopened
    paths:
      - 'inventories/production/group_vars/*/docker_version.yml'
Een renovate yaml comment had ik al voor elkaar gekregen, de docker-version string had ik al in een group var, het ging alleen om de naamgeving van de file en hoe daarop te triggeren.
Goed idee, maar ik gebruik bijna geen GitHub. En aangezien het dus nog niet in Forgejo zit, gebruik ik het sowieso niet :>. Ik heb er enorm veel schik in om alles zelf te hosten. Dat probeer ik dus zover als het kan. GitHub is prima, maar ik vind bijv. Copilot enorm ruk. Ook omdat ik niet alles in de cloud wil hebben...
Het ging mij meer om het principe van een merge queue, misschien is het ook wel op een andere manier te bereiken, weet ik niet.

Ik vind self-hosting ook heel gaaf, maar kies er wel voor bepaalde zaken bewust buiten de deur te houden.
Mijn resources op mijn server zijn beperkt (TrueNAS Scale draait op een HP Microserver Gen10 met 16GB ram en dat laatste is een behoorlijke bottleneck).

Daarentegen is GitHub niet mijn favoriete plek om mijn broncode op te slaan. Ik had al een GitHub account ver voor de overname van Microsoft. Liever gebruik ik een EU privacyvriendelijk alternatief. Self-hosting vind ik nog wat spannend: als mijn server of docker host down is, kan ik ook niet meer bij de broncode. Het omgekeerde is natuurlijk ook waar als GitHub besluit mijn account te closen :).

Maar wat me ook nog tegenhoudt is dat ik bij Woodpecker CI (wat draaide op mijn docker host) een kip-ei probleem had. Als het Playbook mijn docker-ce package ging upgraden, stopte Woodpecker CI dus ook en hield mijn Playbook ermee op. Mijn GitHub Local Runner draait op een eigen Container op mijn TrueNAS. Dan zou ik een extra Container oid moeten hebben met een git server.

Hoe doe heb jij dat ingericht?
Wat dat betreft is zo ongeveer het enige wat ik nog echt mis is een mailserver. Laatst wel naar Docker mailserver gekeken, maar ik wilde het eigenlijk achter Traefik hebben en dat ging niet. Misschien dat ik binnenkort nog eens een poging waag.
Persoonlijk ga ik daar niet (meer) aan beginnen en is e-mail een goed voorbeeld waarvoor ik liever een privacyvriendelijk, EU-hosted alternatief zoek en daar graag voor betaal. In een ver verleden MDaemon op Windows gedraaid maar tegenwoordig pas ik daarvoor.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
blackd schreef op woensdag 18 maart 2026 @ 19:50:
[...]

Ik zag ergens anders dat jij periodiek een release doet van je codebase.
Op dit moment doe ik een nightly release en dan apply ik de gehele omgeving. Dat zou ik nog steeds kunnen doen, maar misschien wat minder vaak (wekelijks bijv.).
Yes. Ik doe een weekly release.

Afbeeldingslocatie: https://tweakers.net/i/y_-pphLiCvfYB6gPOfb3SrNGfkI=/fit-in/4000x4000/filters:no_upscale():strip_exif()/f/image/qJ0iNHcXnpmSQKLzlgfwdNaM.png?f=user_large

Die wordt op zondag / maandag automatisch aangemaakt, of anders op de volgende dag mocht die gemist zijn om de een of andere reden.

Verder zijn mijn release notes niets meer dan een opsomming van commits:
Members only:
Alleen zichtbaar voor ingelogde gebruikers. Inloggen
Deze release doe ik voornamelijk om bij te kunnen houden waar er iets is gebeurd of eventueel misgaat. In principe zit alles in commit logs, maar ik vind dit mij net wat meer inzicht geven.
Daarnaast heb ik tot nu toe bijna alles zelf geleerd wat betreft Ansible, deze discussies voeren versnelt het leerproces, dus dat vind ik erg tof! :).
d:)b Same
Hele goede suggestie, ik was al die richting op aan het bewegen. Ik heb al een group 'pkg_docker' met de hosts waarop docker draait dus een group_vars/pkg_docker/docker_version.yml vind ik een mooie.
Misschien flauw, maar waarom pkg_docker? Een eigenschap van de host is toch docker of containers en niet de package containers? Ik heb ook een group dns (of dns_server) bijvoorbeeld, die zou ik ook AdGuard Home kunnen noemen of pkg_adguardhome of container_adguardhome, maar dat vind ik niet beschrijvend genoeg en misschien ook niet helemaal de waarheid als het dns servers zijn, want het zou ook Pi-Hole kunnen zijn.

Wat ik daarmee vooral bedoel te zeggen is dat ik dus een bewust onderscheid maak ik naamgeving en merk in rollen. Immers zijn dat de pakketten die AdGuard Home of Pi-Hole installeren én de functionele groepen in de inventory. Bijvoorbeeld dns of dns_server. Waarbij dns bij mij beschrijvend genoeg is. Omdat alle machines al een dns client hebben en dat dus niet apart benoemd hoeft te worden.

Docker is in mijn geval vergelijkbaar met Luxaflex, wat eigenlijk gewoon lamellen zijn O-). Onder water zal het me roesten welke container technologie er draait, als ik maar zeker weet dat wanneer ik een container deploy deze daadwerkelijk opstart. Zo heb ik dus ook de groepen ci en git. Maar ook zigbee, thread en zwave. Dan kies ik er namelijk bewust voor om een host met een compatibel dongle in de juiste groep te zetten.
Het ging mij meer om het principe van een merge queue, misschien is het ook wel op een andere manier te bereiken, weet ik niet.
Ik bedoelde het niet vervelend. Het concept is me bekend en zou prachtig zijn, maar ja, als het er niet in zit kan ik het ook niet gebruiken O-) :+.
Mijn resources op mijn server zijn beperkt (TrueNAS Scale draait op een HP Microserver Gen10 met 16GB ram en dat laatste is een behoorlijke bottleneck).
Ik heb jaren met een J4105 gespeeld en later ook een J1800 in een NAS. Ik weet hoe het is om met beperkte riemen te roeien :9. Forgejo en Gitea zijn gelukkig heel lichtgewicht. Het kan geen kwaad om een push of pull mirror te hebben. En laat die functionaliteit nou standaard in beide pakketten zitten :). Dan hoef je nog geen CI te gebruiken.
Daarentegen is GitHub niet mijn favoriete plek om mijn broncode op te slaan. Ik had al een GitHub account ver voor de overname van Microsoft.
Mja same. Ik heb niet zoveel tegen Microsoft, maar ik vind Copilot / AI die mijn code analyseert en daar gratis mee leert geen heel prettig gevoel.
Liever gebruik ik een EU privacyvriendelijk alternatief.
Codeberg 8) of GitLab zijn dan goede alternatieven.
Self-hosting vind ik nog wat spannend: als mijn server of docker host down is, kan ik ook niet meer bij de broncode. Het omgekeerde is natuurlijk ook waar als GitHub besluit mijn account te closen :).
Dan moet je zorgen dat je server of Docker niet down is :> . Duidelijk een skill issue :+ _O- . Nee joh, slap geouwehoer.

Ik maak met Kopia incrementele, versleutelde, de-duplicerende backups van mijn data en daar kan ik, zo heb ik inmiddels geleerd, goed op vertrouwen. Ik maak periodiek ook koude kopieën en de data schrijf ik weg naar een remote server en een Drive. Daarnaast heb ik uiteraard een kopie van mijn Git repo op mijn workstation. Kwijtraken zal mij dus niet bijster snel overkomen. En herstel heb ik al meermaals uitgetest.
Maar wat me ook nog tegenhoudt is dat ik bij Woodpecker CI (wat draaide op mijn docker host) een kip-ei probleem had. Als het Playbook mijn docker-ce package ging upgraden, stopte Woodpecker CI dus ook en hield mijn Playbook ermee op. Mijn GitHub Local Runner draait op een eigen Container op mijn TrueNAS. Dan zou ik een extra Container oid moeten hebben met een git server.

Hoe doe heb jij dat ingericht?
Dat is bij mij ook nog een heikel punt. Ik heb daar wel over nagedacht en kwam tot een paar oplossingen:
  • Uitvoeren vanaf mijn workstation
  • Host A Host B laten updaten en daarna vice-versa
  • Tijdelijk een extra container opzetten, de build afbreken, starten in de tijdelijke container en weer weggooien
  • Permanent een container laten draaien voor updates
De tweede optie is op zichzelf het meest geschikt, maar nu voer ik het periodiek uit vanaf mijn workstation. Forgejo wordt ook niet bijster vaak geügpraded en dat geeft vooralsnog geen problemen.

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op woensdag 18 maart 2026 @ 21:17:
Yes. Ik doe een weekly release.

Verder zijn mijn release notes niets meer dan een opsomming van commits:

Deze release doe ik voornamelijk om bij te kunnen houden waar er iets is gebeurd of eventueel misgaat. In principe zit alles in commit logs, maar ik vind dit mij net wat meer inzicht geven.
Hier hetzelfde qua release notes.
Maar doe jij dan ook die periodieke uitrol?
Misschien flauw, maar waarom pkg_docker?
Sorry voor je relaas en ik snap je helemaal, maar ik had al een host genaamd docker en wilde geen name collisions.
Ik heb jaren met een J4105 gespeeld en later ook een J1800 in een NAS. Ik weet hoe het is om met beperkte riemen te roeien :9. Forgejo en Gitea zijn gelukkig heel lichtgewicht. Het kan geen kwaad om een push of pull mirror te hebben. En laat die functionaliteit nou standaard in beide pakketten zitten :). Dan hoef je nog geen CI te gebruiken.
Dat is best interessant, dat ga ik eens onderzoeken.
Codeberg 8) of GitLab zijn dan goede alternatieven.
d:)b
Ik maak met Kopia incrementele, versleutelde, de-duplicerende backups van mijn data en daar kan ik, zo heb ik inmiddels geleerd, goed op vertrouwen.
Hier moet ik nog wat mee, dat is ook de reden dat ik geen Immich draai maar een dienst afneem.

Ik zou ook paperless willen draaien, maar dan moet ik wel de backup strategie strak in orde hebben.
Dat is bij mij ook nog een heikel punt. Ik heb daar wel over nagedacht en kwam tot een paar oplossingen:
  • Uitvoeren vanaf mijn workstation
  • Host A Host B laten updaten en daarna vice-versa
  • Tijdelijk een extra container opzetten, de build afbreken, starten in de tijdelijke container en weer weggooien
  • Permanent een container laten draaien voor updates
De tweede optie is op zichzelf het meest geschikt, maar nu voer ik het periodiek uit vanaf mijn workstation. Forgejo wordt ook niet bijster vaak geügpraded en dat geeft vooralsnog geen problemen.
Ik had Woodpecker op een gegeven moment uit de playbook gehaald met tags en die update ik vanaf mijn pc. Dat ging goed. Maar docker is een ander verhaal.

De Github runner update zichzelf. In de container draait verder niet zoveel.
Dus op dit moment houd ik die container buiten schot wat betreft de playbooks.

Misschien is ansible-pull ook nog een alternatief?
Door met een scheduled task op de machine zelf het playbook uit te voeren.
Ik heb het verder nog niet gebruikt, dus misschien sla ik de plank compleet mis.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:16
blackd schreef op woensdag 18 maart 2026 @ 22:13:
[...]

Hier hetzelfde qua release notes.
Maar doe jij dan ook die periodieke uitrol?
Nee, nog niet. Dat is 's nachts en ik doe geen uitrollen 's nachts.

Wederom is dit iets wat ik op mijn lijstje heb staan, maar gewoon nog geen noodzaak voor heb gehad of niet aan ben toegekomen.
Sorry voor je relaas en ik snap je helemaal, maar ik had al een host genaamd docker en wilde geen name collisions.
Maak je niet druk :P. Ik ben tijdens mijn studie en later tijdens mijn werk doodverveeld met functional en non-functional requirements. Blijkbaar heeft het toch indruk gemaakt O-). Inmiddels is het een concept waar ik wat strakker aan vast houd. Het helpt dan ook als ik ergens van dienst wissel. Mijn vrouw of ik hoeven dan bijvoorbeeld geen nieuwe / andere URL te onthouden voor zoiets als de router, want dat is gewoon 'router.domein.nl' en niet 'asus.domein.nl' of 'unifi.domein.nl'.
Hier moet ik nog wat mee, dat is ook de reden dat ik geen Immich draai maar een dienst afneem.

Ik zou ook paperless willen draaien, maar dan moet ik wel de backup strategie strak in orde hebben.
Immich en Paperless zijn twee van mijn meest gebruikte diensten :D. Kopia is op zichzelf niet bijster complex om op te zetten of te beheren. Het is ook niet super fancy of zo. Van Docker applicaties neem ik over het algemeen ook gewoon snapshots mee, behalve van databases ivm WAL. Die gooi ik dan in een .kopiaignore. Van de databases maak ik overigens een dump en die neem ik dan wel mee in de backup.
Maar docker is een ander verhaal.
Ah, dat was even niet binnengekomen O-). Ja, niet dus :|...
Misschien is ansible-pull ook nog een alternatief?
Door met een scheduled task op de machine zelf het playbook uit te voeren.
Ik heb het verder nog niet gebruikt, dus misschien sla ik de plank compleet mis.
Zag ik laatst ook langskomen. Neem ik ook nog even mee. Dit zou mij ook nog helpen voor wat andere zaken waar ik evt. een Ansible task of play wil uitvoeren zonder dat ik direct allemaal rechten hoef toe te kennen :).

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op woensdag 18 maart 2026 @ 22:38:
Dat is 's nachts en ik doe geen uitrollen 's nachts.
Wat misschien nog wel een interessante aanpak is om je playbook in --diff mode te draaien. Hiermee zie je verschillen t.o.v. desired state. Dat in combinatie met --check mode, kun je als het ware controleren in hoeverre je afwijkt van je gewenste configuratie. Dat zou je prima 's nachts kunnen draaien, waarna je 's ochtends een lijstje met afwijkingen kan raadplegen en kijken of er actie nodig is.

Je moet dan alleen wel goed in de smiezen houden of je tasks geen ongewenste changes aanbrengen op het systeem. In een paar van mijn playbooks update ik de apt cache en dat resulteert in een changed state. Je kan dan uren discussieren of dat gewenst is of niet, maar het rapporteert wel zo (tenzij je changed_when opgeeft).
Inmiddels is het een concept waar ik wat strakker aan vast houd. Het helpt dan ook als ik ergens van dienst wissel.
Ik snap je, maar dit ging om een groep van hosts waar docker draait. Eigenlijk dus 'dockerhosts' of 'dockerservers' (analoog aan webservers, dbservers) in het patroon group inventory by function. Ik heb nl. 3 machines waar docker-ce op draait: twee dnsservers en een TrueNAS machine.

Maar eigenlijk zou het iets als 'container orchestration' moeten noemen, dan kan dat docker, podman, lxc, k8s, etc. zijn. Maar ja, aan de andere kant kan ik het ook niet zomaar uitwisselen. Mijn roles zijn toegespitst op docker (compose) dus niet eenvoudig uitwisselbaar.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023

Pagina: 1 ... 17 18 Laatste