• Mars Warrior
  • Registratie: Oktober 2003
  • Laatst online: 22-03 14:59

Mars Warrior

Earth, the final frontier

Haha @blackd , nog meer input voor mijn arme hersentjes :+

Vwb betreft je probleem of omweg om de keys te kunnen lezen in je .env file: daarvoor wil ik dus SOPS gebruiken. De keys blijven volledig leesbaar, enkel de values worden geencrypt.

Zo'n bestand kun je dus ook gewoon in Git gooien. Niemand kan er wat mee. Decrypten is met je SSH key, die je toch nodig hebt voor Ansible om te kunnen deployen. Dus onderdeel van de Action of een Playbook 8)

Nergens dus een bestand met leesbare secrets, zeker niet als je met vscode edit: die en/decrypt automatisch vanuit de editor. Je kunt meerdere SSH Keys gebruiken, dus dat is ook nog een plus vind ik.

En het is nu Vroooeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeem tijd :henk

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


  • blackd
  • Registratie: Februari 2001
  • Niet online
@Mars Warrior Ja, dat kan natuurlijk ook. Maar dat kan met Ansible Vault ook.
Ik heb ervoor gekozen om alle secrets in 1 yaml bestand te zetten en die in zijn geheel te encrypten.

Houd er in de keuze van je oplossing wel rekening mee of je nog andere tooling gebruikt om je bestanden te verwerken. Je hebt al VSCode benoemd. Maar ik draai zelf Ansible Lint en Docker Compose Lint (ook als GitHub action) bij elke pull request om de repo te valideren. Ansible Lint ondersteunt ook Ansible Vault.
https://docs.ansible.com/projects/lint/
https://docs.ansible.com/projects/lint/usage/#vaults

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


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:21
T.a.v. het cachen van Ansible nog een tip, ik heb een eigen docker container in beheer (gebaseerd op ansible-dev-tools container) die ik zowel als devcontainer in VSCode gebruik als base image voor mijn Self hosted runner. Hier heb ik de versies van Python, Ansible, Ansible Lint, mijn gebruikte Galaxy Collections en pip dependencies in gefixeerd. Ik onderhoud deze docker container in een aparte repository en bouw deze met Ansible Builder als een execution environment. Ik ben alleen niet heel gelukkig met Fedora als base os. Ik zou dit op termijn nog een keer willen omzetten naar een Debian based OS.
Je zou ervoor kunnen kiezen je runner (of dat nou Woodpecker is of een Github local runner) uit te laten voeren in een eigen container met daarin alle benodigde spullen al geïnstalleerd.
Dat heb ik ook een tijdje gehad, maar vond ik onhandig. Ik wil op mijn workstation niet per se afhankelijk zijn van Docker / devcontainers en/of Visual Studio Code. Ook wilde ik graag mijn Ansible requirements graag meenemen in de container. Daardoor had ik echter twee keer dezelfde dependencies in twee aparte repo's. Dat voelde niet zo lekker.

Ter referentie mijn Ansible Dockerfile
Docker:
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
FROM node:22.17-alpine

ADD requirements.txt requirements.yml /

RUN apk add --no-cache ca-certificates \
                       git \
                       python3 \
                       py3-pip \
                       openssh-client \
                       openssl \
                       rsync \
                       sshpass \
                       sudo \
    && \
    pip3 install --ignore-installed \
                 --break-system-packages \
                 -r /requirements.txt \
    && \
    ansible-galaxy install -r /requirements.yml \
    && \
    mkdir -p /ansible \
    && \
    rm -rf /root/.cache \
           /requirements.txt \
           /requirements.yml

WORKDIR /ansible

ENTRYPOINT ["ansible-playbook"]
CMD ["--version"]

De Node versie zou best geüpgraded mogen worden. In de requirements.txt had ik dan o.a. Ansible staan:

code:
1
2
ansible-core==2.18.6
ansible-lint==25.6.1

En in de requirements.yml stonden dan mijn (externe) roles en collections.

Ik regel dit dus nu in mijn Ansible / infra / Docker repo. Om toch repeatable builds te krijgen heb ik een aantal bestanden aangemaakt:
  • .python-version
  • requirements.txt
  • requirements.yml
Bij het starten van de workflow gebruikt de Forgejo Act runner de generieke setup-python action. Die action gebruikt vervolgens het .python-version bestand om de Python versie te bepalen die geïnstalleerd wordt. Python wordt geïnstalleerd in de hosted tool cache die gedeeld wordt tussen builds. Dezelfde action zet direct ook een cache op voor Python requirements, waar Ansible ook in staat :).

In dezelfde repo heb ik ook een setup.sh script staan voor op mijn workstation. Vanuit daar wordt, wanneer nodig, pyenv geïnstalleerd en geconfigureerd. Ik heb ook nog gekeken naar uv, maar dat project was nog niet volwassen genoeg om effectief te zijn. In datzelfde script installeer ik vervolgens wederom dependencies, maar dan dus in een virtualenv binnen pyenv. Ook controleert dit script op een vault pass en kan deze direct geconfigureerd worden. Afijn, alles om te starten.

  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:21
Mars Warrior schreef op zondag 7 december 2025 @ 13:59:
Zo'n [SOPS] bestand kun je dus ook gewoon in Git gooien. Niemand kan er wat mee. Decrypten is met je SSH key, die je toch nodig hebt voor Ansible om te kunnen deployen. Dus onderdeel van de Action of een Playbook 8)
Dus hetzelfde als Ansible Vault, maar dan moet ik nog een extra tool hebben en integreert het niet lekker met Ansible :+.

Ik zou ook mijn SSH key kunnen gebruiken als vault pass. Dat is immers gewoon een string. Als je echter in een team werkt is dat onhandig. Bij mij is dit dus gewoon een shared secret die toevallig alleen ik gebruik.
blackd schreef op zondag 7 december 2025 @ 18:55:
@Mars Warrior Ja, dat kan natuurlijk ook. Maar dat kan met Ansible Vault ook.
Ik heb ervoor gekozen om alle secrets in 1 yaml bestand te zetten en die in zijn geheel te encrypten.
Ik heb per group en host vault bestanden. De setup die je eerder aangaf met mappings (bijv. vault.my_secret) gebruik ik expliciet niet. Ik heb liever expliciete variabelen, dus vault_my_secret. Dat komt omdat ik in het verleden wat nare ervaringen heb gehad met het samenvoegen van dergelijke objecten en onverwachte resultaten. Maar goed, dat is natuurlijk stijl :).
Houd er in de keuze van je oplossing wel rekening mee of je nog andere tooling gebruikt om je bestanden te verwerken. Je hebt al VSCode benoemd. Maar ik draai zelf Ansible Lint en Docker Compose Lint (ook als GitHub action) bij elke pull request om de repo te valideren.
:Y

Bij elke push / PR draait Ansible Lint op mijn Git server:

YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
jobs:
  ansible-lint:
    name: Ansible Lint
    runs-on: ubuntu-latest

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

      - name: 🏗️ Setup Ansible
        id: setup-ansible
        uses: ./.forgejo/actions/setup-ansible
        with:
          vault-pass: ${{ secrets.ANSIBLE_VAULT_KEY }}

      - name: 🕵️‍♀️ Run Ansible Lint
        run: ansible-lint
        env:
          ANSIBLE_VAULT_PASSWORD_FILE: >-
            ${{ steps.setup-ansible.outputs.vault-pass-file }}

ansible-lint zit namelijk in de requirements.txt en wordt standaard mee geïnstalleerd :D.

Ook gebruik ik pre-commit hooks om Ansible Lint te draaien voordat ik commit. Dat heeft ook al enkele oopsies voorkomen en was verrassend eenvoudig op te zetten. Tevens heb ik een eigen pre-commit hook gemaakt die controleert op Ansible Vault files en de commit abort wanneer ik dergelijke bestanden in plain text probeer te committen.

Docker Compose Lint lijkt me interessant, behalve dan dat ik dus mijn Compose bestanden maak met Jinja :|. Daar moet ik dus nog even vanaf zien. Anderzijds valideer ik Compose bestanden sowieso voor een Up.

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op zondag 7 december 2025 @ 19:40:
Dat heb ik ook een tijdje gehad, maar vond ik onhandig. Ik wil op mijn workstation niet per se afhankelijk zijn van Docker / devcontainers en/of Visual Studio Code. Ook wilde ik graag mijn Ansible requirements graag meenemen in de container. Daardoor had ik echter twee keer dezelfde dependencies in twee aparte repo's. Dat voelde niet zo lekker.
Wat betreft het eerste, snap ik wat je zegt. Momenteel heb ik ook ansible gewoon nog 'lokaal' geinstalleerd staan.
Het had juist mijn voorkeur om overal exact dezelfde dependencies te hebben. Zowel in CI als lokaal in development.

Ik heb nu inderdaad requirements.yml dubbel geadministreerd staan, dat vind ik wel jammer aan deze setup. Ansible-Lint heeft 'm ook gewoon in de project dir nodig.
Mijn oplossing: een sync d.m.v. een github action van de ene repo naar de andere met deze action.

