• alex3305
  • Registratie: Januari 2004
  • Laatst online: 03-04 15:09
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: 03-04 15:09
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: 03-04 15:09
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
  • Nu online
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: 03-04 15:09
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: 03-04 15:09
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: 03-04 15:09
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: 03-04 15:09
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: 03-04 15:09
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: 03-04 15:09
@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: 03-04 15:09
@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: 03-04 15:09
@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: 03-04 15:09
@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: 03-04 15:09
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: 03-04 15:09
@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: 03-04 15:09
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: 03-04 15:09
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


  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op woensdag 18 maart 2026 @ 22:38:
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.
Ik heb een andere backup strategie, namelijk dat TrueNAS verantwoordelijk is voor het backuppen van de data naar twee online storage providers (ook dat is nog US based en staat nog op mijn lijstje, maar goed, kan niet alles tegelijk :D).

Backup van mijn data op TrueNAS is dus wel geregeld, maar voor mijn docker apps nog niet. Kopia is voor mij niet perse nodig want op zich ben ik tevreden met de replicatie die in TrueNAS is ingebouwd.

Per Docker compose project heb ik grofweg de volgende structuur:
- Een folder waarin het compose project staat waar docker compose up gedaan wordt
- Een folder (met verschillende subfolders) waar alle data leeft, dit splits ik op per compose project per service, dus bijv.
code:
1
2
3
..../authentik/redis/data
..../authentik/postgresql/data
..../authentik/server/media
Wil ik een backup van authentik data, dan zou ik die authentik folder dus helemaal kunnen repliceren zodat deze wordt meegenomen in de backup van TrueNAS.
Maar voor de database, zoals je zelf al schetst, is dat wat uitdagender want dan moet je een db dump hebben en die meenemen in de backup.

Hoe pak jij dit aan?

Een mogelijke aanpak die ik had bedacht is om een backup playbook of task te maken die voor elke postgresql db een dump maakt. Of omgekeerd, eigenlijk zou ik per app een backup task willen hebben en dan voor alle apps de backup task willen runnen.

Veel apps hebben geen database en zijn eenvoudig te backuppen (ZFS snapshot zou voldoende zijn), maar ik heb er een paar met een eigen database. Sommige apps hebben ook een backup / export functie, denk aan de unifi controller. Dus eigenlijk wil ik dat per app afhandelen.

De stappen zijn hier beschreven met gebruik van de postgres_db Ansible module. Dat zou dan voor één app werken, dat wil ik dan doortrekken naar meerdere apps.

Of is dit bij jou onderdeel van een Kopia action?

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


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 03-04 15:09
@blackd Goede vraag, daar ben ik toevallig de afgelopen week mee bezig geweest :D.

Momenteel draai ik vanuit Unraid's crontab een script om een database dump te maken. Bijvoorbeeld:
Bash:
1
2
3
4
5
# MariaDB
docker exec -i home-assistant-database sh -c 'mariadb-dump --all-databases > /var/lib/mysql/dump.sql'

# PostgreSQL
docker exec -i paperless-ngx-database sh -c 'PGPASSWORD=$POSTGRES_PASSWORD pg_dumpall --username=$POSTGRES_USER' > /mnt/applications/appdata/paperless-ngx/database.sql
Dat gaat periodiek en dat gaat dus ook periodiek met de Kopia backup mee. Waarom niet vanuit Kopia zelf? Omdat Kopia dan rechten zou moeten hebben in de containers of op de host. Dat is niet iets wat ik wil.

Eerder in dit topic heeft @Mars Warrior aangegeven dat hij een DB Backup container gebruikt en die richting wilde ik eigenlijk ook op. Echter ben ik de afgelopen week met Ofelia bezig geweest.

Ofelia is een relatief simpele task scheduler die gebruik maakt van Docker labels. Omdat het simpel is kost het ook weinig resources. Tegelijkertijd wil ik ook niet veel functies, behalve taken. Maar bovenstaande wordt dan dus:
YAML:
1
2
3
4
5
6
services:
  mariadb:
    labels:
      ofelia.enabled: true
      ofelia.job-exec.home-assistant-database-dump.schedule: "35 */4 * * *"
      ofelia.job-exec.home-assistant-database-dump.command: "sh -c 'mariadb-dump --all-databases > /var/lib/mysql/dump.sql'"
Nu heb ik dit nog niet getest, maar andere tasks zoals het syncen van mijn backups en een andere database dump waarmee ik test lijken vooralsnog prima te werken :).

  • blackd
  • Registratie: Februari 2001
  • Niet online
@alex3305 Thanks voor het uiteenzetten van de opties, dat helpt enorm. De route van Ofelia als task scheduler en dan per compose project je database dump definieren als label spreekt mij op dit moment het meeste aan.

Je draait dan het commando in de container (in dit geval van de mariadb van Home Assistant) en plaatst de database dump dan in een directory die gemount is op het host systeem, waarna Kopia dit oppikt en meeneemt in de backup?

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


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 03-04 15:09
blackd schreef op zaterdag 21 maart 2026 @ 14:56:
Je draait dan het commando in de container (in dit geval van de mariadb van Home Assistant) en plaatst de database dump dan in een directory die gemount is op het host systeem, waarna Kopia dit oppikt en meeneemt in de backup?
Excuses, ik besef me nu dat ik daar een klein beetje te summier was O-).