Ik had eerst de execution environment in dezelfde repo staan (geinspireerd door dbrennand op GitHub) maar dat werd een rommeltje met twee aparte releases in 1 project.
alex3305 schreef op zondag 7 december 2025 @ 19:48:
Ook gebruik ik pre-commit hooks om Ansible Lint te draaien voordat ik commit. Dat heeft ook al enkele oopsies voorkomen en was verrassend eenvoudig op te zetten. Tevens heb ik een eigen pre-commit hook gemaakt die controleert op Ansible Vault files en de commit abort wanneer ik dergelijke bestanden in plain text probeer te committen.
Dat staat nog op mijn wensenlijstje.
Docker Compose Lint lijkt me interessant, behalve dan dat ik dus mijn Compose bestanden maak met Jinja :|. Daar moet ik dus nog even vanaf zien. Anderzijds valideer ik Compose bestanden sowieso voor een Up.
Ik template ook mijn Compose bestanden maar het enige wat er eigenlijk gevuld wordt zijn de standaard variabelen (${}) en die worden weer gevoed door het .env bestand. En die template ik ook, die wordt gevoed door Ansible.

Voorbeeldje docker-compose.yml in jellyfin role (snippet):
YAML:
1
2
3
4
5
6
7
8
services:
  jellyfin:
    image: jellyfin/jellyfin:10.11.4@sha256:aab0b50a3ce43a41621fc7040a379cc57174059aec8f9c17a90176649a0c1ab1
    container_name: jellyfin
    volumes:
      - ${HOST_VOLUME_CONFIG}:/config
      - ${HOST_VOLUME_CACHE}:/cache
      - ${HOST_VOLUME_MEDIA}:/media

.env.j2
YAML:
1
2
3
HOST_VOLUME_CONFIG="{{ jellyfin__compose_volume_config }}"
HOST_VOLUME_CACHE="{{ jellyfin__compose_volume_cache }}"
HOST_VOLUME_MEDIA="{{ jellyfin__compose_volume_media }}"

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


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:21
blackd schreef op zondag 7 december 2025 @ 20:29:
[...]

Wat betreft het eerste, snap ik wat je zegt. Momenteel heb ik ook ansible gewoon nog 'lokaal' geinstalleerd staan.
Het had juist mijn voorkeur om overal exact dezelfde dependencies te hebben. Zowel in CI als lokaal in development.
Yes. Maar dat heb ik dus :). Want lokaal gebruik ik pyenv met een virtualenv die met pip de requirements.txt installeert met daarin o.a. Ansible Core en Ansible Lint. En de CI omgeving doet setup-python hetzelfde. Allebei maken ze gebruik van dezelfde python versie dmv het .python-version bestand. Renovate update hier (wederom) de dependencies.

Ik vind het overigens een voordeel om lokaal geen globale Ansible meer te hebben. Dan kan ik ook niet per abuis een verkeerde of oude versie gebruiken.
Dat staat nog op mijn wensenlijstje.
.pre-commit-config.yaml
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: check-shebang-scripts-are-executable
      - id: detect-private-key
      - id: end-of-file-fixer
      - id: trailing-whitespace

  - repo: https://github.com/ansible/ansible-lint
    rev: v25.12.0
    hooks:
      - id: ansible-lint


In de requirements.txt zit pre-commit==4.5.0 en activeren is dan niets meer dan pre-commit install.
Ik template ook mijn Compose bestanden maar het enige wat er eigenlijk gevuld wordt zijn de standaard variabelen (${}) en die worden weer gevoed door het .env bestand. En die template ik ook, die wordt gevoed door Ansible.
Ik template de Compose bestanden zelf ook. Best uitgebreid overigens :). Recent ben ik wat met Ghost in de weer geweest en dan komt er zoiets uit. Dit is een snippet als voorbeeld:

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
#jinja2: lstrip_blocks: True, trim_blocks: True
---
{{ ansible_managed | comment }}

name: {{ _compose_stack_name }}

services:
  ghost:
    container_name: ${COMPOSE_PROJECT_NAME}
    image: ghost:6.10.0-alpine
    environment:
      NODE_ENV: production
      url: ${GHOST_URL}
      database__client: mysql
      database__connection__host: database
      database__connection__user: ${DATABASE_USERNAME}
      database__connection__password: ${DATABASE_PASSWORD}
      database__connection__database: ${DATABASE_NAME}
    networks:
      ingress:
      internal:
    volumes:
      - {{ ghost_uploads_dir }}:/var/lib/ghost/content
    depends_on:
      database:
        condition: service_healthy
      {% if not ghost_use_hosted_activitypub %}
      activitypub:
        condition: service_started
        required: false
      {% endif %}
    {% if ghost_docker_options is defined %}
    {{ ghost_docker_options | to_nice_yaml | indent(4) }}
    {%- endif %}
    labels:
      traefik.enable: true
      traefik.http.routers.{{ _compose_stack_name }}.rule: "Host(`{{ ghost_domain }}`)"
      traefik.http.routers.{{ _compose_stack_name }}.middlewares: "anubis@docker"
      traefik.http.routers.{{ _compose_stack_name }}.service: "{{ _compose_stack_name }}"
      traefik.http.services.{{ _compose_stack_name }}.loadbalancer.server.port: "2368"
      {%- if _is_unraid +%}
      net.unraid.docker.icon: https://avatars.githubusercontent.com/u/2452804?s=200&v=4
      net.unraid.docker.managed: ansible
      net.unraid.docker.shell: /bin/bash
      {% endif %}

Secrets komen bij mij in de .env.j2 zodat deze niet direct zichtbaar zijn.

Conditionals zijn bij mij hier enorm belangrijk omdat ik afhankelijk van variabelen nog weleens het een of het andere uitrol. Bijvoorbeeld een adguard_home_sync op een secundaire node. Dan hoef ik geen twee Compose bestanden te onderhouden. Profielen zijn uiteraard ook nog een optie, maar dat vind ik niet heel transparent. Laatst heb ik daar wel meegespeeld in OpenCloud / OCIS, maar dan wordt het heel snel, heel complex. Met name als je geen of weinig ervaring in de desbetreffende repo hebt.

Bij de labels moet ik (helaas) de Jinja expressie gebruiken omdat Docker Compose ${COMPOSE_PROJECT_NAME} deze al literal neemt in de label naam :F. Volgens mij is dat niet zo bij de andere syntax, maar ik ga dat niet helemaal omgooien om zoiets doms.

Overigens is dit ook weer allemaal een kwestie van smaak en is het geheel uiteraard fluïde.

  • Mars Warrior
  • Registratie: Oktober 2003
  • Laatst online: 22-03 14:59

Mars Warrior

Earth, the final frontier

blackd schreef op zondag 7 december 2025 @ 20:29:
[...]
Voorbeeldje docker-compose.yml in jellyfin role (snippet):
YAML:
1
2
3
4
5
6
7
8
services:
  jellyfin:
    image: jellyfin/jellyfin:10.11.4@sha256:aab0b50a3ce43a41621fc7040a379cc57174059aec8f9c17a90176649a0c1ab1
    container_name: jellyfin
    volumes:
      - ${HOST_VOLUME_CONFIG}:/config
      - ${HOST_VOLUME_CACHE}:/cache
      - ${HOST_VOLUME_MEDIA}:/media

.env.j2
YAML:
1
2
3
HOST_VOLUME_CONFIG="{{ jellyfin__compose_volume_config }}"
HOST_VOLUME_CACHE="{{ jellyfin__compose_volume_cache }}"
HOST_VOLUME_MEDIA="{{ jellyfin__compose_volume_media }}"
W44r0m z0 dµßß13 0p?? W44r0m n13t m33t33n 1n d3 3nv f1l3 d3 ju1$t3 k3¥ v4|u3z?? Nu m00t j3 t0¢h 3 d1ng3n b1jh0µd3n!! D4t 0nt9a4t m1j 3v3n…

0ƒ h33ƒt d4t t3 m4k3n m3t d3 V4µ|t??

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


  • blackd
  • Registratie: Februari 2001
  • Niet online
@alex3305 ja dat soort uitgebreidere jinja templating gebruik ik niet. Eigenlijk moet ik zeggen dat ik de template module gebruik, maar ik template niks, want ik kan net zo goed een copy doen. Anders snapt dclint het niet.

@Mars Warrior
In de .env file staan bij mij verschillende soorten waardes, bijv:
- secrets. Die staan zoals gezegd in een apart bestand bij mij.
- host afhankelijke waardes, die worden gevoed door group vars of host vars.

In dit voorbeeld staan absolute paden en die kunnen dus per host in theorie verschillend zijn. Dat wil je niet in je role vastleggen, die dient generiek te zijn.

Daarnaast kan ik de paden als het een variabele in ansible is, hergebruiken. Bijv voor aanmaken dataset, controleren permissies, dat soort zaken.

Ik ben overigens nog wel zoekende naar de juiste structuur qua variabelen. Ik heb laatst variabelen in playbooks gemigreerd naar group_vars. Maar e.e.a kan vast nog beter georganiseerd.

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


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:21
blackd schreef op zondag 7 december 2025 @ 22:12:
@alex3305 ja dat soort uitgebreidere jinja templating gebruik ik niet. Eigenlijk moet ik zeggen dat ik de template module gebruik, maar ik template niks, want ik kan net zo goed een copy doen. Anders snapt dclint het niet.
Zo'n vermoeden had ik al :+ :9. Daar is natuurlijk niets mis mee hè.

Ik gebruik de Jinja templates dus in Compose ook als feature toggles. Dat kan soms verdomde handig zijn. Alhoewel de andere kant van de medaille verbositeit is. Met andere woorden, meer code om hetzelfde of soms minder te bereiken :+. Komt er ook nog bij dat ik vanuit mijn werk enorm veel met Jinja heb gewerkt en er dus best aardig in ben, al zeg ik het zelf :P. En ik gebruik het veel in Home Assistant. Ik schrik er dus niet zo snel van.

Ik gebruik daarnaast in elke Compose _docker_options zodat ik CPUs en memory kan limiteren waar nodig. Dit doe ik o.a. voor stroombesparing.
Ik ben overigens nog wel zoekende naar de juiste structuur qua variabelen. Ik heb laatst variabelen in playbooks gemigreerd naar group_vars. Maar e.e.a kan vast nog beter georganiseerd.
Ik probeer variabelen zoveel mogelijk toe te passen waar ze horen. Serial numbers en keys horen IMHO niet bij een host, maar bij een groep. En dan eigenlijk zelfs de groep all. Immers veranderd de groepenstructuur in de inventory niets aan de toepasbaarheid van een dergelijke key. Mijn Maxmind GeoIP API sleutel gebruik ik dan zo:

YAML:
1
2
3
4
5
6
7
8
# group_vars/all/vault.yml
vault_maxmind_api_key: "secret string here..."

# group_vars/all/all.yml
maxmind_api_key: "{{ vault_maxmind_api_key }}"

# host_vars/leetower/maxmind_geoip.yml OF group_vars/docker/maxmind_geoip.yml
maxmind_geoip_api_key: "{{ maxmind_api_key }}"

De maxmind_geoip role op host leetower (of groep docker als je het op meerdere hosts gebruikt) vereist de API key geprefixed met de role_name. Maar die key hoort wat mij betreft niet bij de specifieke host of groep thuis, maar is algemeen voor mijn play(s).

Ook hier is het aardig verbose, maar zorgt het wat mij betreft wel voor de nodige duidelijkheid. En dat is met Ansible geen overbodige luxe :).

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op zondag 7 december 2025 @ 20:49:
Yes. Maar dat heb ik dus :). Want lokaal gebruik ik pyenv met een virtualenv die met pip de requirements.txt installeert met daarin o.a. Ansible Core en Ansible Lint. En de CI omgeving doet setup-python hetzelfde. Allebei maken ze gebruik van dezelfde python versie dmv het .python-version bestand. Renovate update hier (wederom) de dependencies.
Ik wil de venv opzet toch nog wel een kans geven, ik had dat voorheen ook wel maar ik denk dat ik een paar stappen gemist heb om alle dependencies te fixeren en alle installaties te automatiseren. Bij de devcontainer loop ik ook wel tegen wat issues aan (vanwege het OS [Fedora] is feature/docker-outside-docker niet mogelijk en geknoei met permissies door verschillende gebruikers in de container vs op het host OS).
Misschien wil ik wel een hybride setup met lokaal een venv en op CI een docker container (met venv?).

Wat ik begrijp heb je dus Ansible-Core en Ansible-Lint in je requirements.txt staan en specificeer je de Python versie in .python-version.

Hoe zit dat dan met de Python versie? Van wat ik lees zul je de globale python versie (op je dev machine) dan in sync moeten houden met je CI build. Hoe pak je dat aan?

Edit:
Daarnaast heb ik ook nog andere dependencies die ik geinstalleerd moet hebben:
- GitHub CLI (via package manager)
- ACT (via GH CLI extension)
- Task (taskfile.dev) (via package manager)
- NPM
- DCLint (als NPM package)
- Renovate (als NPM package)

Voorheen heb ik een development playbook gemaakt waarin dit soort zaken geautomatiseerd geinstalleerd werden. Nu zit dat in mijn Execution Environment Docker image.
alex3305 schreef op maandag 8 december 2025 @ 11:54:
Ik probeer variabelen zoveel mogelijk toe te passen waar ze horen. Serial numbers en keys horen IMHO niet bij een host, maar bij een groep. En dan eigenlijk zelfs de groep all. Immers veranderd de groepenstructuur in de inventory niets aan de toepasbaarheid van een dergelijke key. Mijn Maxmind GeoIP API sleutel gebruik ik dan zo:
Ik heb API keys e.d. inderdaad in group_vars/all/main.yml en secrets in group_vars/all/secrets.yml en de encrypted versie in group_vars/all/vault.yml.

Daarnaast zoveel als mogelijk alle variabelen die nodig zijn voor de roles in group_vars/<groep>/<role>.yml.
De enige host_vars zijn ansible_host, ansible_user, ansible_password, ansible_connection en vergelijkbaar.

Qua inventory heb ik het ook geordend naar stage:
code:
1
2
3
4
5
6
7
8
9
10
11
12
inventories/
├── development
├── production
│   ├── group_vars
│   │   ├── all
│   │   └── <group>
│   └── host_vars
└── staging
    ├── group_vars
    │   ├── all
    │   └── <group>
    └── host_vars

Staging is voor mij een gevirtualiseerde evenknie van mijn productieomgeving.
Daar heb ik in VirtualBox een TrueNAS installatie draaien met dezelfde configuratie qua pools waarmee ik eenvoudig de Jail, Docker installatie en Docker Containers kan testen bij upgrades van TrueNAS.
Het liefst zou ik de group_vars op 1 plek hebben maar dat is me nog niet gelukt.

Maar stiekem heb ik nog wel wat variabelen in de roles/<role>/vars/main.yml zitten die ik een keer moet migreren naar de groep.
Zo heb ik sinds kort een docker groep gemaakt want ik had de Docker versies nog niet gefixeerd. Met de Traefik API compatibility issue liep ik daar snel tegenaan. Ik gebruik overigens de geerlingguy.docker role via Galaxy.

[ Voor 6% gewijzigd door blackd op 09-12-2025 10:47 ]

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


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:21
blackd schreef op dinsdag 9 december 2025 @ 10:07:
[...]

Ik wil de venv opzet toch nog wel een kans geven, ik had dat voorheen ook wel maar ik denk dat ik een paar stappen gemist heb om alle dependencies te fixeren en alle installaties te automatiseren. Bij de devcontainer loop ik ook wel tegen wat issues aan (vanwege het OS [Fedora] is feature/docker-outside-docker niet mogelijk en geknoei met permissies door verschillende gebruikers in de container vs op het host OS).
Misschien wil ik wel een hybride setup met lokaal een venv en op CI een docker container (met venv?).

Wat ik begrijp heb je dus Ansible-Core en Ansible-Lint in je requirements.txt staan en specificeer je de Python versie in .python-version.
Yes :Y .

requirements.txt
code:
1
2
3
4
5
ansible-core==2.20.0
ansible-dev-tools==25.12.0
ansible-lint==25.12.0
pre-commit==4.5.0
yamllint==1.37.1


.python-version
code:
1
3.14.2

En dit wordt wederom netjes bijgehouden met Renovate:

renovate.json
JSON:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "packageRules": [
    {
      "description": "Limit requirements to once a week",
      "matchFileNames": [
        "requirements.txt",
        "requirements.yml"
      ],
      "schedule": ["* * * * 3"]
    },
    {
      "description": "Update Python version",
      "matchFileNames": [".python-version"],
      "minimumReleaseAge": "30 days",
      "internalChecksFilter": "strict",
      "matchDatasources": ["python-version"]
    }
  ]
}


Waarbij ik dus afwachtend ben met het updaten van Python.
Hoe zit dat dan met de Python versie? Van wat ik lees zul je de globale python versie (op je dev machine) dan in sync moeten houden met je CI build. Hoe pak je dat aan?
Dat regel ik dus met pyenv. Die staat in mijn home directory en houdt net zoals bijvoorbeeld nvm voor Node een aparte Python environment bij. Installatie en configuratie is dood eenvouudig:

# Requirements installeren voor Debian
sudo apt update
sudo apt install build-essential gdb lcov \
                 pkg-config libbz2-dev libffi-dev libgdbm-dev \
                 libgdbm-compat-dev liblzma-dev libncurses5-dev \
                 libreadline6-dev libsqlite3-dev libssl-dev lzma lzma-dev \
                 tk-dev uuid-dev zlib1g-dev libmpdec-dev libzstd-dev

# pyenv automatic installer
curl -fsSL https://pyenv.run | bash

Waarna ik in mijn .zshrc pyenv configureer voor mijn shell:

Bash:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/zsh
# shellcheck shell=zsh
#
# 3) .zshrc - Zsh file loaded for interactive shell sessions
#

ZDOTDIR="${ZDOTDIR:-$HOME}"

# Set the list of directories that zsh searches for commands.
path=(
  $HOME/{,s}bin(N)
  $HOME/.local/{,s}bin(N)
  $HOME/.pyenv/bin(N)
  $HOME/.dotnet/tools(N)
  /usr/local/{,s}bin(N)
  $path
)

# Pyenv
export PYENV_ROOT="$HOME/.pyenv"
eval "$(pyenv init --path)"

Mijn zsh configuratie heb ik in mijn dotfiles repo staan en de installatie van pyenv staat, zoals ik eerder al zei, in mijn infra repo. Ik heb daar een setup scriptje staan die alle benodigde dependencies automatisch kan installeren:
Afbeeldingslocatie: https://tweakers.net/i/z3GKVXJew8cPhCSXH7VIWNb6t3Y=/800x/filters:strip_exif()/f/image/eZz1YEkUjiTq82jUfyF1sdMv.png?f=fotoalbum_large