Het commando wordt inderdaad uitgevoerd in de Docker container en de dump wordt in dezelfde directory geplaatst als de database files van MariaDB of PostgreSQL. Alhoewel dat normaliter niet helemaal gewenst is, vind ik dat wel het meest praktisch. Een extra mount zou ook nog kunnen als je wat meer scheiding zou wensen.

Ik regel dan met een .kopiaignore dat de raw database bestanden niet meegenomen worden. Bijvoorbeeld bij Home Assistant:
code:
1
2
3
4
5
6
7
config/*.log
config/*.log*
config/tmp_core_entity

database/*
database/**
!database/dump.sql
Toevallig heb ik deze setup nog niet geactiveerd voor Home Assistant, maar wel bij mijn Outline wiki en daar ziet er dat in Kopia dan zou uit:
Afbeeldingslocatie: https://tweakers.net/i/Z_-ddkcwha29deFKpqfqqzs0CKk=/800x/filters:strip_exif()/f/image/ZFLqZPHjmnBQxvmU67IvNkHm.png?f=fotoalbum_large

  • blackd
  • Registratie: Februari 2001
  • Niet online
blackd schreef op zondag 14 december 2025 @ 14:18:
Wat snippets van mijn ansible-ee repo:
execution-environment.yml
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
--
version: 3

images:
  base_image:
    name: ghcr.io/ansible/community-ansible-dev-tools:v25.11.0@sha256:c3ee333e84517404d0940e9fd97b247b18cf60e957cbd1bb45e79ca84848beaa

dependencies:
  galaxy: requirements.yml
  python: requirements.txt

additional_build_steps:
  [..]
In de additional_build_steps installeer ik:
  • glibc-langpack-en (via dnf)
  • docker-ce-cli (via install script)
  • nodejs npm (via dnf)
  • gh-cli (via dnf)
  • dclint (via npm)
  • action-validator (via npm)
Weer even gestoeid met mijn execution environment.
Aanleiding was dat Fedora42 standaard met nodejs22 komt en Renovate config validator nodejs24 prefereert.
Dat laatste heb ik helaas niet helemaal kunnen oplossen zoals ik het wilde.

Mijn nieuwe execution-environment.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
---
version: 3

images:
  base_image:
    name: ghcr.io/ansible/community-ansible-dev-tools:v26.3.1@sha256:026a44e20b2d66d4192a1cc8d9dbd17a53b58ced4a7b75c01eafbcdf70f6ae98

dependencies:
  galaxy: requirements.yml
  python: requirements.txt
  system: bindep.txt

additional_build_files:
  - src: files/docker-ce.repo
    dest: configs
  - src: files/gh-cli.repo
    dest: configs
  - src: files/task.repo
    dest: configs

additional_build_steps:
  prepend_base:
    - ADD _build/configs/docker-ce.repo /etc/yum.repos.d/docker-ce.repo
    - ADD _build/configs/gh-cli.repo /etc/yum.repos.d/gh-cli.repo
    - ADD _build/configs/task.repo /etc/yum.repos.d/task.repo

  append_final:
    - RUN npm install --g dclint@3.1.0
    - RUN npm install --g @action-validator/core @action-validator/cli --save-dev
    - RUN dnf clean all && rm -rf /var/cache/dnf
    - RUN rm -rf /tmp/* /var/tmp/*
De grote verschillen:
  1. system: bindep.txt toegevoegd, dit is een lijst met packages die via de package manager geinstalleerd worden. Hiervoor had ik RUN dnf install -y commando's in de append_base stap.
  2. additional_build_files bevat nu 3 custom repo's voor docker-ce, gh-cli en task. Die laatste was nog lastig, maar uiteindelijk via de juiste URL een config weten te downloaden. Deze files kopieer ik naar de juiste plek in de additional_build_steps.
  3. append_final hier installeer ik nu twee npm dependencies, via bindep.txt lukte me dat niet dus dan maar zo.
Het lukte mij ook niet de nodejs standaard naar 24 te krijgen. met dnf nodejs24 installeren lukt wel, maar dan is hij nog niet de default. Als iemand nog tips heeft hiervoor.. (gaat om fedora 24). Hier staat uitgelegd hoe je extra versies kunt installeren. De route via dnf modules werkt niet meer. Via nvm wordt heel omslachtig met install scripts.

bindep.txt: welke door ansible-builder gebruikt wordt:
code:
1
2
3
jq [platform:rpm]
docker-ce-cli [platform:rpm]
gh [platform:rpm]
Het jammere is dan weer dat bindep.txt wel versies ondersteunt (analoog aan pip) maar dat ansible-builder dat weer niet snapt. Kan ik de versies niet pinnen.

Uiteindelijk ervoor gekozen nodejs24 via een feature in devcontainer te installeren:
JSON:
1
2
3
4
5
6
7
8
9
10
{ 
  [..]
  "features": {
    "ghcr.io/devcontainers/features/node:1": {
      "version": "24.14.0",
      "nvmVersion": "0.39.5"
    }
  },
  [..]
}
Daardoor duurt het rebuilden wel wat langer, dus liever zou ik nodejs24 als default hebben in de container.

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

Pagina: 1 ... 17 18 Laatste