Op de CI omgeving zorgt de GitHub setup-python action voor de setup van de juiste Python versie op basis van het .python-version bestand:
quote: GitHub Setup Python Action
Basic usage
[...]
The python-version input is optional. If not supplied, the action will try to resolve the version from the default .python-version file. [...]
Python wordt hier in de hosted tool cache geïnstalleerd (en dus gecached), evenals de dependencies. Theoretisch is dat een security risico, maar dat neem ik voor lief.
Daarnaast heb ik ook nog andere dependencies die ik geinstalleerd moet hebben:
- GitHub CLI (via package manager)
- ACT (via GH CLI extension)
- Task (taskfile.dev) (via package manager)
- NPM
- DCLint (als NPM package)
- Renovate (als NPM package)
Ik beargumenteer niet dat alle packages verplicht in een venv moeten hè :). Je mag best afhankelijk zijn van het OS of een externe package manager. Ik vind alleen de aanpak van een Docker container hier onnodig en onhandig. Evenals de afhankelijkheid van een devcontainer, aangezien dat weer redelijk afhankelijk is van VSCode. Ik vind een vendor lock-in van een editor namelijk nogal beroerd :X.

In mijn zsh omgeving heb ik sowieso nvm - en dus npm - geconfigureerd staan. De installatie van deze afhankelijkheden zou ik dus simpelweg meenemen in mijn setup script.

Voorheen heb ik een development playbook gemaakt waarin dit soort zaken geautomatiseerd geinstalleerd werden. Nu zit dat in mijn Execution Environment Docker image.
Staging is voor mij een gevirtualiseerde evenknie van mijn productieomgeving.
Daar heb ik in VirtualBox een TrueNAS installatie draaien met dezelfde configuratie qua pools waarmee ik eenvoudig de Jail, Docker installatie en Docker Containers kan testen bij upgrades van TrueNAS.
Het liefst zou ik de group_vars op 1 plek hebben maar dat is me nog niet gelukt.
Ja dat is leuk :). Voor thuis heb ik alles fail-fast met één omgeving. Waarbij ik moet toegeven dat er over het algemeen bijzonder weinig kapot vliegt of langdurig kapot gaat. Door Renovate heb ik het vertrouwen om het op deze manier te doen. Rollbacks zijn namelijk triviaal geworden.
Ik gebruik overigens de geerlingguy.docker role via Galaxy.
Die kende ik niet. Mja, Jeff Geerling wel, maar niet zijn role. Wel grappig om te zien dat mijn role nagenoeg gelijk is aan zijn role :F :D.

  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:21
Even iets anders dan al het Ansible geweld :D. De laatste tijd krijg ik regelmatige vage foutmeldingen in mijn Forgejo Runner dind omgeving. Gisteren ben ik op speurtocht geweest en ben erachter gekomen dat het komt door cross compilen. Blijkbaar wordt de binfmt_misc kernel module niet meegenomen bij rootless dind 8)7. Ondanks een --privileged flag. Gek genoeg werkt het wel als ik een verse Alpine container maak met daarin bijv. Docker of podman.

Aan de hand daarvan was ik nog bezig gegaan met Docker Bake. Ik wil namelijk kijken of ik verschillende varianten van mijn container kan maken. In eerste instantie om mee te testen, maar daarna wellicht ook om uit te brengen.

Het ziet er allemaal leuk uit, maar eigenlijk vind ik het ook wel weer gedoe. Er wordt hcl gebruikt voor configuratie. Helemaal prima, behalve dan dat ik dat weer helemaal nergens anders gebruik :X.

Wel grappig want ik had op mijn persoonlijke issue lijst momenteel nog drie punten staan:
  1. Docker bake uitproberen
  2. Podman ipv dind uitproberen
  3. ARM (qemu) builds fixen
En dat komt nu toevallig allemaal bij elkaar :P. Immers kan ik met een test met podman waarschijnlijk qemu oplossen of een workaround maken. En kan ik met Docker bake eenvoudig twee varianten bouwen zodat de oude versie niet breekt ;).

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op dinsdag 9 december 2025 @ 12:10:
Dat regel ik dus met pyenv. Die staat in mijn home directory en houdt net zoals bijvoorbeeld nvm voor Node een aparte Python environment bij. Installatie en configuratie is dood eenvouudig:
Nice, pyenv had ik even gemist. Ik had in het verleden alleen een venv gemaakt met de standaard module in Python. Ik ga dit verder onderzoeken, bedankt!
Ik beargumenteer niet dat alle packages verplicht in een venv moeten hè :). Je mag best afhankelijk zijn van het OS of een externe package manager.
Mijn doel is ook niet om het allemaal in een venv te proppen maar ik wil voor (mijzelf, haha) een eenvoudig en reproduceerbaar proces hebben om alles wat nodig is te installeren. Mag best global / system wide zijn, zolang ik maar dezelfde versies heb op mijn development laptop als op de CI omgeving.

Zoals ik zei heb ik Woodpecker gebruikt als CI tool, daarvoor wilde ik alles via Semaphore UI laten lopen. Dat was een drama wat betreft dependencies op de ansible control node, daar heb ik best e.e.a. voor moeten 'hacken'. Uiteindelijk draait je Ansible Playbook daar in een aparte container, waardoor je met een playbook getarget op 'local' ook de nodige dependencies kunt installeren. Alleen dat duurde op mijn machine allemaal best wel lang.

Hier komt ook mijn aversie tegen Bitwarden secrets terug, de installatie was een drama vanwege een bug die nog steeds open staat. En de oplossing? Een license file publiceren bij je volgende release. :X Door het ontbreken daarvan moest ik de SDK vanuit source installeren, waar weer de nodige dev dependencies voor nodig waren.
Ik vind alleen de aanpak van een Docker container hier onnodig en onhandig. Evenals de afhankelijkheid van een devcontainer, aangezien dat weer redelijk afhankelijk is van VSCode. Ik vind een vendor lock-in van een editor namelijk nogal beroerd :X.
Ik ben ook geen fan van vendor lock-in.
De container die ik heb ontwikkeld is wat dat betreft multi-purpose. Je kan hem als devcontainer gebruiken, je kan hem als container in GitHub Actions gebruiken en het is een execution environment voor Ansible Navigator. Voor dat laatste heb je nog steeds wel Python, Ansible-Navigator en Docker nodig.
Ja dat is leuk :). Voor thuis heb ik alles fail-fast met één omgeving. Waarbij ik moet toegeven dat er over het algemeen bijzonder weinig kapot vliegt of langdurig kapot gaat. Door Renovate heb ik het vertrouwen om het op deze manier te doen. Rollbacks zijn namelijk triviaal geworden.
Ik ga ook niet elke wijziging via staging laten lopen, maar zoiets fundamenteels als het onderliggende OS updaten vind ik wel dusdanig dat ik dit eerst wat uitgebreider ga testen.
Door gebruik van Renovate is mijn update proces ook veel betrouwbaarder geworden. Ik auto merge alleen patch en digest updates, minor en hoger review ik altijd de release notes (door schade en schande wijs geworden). Met name de apps met databases is wat ingewikkelder updaten.

Ik kom van TrueNAS Scale in de tijd dat TrueCharts nog een ding was. Dit werd vrij rap niet meer ondersteund. Toen kwam jailmaker waarin ik docker kon draaien. Daarna ging TrueNAS scale ook naar docker bewegen voor ingebouwde apps (met hun eigen app-store). Ik kies er bewust voor dat niet meer te gebruiken maar alles in een aparte omgeving via Ansible te onderhouden om zo flexibel te blijven. Vooralsnog is 'Instances' in TrueNAS Scale experimenteel en werkt Jailmaker ook nog gewoon. Dus er zijn twee manieren om een omgeving te creëren op mijn TrueNAS machine waarin ik Docker + all mijn Compose projects kan uitrollen.
Die kende ik niet. Mja, Jeff Geerling wel, maar niet zijn role. Wel grappig om te zien dat mijn role nagenoeg gelijk is aan zijn role :F :D.
Hij heeft best handige roles en zijn content over Ansible vond ik erg leerzaam. Misschien nog een tip voor @Mars Warrior.

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


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:21
blackd schreef op dinsdag 9 december 2025 @ 12:49:
Nice, pyenv had ik even gemist. Ik had in het verleden alleen een venv gemaakt met de standaard module in Python. Ik ga dit verder onderzoeken, bedankt!
Met standaard Python en venv is het inderdaad een groot drama. uv is the new kid on the block en daarmee dus ook fancy. Met mijn progressieve aanpak wilde ik die eigenlijk gebruiken. Vooral omdat ik dan een pyproject.toml of uv.toml kon toepassen. Dan zou ik ook geen extra requirements.txt meer hebben. Echter kreeg ik dat een paar maanden geleden niet lekker werkend met Ansible. Pyenv voldoet dan gewoon.
Mijn doel is ook niet om het allemaal in een venv te proppen maar ik wil voor (mijzelf, haha) een eenvoudig en reproduceerbaar proces hebben om alles wat nodig is te installeren. Mag best global / system wide zijn, zolang ik maar dezelfde versies heb op mijn development laptop als op de CI omgeving.
100%. Professioneel weet ik dat dat super waardevol is. Vandaar dat ik dat privé ook toepas. Het kost dan vooraf wellicht wat meer tijd om in te richten en op te zetten, dat verdien je op een later moment weer terug.
Ik kom van TrueNAS Scale in de tijd dat TrueCharts nog een ding was. Dit werd vrij rap niet meer ondersteund. Toen kwam jailmaker waarin ik docker kon draaien. Daarna ging TrueNAS scale ook naar docker bewegen voor ingebouwde apps (met hun eigen app-store). Ik kies er bewust voor dat niet meer te gebruiken maar alles in een aparte omgeving via Ansible te onderhouden om zo flexibel te blijven. Vooralsnog is 'Instances' in TrueNAS Scale experimenteel en werkt Jailmaker ook nog gewoon. Dus er zijn twee manieren om een omgeving te creëren op mijn TrueNAS machine waarin ik Docker + all mijn Compose projects kan uitrollen.
Ik heb dus destijds de Unraid afslag genomen. Met name omdat ik al enorm veel ervaring had met Docker, Docker Compose en Kubernetes. Daarom heeft TrueCharts mij dus nooit aangesproken en vond ik dat eigenlijk eerder een nadeel dan een voordeel :|. Dat is ook de reden dat ik Portainer niet (meer) gebruik. Portainer gebruikt namelijk ander jargon dan Docker en Compose. Dat stoort mij dan gigantisch.

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op dinsdag 9 december 2025 @ 12:10:
.python-version
code:
1
3.14.2

[..]

Ik heb daar een setup scriptje staan die alle benodigde dependencies automatisch kan installeren:
[Afbeelding]

Op de CI omgeving zorgt de GitHub setup-python action voor de setup van de juiste Python versie op basis van het .python-version bestand:
Ik heb nu even als test .python-version toegevoegd in mijn repo en Renovate triggert daar op.
Ik gebruik het alleen nog niet in CI/lokaal om de Python versie gelijk te houden.

Hoe 'enforce' je dat je development machine ook dezelfde python versie gebruikt in jouw pyenv t.o.v. wat in de repo gedefinieerd staat? Want als Renovate triggert op een nieuwe Python versie zul je jouw pyenv virtualenv opnieuw moeten opbouwen neem ik aan?

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


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:21
blackd schreef op woensdag 10 december 2025 @ 09:48:
Hoe 'enforce' je dat je development machine ook dezelfde python versie gebruikt in jouw pyenv t.o.v. wat in de repo gedefinieerd staat? Want als Renovate triggert op een nieuwe Python versie zul je jouw pyenv virtualenv opnieuw moeten opbouwen neem ik aan?
Dat klopt. Ik forceer het inderdaad niet, daar heb je helemaal gelijk in. Ik draai mijn setup script met enige regelmaat. O-)

Je zou natuurlijk met Ansible pre_tasks kunnen controleren of de huidige Python versie gelijk is aan die in .python-version. Idem voor Ansible of andere pakketten.

Als alternatief zou je in zsh (waarschijnlijk ook in andere shells) een shell hook kunnen opzetten zodat bijv. pyenv geüpdatet wordt wanneer je in die directory komt. Dat doe ik al met oh-my-zsh en pyenv:

.oh-my-zsh/custom/python-venv.zsh
Bash:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/zsh
# shellcheck shell=zsh
#
# python-venv.zsh - Automatically venv when possible!
# Source: https://dev.to/moniquelive/auto-activate-and-deactivate-python-venv-using-zsh-4dlm
#

python_venv() {
  MYVENV=./.venv

  # when you cd into a folder that contains $MYVENV
  [[ -d $MYVENV ]] && source $MYVENV/bin/activate > /dev/null 2>&1
  # when you cd into a folder that doesn't
  [[ ! -d $MYVENV ]] && deactivate > /dev/null 2>&1
}

autoload -U add-zsh-hook
add-zsh-hook chpwd python_venv

python_venv


En je zou dit ook in de editor (VSCode) kunnen regelen. Ik doe dat bijvoorbeeld voor mijn Home Assistant Configuration repository. Daar maak ik een aantal (mock) bestanden aan zodat de configuratie check in ieder geval werkt.

.vscode/tasks.json
JSON:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "setup",
            "type": "shell",
            "command": "./setup.sh",
            "runOptions": {
              "runOn": "folderOpen"
            },
            "presentation": {
              "echo": false,
              "reveal": "silent",
              "focus": false,
              "panel": "shared",
              "close": true,
            }
        }
    ]
}


Het is dus een klein beetje behelpen op sommige vlakken. Mijn oplossing is ook verre van perfect. Aan de andere kant zijn veranderingen veelal incrementeel. Immers accepteer ik expliciet bepaalde minor's. Dan is het dus ook niet bijster erg als ik een keer een versie achterloop, mits ik niet tegen problemen aanloop.

  • blackd
  • Registratie: Februari 2001
  • Niet online
Ook maar even opgezet:
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
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: check-shebang-scripts-are-executable
      - id: detect-private-key
      - id: end-of-file-fixer
      - id: trailing-whitespace

  - repo: https://github.com/renovatebot/pre-commit-hooks
    rev: 42.52.4
    hooks:
      - id: renovate-config-validator

  - repo: https://github.com/docker-compose-linter/pre-commit-dclint
    rev: v3.1.0
    hooks:
      - id: dclint

  - repo: https://github.com/ansible/ansible-lint
    rev: v25.12.0
    hooks:
      - id: ansible-lint
        pass_filenames: true

  - repo: https://github.com/mpalmer/action-validator
    rev: v0.8.0
    hooks:
      - id: action-validator

Het meeste draait vrij snel (alleen changes). Over ansible-lint ben ik alleen nog niet heel tevreden..

Om vervolgens te gebruiken moet ik dat installeren, daarom in devcontainer.json:
YAML:
1
2
3
4
{
  [...]
  "postStartCommand": "pre-commit install"
}

NB: Mocht je een foutmelding krijgen over ontbrekende locale bij gebruik pre-commit, installeer dan glibc-langpack-en.
alex3305 schreef op woensdag 10 december 2025 @ 19:39:
Dat klopt. Ik forceer het inderdaad niet, daar heb je helemaal gelijk in. Ik draai mijn setup script met enige regelmaat. O-)

Je zou natuurlijk met Ansible pre_tasks kunnen controleren of de huidige Python versie gelijk is aan die in .python-version. Idem voor Ansible of andere pakketten.
Heb ik ook aan zitten denken maar druist in tegen de manier waarop het bij mij nu werkt, ik laat de python en ansible versie in de docker container leidend zijn en verifieer of mijn playbook daarop runt.
Deze versies zijn embedded in de community-ansible-dev-tools docker image.

Ik heb geprobeerd om de dependencies geautomatiseerd te installeren maar kom dan vrij snel op het punt dat ik in mijn GitHub Self Hosted runner de workflow in een container wil runnen. Laat dat nou net mijn ansible-ee image kunnen zijn :). Enige nadeel is zoals gezegd dat dit o.b.v. fedora is en niet debian/ubuntu.

Wat dat betreft kan een devcontainer wel snel een update van deze dependencies forceren. Zodra renovate een update ziet van een van de dependencies, wordt de PR gevalideerd en indien mogelijk automatisch gemerged. De nightly release produceert een nieuwe docker image. Deze wordt vervolgens in mijn playbook repo door Renovate getriggerd. Wanneer dit gemerged wordt naar main, wordt het ook doorgezet naar develop. Dan krijg ik gelijk van VSCode een melding of ik de container wil rebuilden.

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)
Sommige zaken zijn geversioneerd, nog niet alles.
Renovate pakt alleen de updates van base_image nog niet op dus ik moet nog even met de renovate config gaan stoeien.

Dit bouw ik dan met een GitHub Action. Daarin roep ik Ansible Builder aan. Ik gebruik daarbij wel docker/setup-buildx-action, docker/metadata-action en docker/build-push-action aangezien Ansible Builder onderwater gewoon docker build aanroept.
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[..]
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3
      id: docker_buildx
      with:
        platforms: linux/amd64,linux/arm64
[..]
    - name: Build Execution Environment image
      working-directory: .
      run: | 
        ansible-builder build \
          --container-runtime docker \
          --extra-build-cli-args "--load --builder ${{ steps.docker_buildx.outputs.name }} --platform linux/amd64"
[..]

De docker buildx builder wordt gebruikt bij het aanroepen van ansible-builder.
De output van deze stap wordt gecached in context/en wordt daarna opgepakt door o.a. docker/buld-push-action.
YAML:
1
2
3
4
5
6
7
    - name: Build and push
      uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6
      with:
        context: context/
        push: ${{ github.ref_type == 'tag' }}
        tags: ${{ steps.docker_meta.outputs.tags }}
        labels: ${{ steps.docker_meta.outputs.labels }}

Deze workflow draait bij elke pull request (zonder release) en bij elke tag (met release).

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


  • blackd
  • Registratie: Februari 2001
  • Niet online
Sorry, nu weer wat meer Ansible en Python geweld.
alex3305 schreef op dinsdag 9 december 2025 @ 14:33:
Met standaard Python en venv is het inderdaad een groot drama. uv is the new kid on the block en daarmee dus ook fancy. Met mijn progressieve aanpak wilde ik die eigenlijk gebruiken. Vooral omdat ik dan een pyproject.toml of uv.toml kon toepassen. Dan zou ik ook geen extra requirements.txt meer hebben. Echter kreeg ik dat een paar maanden geleden niet lekker werkend met Ansible. Pyenv voldoet dan gewoon.
Ik las vandaag dat ansible-dev-environment onderwater uv gebruikt.
Het belooft met het commando ade Python, ansible en collections isolatie met venv support.
Wellicht is dat voor jou (nogmaals?) het onderzoeken waard?
alex3305 schreef op woensdag 10 december 2025 @ 19:39:
Je zou natuurlijk met Ansible pre_tasks kunnen controleren of de huidige Python versie gelijk is aan die in .python-version. Idem voor Ansible of andere pakketten.
Ik kwam vandaag een interessante pre-commit-hook tegen in bovengenoemde repo.
https://github.com/ansibl...in/.pre-commit-hooks.yaml
YAML:
1
2
3
4
5
6
7
8
9
---
- id: check-platform-constraints
  name: Check platform constraints and update renovate.json
  entry: check-platform-constraints
  language: python
  additional_dependencies: ["packaging>=23.2", "pyyaml"]
  files: ^pyproject\.toml$
  pass_filenames: false
  description: Validates dependencies against platform constraints and updates renovate.json


Het bijbehorende script: https://github.com/ansibl...k_platform_constraints.py
Python:
1
2
3
4
5
6
7
8
#!/usr/bin/env python3
"""Validate and enforce platform constraints.

This script:
1. Defines platform constraints as constants
2. Validates dependencies in pyproject.toml against these constraints
3. Updates renovate.json with allowedVersions rules to prevent automated bumps
"""

En de config met constraints:
https://github.com/ansibl.../platform-constraints.txt
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Platform compatibility constraints for AAP and RHEL
# These represent the MAXIMUM versions we can use to remain compatible
# with downstream platform packages

# AAP 2.5/2.6 ships ansible-core 2.16.x
ansible-core<2.17

# RHEL 8/9 ships cffi 1.15.x
cffi<1.16

# RHEL 8/9 ships setuptools 65.5.1
setuptools<65.6

# galaxy-importer constraint
packaging<25.0

Een dergelijke aanpak is wellicht ook interessant.

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


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:21
@blackd Zeker. Thanks voor je aanvullingen :). Ik had je post eerder vandaag ook gelezen en met jouw aanpak is zeker niets mis. Alleen is het niet helemaal mijn smaak. Ik ben gewoon een beetje allergisch voor devcontainers (leuk om te noemen in het Docker topic O-) ). Niet omdat het niet werkt of omdat het slecht is, maar vanwege het gedoe met containers op Windows al dan niet in combinatie met WSL(2). Ik wil mezelf die complexiteit liever niet meer op de hals halen. Althans niet nu.
blackd schreef op zondag 14 december 2025 @ 19:37:
Ik las vandaag dat ansible-dev-environment onderwater uv gebruikt.
Het belooft met het commando ade Python, ansible en collections isolatie met venv support.
Wellicht is dat voor jou (nogmaals?) het onderzoeken waard?
Misschien wel, maar voor nu werkt pyenv prima. Ik kan het issue zo 1-2-3 niet vinden...

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

Maar het ging er om dat tools niet zomaar geïnstalleerd konden worden vanuit een pyproject.toml. Wellicht is dat nu (een paar maanden later) wel het geval. Aangezien ik nu een degelijke setup heb laat ik het even zo :).

Die pre-commit hook is nog wel een interessante. Dat zou je ook al quick and dirty kunnen doen O-)

Bash:
1
2
3
$(python --version | awk '{print $2}') = $(cat .python-version) ] && echo "true" || echo "false"
# of 
$(python --version | awk '{print $2}') = $(cat .python-version) ] && exit 0 || exit 1

  • Mars Warrior
  • Registratie: Oktober 2003
  • Laatst online: 22-03 14:59

Mars Warrior

Earth, the final frontier

Mijn hoofd zit nog beetje vol van de afgelopen Forgejo/Ansible posts. Ik ga het voorlopig toch wat simpeler aanpakken. En pas daarna uitbouwen volgend jaar.

Daarom nog een wat info van CrowdSec, Alerts per dag en domein.
Des te roder, des te meer Alerts op dat domein op die dag. Groen is beter, en zwart is het beste, namelijk niks geen alerts!

Na de "massale" aanvallen van begin december (400-500 Alerts per dag) stapsgewijs wat maatregelen genomen:
  • Handmatige block van het verre oosten (Japan, Singapore, Zuid-Korea, India, Australie, etc.) voor de MICROSOFT ASN en AMAZON-02 ASN. Het gros van de Alerts kwam uit deze ASNs namelijk
  • Scripten - elke dag via cron - van de actuele Abuse Ip database richting CrowdSec. Deze lijst is actueel.
Het resultaat mag er zijn zou ik zeggen. Bijna niks meer op de domeinen (de regels onder <ip>).
Het aantal decisions/bans per dag is nu op een paar vingers te tellen :henk

Afbeeldingslocatie: https://tweakers.net/i/Ple2ErMBs8vtXEnJVTlU2gJ87J4=/800x/filters:strip_icc():strip_exif()/f/image/FejRWwBMYGw15L5s1JbChAa8.jpg?f=fotoalbum_large

Dat wordt natuurlijk veroorzaakt doordat de firewall het overgrote deel van het verkeer blokkeert. En dan met name de cscli-import blocklist met ca 70.000 extra decisions bovenop de CAPI lijst van 15.000.
  • De firewall laat een aardige toename richting 4.000 - 5.000 drops per dag zien
  • Het cscli-import deel is sommige dagen voor 90-95% verantwoordelijk voor het aantal drops. Die actuele lijsten werken dus perfect!
  • De CAPI lijst doet steeds minder. Het was ooit ca 30%, en laatste tijd rond de 5%. Vanaf laatste week november ben ik al zelf lijsten gaan toevoegen als test. Die overlappen blijkbaar enorm met de CAPI lijst.
Oftewel: ook met publiek verkrijgbare lijsten kun je een goede verdediging opbouwen.
Je hebt echt geen abbo van CrowdSec nodig. Het is natuurlijk wel extra werk, maar als het eenmaal draait, draait het. En ik update nu 1x per dag, terwijl die lijsten vaak 1x per uur of 30 minuten geactualiseerd worden. Het kan dus nog beter.

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

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


  • DjoeC
  • Registratie: November 2018
  • Laatst online: 22:59
Ik ben met allerlei aanpassingsklusjes bezig zoals het optuigen van een nieuwe Docker omgeving. Tot heden gebruik ik voor de netwerking een user_bridge omdat die communicatie tussen containers mogelijk maakt. Ik kan die containers natuurlijk ook via <host>:<gemapte poort> bereiken, maar ik zou graag willen dat ik een flink aantal containers - zoals Mariadb - zowel vanuit de rest van het netwerk als onderling in Docker via een hostnaam mariradb1.mijn.lan kan bereiken.

Ik meen dat dit ook met userbridge ooit gewerkt heeft door in mijn lokale dns die hostnaam op te nemen met het IP adres van de Docker machine maar dat lijkt niet altijd te werken.... Pihole heb ik al heel lang draaien op een macvlan met eigen IP adres.

De vraag: Is het gebruik van macvlan een "slechte" gewoonte, zo ja waarom, zo nee waarom niet? Voor mij lijkt het voordeel dat de container met macvlan op elke willekeurige machine in de lucht kan komen terwijl dat met user_bridge niet zo is.... Zijn er simpele, werkbare alternatieven?

  • Mars Warrior
  • Registratie: Oktober 2003
  • Laatst online: 22-03 14:59

Mars Warrior

Earth, the final frontier

@DjoeC. Is Traefik een optie om als L4 proxy te laten fungeren?

Dat deed ik voorheen met de Caddy L4 plug-in met de nodige beperkingen. Nu met Traefik
Nog niet gebruikt.

Je hebt dan altijd een centraal toegangspunt en ook een URL.

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


  • DjoeC
  • Registratie: November 2018
  • Laatst online: 22:59
Mars Warrior schreef op zondag 4 januari 2026 @ 17:06:
@DjoeC. Is Traefik een optie om als L4 proxy te laten fungeren?

Dat deed ik voorheen met de Caddy L4 plug-in met de nodige beperkingen. Nu met Traefik
Nog niet gebruikt.

Je hebt dan altijd een centraal toegangspunt en ook een URL.
Tja, ik gebruik nu NPM als reverse proxy. Die zal ook wel wat dingen kunnen (en gebruik ik ook af en toe wat truukerig) maar ik wilde dit eigenlijk in Docker zelf oplossen omdat het naar mijn idee ook een Docker uitdaging is. Een extra stap ertussen of erbij doe ik liever niet ;)

Ik gebruik NPM o.a. om de verschillende webinterfaces van binnenuit en soms ook van buitenuit bereikbaar te maken. Maar om dat ook voor databases en MQTT etc in te zetten gaat me wel wat ver.

[ Voor 13% gewijzigd door DjoeC op 04-01-2026 17:31 ]


  • Mars Warrior
  • Registratie: Oktober 2003
  • Laatst online: 22-03 14:59

Mars Warrior

Earth, the final frontier

DjoeC schreef op zondag 4 januari 2026 @ 17:30:
[...]

Tja, ik gebruik nu NPM als reverse proxy. Die zal ook wel wat dingen kunnen (en gebruik ik ook af en toe wat truukerig) maar ik wilde dit eigenlijk in Docker zelf oplossen omdat het naar mijn idee ook een Docker uitdaging is. Een extra stap ertussen of erbij doe ik liever niet ;)

Ik gebruik NPM o.a. om de verschillende webinterfaces van binnenuit en soms ook van buitenuit bereikbaar te maken. Maar om dat ook voor databases en MQTT etc in te zetten gaat me wel wat ver.
Aha. Het was maar een idee.

Voorheen gebruikte ik ook macvlan. Werkte goed. Maar ik wilde meer afscherming en eenvoud.

En de meeste databases die ik gebruik hebben een webconsole. Dus altijd via Traefik intern bereikbaar via een URL.

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


  • DjoeC
  • Registratie: November 2018
  • Laatst online: 22:59
Mars Warrior schreef op zondag 4 januari 2026 @ 22:28:
[...]

Aha. Het was maar een idee.

Voorheen gebruikte ik ook macvlan. Werkte goed. Maar ik wilde meer afscherming en eenvoud.

En de meeste databases die ik gebruik hebben een webconsole. Dus altijd via Traefik intern bereikbaar via een URL.
Dan moet ik me echt wat meer in Traefik of Caddy gaan verdiepen. NPM vind ik heerlijk snel in te richten, lets encrypt werkt feilloos en ook de accesslijsten ben ik blij mee.. Maar misschien mis ik iets dat nog beter en toch simpel werkt.....

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

DjoeC schreef op zondag 4 januari 2026 @ 16:50:
Ik ben met allerlei aanpassingsklusjes bezig zoals het optuigen van een nieuwe Docker omgeving. Tot heden gebruik ik voor de netwerking een user_bridge omdat die communicatie tussen containers mogelijk maakt. Ik kan die containers natuurlijk ook via <host>:<gemapte poort> bereiken, maar ik zou graag willen dat ik een flink aantal containers - zoals Mariadb - zowel vanuit de rest van het netwerk als onderling in Docker via een hostnaam mariradb1.mijn.lan kan bereiken.

Ik meen dat dit ook met userbridge ooit gewerkt heeft door in mijn lokale dns die hostnaam op te nemen met het IP adres van de Docker machine maar dat lijkt niet altijd te werken.... Pihole heb ik al heel lang draaien op een macvlan met eigen IP adres.

De vraag: Is het gebruik van macvlan een "slechte" gewoonte, zo ja waarom, zo nee waarom niet? Voor mij lijkt het voordeel dat de container met macvlan op elke willekeurige machine in de lucht kan komen terwijl dat met user_bridge niet zo is.... Zijn er simpele, werkbare alternatieven?
Wat bedoel je met user_bridge? Je kunt, in combinatie met docker compose toch ook gewoon gemakkelijk werken met diverse interne en externe netwerken? Dan hoef je niet eens poorten te forwarden, containers op hetzelfde netwerk kunnen elkaar dan ook bereiken, zonder een port forward hoeven in te stellen, dat lijkt mij dus een veel minder complexe methode, ik gebruik het best veel. Met macvlan heb ik in elk geval nog nooit hoeven werken. Enige is af en toe network_mode: host (en dan moet je wel poorten forwarden), maar dat is het dan wel.

Ik begrijp niet helemaal waarom je direct wilt kunnen verbinden met een database in Docker, laat dat lekker aan de applicaties (waarvoor je de database nodig hebt) over...

[ Voor 3% gewijzigd door CH4OS op 05-01-2026 01:39 ]


  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Mars Warrior schreef op woensdag 17 december 2025 @ 14:22:
Mijn hoofd zit nog beetje vol van de afgelopen Forgejo/Ansible posts. Ik ga het voorlopig toch wat simpeler aanpakken. En pas daarna uitbouwen volgend jaar.

Daarom nog een wat info van CrowdSec, Alerts per dag en domein.
Des te roder, des te meer Alerts op dat domein op die dag. Groen is beter, en zwart is het beste, namelijk niks geen alerts!

Na de "massale" aanvallen van begin december (400-500 Alerts per dag) stapsgewijs wat maatregelen genomen:
  • Handmatige block van het verre oosten (Japan, Singapore, Zuid-Korea, India, Australie, etc.) voor de MICROSOFT ASN en AMAZON-02 ASN. Het gros van de Alerts kwam uit deze ASNs namelijk
  • Scripten - elke dag via cron - van de actuele Abuse Ip database richting CrowdSec. Deze lijst is actueel.
Het resultaat mag er zijn zou ik zeggen. Bijna niks meer op de domeinen (de regels onder <ip>).
Het aantal decisions/bans per dag is nu op een paar vingers te tellen :henk

[Afbeelding]

Dat wordt natuurlijk veroorzaakt doordat de firewall het overgrote deel van het verkeer blokkeert. En dan met name de cscli-import blocklist met ca 70.000 extra decisions bovenop de CAPI lijst van 15.000.
  • De firewall laat een aardige toename richting 4.000 - 5.000 drops per dag zien
  • Het cscli-import deel is sommige dagen voor 90-95% verantwoordelijk voor het aantal drops. Die actuele lijsten werken dus perfect!
  • De CAPI lijst doet steeds minder. Het was ooit ca 30%, en laatste tijd rond de 5%. Vanaf laatste week november ben ik al zelf lijsten gaan toevoegen als test. Die overlappen blijkbaar enorm met de CAPI lijst.
Oftewel: ook met publiek verkrijgbare lijsten kun je een goede verdediging opbouwen.
Je hebt echt geen abbo van CrowdSec nodig. Het is natuurlijk wel extra werk, maar als het eenmaal draait, draait het. En ik update nu 1x per dag, terwijl die lijsten vaak 1x per uur of 30 minuten geactualiseerd worden. Het kan dus nog beter.

[Afbeelding]
Ik ben wel benieuwd hoe je CrowdSec aan de praat hebt gekregen. Ik heb een poosje terug dit ook gebruikt, maar na verloop van tijd stopte het gewoon met werken, bleek de API key ongeldig of zo. Omdat ik het vervolgens niet 1 2 3 meer aan de praat kreeg, maar wel services had die ik wel bereikbaar wilde hebben, heb ik daarom de filtering nu anders opgelost. Maar voor de services die ik wel publiekelijk heb nog, wil ik wel CrowdSec nog tussen zetten. Ik zou CrowdSec dan als plug-in gebruiken voor Traefik, aangezien ik nog geen (dedicated) firewall (ik ben van plan een OpnSense doos neer te gaan zetten ergens dit jaar) heb.

  • DjoeC
  • Registratie: November 2018
  • Laatst online: 22:59
CH4OS schreef op maandag 5 januari 2026 @ 01:33:
[...]

Wat bedoel je met user_bridge? Je kunt, in combinatie met docker compose toch ook gewoon gemakkelijk werken met diverse interne en externe netwerken? Dan hoef je niet eens poorten te forwarden, containers op hetzelfde netwerk kunnen elkaar dan ook bereiken, zonder een port forward hoeven in te stellen, dat lijkt mij dus een veel minder complexe methode, ik gebruik het best veel. Met macvlan heb ik in elk geval nog nooit hoeven werken. Enige is af en toe network_mode: host (en dan moet je wel poorten forwarden), maar dat is het dan wel.

Ik begrijp niet helemaal waarom je direct wilt kunnen verbinden met een database in Docker, laat dat lekker aan de applicaties (waarvoor je de database nodig hebt) over...
user_bridge is/was noodzakelijk omdat de "normale" docker bridge mode bij aanvang van mijn docker reis geen contacten tussen containers/services toeliet. Mogelijk is dat veranderd of heb ik nog steeds het hele docker netwerk geneuzel niet door ;)

Netwerk mode Host ken ik (nog) niet. Zal me eens inlezen.

Database: Benaderen vanaf Windows machines, andere SBC's. Mosquitto idem en vanaf ESP bordjes, etc. Er is voor mij wel degelijk een reden om in containers draaiende applicaties vanaf extern, maar ook vanaf intern (andere containerized applicaties zoals Nextcloud, eigen domotica, weerstation, etc.) te kunnen benaderen. Ik wil gewoon 1 database (eventueel als failsafe over 2 instanties op 2 docker hosts), 1 Mosquitto gekoppeld over 2 of meer instanties (dat werkt best mooi) etc. Ofwel: ik weet eigenlijk wat ik wil maar nog niet altijd hoe het slim en eenvoudig onderhoudbaar op te zetten is. Linux, Docker en nog veel meer zijn mijn hobby en niet mijn vak. Vragen om tips en weer veel lezen en leren dus....

  • Mars Warrior
  • Registratie: Oktober 2003
  • Laatst online: 22-03 14:59

Mars Warrior

Earth, the final frontier

CH4OS schreef op maandag 5 januari 2026 @ 01:43:
[...]
Ik ben wel benieuwd hoe je CrowdSec aan de praat hebt gekregen. Ik heb een poosje terug dit ook gebruikt, maar na verloop van tijd stopte het gewoon met werken, bleek de API key ongeldig of zo. Omdat ik het vervolgens niet 1 2 3 meer aan de praat kreeg, maar wel services had die ik wel bereikbaar wilde hebben, heb ik daarom de filtering nu anders opgelost. Maar voor de services die ik wel publiekelijk heb nog, wil ik wel CrowdSec nog tussen zetten. Ik zou CrowdSec dan als plug-in gebruiken voor Traefik, aangezien ik nog geen (dedicated) firewall (ik ben van plan een OpnSense doos neer te gaan zetten ergens dit jaar) heb.
Er is een CrowdSec plugin/middleware voor Traefik die wordt aanbevolen. Die heb ik gewoon gebruikt. Dat werkt al probleemloos sinds vorig jaar oktober.

Ik ben daarnaast de firewall docker container (iptables) gaan gebruiken van CrowdSec en dat werkt ook probleemloos. Omdat bijna alles op één server draait heb ik ook geen behoefte aan een externe firewall. Alle bans en allowlists (voorheen whitelists) komen automagisch in de firewall terecht.

Door gebruik te maken van externe blocklists die je met een import decisions inleest (helaas geen ondersteuning voor eigen blocklists, zal wel een commerciële reden hebben) heb ik het aantal events/alerts/decisions van CrowdSec zelf drastisch kunnen verlagen: op sommige dagen met 100% :9~

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

De effectiviteit van de firewall is dus uitstekend: gisteren had ik een flinke scan vanuit SECFIREWALLAS die ff ruim 3.000 drops liet zien in korte tijd voor een totaal van ca 5.000 drops. Die stond dus al op een ban lijst.

Afbeeldingslocatie: https://tweakers.net/i/4kUeFR4sgW2OO_O8cWZLaiReLh4=/800x/filters:strip_exif()/f/image/50MxTwEJVOvVBpH3KkwA9iGe.png?f=fotoalbum_large

Ik ben er blij mee. Het scheelt aan de ene kant ca 0,5% CPU (en dus Wattjes), al neemt (helaas) aan de andere kant het syncen van op dit ogenblik 125.000 bans ook weer de nodige CPU cycles in beslag.

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


  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Mars Warrior schreef op maandag 5 januari 2026 @ 12:45:
Er is een CrowdSec plugin/middleware voor Traefik die wordt aanbevolen. Die heb ik gewoon gebruikt. Dat werkt al probleemloos sinds vorig jaar oktober.
Ja, volgens mij gebruikte ik deze middleware juist. :) Binnenkort maar weer eens proberen, al heb ik nu ook niet echt inzichtelijk wat er binnenkomt. Hoe maak je deze grafieken bijvoorbeeld? :)

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

DjoeC schreef op maandag 5 januari 2026 @ 11:44:
Database: Benaderen vanaf Windows machines, andere SBC's. Mosquitto idem en vanaf ESP bordjes, etc. Er is voor mij wel degelijk een reden om in containers draaiende applicaties vanaf extern, maar ook vanaf intern (andere containerized applicaties zoals Nextcloud, eigen domotica, weerstation, etc.) te kunnen benaderen. Ik wil gewoon 1 database (eventueel als failsafe over 2 instanties op 2 docker hosts), 1 Mosquitto gekoppeld over 2 of meer instanties (dat werkt best mooi) etc. Ofwel: ik weet eigenlijk wat ik wil maar nog niet altijd hoe het slim en eenvoudig onderhoudbaar op te zetten is. Linux, Docker en nog veel meer zijn mijn hobby en niet mijn vak. Vragen om tips en weer veel lezen en leren dus....
Ah, ik heb gewoon gescheiden stacks gemaakt. Daardoor kunnen versies van de databases ook verschillen. Bijvoorbeeld omdat het ene programma niet altijd support heeft voor de bleeding edge of laatste stabiele versies van een database. Dat heeft ook als voordeel dat men ook niet afhankelijk is van elkaar en stacks niet omvallen omdat een andere stack omvalt. Ik denk dat als je gerichter advies wilt (en ik moet zeggen, ik heb niet alles terug gelezen in dit topic) het wellicht ook handig is om te weten hoe je nu een en ander hebt en wat je gebruikt.

[ Voor 7% gewijzigd door CH4OS op 05-01-2026 15:18 ]


  • Mars Warrior
  • Registratie: Oktober 2003
  • Laatst online: 22-03 14:59

Mars Warrior

Earth, the final frontier

CH4OS schreef op maandag 5 januari 2026 @ 15:05:
[...]
Ja, volgens mij gebruikte ik deze middleware juist. :) Binnenkort maar weer eens proberen, al heb ik nu ook niet echt inzichtelijk wat er binnenkomt. Hoe maak je deze grafieken bijvoorbeeld? :)
De grafieken maak in in Metabase (gratis versie). Voorheen leverde CrowdSec een metabase container mee, maar dat doen ze niet meer omdat ze vinden dat hun console meer kan. Ach ja, keep dreaming :D

Ik heb wel bergen aan scripts om zaken te verwerken en binnen te halen, dus de grafieken zijn de resultaten van heel wat weekjes werk.

Overigens is data verwerking mijn werk, dus dan zijn dit soort dingen voor mij gewoon leuk werk!

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


  • DjoeC
  • Registratie: November 2018
  • Laatst online: 22:59
CH4OS schreef op maandag 5 januari 2026 @ 15:13:
[...]
Ah, ik heb gewoon gescheiden stacks gemaakt. Daardoor kunnen versies van de databases ook verschillen. Bijvoorbeeld omdat het ene programma niet altijd support heeft voor de bleeding edge of laatste stabiele versies van een database. Dat heeft ook als voordeel dat men ook niet afhankelijk is van elkaar en stacks niet omvallen omdat een andere stack omvalt. Ik denk dat als je gerichter advies wilt (en ik moet zeggen, ik heb niet alles terug gelezen in dit topic) het wellicht ook handig is om te weten hoe je nu een en ander hebt en wat je gebruikt.
Ik heb even bijgelezen over "host" networking. Dat kan werken voor sommige containers maar als ik er tig heb die poort 80 of 3000 gebruiken gaat dat natuurlijk niet. Maar, ik ga eens kijken wat voor mij de beste optie is.

Effectief heb ik nu ~30 containers op 1 machine. De meesten daarvan hoeven niet naar buiten open te staan maar bijvoorbeeld alle Joomla instanties (nu poort 80) wel. Bij "sommige" containers is een aangepaste poort via configatie aan te passen maar niet bij allemaal, daar moet dus nog steeds poortmapping gebeuren. Geen probleem, die kan ik allemaal via NPM eenvoudig benaderen.

Stacks gebruik ik niet - minimale uitzonderingen daar gelaten. Ik heb me daar in het begin van mijn Docker inspanningen aan gebrand. Liever 1 losse database om te beheren dan 10 "embedded".... Ook vanuit andere overwegingen gebruik ik 1 MariaDB LTS voor alle generieke database dingen in mijn totale netwerk. Samen met "ghcr.io/tiredofit/docker-db-backup:latest" als container, phpmyadmin in een container en Navicat op de PC is beheer dan "simpel". Ook Mosquitto draai ik 1 keer (heb wat ervaring met zeer grootschalige MQ omgevingen), ook dat is prima beheersbaar met de paar honderd duizend berichten per dag. Op alle uitgangspunten zijn uitzonderingen mogelijk.

Pihole draait via macvlan opeen eigen (vast) ip adres. Dat is ook meteen de (lokale) DNS voor alles in het netwerk (samen met unbound).

Macvlan heeft voordelen want ik kan containers opstarten op (1 uit) meedere machines zonder dat ik de routering hoef aan te passen: De DNS naam veranderd niet, kwestie down brengen op machine 1, opstarten op machine 2.

Maar, zelf met deze (voor mij) uitgesproken manier van inrichten zal er best iets beters met minder inspanning mogelijk zijn, dat zoek ik dus, Alleen zie ik het, ondanks de goede inhoudelijke reacties van mensen hier, nog niet als eenvoudiger voor me - en dat ligt vast aan mij. Misschien lijdt ik aan tunnelvisie.

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

@DjoeC De Joomla installaties zet je dan toch achter Traefik / Caddy / Nginx Proxy Manager?

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

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

[ Voor 14% gewijzigd door CH4OS op 05-01-2026 16:40 ]


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

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

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

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

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

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


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

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

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

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

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

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

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

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

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

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


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

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

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


  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

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

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


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

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

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

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

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


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

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

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

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

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

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


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

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

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

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

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

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


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

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

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

Iemand een idee?

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


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

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

Iemand een idee?
Zoiets als Wallos?

  • ThinkPad
  • Registratie: Juni 2005
  • Laatst online: 21:41
Yes perfect!

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

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

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

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

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

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

Blog


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

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

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

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

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

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

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

Mijn USG en PiHole wlke ook samen.

Blog


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

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

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

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

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

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

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

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

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

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

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

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

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

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

Verwijderd

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

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

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

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

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

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

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

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

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

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

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

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

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

Blog


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

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

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

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

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

  • Mars Warrior
  • Registratie: Oktober 2003
  • Laatst online: 22-03 14:59

Mars Warrior

Earth, the final frontier

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

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

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

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

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

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

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

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

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

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


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

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

Blog


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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

  • Ghoulli
  • Registratie: Juli 2021
  • Laatst online: 20:30

Ghoulli

Snapt er niks van.

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

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

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

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

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

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

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


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

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

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

makes it run like clockwork


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

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

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

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

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

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

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

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

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

  • ElCondor
  • Registratie: Juni 2001
  • Laatst online: 22-03 10:57

ElCondor

Geluk is Onmisbaar

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

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

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

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

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

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


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

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

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

De eerste commit in deze repository dateert alweer uit 2019

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

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

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

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

  • ElCondor
  • Registratie: Juni 2001
  • Laatst online: 22-03 10:57

ElCondor

Geluk is Onmisbaar

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

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

[Afbeelding]

De eerste commit in deze repository dateert alweer uit 2019

[Afbeelding]


[...]

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

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

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

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

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

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

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

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

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

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


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


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

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

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

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

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

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

  • ElCondor
  • Registratie: Juni 2001
  • Laatst online: 22-03 10:57

ElCondor

Geluk is Onmisbaar

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

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

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

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

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


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

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

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

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

  • ElCondor
  • Registratie: Juni 2001
  • Laatst online: 22-03 10:57

ElCondor

Geluk is Onmisbaar

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

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

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

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


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

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

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

  • ElCondor
  • Registratie: Juni 2001
  • Laatst online: 22-03 10:57

ElCondor

Geluk is Onmisbaar

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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


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

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

# place custom docker compose project setup here

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

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

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

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

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

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

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

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

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

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

- name: Prepare
  hosts: molecule
  gather_facts: true

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

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

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

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

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

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

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

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

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

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

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

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

  tasks:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

name: {{ compose_stack_name }}

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

Pagina: 1 ... 17 18 Laatste