9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Dit heb ik dus ook: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.
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 |
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 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:
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] |
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:
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 ] |
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 |
extensions/molecule/inventory.yml:
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 ] |
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:
1
|
Dan de converge stap, het toepassen van de role op de test resource:
extensions/molecule/dockge/converge.yml:
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 |
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:
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 |
extensions/molecule/default/tasks/assert-container.yml:
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." |
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:
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 |
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:
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 |
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
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.
Ik vind het wel enorm leuk om te zien dat onze Docker + Ansible aanpak enorm veel overeenkomsten heeft
Ik heb momenteel mijn structuur zo opgezet, met als voorbeeld mijn 'common' role.
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 |
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) }} |
Elke set met tasks begint bij mij overigens hetzelfde:
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 |
De assertions gebruik ik puur en alleen om geen oneindige herhaling van code / configuratie te hebben. Een paar voorbeelden:
assert/docker.networks.yml
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 }}" |
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 |
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 |
Doe jij dat dus dynamisch? Want nu geef ik bij elke role de bestanden mee...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.
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" |
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:
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 |
Goed om te horen, zeker leuk dat we veel overeenkomsten hebben en van de verschillen kunnen we denk ik alleen maar lerenalex3305 schreef op vrijdag 13 maart 2026 @ 10:17:
@blackd Thanks voor de enorm uitgebreide postIk heb er nu even doorheen gelezen, maar dit zet ik zeker op mijn lijstje om op een later moment op te gaan pakken
.
Ik vind het wel enorm leuk om te zien dat onze Docker + Ansible aanpak enorm veel overeenkomsten heeft.
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.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"
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
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Precies. Dat vind ik echt heel waardevolblackd 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.
Ah juist. Dan valt bij mij het spreekwoordelijke kwartjeWat 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 inderdaad veel templating. In mijn vorige post sprak ik bijvoorbeeld over home_assistant_networks en die template ik dan ook in mijn Compose (snippet):
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 %} |
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 |
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:
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 |
Bij mij is het templaten dus ook organisch gegroeid, maar inmiddels een groot onderdeel van mijn Compose setup.
Goed dat je me hier nogmaals aan herinnerdMaar 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.
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.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.
Geen probleemWat 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
.
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
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 |
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] |
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.alex3305 schreef op vrijdag 13 maart 2026 @ 13:13:
Ik gebruik inderdaad veel templating.
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.
Hier ben ik dus een andere weg in geslagen en heb ik een template compose role gemaakt: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.
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 |
[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:
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 |
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.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
.
Dat kan ik me heel goed voorstellen.In sommige gevallen - maar lang nog niet overal- 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.
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
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.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.
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.
Yes. Dit snap ik. Dit had ik eerst ook zoHier ben ik dus een andere weg in geslagen en heb ik een template compose role gemaakt:
InteressantNightly wordt mijn omgeving geupgrade met een playbook, die voer ik eerst uit in check mode, daarna apply ik de configuratie.
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.
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'-effectDat 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.
Hoe doe je dit?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.
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
Ik gebruik ook tags, maar ik heb aparte playbooks en meta-playbooks.blackd schreef op vrijdag 13 maart 2026 @ 22:05:
Ik heb één main playbook die weer andere playbooks include, de enige manier om daar selectief mee om te gaan die ik had gevonden is met tags. Maar dat vereist discipline.
Neem ik bijvoorbeeld AdGuard home, dan heb ik dus het playbook playbooks/apps/adguard_home.yml.
1
2
3
4
5
6
| - name: Deploy AdGuard Home hosts: dns roles: - role: adguard_home tags: [app, dns, infra, adguard, adguard_home] |
1
2
3
4
5
6
7
8
9
10
11
| - name: Deploy AdGuard Home ansible.builtin.import_playbook: adguard_home.yml - name: Deploy ddclient ansible.builtin.import_playbook: ddclient.yml - name: Deploy Beszel ansible.builtin.import_playbook: beszel.yml - name: Deploy Gatus ansible.builtin.import_playbook: gatus.yml |
1
2
3
4
5
6
7
| - name: Deploy Infra ansible.builtin.import_playbook: infra.yml - name: Deploy Traefik ansible.builtin.import_playbook: traefik.yml # de rest van het playbook is hier niet relevant... |
1
2
3
4
5
6
7
8
| - name: Setup Hosts ansible.builtin.import_playbook: hosts/all.yml - name: Setup Docker ansible.builtin.import_playbook: docker.yml - name: Install apps ansible.builtin.import_playbook: apps/all.yml |
- playbooks/apps/adguard_home.yml gebruik ik wanneer ik alleen AdGuard Home deploy
- playbooks/apps/infra.yml gebruik ik bij het deployen van de basis infra
- playbooks/apps/all.yml gebruik ik bij het deployen van alle apps (eventueel met een host list) bijvoorbeeld wanneer ik een 'bulk' aan aanpassingen heb gedaan zoals CPU of mem toewijzingen
- playbooks/all.yml gebruik ik bij een verse install
1
2
3
4
5
6
7
8
9
10
11
12
| - name: Deploy Mosquitto ansible.builtin.import_playbook: mosquitto.yml - name: Deploy Zigbee2MQTT ansible.builtin.import_playbook: zigbee2mqtt.yml - name: Deploy Home Assistant hosts: home_assistant roles: - role: home_assistant tags: [app, infra, home-assistant, home_assistant] |
Doordat Ansible idempotent is zou ik uiteraard ook altijd all.yml of apps/all.yml kunnen gebruiken. Dit doe ik voornamelijk vanwege het af kunnen kaderen (kom ik zo op) en performance bij het ontwikkelen. Ik wil niet altijd alles of grote gedeeltes deployen. Ik besef me ook dat dit een kwestie van smaak is.
Met bovenstaande dus in het achterhoofd heb ik mijn Forgejo workflow een path-mapping toegewezen. Om dus met AdGuard Home verder te gaan, .forgejo/workflows/adguard_home.yaml:Hoe doe je dit?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
| name: Deploy AdGuard Home # yamllint disable-line rule:truthy on: push: branches: - main paths: - roles/adguard_home/** pull_request: types: - opened - reopened - synchronize paths: - roles/adguard_home/** workflow_dispatch: inputs: check_mode: description: "Check mode (dry-run)" default: false required: false type: boolean concurrency: group: ${{ github.repository }} jobs: deploy: name: Deploy AdGuard Home runs-on: ubuntu-latest timeout-minutes: 5 steps: - name: ⤵️ Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: 🏗️ Setup Python id: setup-python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: cache: 'pip' cache-dependency-path: 'requirements.txt' - name: 👷 Install Python dependencies if: steps.setup-python.outputs.cache-hit != 'true' shell: bash run: pip install -r requirements.txt - name: 📦 Setup Ansible Galaxy Cache id: ansible-galaxy-cache uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5 with: path: | .ansible ~/.ansible key: ${{ runner.os }}-ansible-${{ hashFiles('**/requirements.yml') }} restore-keys: | ${{ runner.os }}-ansible- - name: 🌌 Install Ansible Galaxy dependencies if: steps.ansible-galaxy-cache.outputs.cache-hit != 'true' shell: bash run: ansible-galaxy install -r requirements.yml - name: 🚧 Setup known hosts id: setup-known-hosts shell: bash run: | if [ -z "${KNOWN_HOSTS}" ]; then echo "No known hosts provided, skipping setup." exit 0 fi KNOWN_HOSTS_FILE="/etc/ssh/known_hosts" mkdir -p /etc/ssh/ echo ${KNOWN_HOSTS} > ${KNOWN_HOSTS_FILE} echo "known-hosts-file=$KNOWN_HOSTS_FILE" >> $GITHUB_OUTPUT echo "SSH known hosts setup at: $KNOWN_HOSTS_FILE" env: KNOWN_HOSTS: ${{ vars.KNOWN_HOSTS }} - name: 🔑 Setup Vault password id: setup-vault-pass shell: bash run: | if [ -z "${VAULT_PASS}" ]; then echo "No vault password provided, skipping setup." exit 0 fi echo "::add-mask::${VAULT_PASS}" if [ -z "$VAULT_PASS_DIRECTORY" ]; then VAULT_PASS_FILE="${{ github.workspace }}/.vault_pass" else mkdir -p "$VAULT_PASS_DIRECTORY" VAULT_PASS_FILE="$VAULT_PASS_DIRECTORY/.vault_pass" fi echo "$VAULT_PASS" > $VAULT_PASS_FILE echo "vault-pass-file=$VAULT_PASS_FILE" >> $GITHUB_OUTPUT echo "Vault password file setup at: $VAULT_PASS_FILE" env: VAULT_PASS: ${{ inputs.vault-pass }} VAULT_PASS_DIRECTORY: ${{ inputs.vault-pass-directory }} - name: 🚀 Run Ansible Playbook uses: dawidd6/action-ansible-playbook@v9 with: playbook: playbooks/apps/adguard_home.yml requirements: requirements.yml key: ${{ secrets.DEPLOY_KEY }} vault_password: ${{ secrets.ANSIBLE_VAULT_KEY }} check_mode: >- ${{ inputs.check_mode == true || github.event_name == 'pull_request' }} |
Ik gebruik voor het deployen een eigen fork van deze GitHub action. Die kerel had namelijk check_mode vernaggeld. Dit is alweer een tijdje geleden, dus de action zou wellicht weer kunnen werken.
De hele Ansible setup heb ik in een workflow zitten zodat ik geen oneindige herhaling van code heb. Tegenwoordig is het ook mogelijk om hiervoor workflow_call te gebruiken.
Tot slot heb ik in Renovate een tijdslot gezet voor auto-merges van Docker applicaties.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| { "packageRules": [ "description": "Update Docker dependencies", "matchFileNames": [ "roles/common/**", "roles/docker/**", "roles/dockge/**", "**/compose.yml", "**/compose.yaml", "**/compose.yml.j2", "**/compose.yaml.j2" ], "automergeSchedule": ["* 10-19 * * 1-6"] } } |
Nu heb ik namelijk regelmatig 3 - 5 Renovate PR's openstaan, terwijl ik voor digests zelfs al alleen branches gebruik
Ik neem aan dat je deze opzet ook kent?
Als je de dependencies op role niveau definieert, zouden ze maar 1x uitgevoerd moeten worden.
En mag ik concluderen uit je post dat je hiermee eigenlijk voor elke app een eigen workflow hebt?
Klinkt als een mooie feature voor mijn role template
Ik heb nu maar 1 workflow die altijd het grote playbook uitvoert. Dat duurt 15 min, dat was ik zat, vandaar dat ik naar een nightly release ben overgestapt.
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Ja, heel kort door de bocht wel jablackd schreef op zaterdag 14 maart 2026 @ 17:02:
@alex3305 interessante aanpak, zo had ik er nog niet over nagedacht. Feitelijk maak je voor alle laagste niveau apps een playbook en installeer je daar ook je dependencies.
Zeker. Sterker nog, die pagina had ik open toen ik mijn post schreefIk neem aan dat je deze opzet ook kent?
Als je de dependencies op role niveau definieert, zouden ze maar 1x uitgevoerd moeten worden.
Daarnaast vind ik dat bijvoorbeeld Mosquitto of Zigbee2MQTT geen echte dependency is van Home Assistant. En misschien is dat niet helemaal waar voor een tool zoals Zigbee2MQTT, maar wel voor Mosquitto. De MQTT broker gebruik ik immers ook op andere plekken. En ook krijg je dan een beetje 'vreemde' afhankelijkheden. Is DNS (AdGuard Home) bijvoorbeeld ergens afhankelijk van? Of monitoring en logging? Maar ja, als ik ze niet heb dan werkt het ook niet. Of in een extremer geval is Traefik met Crowdsec bij mij afhankelijk van het Vaultwarden (logging) pad. Is dan Vaultwarden een afhankelijkheid van Traefik? Eigenlijk wel... Maar dat voelt niet zo goed
Collecties zouden hier de uitkomst bieden, maar daarbij zijn afhankelijkheden op andere rollen of collecties alleen mogelijk als deze in de centrale Ansible Galaxy repository staan. En dat wil ik niet
Ik zit hier dus een beetje tussen wal en schip
Kort door de bocht wel. Er zijn uiteraard uitzonderingen. Home Assistant is zo'n uitzondering waarbij die wel alle afhankelijkheden include, maar geen op zichzelf staand playbook heeft.En mag ik concluderen uit je post dat je hiermee eigenlijk voor elke app een eigen workflow hebt?
Klinkt als een mooie feature voor mijn role template.
Ik haal het volgens mij niet in 15 minutenIk heb nu maar 1 workflow die altijd het grote playbook uitvoert. Dat duurt 15 min, dat was ik zat, vandaar dat ik naar een nightly release ben overgestapt.
Nee, dat was mijn vorige werk. Daar deden we volledige cloud inrichtingen met Ansible. Daar zaten we ook ruim over de 100 rollen heen. Dan is een volledige play - ook per host - niet meer praktisch. Ik heb het dan ook over een Ansible setup van ruim 12 jaar oud.
Dit patroon zie je overigens ook al bij de grotere setups van bijv. Red Hat zelf. Dus heel vreemd is het niet.
Ik heb wel op die manier dependencies opgegeven, zo heb ik een dockerproxy role toegevoegd aan mijn setup en alles wat iets met het docker socket nodig heeft, heeft als dependency de dockerproxy role.alex3305 schreef op zaterdag 14 maart 2026 @ 17:51:
Zeker. Sterker nog, die pagina had ik open toen ik mijn post schreef. Maar een role dependency is wederom per playbook, omdat ik meerdere playbooks uitvoer werkt dat dus niet zoals ik hoop dat dat werkt. Ik moet daarbij wel opmerken dat ik het niet heb getest
. Wel om meerdere roles uit te voeren in twee playbooks en die worden dan dus ook twee keer uitgevoerd. Verder las ik wat online discussies en documentaties waarbij aangegeven wordt dat role deduplication alleen per play plaatsvindt.
Dat werkt inderdaad binnen een playbook prima, want dat is hoe ik het nu heb ingericht.
Op mijn TrueNAS machine heb ik een jailmaker jail, waar ik alle docker compose projecten naar deploy.
Daarvoor heb ik één playbook truenas_apps.yml waarin alle docker compose projecten als roles staan, ieder met een eigen tag.
Dat HomeAssistant een dependency heeft op Zigbee2MQTT vind ik wel wat voor te zeggen, ook dat Zigbee2MQTT een broker nodig heeft, vind ik een goede dependency. Maar het maakt ook wel uit wanneer je de dependency nodig hebt, al bij het opstarten of pas bij het configureren van de applicaties.Daarnaast vind ik dat bijvoorbeeld Mosquitto of Zigbee2MQTT geen echte dependency is van Home Assistant. En misschien is dat niet helemaal waar voor een tool zoals Zigbee2MQTT, maar wel voor Mosquitto. De MQTT broker gebruik ik immers ook op andere plekken. En ook krijg je dan een beetje 'vreemde' afhankelijkheden. Is DNS (AdGuard Home) bijvoorbeeld ergens afhankelijk van? Of monitoring en logging? Maar ja, als ik ze niet heb dan werkt het ook niet. Of in een extremer geval is Traefik met Crowdsec bij mij afhankelijk van het Vaultwarden (logging) pad. Is dan Vaultwarden een afhankelijkheid van Traefik? Eigenlijk wel... Maar dat voelt niet zo goed.
Een DNS server heb je nodig, dat klopt. Maar dat kun je ook op een andere manier afdwingen, nl: volgorde in je playbooks, zoals je dat bij Docker ook gedaan hebt.
Ik heb een vergelijkbaar playbook voor docker met een groep in mijn inventory en daar kan ik opgeven op welke hosts ik docker geïnstalleerd wil hebben.
Maar hoe pas jij jouw patroon toe bij apps die je op meerdere machines deployed?
Want ik kan me voorstellen dat als je Traefik op meerdere hosts deployed, dat je workflow file triggert op roles/traefik/* maar als je dan meerdere playbooks (aanname) moet aanroepen heb je eigenlijk de link tussen host en app op twee plekken liggen: in je playbooks én je workflow.
Of heb je één playbook per app en dan in die playbooks geconfigureerd op welke host (of groep) je de zaken deployed?
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Fair enough. Alleen was ik 1 detail nog vergetenblackd schreef op zaterdag 14 maart 2026 @ 19:56:
[...]
Dat HomeAssistant een dependency heeft op Zigbee2MQTT vind ik wel wat voor te zeggen, ook dat Zigbee2MQTT een broker nodig heeft, vind ik een goede dependency. Maar het maakt ook wel uit wanneer je de dependency nodig hebt, al bij het opstarten of pas bij het configureren van de applicaties.
In principe is er één 'hoofd' playbook per gedeployde dienst. Dus voor Traefik, die op al mijn Docker hosts draait, wordt dus gedeployed naar de groep docker vanuit hetzelfde playbook. Idem voor Docker en Docker Compose. Beszel draait op alle hosts, maar daarbij configureer ik in de host_vars welke variant ik deploy.Ik heb een vergelijkbaar playbook voor docker met een groep in mijn inventory en daar kan ik opgeven op welke hosts ik docker geïnstalleerd wil hebben.
Maar hoe pas jij jouw patroon toe bij apps die je op meerdere machines deployed?
Want ik kan me voorstellen dat als je Traefik op meerdere hosts deployed, dat je workflow file triggert op roles/traefik/* maar als je dan meerdere playbooks (aanname) moet aanroepen heb je eigenlijk de link tussen host en app op twee plekken liggen: in je playbooks én je workflow.
Of heb je één playbook per app en dan in die playbooks geconfigureerd op welke host (of groep) je de zaken deployed?
Om nog even bij Home Assistant terug te komen, deze wordt gedeployed op meerdere hosts vanuit één hoofd playbook, namelijk:
- home_assistant
- mqtt
- thread
- zigbee
- zwave
Volgens mij zijn er geen machine/container afhankelijkheden als je ze als losse containers draait. Mogelijk wel als je de HA integratie gebruikt. Bij mij gaat het prima over machines/servers heen.alex3305 schreef op zaterdag 14 maart 2026 @ 21:01:
[...]
Fair enough. Alleen was ik 1 detail nog vergeten. Zigbee2MQTT draait mijn niet op mijn primaire machine. En Mosquitto niet op mijn secundaire machine
. Dit is in dit geval wel nodig, althans zo lees ik de documentatie.
HA praat met mosquitto op server/poort niveau, Z2M idem.
JaDjoeC schreef op zaterdag 14 maart 2026 @ 21:31:
[...]
Volgens mij zijn er geen machine/container afhankelijkheden als je ze als losse containers draait. Mogelijk wel als je de HA integratie gebruikt. Bij mij gaat het prima over machines/servers heen.
HA praat met mosquitto op server/poort niveau, Z2M idem.
Het gaat erover als je als dependency markeert in een meta/main.yml in Ansible zoals @blackd bedoelde en zoals hier beschreven in de Ansible documentatie dat deze niet over meerdere target hosts uit de inventory heengaat.
Ik wil dus de Mosquitto container via mijn Mosquitto role op mijn mqtt host uit de inventory parkeren, maar Zigbee2MQTT moet op de zigbee host én tot slot moet Home Assistant op de home_assistant host. Ansible heeft in principe geen kennis of context of deze hosts daadwerkelijk verschillend of gelijk zijn. Maar volgens mij gaat dat niet met role dependencies, wat volgens de documentatie ook semenatisch meer prerequisites zijn.
Volgens mij is er wel een uitzondering mogelijk hierop met delegate_to.alex3305 schreef op zaterdag 14 maart 2026 @ 21:37:
Het gaat erover als je als dependency markeert in een meta/main.yml in Ansible zoals @blackd bedoelde en zoals hier beschreven in de Ansible documentatie dat deze niet over meerdere target hosts uit de inventory heengaat.
In mijn base role kan ik een directory maken op mijn TrueNAS machine. Dat doe ik in principe eerst op de TrueNAS host als zfs dataset, daarna in de TrueNAS jail.
De zfs dataset task draai ik met delegate to op de nas host, de role zelf gaat in de jail.
Oh ja en de jail mag niet met de nas praten dus ik gebruik een jump host.
Maar met een playbook is veel netter imho want met delegate to fixeer je de host in de role zelf.
Ik had al zo'n vermoedenalex3305 schreef op zaterdag 14 maart 2026 @ 21:01:
Fair enough. Alleen was ik 1 detail nog vergeten. Zigbee2MQTT draait mijn niet op mijn primaire machine. En Mosquitto niet op mijn secundaire machine
.
Ik ga deze aanpak ook een keer proberen en kijken of het mij bevalt.
De templates in compose files ontkom ik denk ik ook niet aan. Ik heb meer duplicatie dan ik dacht (*Arr stack in uhd en 4k).
De gescheiden paden voor config e.d lukt nog wel, maar de traefik labels wordt lastig zonder templates vrees ik.
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Yes. Daar had ik ook nog aan gedacht, maar een delegate_to zonder eerst een setup / gather_facts vind ik niet transparant en onverwacht. Daar blijf ik als het even kan dus ook van weg. Tijdens het opzetten van bijv. Swarm werkt een dergelijke constructie wel goed. Dan wil je bijv. alleen tasks uitvoeren op (de eerste) Swarm manager(s).blackd schreef op zaterdag 14 maart 2026 @ 22:29:
[...]
Volgens mij is er wel een uitzondering mogelijk hierop met delegate_to.
Ook dat nog. Nu zijn mijn rollen juist op zichzelf staand van de inventory en plays.Maar met een playbook is veel netter imho want met delegate to fixeer je de host in de role zelf.
Ik heb er uiteindelijk echt geen enkele moeite meer mee, omdat het dus gemeengoed is. Het was ook al iets waar ik eerder al genoeg ervaring mee had.De templates in compose files ontkom ik denk ik ook niet aan.
Zoals ik eerder in deze post al aangaf wil ik ook nog een keer gaan kijken naar includes / lookups van templates om vaste stukken uit de compose te templaten. Ik heb bijvoorbeeld Unraid labels die overal hetzelfde zijn met wat kleine verschillen. Aan de andere kant werkt dit voor mij en is het duidelijk en transparant. Daarmee bedoel ik dat ik na een half jaar ook nog weet wat er staat. Soms is meer dus beter en de noodzaak nu niet zo hoog
Ik kan (nog) niet leunen op jaren ervaring Jinja2 templates dus voor mij is het nieuw.alex3305 schreef op zaterdag 14 maart 2026 @ 22:44:
Ik heb er uiteindelijk echt geen enkele moeite meer mee, omdat het dus gemeengoed is. Het was ook al iets waar ik eerder al genoeg ervaring mee had.
Wel heb ik in het verleden wat ervaring opgedaan met genereren van bijv. config files met Jinja2 templates.
Maar zo uitgebreid is voor mij nieuw, wat het dan lastiger maakt is dat ik snel feedback wil hebben of het eindresultaat (na templating) qua syntax klopt. Daarvoor heb ik nu dclint maar dat gaat niet werken op een .j2 variant van compose.yml. Hoe had jij bedacht dat aan te gaan pakken? Wat je zou kunnen doen is in Molecule een stap toevoegen die de syntax van compose.yml valideert, zodat je snel feedback hebt. Of je voert een template uit op de lokale machine en valideert dan met dclint. Of had je een andere aanpak bedacht?
Dat zou een mooie use case zijn voor een herbruikbare role om bepaalde docker labels te templaten en deze logica maar op één plek te leggen. Want ik neem aan dat je met includes de docker compose includes bedoelt? Met standaard docker compose merging zou je ook je compose file modulair kunnen opzetten:Zoals ik eerder in deze post al aangaf wil ik ook nog een keer gaan kijken naar includes / lookups van templates om vaste stukken uit de compose te templaten. Ik heb bijvoorbeeld Unraid labels die overal hetzelfde zijn met wat kleine verschillen.
1
2
3
4
| - compose.yml [base] - compose.labels.yml [docker labels] - compose.networks.yml [docker networks] - .. enzovoorts |
Ik ben (met de power van AI) begonnen om voor elke role in mijn TrueNAS playbook een apart playbook aan te maken en deze in het TrueNAS playbook te importeren.alex3305 schreef op zaterdag 14 maart 2026 @ 14:48:
Ik gebruik ook tags, maar ik heb aparte playbooks en meta-playbooks.
Neem ik bijvoorbeeld AdGuard home, dan heb ik dus het playbook playbooks/apps/adguard_home.yml.
Stiekem gebruikte ik namelijk best vaak de -l limit en -t tags om of alle apps of één app te deployen. Een playbook per app is dus een logische keuze.
Mijn plan van aanpak is als volgt:
- Playbook per app, import in de 'main' playbooks zodat ik ze altijd raak.
- Workflow per app, waarbij ik trigger op de betreffende role(s), ik configureer hier het molecule scenario wat bij de role hoort én welk playbook erbij hoort, dan roep ik een herbruikbare workflow aan (zie hieronder).
- Herbruikbare workflow maken, hier zit alle logica in voor CI, zoals Molecule test uitvoeren, Ansible Playbook in Check mode en Deployment.
Ik heb ook jouw tips voor asserts en naamgeving van de tasks in de common role al doorgevoerd.
[ Voor 26% gewijzigd door blackd op 15-03-2026 10:21 ]
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Dat is gewoon een skill issueblackd schreef op zondag 15 maart 2026 @ 09:40:
Ik kan (nog) niet leunen op jaren ervaring Jinja2 templates dus voor mij is het nieuw.
Wel heb ik in het verleden wat ervaring opgedaan met genereren van bijv. config files met Jinja2 templates.
Maar zo uitgebreid is voor mij nieuw, wat het dan lastiger maakt is dat ik snel feedback wil hebben of het eindresultaat (na templating) qua syntax klopt. [...] Hoe had jij bedacht dat aan te gaan pakken?
Maar om jouw vraag te beantwoorden; waarom template je het niet gewoon? Bij Jinja2 syntax fouten krijg je toch een foutmelding van Ansible, ook in check mode. Daarna valideer ik de uitgeschreven template met Compose zoals ik in mijn eerdere post liet zien.
Ik zou nog wat extra stappen kunnen toevoegen door bijvoorbeeld met een lookup plugin de yaml terug in te laden in Ansible en wat simpele assertions te doen. Bijvoorbeeld dat er services zijn. Alleen vind ik dat veel extra moeite en tijd met waarschijnlijk weinig concreet resultaat.
Dat zou ook nog kunnen, maar aangezien ik (nog) geen Molecule heb is dat bij mij niet van toepassing.Wat je zou kunnen doen is in Molecule een stap toevoegen die de syntax van compose.yml valideert, zodat je snel feedback hebt. Of je voert een template uit op de lokale machine en valideert dan met dclint. Of had je een andere aanpak bedacht?
Tijdens mijn vorige werk werd voor Docker applicaties de template weggeschreven naar een /tmp/, gevalideerd en daarna gekopieerd naar de juiste directory. Dat werkt in tegenstelling tot mijn aanpak ook in check mode.
Nee, ik bedoel lookup templates.Dat zou een mooie use case zijn voor een herbruikbare role om bepaalde docker labels te templaten en deze logica maar op één plek te leggen. Want ik neem aan dat je met includes de docker compose includes bedoelt? Met standaard docker compose merging zou je ook je compose file modulair kunnen opzetten:code:
1 2 3 4 - compose.yml [base] - compose.labels.yml [docker labels] - compose.networks.yml [docker networks] - .. enzovoorts
Ik wil geen gesplitste Compose configuratie, daar heb ik immers Ansible voor. Die moet de juiste puzzelstukjes als geheel naar de target host zetten. En of dat dan lokaal in 1 stukje of 200 stukjes zit kan me een spreekwoordelijke worst wezen. Ik vind gesplitste Compose namelijk ondoorzichtig. Daarbij komt nog dat software zoals Dockge of Portainer daar niet of niet goed mee om kan gaan.
Klinkt als een mooie stapIk ben (met de power van AI) begonnen om voor elke role in mijn TrueNAS playbook een apart playbook aan te maken en deze in het TrueNAS playbook te importeren.
Stiekem gebruikte ik namelijk best vaak de -l limit en -t tags om of alle apps of één app te deployen. Een playbook per app is dus een logische keuze.
Mijn plan van aanpak is als volgt:Later kan ik dit uitbreiden naar de generieke playbooks, ik heb playbooks voor het configureren van unattended upgrades op alle machines en docker upgrades op alle machines (docker-ce).
- Playbook per app, import in de 'main' playbooks zodat ik ze altijd raak.
- Workflow per app, waarbij ik trigger op de betreffende role(s), ik configureer hier het molecule scenario wat bij de role hoort én welk playbook erbij hoort, dan roep ik een herbruikbare workflow aan (zie hieronder).
- Herbruikbare workflow maken, hier zit alle logica in voor CI, zoals Molecule test uitvoeren, Ansible Playbook in Check mode en Deployment.
Ik heb ook jouw tips voor asserts en naamgeving van de tasks in de common role al doorgevoerd.
Daar ga ik ook wel naar toe bewegen vermoed ik, eerst de apps als losse playbooks apart deploybaar maken en dan kan ik daarna de duplicatie in rollen wegwerken door de compose files dynamischer te maken met templating en d.m.v. variabelen sturen hoe de role meerdere keren gedeployed kan worden.alex3305 schreef op zondag 15 maart 2026 @ 14:06:
Maar om jouw vraag te beantwoorden; waarom template je het niet gewoon? Bij Jinja2 syntax fouten krijg je toch een foutmelding van Ansible, ook in check mode. Daarna valideer ik de uitgeschreven template met Compose zoals ik in mijn eerdere post liet zien.
Het gaat mij om de controle niet alleen om de Jinja2 syntax van het template, maar ook om het resultaat van de compose file na templating.
Ik zie nu dat ansible.builtin.template ook een validate parameter heeft en dat deze een tmp locatie gebruikt. Je zou daar ook docker compose config in kunnen doen, toch?
Heb jij die bewust niet gebruikt en 'm als aparte stap opgenomen?
Het leek mij ook onoverzichtelijk maar al speurende door de docs kwam ik deze opties tegen. Het ging toen met name om hoe ik in de test-uitvoer bepaalde zaken anders moest doen of over moest slaan. Denk aan een stub CA voor Let's encrypt + Traefik bij het uitvoeren van Molecule.Nee, ik bedoel lookup templates.
Ik wil geen gesplitste Compose configuratie, daar heb ik immers Ansible voor. Die moet de juiste puzzelstukjes als geheel naar de target host zetten. En of dat dan lokaal in 1 stukje of 200 stukjes zit kan me een spreekwoordelijke worst wezen. Ik vind gesplitste Compose namelijk ondoorzichtig. Daarbij komt nog dat software zoals Dockge of Portainer daar niet of niet goed mee om kan gaan.
Ik vind persoonlijk één compose file ook veel overzichtelijker dan allemaal losse stukjes, dus daarover zijn we het eens
Ja, dat is ook mijn aanpak.Klinkt als een mooie stap. Zoiets doe ik dan vaak in een PR / feature branch om even te kijken hoe het mij bevalt. Het kan dan ook best zijn dat ik alles nog maar eens terugbouw omdat het dus niet bevalt
.
[ Voor 3% gewijzigd door blackd op 15-03-2026 15:06 ]
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Zo heb ik het ook gedaanblackd schreef op zondag 15 maart 2026 @ 15:02:
Daar ga ik ook wel naar toe bewegen vermoed ik, eerst de apps als losse playbooks apart deploybaar maken en dan kan ik daarna de duplicatie in rollen wegwerken door de compose files dynamischer te maken met templating en d.m.v. variabelen sturen hoe de role meerdere keren gedeployed kan worden.
Mij ookHet gaat mij om de controle niet alleen om de Jinja2 syntax van het template, maar ook om het resultaat van de compose file na templating.
Zeker zou dat kunnen en het is dus inderdaad een bewuste keuze om daar een aparte stap van te maken. Althans 'bewuste' keuze. Want als je de documentatie leest kom je er direct achter waarom dat niet gaat:Ik zie nu dat ansible.builtin.template ook een validate parameter heeft en dat deze een tmp locatie gebruikt. Je zou daar ook docker compose config in kunnen doen, toch?
Heb jij die bewust niet gebruikt en 'm als aparte stap opgenomen?
En het docker compose config commando accepteert geen input path.quote: AnsibleParameters
Parameter Comments validate
stringThe validation command to run before copying the updated file into the final destination.
A temporary file path is used to validate, passed in through %s which must be present as in the examples below.
Also, the command is passed securely so shell features such as expansion and pipes will not work.Examples
YAML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - name: Copy a new sudoers file into place, after passing validation with visudo ansible.builtin.template: src: /mine/sudoers dest: /etc/sudoers validate: /usr/sbin/visudo -cf %s - name: Update sshd configuration safely, avoid locking yourself out ansible.builtin.template: src: etc/ssh/sshd_config.j2 dest: /etc/ssh/sshd_config owner: root group: root mode: '0600' validate: /usr/sbin/sshd -t -f %s backup: yes
Volgens de docs moet je dan kijken naar handling complex validation. Dat lijkt op hoe ik het doe muv de rescue en always blokken. Dat heb ik door luiheid simpelweg niet geïmplementeerd. Wederom weer iets voor op het lijstje
Ik denk dat we het over heel veel zaken eens zijnIk vind persoonlijk één compose file ook veel overzichtelijker dan allemaal losse stukjes, dus daarover zijn we het eens.
alex3305 schreef op zondag 15 maart 2026 @ 15:34:
En het docker compose config commando accepteert geen input path.
1
2
3
4
5
6
7
| ansible.builtin.template: src: "compose.yaml" dest: ".." owner: ".." group: ".." mode: ".." validate: "docker compose -f %s config" |
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
👀 Hier inmiddels ookblackd schreef op zondag 15 maart 2026 @ 15:52:
[...]YAML:werkt hier perfect
1 2 3 4 5 6 7 ansible.builtin.template: src: "compose.yaml" dest: ".." owner: ".." group: ".." mode: ".." validate: "docker compose -f %s config"
@blackd Toch niet helemaal. Dit werkt niet lekker met verplichte .env bestanden. Ik ga er een combinatie van maken
[ Voor 14% gewijzigd door alex3305 op 15-03-2026 16:26 ]
Het lukte mij niet om met de --env-file de reeds geplaatste .env file mee te nemen in de validatie.
Daarnaast wil je beide files rollbacken wanneer er iets mis gaat.
Dan maar een extra stap opnemen zoals jij, dit wordt vaker toegepast zo te zien.
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Ik ben bezig geweest met de aanpassingen om de deployment op een vergelijkbare manier te doen als jij, met het verschil dat ik per app een deploy-appname.yaml workflow heb, deze meerdere reusable workflows aanroept (test, check, deploy) maar ik loop vast met concurrency groups. Ik gebruik GitHub actions, de syntax is vergelijikbaar en volgens mij de werking van concurrency groups ook.alex3305 schreef op zaterdag 14 maart 2026 @ 14:48:
Met bovenstaande dus in het achterhoofd heb ik mijn Forgejo workflow een path-mapping toegewezen. Om dus met AdGuard Home verder te gaan, .forgejo/workflows/adguard_home.yaml:YAML:
1 2 3 4 name: Deploy AdGuard Home concurrency: group: ${{ github.repository }}
Als ik bovenstaande zo lees, zou je bij een PR wat meerdere deployment workflows triggert, ervoor zorgen dat andere workflows (binnen of buiten dezelfde PR) gecancelled worden (de default van cancel-in-progress is true waardoor er één winnaar overblijft). Klopt dat of heb ik dat verkeerd begrepen?
Ik heb e.e.a. op meerdere manieren geprobeerd:
In de composite workflow op workflow niveau, concurrency group [repo], cancel false
In de composite workflow op job niveau, concurrency group [repo], cancel false bij alleen de deploy
In de reusable workflow op job niveau, concurrency group [repo], cancel false bij alleen de deploy
Daarnaast nog geprobeerd om voor de andere jobs een concurrency group met workflow+github ref toe te voegen en cancel op true te zetten.
Wat ik wil bereiken is dat de Test en Check (playbook --check) gecancelled mogen worden in de context van de PR als er een nieuwe push op de featurebranch is, maar dat de Deploy nadat de PR gemerged is, altijd blijft doorlopen en niet onderbroken wordt.
Voor elke deploy workflow moet eerst de Test en dan de Check worden uitgevoerd. Dat lukt op zich met needs: in de workflow. Elke workflow op zich moet gewoon door blijven lopen, ook parallel.
Daarnaast wil ik ook dat er maar één deploy mogelijk is per keer. Al is dat min of meer afgedwongen doordat ik de Ansible Playbook job altijd op mijn self-hosted runner draai, de rest op GitHub Actions runners.
Ik heb het vermoeden dat ik een ander niveau van concurrency group nodig heb en het voldoende is om maar één local runner te hebben zodat alle playbook workflows sequentieel worden uitgevoerd.
Edit: het probleem opschrijven lost het halve probleem op, ik heb nu een concurrency group gemaakt deploy-$(appname)-to-production en met een 5 tal workflows ben ik dat nu aan het testen.
[ Voor 3% gewijzigd door blackd op 16-03-2026 09:16 ]
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Het linten gebeurd bij mij per commit, dus:
1
2
3
| concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true |
1
2
| concurrency: group: ${{ github.workflow }} |
1
2
3
| concurrency: group: ${{ github.workflow }} cancel-in-progress: ${{ !contains(github.ref, 'main')}} |
Bij mij werkt dit volgens mij wel zoals ik verwacht. Althans ik kan mij zo niet herinneren dat ik gek gedrag heb opgemerkt...
Mijn aanpak geschetst in de edit lijkt goed te werken en komt globaal overeen met jouw oplossing.
Ik heb nu alleen aparte steps voor check en deploy, misschien voeg ik dat nog samen.
De check is afhankelijk van test, de deploy hoeft dat niet te zijn.
Ik heb een aparte workflow voor linting, ik gebruikt reviewdog en die doet ansible lint en dclint.
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Je zou ook nog workflow_call kunnen gebruiken om workflows te hergebruiken.
Mijn check / deploy is wel dezelfde workflow want immers is dat hetzelfde met uitzondering van een 'check_mode' parameter.
Zoiets?alex3305 schreef op maandag 16 maart 2026 @ 13:19:
Je zou ook nog workflow_call kunnen gebruiken om workflows te hergebruiken.
.github/workflows/deploy-authentik.yml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| name: Authentik on: push: branches: - main paths: - 'roles/authentik/**' pull_request: types: - opened - synchronize - reopened paths: - 'roles/authentik/**' workflow_dispatch: inputs: check_mode: description: "Check mode (dry-run)" default: false required: false type: boolean jobs: deploy: name: Deploy uses: ./.github/workflows/deploy-generic.yml with: ansible_playbook_path: playbooks/apps/authentik.yml molecule_scenario: "authentik" check_mode: ${{ inputs.check_mode == true || github.event_name == 'pull_request' }} secrets: inherit |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| on: workflow_call: inputs: molecule_scenario: description: "Molecule (test) scenario to run" required: true type: string ansible_playbook_path: description: "Ansible Playbook path (relative to project root)" required: true type: string check_mode: description: "Check mode (dry-run)" default: false required: false type: boolean jobs: test: name: Molecule if: inputs.check_mode == true uses: ./.github/workflows/molecule.yml with: scenario: ${{ inputs.molecule_scenario }} secrets: inherit concurrency: group: "${{ github.workflow }}-${{ github.head_ref }}" cancel-in-progress: true check: name: Deploy (dry run) if: inputs.check_mode == true uses: ./.github/workflows/ansible-playbook.yml needs: [test] with: ansible-playbook-check-mode: true playbook-file: ${{ inputs.ansible_playbook_path }} secrets: inherit concurrency: group: "${{ github.workflow }}-${{ github.head_ref }}" cancel-in-progress: true deploy: name: Deploy if: inputs.check_mode == false uses: ./.github/workflows/ansible-playbook.yml with: ansible-playbook-check-mode: false playbook-file: ${{ inputs.ansible_playbook_path }} secrets: inherit concurrency: group: ${{ github.workflow }} cancel-in-progress: false |
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
1
2
3
4
5
6
7
8
9
10
11
12
13
| on: workflow_call: inputs: run_test: description: "Run Molecule Test(s)" default: true required: false type: boolean jobs: test: name: Molecule if: inputs.run_test == true || inputs.check_mode == true |
Volgens mij kom ik dan in de knoei met mijn job > check, die needs: [test] ?alex3305 schreef op maandag 16 maart 2026 @ 19:17:
@blackd Ja precies. Dan zou je zelfs nog de test als conditional kunnen opnemen, bijvoorbeeld:
Dan hoef je dat ook niet elke keer als parameter mee te geven, maar wordt het standaard toch gedaan.
Let op dat die /** glob geen dotfiles matched, dus een change in je .env wordt niet opgepakt.alex3305 schreef op zaterdag 14 maart 2026 @ 14:48:
.forgejo/workflows/adguard_home.yaml:YAML:
1 2 3 4 5 6 7 name: Deploy AdGuard Home # yamllint disable-line rule:truthy on: push: paths: - roles/adguard_home/**
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Deze deployment workflow werkt goed wanneer een role wordt aangepast (bijv. door renovate die een versie upgrade uitvoert) of omdat je een refactoring doet aan tasks binnen een role.alex3305 schreef op zaterdag 14 maart 2026 @ 14:48:
.forgejo/workflows/adguard_home.yaml:YAML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 name: Deploy AdGuard Home # yamllint disable-line rule:truthy on: push: branches: - main paths: - roles/adguard_home/** pull_request: types: - opened - reopened - synchronize paths: - roles/adguard_home/** workflow_dispatch: inputs: check_mode: description: "Check mode (dry-run)" default: false required: false type: boolean
Maar het roept bij mij de vraag op hoe je omgaat met wijzigingen van configuratie?
Denk aan inventory group variabelen of .env files. Want ik neem aan dat je bij een wijziging van configuratie van een app het bijbehorende playbook óók wilt kunnen runnen in een PR.
Een van de best practices in Ansible is om variabelen per group vast te leggen in je inventory, maar daar triggert deze workflow niet op.
Daarnaast de vraag, hoe ga je om met (controleren van) wijzigingen van de playbooks zelf? Heb je hier een aparte workflow voor of is dat onderdeel van de deploy workflow?
Want een ansible-playbook check mode dient meerdere doelen, waaronder het controleren of het playbook nog correct werkt.
Zou je dus bij de path mapping per deployment van een app niet ten minste ook willen toevoegen:
- Het playbook waarmee de deployment plaatsvindt
Bijv. in het voorbeeld van MQTT broker, Z2M, HA. Bij deploy HA, neem je dan ook changes in de playbooks van MQTT, Z2M mee? Ergens wel logisch, maar tegelijkertijd leg je die logica dan twee keer vast.
- De inventory files waarmee de role variabelen gevoed worden
Of heb je een andere aanpak hiervoor?
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Alhoewel ik best het e.e.a. strak heb ingericht is er bij mij ook nog ruimte voor verbetering. Met andere woorden, ik heb dat nu niet. Ik heb dat eigenlijk ook niet helemaal nodig. In ieder geval niet met mijn workflow. In principe doe ik na het wijzigen van mijn group_vars of host_vars sowieso een deploy vanaf mijn lokale workstation. Enerzijds om het te testen en direct problemen op te lossen, anderzijds omdat ik snel resultaat wil
Tegelijkertijd heb ik ook mijn vars voor een heel groot gedeelte opgesplitst per role. Simpelweg omdat ik veel liever met veel kleine bestanden werk dan met 1 grote. Want...
Ik heb het hier vaker op Tweakers verteld, maar ik ben slechtziend en heb een zichtvermogen van circa 20%. Mijn letters zijn dus ietsjes groter dan ehh gemiddeld
/f/image/fiJ0JVklSNU8OrkNoGmzQZGk.png?f=fotoalbum_large)
Dit venster neemt 75% van mijn 32" display in beslag. Een display waar ik een 25-30 centimeter vanaf zit
Ik ben dus bijna verplicht om veel kleine bestanden te gebruiken. Sterker nog, van Traefik heb ik zelfs twee vars bestanden in mijn group_vars, één met de configuratie en de andere met de dynamische reverse proxy configuratie. In mijn group_vars heb ik daarbij de variabelen die nodig zijn voor het geheel, dus domeinnaam, middleware configuratie, ingress netwerk, etc. En in de host_vars staan alleen variabelen die nodig zijn voor die host.
Bij een check (en deployment, want dat is bij mij hetzelfde) doe ik sowieso een deploy van het playbook. In sommige gevallen de applicatie zelf, maar in andere gevallen de complete stack. Dat is een beetje afhankelijk van de applicatie en wat ik prettig vind. Ik heb dan wat Shields in mijn README die ik kan checken wat de status is en eventueel Gatus voor status. Het feest gaat sowieso niet door bij een probleem in het playbook, inclusief validatie problemen.
Ook Renovate rolt het hele playbook uit bij een versie upgrade, maar altijd in check mode in de PR. Als een check mode niet slaagt wordt het PR niet gemerged. Klaar, uit. Ik vind dat veilig genoeg.
Eigenlijk heb ik de afgelopen jaar of jaren nog geen een echte probleem deployment gehad. Behalve dan door mijn eigen gepruts. Vaak door haastigheid
/f/image/8KlmEVfgKNTd5n50eKzV2ymK.png?f=fotoalbum_large)
Niet om te pochen, maar dit gaat dus om ~1000 runs per maand of gemiddeld zo'n 30 per dag. Als er dan niet echt iets misgaat vind ik het wel best.
Met mijn vragen probeer ik te ondekken hoe jouw workflow is ingerichtalex3305 schreef op dinsdag 17 maart 2026 @ 21:18:
@blackd Goede vragen
Alhoewel ik best het e.e.a. strak heb ingericht is er bij mij ook nog ruimte voor verbetering. Met andere woorden, ik heb dat nu niet. Ik heb dat eigenlijk ook niet helemaal nodig. In ieder geval niet met mijn workflow. In principe doe ik na het wijzigen van mijn group_vars of host_vars sowieso een deploy vanaf mijn lokale workstation. Enerzijds om het te testen en direct problemen op te lossen, anderzijds omdat ik snel resultaat wil. Wijzigingen in de vars worden dus door middel van het fail fast principe snel getest.
We hebben weer een overeenkomst te pakken, mijn workflow voor grote wijzigingen of nieuwe roles is ook dat ik dit op mijn laptop ontwikkel en (uiteindelijk) ga uittesten op de omgeving. Met molecule heb ik daar nog een test resource bij die ik eerder kan gebruiken. De --diff parameter is daarbij heel handig om direct bij converge te zien wat je output is (bijv. de output van een template task).
extensions/molecule/config.yml
1
2
3
4
5
6
7
8
9
10
| --- ansible: executor: args: ansible_playbook: - --diff - --force-handlers - --inventory=${MOLECULE_SCENARIO_DIRECTORY}/../inventory.yml env: [.snip.] |
Los van jouw beperking in zichtvermogen vind ik het zelf ook prettig om met kleine overzichtelijke eenheden te werken. Dus ik wil ook toewerken naar een config file per role.Tegelijkertijd heb ik ook mijn vars voor een heel groot gedeelte opgesplitst per role. Simpelweg omdat ik veel liever met veel kleine bestanden werk dan met 1 grote. Want...
Ik ben dus bijna verplicht om veel kleine bestanden te gebruiken. Sterker nog, van Traefik heb ik zelfs twee vars bestanden in mijn group_vars, één met de configuratie en de andere met de dynamische reverse proxy configuratie. In mijn group_vars heb ik daarbij de variabelen die nodig zijn voor het geheel, dus domeinnaam, middleware configuratie, ingress netwerk, etc. En in de host_vars staan alleen variabelen die nodig zijn voor die host.
Ik zou daar wat meer op willen in zoomen, want in jouw screenshot staan variabelen die bedoeld zijn voor de role beszel en in de tree explorer staat er een voor de role adguard_home.
Ik had die op group_vars niveau verwacht.
Ik heb het nu zo ingericht:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| production ├── group_vars │ ├── all │ │ ├── main.yml │ │ ├── secrets.yml │ │ └── vault.yml │ ├── truenas_apps │ │ ├── authentik.yml [..snip..] │ │ └── uptime_kuma.yml │ └── truenas_host │ └── jailmaker.yml ├── host_vars │ ├── docker.yml │ ├── localhost.yml │ └── nas.yml └── inventory.yml |
1
2
3
4
5
6
7
8
9
10
11
12
| truenas_host: hosts: nas: truenas_apps: hosts: docker: truenas_shared: children: truenas_hosts: truenas_apps: |
Ik heb dus een indirectie via een group:
docker (=host, met een IP adres, dit is een jail op de TrueNAS machine) > truenas_apps (=group)
Alle playbooks apply ik op de group, niet op de host.
Als gevolg hiervan heb ik alle role variabelen in de truenas_apps group een eigen file gegeven met de role variabelen.
In host_vars staan echt alleen host specifieke variabelen:
inventory/production/host_vars/nas.yml:
1
2
3
4
5
| ansible_host: [..] ansible_user: [..] ansible_password: "{{ secrets.truenas_admin_password }}" ansible_become_password: "{{ secrets.truenas_admin_password }}" ansible_ssh_common_args: '[ jump host ]' |
Daarnaast vraag ik me af, ik heb compose stacks die ik 2x uitrol, dat zijn nu twee roles, maar die wil/kan ik generaliseren naar één role. Bijv. traefik en traefik_external. Die hebben allebei een aparte folder voor het compose project. Ik ontkom er niet aan om de variabele die de folder naam stuurt, in het playbook te specificeren:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| --- - name: Deploy traefik hosts: truenas_apps roles: - role: traefik vars: traefik__stack_name: traefik traefik__external: false - role: traefik vars: traefik__stack_name: traefik-external traefik__external: true [ andere variabelen die anders zijn, zoals poorten, labels ... ] |
Met 'het playbook' bedoel je jouw meta playbooks/all.yml en dat gebruik je op jouw lokale machine?Bij een check (en deployment, want dat is bij mij hetzelfde) doe ik sowieso een deploy van het playbook. In sommige gevallen de applicatie zelf, maar in andere gevallen de complete stack. Dat is een beetje afhankelijk van de applicatie en wat ik prettig vind. Ik heb dan wat Shields in mijn README die ik kan checken wat de status is en eventueel Gatus voor status. Het feest gaat sowieso niet door bij een probleem in het playbook, inclusief validatie problemen.
Of heb je hier ook een check/deploy workflow voor in CI?
Want wanneer je klaar bent met lokaal ontwikkelen wil je wel de lint, test, check en deploy ook uitvoeren en testen of je checkin compleet is. Hoe maak je dan het onderscheid tussen de overige deploy workflows die voor Renovate gebruikt worden?
Wat bedoel je met een versie upgrade? Bedoel je hiermee dependencies zoals ansible-core, python, collections en external-roles?Ook Renovate rolt het hele playbook uit bij een versie upgrade, maar altijd in check mode in de PR. Als een check mode niet slaagt wordt het PR niet gemerged. Klaar, uit. Ik vind dat veilig genoeg.
Ik zie de volgende stromen aan changes in mijn repo voorbij komen:
- Docker image upgrades, getriggerd door Renovate, onderdeel van een role.
- Package updates (docker-ce, apt packages, dat soort dingen), getriggerd door Renovate, onderdeel van een (externe) role.
- Core updates (ansible-core, python, roles, collections), onderdeel van mijn execution environment, getriggerd door Renovate vanuit mijn andere repo.
- Development updates (pre-commit, ansible-lint, renovate-cli, ...), getriggerd door Renovate, onderdeel van andere files in mijn repo (pre-commit-config.yml, etc.).
- Renovate reconfigure
- Workflow aanpassingen
- Feature/Fix PR's, getriggerd door mijzelf, aanpassingen in al het bovenstaande mogelijk.
Flow 1 heb ik nu met de deploy-<role>.yml workflows wel goed ingericht, maar de overige flows wil ik nog kijken of ik dat wat strakker kan inrichten.
Ik de laatste tijd eigenlijk ook niet, maar ik kom van Semaphore UI, daarna Woodpecker CI en nu Github Actions. Ik heb de afgelopen tijd wel e.e.a. aan wijzigingen doorgevoerd om sneller feedback te krijgen door meer te linten en testen. Ik ben afgestapt van Semaphore UI vanwege de inflexibiliteit van de run omgeving (de container waar je playbook draait) en de keuzes die ik toen had gemaakt (bitwarden integratie) wat heel lastig op te zetten was. Woodpecker CI was daar al wat beter in, maar toen ging ik ook Github Actions gebruiken en dan is de wisselwerking niet te doen (bijv. check mode afhankelijk van een job test). Daarom helemaal over naar Github Actions. Tot nu toe gaat dat goed, maar de job moet niet te groot zijn. Ik heb de eerste 'out of disk space' al gehad bij een Molecule test met alle scenario's.Eigenlijk heb ik de afgelopen jaar of jaren nog geen een echte probleem deployment gehad.
Ik gebruik nu dus Github Actions, deels de Github runners en deels lokaal. Als ik een grote refactoring doe, kom ik makkelijk aan de 2000 minuten/maand (=limiet). Ik heb vorige maand ook 900 jobs gedraaid, 1600min en dan doe ik niks geks.
Mijn initial commit van deze repo was Dec 2024. Ik ben ergens in Jun 2024 met Ansible gestart, dat was om Pi-Hole in een HA cluster te draaien. Mijn job is wel in de IT maar als software engineer, dus ik doe dit puur voor de hobby.
Is het al tijd voor een 'Ansible Automation' topic
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Yes. En ik krijg inzicht in hoe jij het doetblackd schreef op woensdag 18 maart 2026 @ 10:29:
Met mijn vragen probeer ik te ondekken hoe jouw workflow is ingericht.
Primair is misschien niet het juiste woord. Primair is het voor alle deployment, maar als ik iets in mijn vars verander dan test ik dat wel eerst met een deployment vanuit mijn lokale host voordat ik dat vanuit CI uitrol. Aangezien een CI deploy bij mij altijd wordt uitgevoerd bij een commit naar main, wordt dus de deployment dus altijd idempotent herhaald.Conclusie is volgens mij dat jij jouw deploy-<app>.yml workflows primair hebt bedoeld voor gebruik van Renovate. Check jij hier dan nog op in de workflow, bijv. met een label in de PR? Ik laat Renovate een label plaatsen, daarmee zijn die PR's herkenbaar.
Ik plaats zeker labels
/f/image/8t1hhHfCXP6MTJrY7Jg9RBsL.png?f=fotoalbum_large)
In principe krijgen Renovate PR's altijd de labels CI en maintenance.
Dat heb je misIk vraag me af of mijn indirectie zin heeft of dat het ook simpeler kan. Want zo te zien heb jij alle role variabelen op host_var niveau geplaatst. Klopt dat of heb ik het mis?
De connection parameters zoals ansible_user, ansible_host, etc. heb ik in mijn inventory opgenomen.
In mijn group_vars staan variabelen die voor heel de groep gelden. De meeste van mijn applicaties zijn Docker applicaties dus de meeste van mijn group_vars bevinden zich bij mij in de docker group. Wellicht dat ik dat nog een keer splits. Pak ik dan home_assistant.yml in mijn docker group_vars, dan heb ik daarin bijvoorbeeld het domein en netwerk staan waarin de Home Assistant applicatie zich bevindt.
In de host_vars van mijn primaire host heb ik ook een home_assistant.yml waarin ik o.a. de cpuset configureer Dit is namelijk host afhankelijk. Op de secundaire host heb ik ook een home_assistant.yml waar ik mijn Zigbee en Z-Wave adapter heb ingesteld. Wederom is dit host afhankelijk. Dit zou je ook in een eigen yml kunnen doen.
Ik heb geen rollen die ik twee keer naar dezelfde host uitrol. Als ik dat wel heb, pas ik inderdaad de variabelen van 1 role aan.Daarnaast vraag ik me af, ik heb compose stacks die ik 2x uitrol, dat zijn nu twee roles, maar die wil/kan ik generaliseren naar één role. Bijv. traefik en traefik_external. Die hebben allebei een aparte folder voor het compose project. Ik ontkom er niet aan om de variabele die de folder naam stuurt, in het playbook te specificeren.
Nee, het playbook van de applicatie die ik aan heb gepast. Het all playbook gebruik ik nauwelijks.Met 'het playbook' bedoel je jouw meta playbooks/all.yml en dat gebruik je op jouw lokale machine?
Of heb je hier ook een check/deploy workflow voor in CI?
Niet? Dat is gewoon dezelfde workflow. Ik gebruik wel een pre-commit hook voordat ik alles commit.Want wanneer je klaar bent met lokaal ontwikkelen wil je wel de lint, test, check en deploy ook uitvoeren en testen of je checkin compleet is. Hoe maak je dan het onderscheid tussen de overige deploy workflows die voor Renovate gebruikt worden?
Ook. Maar ik bedoel hiermee de applicatie uit Docker Compose.Wat bedoel je met een versie upgrade? Bedoel je hiermee dependencies zoals ansible-core, python, collections en external-roles?
Ik zie dat toch net anders. Ik heb 1 flow per Compose applicatie of stack. Op het moment dat er een stack aangepast wordt, wordt deze in check mode uitgevoerd en uiteindelijk deployed. Alle andere tooling die daaronder zit komt automatisch mee en wil ik dus niet apart testen. Met andere woorden: dat geloof ik wel. Omdat ik toch fail fast gebruik zie ik problemen snel genoeg.Eigenlijk wil je per flow van werk een goede CI inrichten om het te testen en waar nodig deployen.
En mocht er toch een onderdeel problemen geven, dan wordt de applicatie niet deployed. Enerzijds omdat waarschijnlijk eerder in het proces het probleem al ontstaat, anderzijds omdat de check mode dan sowieso faalt en het PR niet wordt gemerged.
Ook wil ik alles zsm deployen, wederom vanwege4 fail fast, maar ook omdat Ansible idempotent hoort te zijn. Zijn er dus constant changes, dan gaat er waarschijnlijk iets anders mis.
Eerder iets over CI / homelab / selfhostingIs het al tijd voor een 'Ansible Automation' topic.
Ik denk dat ik dit alles even moet laten bezinken en verder moet gaan met de playbooks gaan opknippen met de juiste path mapping en de juiste roles applyen.
Want het risico wat ik zie met opknippen en niet het main.yml playbook te gebruiken is dat je iets mist met je checkins en niet uitrolt, zodat je omgeving niet (compleet) in de desired state is. Maar misschien is dat een gevoel wat nu ontstaat door dit opknippen en dat er straks niks meer aan de hand is.
Daarnaast zit ik nog te puzzelen (in mijn hoofd) hoe ik bepaalde generieke (externe) rollen goed moet organiseren en laten triggeren door Renovate. Bijv. voor docker gebruik ik geerlingguy.docker en daarmee kan ik de docker-ce version configureren. Dat is nu een group variable, dus dan moet het docker-ce playbook daarop triggeren. Vandaar mijn vragen over host_vars en group_vars.
Al eens naar een merge-queue gekeken? Ik zag dat Github het wel ondersteunt, maar alleen voor betalende klanten of openbare repo's. Voor Forejo staat een feature request open zag ik.alex3305 schreef op zaterdag 14 maart 2026 @ 14:48:
Nu heb ik namelijk regelmatig 3 - 5 Renovate PR's openstaan, terwijl ik voor digests zelfs al alleen branches gebruik![]()
. Dat houdt elkaar ook nog eens op, want elke keer moeten PR's gesynct worden én wordt er dus opnieuw een Ansible-playbook met check mode uitgevoerd om te testen of het geheel nog werkt.
[ Voor 30% gewijzigd door blackd op 18-03-2026 12:49 ]
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Toen ik Ansible gebruikte op grotere omgevingen en met klanten rolde we ook vaak alleen specifieke veranderingen en/of klantapplicaties uit. En dan periodiek alles. Wat mij betreft is dat een prima verhouding, maar dat is natuurlijk een kwestie van smaak. Net zoals met veel aspecten die ik hier neerpen. Het is bijvoorbeeld ook niet verkeerd om klein te beginnen en uit te bouwen. Of een andere opzet dan de mijne te hebben. Ik vind dit fijn, jij misschien niet. Prima, toch? Ik vind het vooral belangrijk om een open blik te houden naar de opzet en mening van anderen. Daar kun je alleen maar van leren
Oh ja. Grappig genoeg heb ik die role dus zelf gebouwd en is die vrijwel gelijk aan die van geerlingguyDaarnaast zit ik nog te puzzelen (in mijn hoofd) hoe ik bepaalde generieke (externe) rollen goed moet organiseren en laten triggeren door Renovate. Bijv. voor docker gebruik ik geerlingguy.docker en daarmee kan ik de docker-ce version configureren. Dat is nu een group variable, dus dan moet het docker-ce playbook daarop triggeren. Vandaar mijn vragen over host_vars en group_vars.
Goed idee, maar ik gebruik bijna geen GitHub. En aangezien het dus nog niet in Forgejo zit, gebruik ik het sowieso nietAl eens naar een merge-queue gekeken? Ik zag dat Github het wel ondersteunt, maar alleen voor betalende klanten of openbare repo's. Voor Forejo staat een feature request open zag ik.
Wat dat betreft is zo ongeveer het enige wat ik nog echt mis is een mailserver. Laatst wel naar Docker mailserver gekeken, maar ik wilde het eigenlijk achter Traefik hebben en dat ging niet. Misschien dat ik binnenkort nog eens een poging waag.
Periodiek het hele playbook runnen zou een goed compromis zijn.alex3305 schreef op woensdag 18 maart 2026 @ 16:44:
Toen ik Ansible gebruikte op grotere omgevingen en met klanten rolde we ook vaak alleen specifieke veranderingen en/of klantapplicaties uit. En dan periodiek alles. Wat mij betreft is dat een prima verhouding, maar dat is natuurlijk een kwestie van smaak. Net zoals met veel aspecten die ik hier neerpen. Het is bijvoorbeeld ook niet verkeerd om klein te beginnen en uit te bouwen. Of een andere opzet dan de mijne te hebben.
Ik zag ergens anders dat jij periodiek een release doet van je codebase.
Op dit moment doe ik een nightly release en dan apply ik de gehele omgeving. Dat zou ik nog steeds kunnen doen, maar misschien wat minder vaak (wekelijks bijv.).
Helemaal eens, daarom geef ik ook aan dat het misschien bij mij nog een kwestie van gewenning is.Ik vind dit fijn, jij misschien niet. Prima, toch? Ik vind het vooral belangrijk om een open blik te houden naar de opzet en mening van anderen. Daar kun je alleen maar van leren.
Mijn repo is aan het groeien, ik loop al langer met de gedachtes om e.e.a. sneller te maken. Maar hoe, dat wist ik niet. Jouw aanpak met deploy per role lijkt tot nu toe een mooie oplossing en ik heb de grootste wijzigingen in mijn playbook al doorgevoerd.
Daarnaast heb ik tot nu toe bijna alles zelf geleerd wat betreft Ansible, deze discussies voeren versnelt het leerproces, dus dat vind ik erg tof!
Hele goede suggestie, ik was al die richting op aan het bewegen. Ik heb al een group 'pkg_docker' met de hosts waarop docker draait dus een group_vars/pkg_docker/docker_version.yml vind ik een mooie, ik moet nog e.e.a. centraliseren maar de workflow voelt zo heel logisch:Oh ja. Grappig genoeg heb ik die role dus zelf gebouwd en is die vrijwel gelijk aan die van geerlingguy. Dat soort dingen zou ik in een 'group_vars/docker/all.yml' zetten en daarop laten triggeren. Of wellicht 'group_vars/docker/version.yml'. Die kun je dan direct door Renovate met een yaml comment laten bijhouden. Zo'n extra file voelt misschien gaar, maar tegelijkertijd is het wel heel erg duidelijk. Immers heb ik ook een python-version bestand in mijn repo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| name: Docker-ce on: push: branches: - main paths: - 'inventories/production/group_vars/*/docker_version.yml' pull_request: types: - opened - synchronize - reopened paths: - 'inventories/production/group_vars/*/docker_version.yml' |
Het ging mij meer om het principe van een merge queue, misschien is het ook wel op een andere manier te bereiken, weet ik niet.Goed idee, maar ik gebruik bijna geen GitHub. En aangezien het dus nog niet in Forgejo zit, gebruik ik het sowieso niet. Ik heb er enorm veel schik in om alles zelf te hosten. Dat probeer ik dus zover als het kan. GitHub is prima, maar ik vind bijv. Copilot enorm ruk. Ook omdat ik niet alles in de cloud wil hebben...
Ik vind self-hosting ook heel gaaf, maar kies er wel voor bepaalde zaken bewust buiten de deur te houden.
Mijn resources op mijn server zijn beperkt (TrueNAS Scale draait op een HP Microserver Gen10 met 16GB ram en dat laatste is een behoorlijke bottleneck).
Daarentegen is GitHub niet mijn favoriete plek om mijn broncode op te slaan. Ik had al een GitHub account ver voor de overname van Microsoft. Liever gebruik ik een EU privacyvriendelijk alternatief. Self-hosting vind ik nog wat spannend: als mijn server of docker host down is, kan ik ook niet meer bij de broncode. Het omgekeerde is natuurlijk ook waar als GitHub besluit mijn account te closen
Maar wat me ook nog tegenhoudt is dat ik bij Woodpecker CI (wat draaide op mijn docker host) een kip-ei probleem had. Als het Playbook mijn docker-ce package ging upgraden, stopte Woodpecker CI dus ook en hield mijn Playbook ermee op. Mijn GitHub Local Runner draait op een eigen Container op mijn TrueNAS. Dan zou ik een extra Container oid moeten hebben met een git server.
Hoe doe heb jij dat ingericht?
Persoonlijk ga ik daar niet (meer) aan beginnen en is e-mail een goed voorbeeld waarvoor ik liever een privacyvriendelijk, EU-hosted alternatief zoek en daar graag voor betaal. In een ver verleden MDaemon op Windows gedraaid maar tegenwoordig pas ik daarvoor.Wat dat betreft is zo ongeveer het enige wat ik nog echt mis is een mailserver. Laatst wel naar Docker mailserver gekeken, maar ik wilde het eigenlijk achter Traefik hebben en dat ging niet. Misschien dat ik binnenkort nog eens een poging waag.
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Yes. Ik doe een weekly release.blackd schreef op woensdag 18 maart 2026 @ 19:50:
[...]
Ik zag ergens anders dat jij periodiek een release doet van je codebase.
Op dit moment doe ik een nightly release en dan apply ik de gehele omgeving. Dat zou ik nog steeds kunnen doen, maar misschien wat minder vaak (wekelijks bijv.).
:strip_exif()/f/image/qJ0iNHcXnpmSQKLzlgfwdNaM.png?f=user_large)
Die wordt op zondag / maandag automatisch aangemaakt, of anders op de volgende dag mocht die gemist zijn om de een of andere reden.
Verder zijn mijn release notes niets meer dan een opsomming van commits:
Daarnaast heb ik tot nu toe bijna alles zelf geleerd wat betreft Ansible, deze discussies voeren versnelt het leerproces, dus dat vind ik erg tof!.
Misschien flauw, maar waarom pkg_docker? Een eigenschap van de host is toch docker of containers en niet de package containers? Ik heb ook een group dns (of dns_server) bijvoorbeeld, die zou ik ook AdGuard Home kunnen noemen of pkg_adguardhome of container_adguardhome, maar dat vind ik niet beschrijvend genoeg en misschien ook niet helemaal de waarheid als het dns servers zijn, want het zou ook Pi-Hole kunnen zijn.Hele goede suggestie, ik was al die richting op aan het bewegen. Ik heb al een group 'pkg_docker' met de hosts waarop docker draait dus een group_vars/pkg_docker/docker_version.yml vind ik een mooie.
Wat ik daarmee vooral bedoel te zeggen is dat ik dus een bewust onderscheid maak ik naamgeving en merk in rollen. Immers zijn dat de pakketten die AdGuard Home of Pi-Hole installeren én de functionele groepen in de inventory. Bijvoorbeeld dns of dns_server. Waarbij dns bij mij beschrijvend genoeg is. Omdat alle machines al een dns client hebben en dat dus niet apart benoemd hoeft te worden.
Docker is in mijn geval vergelijkbaar met Luxaflex, wat eigenlijk gewoon lamellen zijn
Ik bedoelde het niet vervelend. Het concept is me bekend en zou prachtig zijn, maar ja, als het er niet in zit kan ik het ook niet gebruikenHet ging mij meer om het principe van een merge queue, misschien is het ook wel op een andere manier te bereiken, weet ik niet.
Ik heb jaren met een J4105 gespeeld en later ook een J1800 in een NAS. Ik weet hoe het is om met beperkte riemen te roeienMijn resources op mijn server zijn beperkt (TrueNAS Scale draait op een HP Microserver Gen10 met 16GB ram en dat laatste is een behoorlijke bottleneck).
Mja same. Ik heb niet zoveel tegen Microsoft, maar ik vind Copilot / AI die mijn code analyseert en daar gratis mee leert geen heel prettig gevoel.Daarentegen is GitHub niet mijn favoriete plek om mijn broncode op te slaan. Ik had al een GitHub account ver voor de overname van Microsoft.
CodebergLiever gebruik ik een EU privacyvriendelijk alternatief.
Dan moet je zorgen dat je server of Docker niet down isSelf-hosting vind ik nog wat spannend: als mijn server of docker host down is, kan ik ook niet meer bij de broncode. Het omgekeerde is natuurlijk ook waar als GitHub besluit mijn account te closen.
Ik maak met Kopia incrementele, versleutelde, de-duplicerende backups van mijn data en daar kan ik, zo heb ik inmiddels geleerd, goed op vertrouwen. Ik maak periodiek ook koude kopieën en de data schrijf ik weg naar een remote server en een Drive. Daarnaast heb ik uiteraard een kopie van mijn Git repo op mijn workstation. Kwijtraken zal mij dus niet bijster snel overkomen. En herstel heb ik al meermaals uitgetest.
Dat is bij mij ook nog een heikel punt. Ik heb daar wel over nagedacht en kwam tot een paar oplossingen:Maar wat me ook nog tegenhoudt is dat ik bij Woodpecker CI (wat draaide op mijn docker host) een kip-ei probleem had. Als het Playbook mijn docker-ce package ging upgraden, stopte Woodpecker CI dus ook en hield mijn Playbook ermee op. Mijn GitHub Local Runner draait op een eigen Container op mijn TrueNAS. Dan zou ik een extra Container oid moeten hebben met een git server.
Hoe doe heb jij dat ingericht?
- Uitvoeren vanaf mijn workstation
- Host A Host B laten updaten en daarna vice-versa
- Tijdelijk een extra container opzetten, de build afbreken, starten in de tijdelijke container en weer weggooien
- Permanent een container laten draaien voor updates
Hier hetzelfde qua release notes.alex3305 schreef op woensdag 18 maart 2026 @ 21:17:
Yes. Ik doe een weekly release.
Verder zijn mijn release notes niets meer dan een opsomming van commits:
Deze release doe ik voornamelijk om bij te kunnen houden waar er iets is gebeurd of eventueel misgaat. In principe zit alles in commit logs, maar ik vind dit mij net wat meer inzicht geven.
Maar doe jij dan ook die periodieke uitrol?
Sorry voor je relaas en ik snap je helemaal, maar ik had al een host genaamd docker en wilde geen name collisions.Misschien flauw, maar waarom pkg_docker?
Dat is best interessant, dat ga ik eens onderzoeken.Ik heb jaren met een J4105 gespeeld en later ook een J1800 in een NAS. Ik weet hoe het is om met beperkte riemen te roeien. Forgejo en Gitea zijn gelukkig heel lichtgewicht. Het kan geen kwaad om een push of pull mirror te hebben. En laat die functionaliteit nou standaard in beide pakketten zitten
. Dan hoef je nog geen CI te gebruiken.
Hier moet ik nog wat mee, dat is ook de reden dat ik geen Immich draai maar een dienst afneem.Ik maak met Kopia incrementele, versleutelde, de-duplicerende backups van mijn data en daar kan ik, zo heb ik inmiddels geleerd, goed op vertrouwen.
Ik zou ook paperless willen draaien, maar dan moet ik wel de backup strategie strak in orde hebben.
Ik had Woodpecker op een gegeven moment uit de playbook gehaald met tags en die update ik vanaf mijn pc. Dat ging goed. Maar docker is een ander verhaal.Dat is bij mij ook nog een heikel punt. Ik heb daar wel over nagedacht en kwam tot een paar oplossingen:De tweede optie is op zichzelf het meest geschikt, maar nu voer ik het periodiek uit vanaf mijn workstation. Forgejo wordt ook niet bijster vaak geügpraded en dat geeft vooralsnog geen problemen.
- Uitvoeren vanaf mijn workstation
- Host A Host B laten updaten en daarna vice-versa
- Tijdelijk een extra container opzetten, de build afbreken, starten in de tijdelijke container en weer weggooien
- Permanent een container laten draaien voor updates
De Github runner update zichzelf. In de container draait verder niet zoveel.
Dus op dit moment houd ik die container buiten schot wat betreft de playbooks.
Misschien is ansible-pull ook nog een alternatief?
Door met een scheduled task op de machine zelf het playbook uit te voeren.
Ik heb het verder nog niet gebruikt, dus misschien sla ik de plank compleet mis.
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Nee, nog niet. Dat is 's nachts en ik doe geen uitrollen 's nachts.blackd schreef op woensdag 18 maart 2026 @ 22:13:
[...]
Hier hetzelfde qua release notes.
Maar doe jij dan ook die periodieke uitrol?
Wederom is dit iets wat ik op mijn lijstje heb staan, maar gewoon nog geen noodzaak voor heb gehad of niet aan ben toegekomen.
Maak je niet drukSorry voor je relaas en ik snap je helemaal, maar ik had al een host genaamd docker en wilde geen name collisions.
Immich en Paperless zijn twee van mijn meest gebruikte dienstenHier moet ik nog wat mee, dat is ook de reden dat ik geen Immich draai maar een dienst afneem.
Ik zou ook paperless willen draaien, maar dan moet ik wel de backup strategie strak in orde hebben.
Ah, dat was even niet binnengekomenMaar docker is een ander verhaal.
Zag ik laatst ook langskomen. Neem ik ook nog even mee. Dit zou mij ook nog helpen voor wat andere zaken waar ik evt. een Ansible task of play wil uitvoeren zonder dat ik direct allemaal rechten hoef toe te kennenMisschien is ansible-pull ook nog een alternatief?
Door met een scheduled task op de machine zelf het playbook uit te voeren.
Ik heb het verder nog niet gebruikt, dus misschien sla ik de plank compleet mis.
Wat misschien nog wel een interessante aanpak is om je playbook in --diff mode te draaien. Hiermee zie je verschillen t.o.v. desired state. Dat in combinatie met --check mode, kun je als het ware controleren in hoeverre je afwijkt van je gewenste configuratie. Dat zou je prima 's nachts kunnen draaien, waarna je 's ochtends een lijstje met afwijkingen kan raadplegen en kijken of er actie nodig is.alex3305 schreef op woensdag 18 maart 2026 @ 22:38:
Dat is 's nachts en ik doe geen uitrollen 's nachts.
Je moet dan alleen wel goed in de smiezen houden of je tasks geen ongewenste changes aanbrengen op het systeem. In een paar van mijn playbooks update ik de apt cache en dat resulteert in een changed state. Je kan dan uren discussieren of dat gewenst is of niet, maar het rapporteert wel zo (tenzij je changed_when opgeeft).
Ik snap je, maar dit ging om een groep van hosts waar docker draait. Eigenlijk dus 'dockerhosts' of 'dockerservers' (analoog aan webservers, dbservers) in het patroon group inventory by function. Ik heb nl. 3 machines waar docker-ce op draait: twee dnsservers en een TrueNAS machine.Inmiddels is het een concept waar ik wat strakker aan vast houd. Het helpt dan ook als ik ergens van dienst wissel.
Maar eigenlijk zou het iets als 'container orchestration' moeten noemen, dan kan dat docker, podman, lxc, k8s, etc. zijn. Maar ja, aan de andere kant kan ik het ook niet zomaar uitwisselen. Mijn roles zijn toegespitst op docker (compose) dus niet eenvoudig uitwisselbaar.
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Ik heb een andere backup strategie, namelijk dat TrueNAS verantwoordelijk is voor het backuppen van de data naar twee online storage providers (ook dat is nog US based en staat nog op mijn lijstje, maar goed, kan niet alles tegelijkalex3305 schreef op woensdag 18 maart 2026 @ 22:38:
Kopia is op zichzelf niet bijster complex om op te zetten of te beheren. Het is ook niet super fancy of zo. Van Docker applicaties neem ik over het algemeen ook gewoon snapshots mee, behalve van databases ivm WAL. Die gooi ik dan in een .kopiaignore. Van de databases maak ik overigens een dump en die neem ik dan wel mee in de backup.
Backup van mijn data op TrueNAS is dus wel geregeld, maar voor mijn docker apps nog niet. Kopia is voor mij niet perse nodig want op zich ben ik tevreden met de replicatie die in TrueNAS is ingebouwd.
Per Docker compose project heb ik grofweg de volgende structuur:
- Een folder waarin het compose project staat waar docker compose up gedaan wordt
- Een folder (met verschillende subfolders) waar alle data leeft, dit splits ik op per compose project per service, dus bijv.
1
2
3
| ..../authentik/redis/data ..../authentik/postgresql/data ..../authentik/server/media |
Maar voor de database, zoals je zelf al schetst, is dat wat uitdagender want dan moet je een db dump hebben en die meenemen in de backup.
Hoe pak jij dit aan?
Een mogelijke aanpak die ik had bedacht is om een backup playbook of task te maken die voor elke postgresql db een dump maakt. Of omgekeerd, eigenlijk zou ik per app een backup task willen hebben en dan voor alle apps de backup task willen runnen.
Veel apps hebben geen database en zijn eenvoudig te backuppen (ZFS snapshot zou voldoende zijn), maar ik heb er een paar met een eigen database. Sommige apps hebben ook een backup / export functie, denk aan de unifi controller. Dus eigenlijk wil ik dat per app afhandelen.
De stappen zijn hier beschreven met gebruik van de postgres_db Ansible module. Dat zou dan voor één app werken, dat wil ik dan doortrekken naar meerdere apps.
Of is dit bij jou onderdeel van een Kopia action?
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Momenteel draai ik vanuit Unraid's crontab een script om een database dump te maken. Bijvoorbeeld:
1
2
3
4
5
| # MariaDB docker exec -i home-assistant-database sh -c 'mariadb-dump --all-databases > /var/lib/mysql/dump.sql' # PostgreSQL docker exec -i paperless-ngx-database sh -c 'PGPASSWORD=$POSTGRES_PASSWORD pg_dumpall --username=$POSTGRES_USER' > /mnt/applications/appdata/paperless-ngx/database.sql |
Eerder in dit topic heeft @Mars Warrior aangegeven dat hij een DB Backup container gebruikt en die richting wilde ik eigenlijk ook op. Echter ben ik de afgelopen week met Ofelia bezig geweest.
Ofelia is een relatief simpele task scheduler die gebruik maakt van Docker labels. Omdat het simpel is kost het ook weinig resources. Tegelijkertijd wil ik ook niet veel functies, behalve taken. Maar bovenstaande wordt dan dus:
1
2
3
4
5
6
| services: mariadb: labels: ofelia.enabled: true ofelia.job-exec.home-assistant-database-dump.schedule: "35 */4 * * *" ofelia.job-exec.home-assistant-database-dump.command: "sh -c 'mariadb-dump --all-databases > /var/lib/mysql/dump.sql'" |
Je draait dan het commando in de container (in dit geval van de mariadb van Home Assistant) en plaatst de database dump dan in een directory die gemount is op het host systeem, waarna Kopia dit oppikt en meeneemt in de backup?
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Excuses, ik besef me nu dat ik daar een klein beetje te summier wasblackd schreef op zaterdag 21 maart 2026 @ 14:56:
Je draait dan het commando in de container (in dit geval van de mariadb van Home Assistant) en plaatst de database dump dan in een directory die gemount is op het host systeem, waarna Kopia dit oppikt en meeneemt in de backup?
Het commando wordt inderdaad uitgevoerd in de Docker container en de dump wordt in dezelfde directory geplaatst als de database files van MariaDB of PostgreSQL. Alhoewel dat normaliter niet helemaal gewenst is, vind ik dat wel het meest praktisch. Een extra mount zou ook nog kunnen als je wat meer scheiding zou wensen.
Ik regel dan met een .kopiaignore dat de raw database bestanden niet meegenomen worden. Bijvoorbeeld bij Home Assistant:
1
2
3
4
5
6
7
| config/*.log config/*.log* config/tmp_core_entity database/* database/** !database/dump.sql |
Weer even gestoeid met mijn execution environment.blackd schreef op zondag 14 december 2025 @ 14:18:
Wat snippets van mijn ansible-ee repo:
execution-environment.ymlYAML:In de additional_build_steps installeer ik:
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: [..]
- 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)
Aanleiding was dat Fedora42 standaard met nodejs22 komt en Renovate config validator nodejs24 prefereert.
Dat laatste heb ik helaas niet helemaal kunnen oplossen zoals ik het wilde.
Mijn nieuwe execution-environment.yml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| --- version: 3 images: base_image: name: ghcr.io/ansible/community-ansible-dev-tools:v26.3.1@sha256:026a44e20b2d66d4192a1cc8d9dbd17a53b58ced4a7b75c01eafbcdf70f6ae98 dependencies: galaxy: requirements.yml python: requirements.txt system: bindep.txt additional_build_files: - src: files/docker-ce.repo dest: configs - src: files/gh-cli.repo dest: configs - src: files/task.repo dest: configs additional_build_steps: prepend_base: - ADD _build/configs/docker-ce.repo /etc/yum.repos.d/docker-ce.repo - ADD _build/configs/gh-cli.repo /etc/yum.repos.d/gh-cli.repo - ADD _build/configs/task.repo /etc/yum.repos.d/task.repo append_final: - RUN npm install --g dclint@3.1.0 - RUN npm install --g @action-validator/core @action-validator/cli --save-dev - RUN dnf clean all && rm -rf /var/cache/dnf - RUN rm -rf /tmp/* /var/tmp/* |
- system: bindep.txt toegevoegd, dit is een lijst met packages die via de package manager geinstalleerd worden. Hiervoor had ik RUN dnf install -y commando's in de append_base stap.
- additional_build_files bevat nu 3 custom repo's voor docker-ce, gh-cli en task. Die laatste was nog lastig, maar uiteindelijk via de juiste URL een config weten te downloaden. Deze files kopieer ik naar de juiste plek in de additional_build_steps.
- append_final hier installeer ik nu twee npm dependencies, via bindep.txt lukte me dat niet dus dan maar zo.
bindep.txt: welke door ansible-builder gebruikt wordt:
1
2
3
| jq [platform:rpm] docker-ce-cli [platform:rpm] gh [platform:rpm] |
Uiteindelijk ervoor gekozen nodejs24 via een feature in devcontainer te installeren:
1
2
3
4
5
6
7
8
9
10
| { [..] "features": { "ghcr.io/devcontainers/features/node:1": { "version": "24.14.0", "nvmVersion": "0.39.5" } }, [..] } |
9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023
Leuk verhaal dat ansible maar een stap te ver voor mij vrees ik.
Wat is de beginners editie hiervan?
Ik zoek 'iets' dat simpeler is dan ansible maar wel beter is dan mijn huidige manier: notepad++ met compose files hier en daar zonder enige versioning of automatisering en af en toe nog een docer run erbij ook als de guide dat voorstelt.
Dat dit niet goed werkt heb ik ondertussen door, maar hoe start ik de weg naar iets beter? Weet dat ik noch Linux guru, noch coder ben maar wel wil leren.
Zit zelf op Windows PC met docker op een Proxmox Host met Docker VM.
- VSCode? na installeren Connect to docker host? Verder helaas option overload dus nog steeds geen idee hoe ik het nu echt zou gebruiken.
EDIT: ok, 'gewoon' SSH naar de docker en je kan rechtstreeks op die machine compose file sbeheren met leuke kleurtjes
- Git? Self-hosted? lab? hub? hoe
Hoe hangt dit allemaal aan elkaar?
[ Voor 6% gewijzigd door witchdoc op 21-04-2026 18:33 ]
Ik heb zowel Dockerfile, docker-compose.yml als de container image zelf in Forgejo (voorheen Gitea) staan (git, container registry en runners ineen). Daarmee heb je versiebeheer van de drie belangrijke onderdelen van Docker. Voor de data heb je meerdere keuzes de meeste van mijn projectjes gebruiken een database of bind volumes die bij allemaal onder de map data staan en dagelijks gebackupped worden naar een externe locatie. Voor Kubernetes/Swarm projecten gebruik ik Rancher voor shared volume of databases of REST api's.witchdoc schreef op dinsdag 21 april 2026 @ 12:32:
ja watte....
Leuk verhaal dat ansible maar een stap te ver voor mij vrees ik.
Wat is de beginners editie hiervan?
Ik zoek 'iets' dat simpeler is dan ansible maar wel beter is dan mijn huidige manier: notepad++ met compose files hier en daar zonder enige versioning of automatisering en af en toe nog een docer run erbij ook als de guide dat voorstelt.
Dat dit niet goed werkt heb ik ondertussen door, maar hoe start ik de weg naar iets beter? Weet dat ik noch Linux guru, noch coder ben maar wel wil leren.
Zit zelf op Windows PC met docker op een Proxmox Host met Docker VM.
- VSCode? na installeren Connect to docker host? Verder helaas option overload dus nog steeds geen idee hoe ik het nu echt zou gebruiken.
- Git? Self-hosted? lab? hub? hoe
Hoe hangt dit allemaal aan elkaar?
Forgejo/Gitea draai ik overigens ook in Docker maar is een aparte VM die in zijn geheel door Proxmox dagelijks gebackupped wordt naar een externe locatie.
Ik ben recentelijk aan mijn Homelab avontuur begonnen (en dus ook nog een redelijke leek, maar met mijn IT achtergrond wel heel snel lerende) en heb daarvoor Unraid draaien, met daarop een container met de app Dockhand.witchdoc schreef op dinsdag 21 april 2026 @ 12:32:
ja watte....
Leuk verhaal dat ansible maar een stap te ver voor mij vrees ik.
Wat is de beginners editie hiervan?
Ik zoek 'iets' dat simpeler is dan ansible maar wel beter is dan mijn huidige manier: notepad++ met compose files hier en daar zonder enige versioning of automatisering en af en toe nog een docer run erbij ook als de guide dat voorstelt.
Dat dit niet goed werkt heb ik ondertussen door, maar hoe start ik de weg naar iets beter? Weet dat ik noch Linux guru, noch coder ben maar wel wil leren.
Zit zelf op Windows PC met docker op een Proxmox Host met Docker VM.
- VSCode? na installeren Connect to docker host? Verder helaas option overload dus nog steeds geen idee hoe ik het nu echt zou gebruiken.
EDIT: ok, 'gewoon' SSH naar de docker en je kan rechtstreeks op die machine compose file sbeheren met leuke kleurtjes
- Git? Self-hosted? lab? hub? hoe
Hoe hangt dit allemaal aan elkaar?
Dit is een container manager waar je heel gemakkelijk al je docker apps kunt beheren. Er zit al een goede compose/env editor in verwerkt, maar deze doet niet aan versiebeheer.
Daarom heb ik Gitea lokaal gehost en deze gekoppeld aan mijn lokaal gehoste Code Server (VS Code) zodat ik nu Code Server gebruik voor het schrijven van m'n yaml/env files, en gitea gebruik voor het bewaren van mijn files en het versiebeheer daarop. Gitea kun je vervolgens weer aan dockhand koppelen zodat je na een commit eventueel automatisch je containers kan laten redeployen.
Dit alles was zelfs voor mij als beginner "relatief" eenvoudig te installeren. Ik heb alles uitgebreid gedocumenteerd (welliswaar in het engels en door AI) maar beschrijft exact alle benodigde stappen en bevat ook mijn deelbare config files. Mocht je interesse hebben dan stuur me maar een DM.
1
| docker run |
Hoe kan ik dat oplossen
script is een simpel python ding in python 3.11-slime image
Als ik docker compose up doe dan zie ik gewoon live alle stdout / stderr output van de container (/software in de container). Note: zonder -d dus, dan draait die op de achtergrond en zie je dus helemaal geen output.divvid schreef op zaterdag 2 mei 2026 @ 12:34:
docker compose vraagje: mijn script geeft output over iteraties. Als ik het run metcode:dan krijg ik direct de output. Als ik docker compose build/up gebruik, dan krijg ik de output pas als alle iteraties klaar zijn (en dat is nou net niet de bedoeling).
1 docker run
Hoe kan ik dat oplossen
script is een simpel python ding in python 3.11-slime image
Ik vind Dockhand ook top, gebruik het nu 3 maanden ofzo denk ik. Gebruik je hierbij dan gevulde .env files? Ik zit nu nog elke keer in een Github private repo te klooien, maar zelfs daar wil ik geen secrets in etc, dus dan moet ik weer met .env.example werken. Misschien moet ik het ook maar gewoon lokaal hosten.Wienen schreef op woensdag 22 april 2026 @ 09:20:
[...]
Ik ben recentelijk aan mijn Homelab avontuur begonnen (en dus ook nog een redelijke leek, maar met mijn IT achtergrond wel heel snel lerende) en heb daarvoor Unraid draaien, met daarop een container met de app Dockhand.
Dit is een container manager waar je heel gemakkelijk al je docker apps kunt beheren. Er zit al een goede compose/env editor in verwerkt, maar deze doet niet aan versiebeheer.
Daarom heb ik Gitea lokaal gehost en deze gekoppeld aan mijn lokaal gehoste Code Server (VS Code) zodat ik nu Code Server gebruik voor het schrijven van m'n yaml/env files, en gitea gebruik voor het bewaren van mijn files en het versiebeheer daarop. Gitea kun je vervolgens weer aan dockhand koppelen zodat je na een commit eventueel automatisch je containers kan laten redeployen.
Dit alles was zelfs voor mij als beginner "relatief" eenvoudig te installeren. Ik heb alles uitgebreid gedocumenteerd (welliswaar in het engels en door AI) maar beschrijft exact alle benodigde stappen en bevat ook mijn deelbare config files. Mocht je interesse hebben dan stuur me maar een DM.
Dat is de reden dat ik voorheen Gitea nu Forgejo lokaal (in docker) heb draaien. Heb je en een git-repo en een docker registry en de mogelijkheid van actions/runners.dehardstyler schreef op zaterdag 2 mei 2026 @ 13:16:
[...]
Ik vind Dockhand ook top, gebruik het nu 3 maanden ofzo denk ik. Gebruik je hierbij dan gevulde .env files? Ik zit nu nog elke keer in een Github private repo te klooien, maar zelfs daar wil ik geen secrets in etc, dus dan moet ik weer met .env.example werken. Misschien moet ik het ook maar gewoon lokaal hosten.
Mijn .env zijn voorzien van alle variabelen en de bijbehorende waardes. Enkel de variabelen van mijn secrets zijn niet voorzien van waardes. Bij het toevoegen van een nieuwe stack importeer ik mijn yaml/env vanuit gitea, dockhand geeft dan aan dat de waardes voor mijn secret variabelen nog handmatig ingevuld moeten worden. Dit doe ik vanuit mijn password manager (zodat ik deze nog wel ergens achter de hand heb) en druk dan op het sleuteltje zodat ze in de vault van Dockhand opgeslagen worden. Vanaf dat moment zijn ze in Dockhand ook niet meer uit te lezen. (vandaar het gebruik van de PW manager)dehardstyler schreef op zaterdag 2 mei 2026 @ 13:16:
[...]
Ik vind Dockhand ook top, gebruik het nu 3 maanden ofzo denk ik. Gebruik je hierbij dan gevulde .env files? Ik zit nu nog elke keer in een Github private repo te klooien, maar zelfs daar wil ik geen secrets in etc, dus dan moet ik weer met .env.example werken. Misschien moet ik het ook maar gewoon lokaal hosten.
Dat is nog mooier indd! Ik ga ef knutselen binnenkort.Wienen schreef op zaterdag 2 mei 2026 @ 14:29:
[...]
Mijn .env zijn voorzien van alle variabelen en de bijbehorende waardes. Enkel de variabelen van mijn secrets zijn niet voorzien van waardes. Bij het toevoegen van een nieuwe stack importeer ik mijn yaml/env vanuit gitea, dockhand geeft dan aan dat de waardes voor mijn secret variabelen nog handmatig ingevuld moeten worden. Dit doe ik vanuit mijn password manager (zodat ik deze nog wel ergens achter de hand heb) en druk dan op het sleuteltje zodat ze in de vault van Dockhand opgeslagen worden. Vanaf dat moment zijn in Dockhand ook niet meer uit te lezen. (vandaag het gebruik van de PW manager)
Inmiddels opgelost. Niet zozeer een docker dingetje, maar een python dingetje. Blijkbaar buffert python de output in non-shell envs.
In de yaml file moet je
1
2
| environment:
- PYTHONUNBUFFERED=1 |
typisch zo'n dingetje waar je een paar uur op stuk bijt. (google was ook niet erg behulpzaam)
[ Voor 47% gewijzigd door divvid op 03-05-2026 15:31 ]
Tuurlijk. Die gaat 'per ongeluk' toegang tot een .env file oid vragen
Oftewel: duizenden onnodige Alerts...
Werd dus tijd voor een aangepaste profiles.yaml...
1
2
3
4
5
6
7
| name: force_vpatch_ban filters: - Alert.GetScenario() == "crowdsecurity/appsec-vpatch" decisions: - type: ban duration: 4h on_success: break |
En hoppa, weg met die idiote onnodige rode Alert blokken
/f/image/NNOCTZqM82VuWnKIIQWODVae.png?f=fotoalbum_large)
Nu blijf ik waarschijnlijk ook weer netjes binnen de 500 alerts per maand voor het gratis account
Verder ga ik nog wat experimenteren met mTLS. Sommige apps ondersteunen dit, dus zou ik nog wat minder alerts binnenkrijgen omdat zo'n bot al helemaal geen verbinding meer kan opbouwen…
Moet wel zeggen dat adoptie traag is. Bitwarden doet er al een jaar over om het in de iOS-app te bouwen, laat staan in de Windows-app. Moeilijk hoor die paar regels code om een certificaat mee te geven. Echt heel moeilijk, en het past elke keer net niet binnen het release window
Self-hosting heeft natuurlijk niet zo veel prioriteit als de eigen stack.
Material 3 Thema's | Swiss Army Knife card | Flex Horseshoe Card
Ik ben nu al een kleine week aan het proberen om een L2 ipvlan aan te maken om een aantal containers binnen een VLAN te beheren, maar dit wil maar niet lukken.
Ik heb de ipvlan aangemaakt met volgend command:
[code]
docker network create -d ipvlan \
--subnet=192.168.X.0/24 \
--gateway=192.168.X.1 \
-o parent=enp5s0.4 \
br0.4
[/code]
Volgende werd in de docker compose file geplaatst per container:
[code]services:
test:
image: test
container_name: test
networks:
br0.4:
ipv4_address: "192.168.X.3"
ports:
- 7878:7878
restart: unless-stopped
networks:
br0.4:
external: true
name: br0.4[/code]
De port van de container staat gedefinieerd in deze file, maar bij het testen heb ik dit weggelaten in de docker compose.
Als ik vanaf mijn laptop de web interface van de containers probeer te bereiken, dan krijg ik een foutmelding dat de pagina niet kan bereikt worden.
Als ik ping vanaf de VLAN van de laptop of vanaf de opnsense firewall naar een IP binnen de IPvlan, dan krijg ik geen reply.
Als ik een trace laat lopen vanaf de VLAN van de laptop of vanaf de firewall naar een IP binnen de IPvlan, dan krijg ik een reply tot en met de fysieke docker host. Maar vanaf dan krijg ik geen reply.
Als ik ping vanuit de docker containers naar de default gateway, dan krijg ik geen reply. Als ik ping vanaf de container naar andere containers binnen de IPvlan, dan lukt dit wel. Pingen naar de docker host lukt dan weer niet, maar dit is normaal gedrag volgens de documentatie van Docker.
Wat heb ik tot nu toe allemaal geprobeerd:
- promiscuous mode ingeschakeld op zowel de docker host als de VLAN interface op de opnsense firewall,
- als test een static route aangemaakt op zowel de docker host, docker container als op de opnsense firewall
- port forwarding op de docker host ingeschakeld
- de poort van de switch waar de fysieke docker host mee is verbonden aangepast naar een trunk port.
- Als test een macvlan netwerk aangemaakt, maar daar hetzelfde probleem
- Als test een L3 IPvlan aangemaakt met een static route en dat lukt wel. Maar dan loopt al het verkeer binnen de VLAN van de docker host en niet op de VLAN van de containers.
In principe zou het moeten lukken volgens de Docker documentatie en volgens Claude, maar toch wil het maar niet werken. Ik heb tevens nog eens alles overlopen met Claude, maar daar draaien we ondertussen ook rondjes.
Iemand die me op weg kan helpen om dit probleem op te lossen? Ik zie even door de bomen het bos niet.
Ga ik toch kijken of ik binnenkort Docker Desktop onder Windows kan uit faseren en over te stappen naar iets anders, of gewoon plat WSL2. Maar blijf het spannend vinden om "opnieuw" te beginnen. Plat een backup maken lijkt niet mogelijk te zijn zodat ik die weer terug kan zetten in een nieuwe omgeving. Heb hier echt al tig keer naar gezocht. Maar eerlijk is eerlijk, zoveel dingen draai ik nog niet welke of een backup nodig hebben of eigenlijk wel met een eigen backup deels teruggezet kunnen worden.
Veel is nog in de teststadium, maar het voelt moeilijk om gewoon te zeggen dat ik genoeg in een backup heb zitten en Docker Desktop deinstalleer en dan of iets nieuws, of gewoon Portainer onder WSL2 docker draai.
Ja, ik ben een twijfelaar en altijd geweest.
Wil je dezelfde hardware blijven gebruiken of ga je er iets langs opbouwen? Als je er nieuwe hardware langs gaat plaatsen is het helemaal makkelijk, dan kun je eenvoudig je compose/env files en bijbehorende data overzetten en alles draait probleemloos verder. Ik ben op dezelfde hardware om gegaan en heb mijn Windows installatie omgezet naar een VM welke ik vervolgens weer binnen Unraid gemount heb om zo alles makkelijker over te kunnen zetten en altijd nog iets had om op terug te vallen.
Ik blijf gewoon bij Windows omdat ik er ook andere dingen bij heb. Ik wil Docker Desktop weg hebben omdat ik ondertussen wel weet dat er weinig extra bij komt kijken en ik heb het idee dat DD steeds meer verbruikt terwijl er eigenlijk weinig bij is gekomen.Wienen schreef op maandag 15 juni 2026 @ 16:12:
Ik ben een paar maanden geleden geswitcht van Windows (met docker desktop) naar Unraid. Dit is allemaal probleemloos verlopen. Het kost wel wat tijd, en Unraid/Linux was nieuw voor me maar met een beetje IT kennis/afiniteit kom je een heel eind!
Wil je dezelfde hardware blijven gebruiken of ga je er iets langs opbouwen? Als je er nieuwe hardware langs gaat plaatsen is het helemaal makkelijk, dan kun je eenvoudig je compose/env files en bijbehorende data overzetten en alles draait probleemloos verder. Ik ben op dezelfde hardware om gegaan en heb mijn Windows installatie omgezet naar een VM welke ik vervolgens weer binnen Unraid gemount heb om zo alles makkelijker over te kunnen zetten en altijd nog iets had om op terug te vallen.
Tuurlijk is een linux variant beter in het opzicht van Docker, maar op dit moment nog geen reden voor mij om over te stappen.
Daarnaast ook gewoon deze hardware nog. Is redelijk zuinig en nog prima voor ons gebruik. Nou ja, mijn gebruik haha.
Zodra docker goed draait en in gebruik is, kan ik altijd kijken naar een upgrade. Maar voor nu qua prijzen niet echt nuttig om die stap te maken.
/edit:
Ik heb nu net Docker Desktop verwijderd... Here goes nothing!
Verwijderen van DD zorgt ook voor het verwijderen van de VM met Docker erin. Ging er niet vanuit, maar had wel een backup van wat ik echt met alles erbij terug wilde hebben.
[ Voor 10% gewijzigd door Arunia op 16-06-2026 11:18 ]
Voor het andere deel heb ik een Windows VM opgetuigd binnen Unraid zodat ik daar altijd nog op terug kan vallen.
Succes met je migratie 💪🏻
Qua installeren met tutorials is het niet heel erg makkelijk.
Enige wat ik zoek is WSL2, Docker en Docker-Compose met dezelfde uitkomst als middels Docker Desktop.
Alleen om één of andere reden loop je toch tegen vage problemen aan.
Docker hello-world doet het in ieder geval. Alleen nu Portainer dan nog wat ik dan het liefste via docker-compose doe, maar wellicht moet ik daar gewoon vanaf stappen.
Zodra portainer erop staat, kan ik kijken of ik daar bij kom en of het naar buiten toe in het netwerk zelf ook werkt.
Enige voordeel is dat DD dit wel automagisch doet voor je. Genoeg mensen die het zonder DD willen, maar om één of andere reden is iedere uitleg weer anders. Wellicht toch dat iedereen het anders doet.
Maar, het lijkt erop dat Portainer nu wel geinstalleerd is. Volgende stap is automatisch laten starten bij een herstart van Windows. Zelfde probleem met Docker Desktop, maar ook dat is opgelost. Startte hiervoor eerst Windows en dan een batch bestand welke Windows weer locked. >_>
[ Voor 13% gewijzigd door Arunia op 16-06-2026 17:19 ]
Op het werk heeft men een server bijeengesprokkeld. Die is dus gratis vanuit de boekhouding gezien, maar heeft wel een 24 core Xeon, 256GB RAM, en over het 10/40GBit netwerk SSD storage
Dus dat is geregeld. Nu ging het tig maanden geleden over het inrichten van deze server. Hij draait op Proxmox + PBS. Ik ga daar 2 VMs maken:
- een VM voor GitOps
- een VM voor productie
Ik neig nu sterk naar:
- Forgejo + runner
- Renovate
- Portainer BE (gratis voor 3 nodes) met Edge Agent op de productie node. Die kan vanuit Git een compose file met alles wat daarbij hoort halen en deployen. Klaar
- Mogelijk wat extra's per container om wat scripting en testen uit te voeren in plaats van de standaard image entry, en die dan aanroepen. Ben ik van alles af. Ook geen gezeur meer met depends_on bij reboot van server.
Erbij:
Als ik meer controle wil hebben is Komodo ook een perfect alternatief. Die kan het bouwen van eigen containers en backuppen van databases ook overnemen. Is dat ook meteen verzorgd en hoef ik ook daar verder niks extra's voor te regelen.
Komodo kan ook met SOPS werken zodat alle .env files ook on the fly tijdens deployment gedecrypt worden. Een VScode plugin doet dat ook met decrypt/encrypt, dus dan kunnen er ook geen wachtwoorden en andere sleutels in git/forgejo komen.
Rathole zou ik dan daarbij als container kunnen gebruiken om een tunnel / bridge op te zetten, zodat ik nog zelf wel lekker met SSH en een browser (socks5) overal bij kan komen, zonder dat poort 22 open moet staan. Daar houden ze niet zo van...
[ Voor 24% gewijzigd door Mars Warrior op 17-06-2026 09:08 ]
Material 3 Thema's | Swiss Army Knife card | Flex Horseshoe Card
Rustdesk en Mealie geinstalleerd waarbij er wel melding gegeven wordt dat de verbinding actief is, maar toch niet helemaal lekker werkt.
Mealie lijkt ook niet helemaal te werken. Container draait, maar daar kom ik dan weer niet bij. Aparte is dan weer dat bij mijn vorige niet Stack variant er 2 poorten open stonden en bij deze dat niet zo is. Maar goed, basis is gelegd. De rest komen we ook wel uit natuurlijk.
Ik wil graag met je meedenken, maar dan zul je toch wel met iets meer info moeten komen. Wellicht enkel ter info bedoeldArunia schreef op woensdag 17 juni 2026 @ 16:25:
Vandaag Docker Engine in WSL2 draaiend waarbij ik Portainer op andere clients aan kan spreken.
Rustdesk en Mealie geinstalleerd waarbij er wel melding gegeven wordt dat de verbinding actief is, maar toch niet helemaal lekker werkt.
Mealie lijkt ook niet helemaal te werken. Container draait, maar daar kom ik dan weer niet bij. Aparte is dan weer dat bij mijn vorige niet Stack variant er 2 poorten open stonden en bij deze dat niet zo is. Maar goed, basis is gelegd. De rest komen we ook wel uit natuurlijk.
Haha, soms post ik gewoon inderdaad ter info. Dat niet altijd alles van een leien dakje gaat.Wienen schreef op woensdag 17 juni 2026 @ 18:47:
[...]
Ik wil graag met je meedenken, maar dan zul je toch wel met iets meer info moeten komen. Wellicht enkel ter info bedoeld
Maar het lijkt nu wel te werken, ook na een Windows herstart komt bijvoorbeeld Portainer weer op. Dus, Mijn WSL2 start automatisch en daarin Docker ook. Kostte wat moeite om de juiste uitleg te vinden.
Nu nog wat dingen fixen en het liefste had ik eigenlijk bepaalde mappen op Windows beschikbaar gehad, maar het is wat het is. Denk ook gewoon gewenning. Ik weet hoe het werkt en kan straks ook bepaalde media mappen beschikbaar maken.
Windows mappen zijn toch in WSL2 beschikbaar onder /c/..........?Arunia schreef op donderdag 18 juni 2026 @ 09:33:
[...]
Haha, soms post ik gewoon inderdaad ter info. Dat niet altijd alles van een leien dakje gaat.
Maar het lijkt nu wel te werken, ook na een Windows herstart komt bijvoorbeeld Portainer weer op. Dus, Mijn WSL2 start automatisch en daarin Docker ook. Kostte wat moeite om de juiste uitleg te vinden.
Nu nog wat dingen fixen en het liefste had ik eigenlijk bepaalde mappen op Windows beschikbaar gehad, maar het is wat het is. Denk ook gewoon gewenning. Ik weet hoe het werkt en kan straks ook bepaalde media mappen beschikbaar maken.
Klopt volgens mij wel. Kwam er andersom wel achter dat in verkenner je geen rechten hebt.synoniem schreef op donderdag 18 juni 2026 @ 17:41:
[...]
Windows mappen zijn toch in WSL2 beschikbaar onder /c/..........?
Daarnaast draait het spul nu wel gelukkig en volgens mij zonder echte problemen. Enige is dat het geheugen gebruik toch nog steeds tegen de 99 procent aan blijft tikken.
Kan zomaar iets anders zijn, maar heb het geheugen gelimiteerd naar 1100MB. Zoveel draait er nog niet.
Je zou zeggen dat 16GB voldoende moet zijn, maar blijkbaar valt dat tegen, terwijl ik best een tijd gewoon geen problemen heb gehad. Anders in deze dure tijden toch maar een upgrade zien te vinden naar 32GB. Moet dan wel de oude vervangen dan omdat ik maar 2 slots heb.
Wat betreft geheugengebruik en performance was het echt een verademing om van Windows over te stappen naar Unraid. Al zal dit voor ieder Linux based OS gelden.
Heb het geheugen ingeperkt en het lijkt rond de 80 procent nu te zitten. Het vage is dat het vroeger geen probleem was en of het nu Windows 10 was of dan nu 11, heb ik geen idee van eigenlijk.
Voor nu de rechten veranderd zodat ik wel op die share kan bewerken, ofwel bestanden kan kopiëren. Dat scheelt weer een stap.
Je kan ook het geheugengebruik per container beperken. Onder linux heb ik dat in de regel niet nodig maar onder Windows schijnt het wel te helpen. Kan overigens ook zijn dat je een container hebt met een geheugenlek waardoor die steeds meer geheugen neemt.Arunia schreef op woensdag 1 juli 2026 @ 19:23:
[...]
Klopt volgens mij wel. Kwam er andersom wel achter dat in verkenner je geen rechten hebt.
Daarnaast draait het spul nu wel gelukkig en volgens mij zonder echte problemen. Enige is dat het geheugen gebruik toch nog steeds tegen de 99 procent aan blijft tikken.
Kan zomaar iets anders zijn, maar heb het geheugen gelimiteerd naar 1100MB. Zoveel draait er nog niet.
Je zou zeggen dat 16GB voldoende moet zijn, maar blijkbaar valt dat tegen, terwijl ik best een tijd gewoon geen problemen heb gehad. Anders in deze dure tijden toch maar een upgrade zien te vinden naar 32GB. Moet dan wel de oude vervangen dan omdat ik maar 2 slots heb.
Op dit moment heb ik het maximum geheugen gebruik op net geen 1100MB staan in .wslconfig.synoniem schreef op vrijdag 3 juli 2026 @ 01:20:
[...]
Je kan ook het geheugengebruik per container beperken. Onder linux heb ik dat in de regel niet nodig maar onder Windows schijnt het wel te helpen. Kan overigens ook zijn dat je een container hebt met een geheugenlek waardoor die steeds meer geheugen neemt.
De kans is zeer groot dat dat nog best veel is, maar dan zou er heel veel geheugen standaard in gebruik zijn. Dat is iets wat ik wel raar vind.
Qua containers heb ik Portainer, Mealie en Rustdesk draaien. Daar komen er nog wel meer bij, maar ik moet even uit zien te vogelen of ik het geheugen gebruik van de containers kan zien. Dit bedenk ik me aan de hand van je bericht natuurlijk, dus nog niet gezocht hierop.
Heb al even gekeken en het lijkt nog ruim onder de 1100MB te zitten. Mealie verbruikt wel verreweg het meeste.
Ben nu Dozzle aan het instellen om zo grafische inzicht te krijgen.
[ Voor 22% gewijzigd door Arunia op 03-07-2026 09:38 ]
Open eens gewoon je taakbeheer binnen Windows en filter daar op geheugen, dan zie je precies wat je grootverbruikers zijn.
In Portainer kun je geheugen gebruik bekijken via de "stats" (statistieken) vzv beschikbaar. Ik heb (o.a.) Dozzle amir20/dozzle:latest draaien waar je het (gemiddeld) geheugengebruik van alle containers gelijk kunt zien - naast dat je meteen de logging vzv beschikbaar kunt bekijken.Arunia schreef op vrijdag 3 juli 2026 @ 08:56:
[...]
Op dit moment heb ik het maximum geheugen gebruik op net geen 1100MB staan in .wslconfig.
De kans is zeer groot dat dat nog best veel is, maar dan zou er heel veel geheugen standaard in gebruik zijn. Dat is iets wat ik wel raar vind.
Qua containers heb ik Portainer, Mealie en Rustdesk draaien. Daar komen er nog wel meer bij, maar ik moet even uit zien te vogelen of ik het geheugen gebruik van de containers kan zien. Dit bedenk ik me aan de hand van je bericht natuurlijk, dus nog niet gezocht hierop.
Heb al even gekeken en het lijkt nog ruim onder de 1100MB te zitten. Mealie verbruikt wel verreweg het meeste.
Ben nu Dozzle aan het instellen om zo grafische inzicht te krijgen.
[Afbeelding]
Opmerkelijk: Op mijn raspberry pi met OMV 7 laat Docker zelf (sudo docker stats) het geheugen gebruik niet zien....
Wienen schreef op vrijdag 3 juli 2026 @ 10:04:
Je kunt in Portainer toch gewoon zien hoeveel geheugen je containers per stuk gebruiken? Ik ben niet bekend met portainer dus weet niet wat er met gemiddeld geheugen bedoeld wordt maar deze zijn al zo laag dat ik me haast niet voor kan stellen dat je containers het probleem zijn van het verhoogde geheugengebruik.
Open eens gewoon je taakbeheer binnen Windows en filter daar op geheugen, dan zie je precies wat je grootverbruikers zijn.
Ik heb hier al eens meer naar gekeken en lijkt ook niet alsof WSL2 en docker het probleem is, maar kom er ook niet achter wat nu precies zoveel verbruikt. Er zijn wat losse programma's die draaien. Deze wil ik langzaamaan verplaatsen naar Docker. Twijfel nog over Plex, maar wellicht die ook.
Crashplan, WSL, Zulu verbruiken wel het meeste. Waarom Edge erbij staat is mij een raadsel. Ja, die heb ik soms open voor uitleg en dergelijke, maar nu was deze afgesloten.
Los van elkaar lijkt het allemaal niet zo heel veel, maar opgeteld loopt het wel hard op denk ik.
Maar met 16GB aan ram zou ik toch wel voldoende moeten hebben. Hiervoor had ik 8GB enkele DIMM en eigenlijk geen problemen. Alles is wel standaard geupdate.
Verkijk je je misschien op wat er voor cache en andere "gebruik geheugen als beschikbaar" taken gebruikt wordt? Ik heb eenzelfde soort actieve taken lijst die niet optelt tot mijn totale geheugengebruik.....Arunia schreef op vrijdag 3 juli 2026 @ 13:33:
[...]
[Afbeelding]
Ik heb hier al eens meer naar gekeken en lijkt ook niet alsof WSL2 en docker het probleem is, maar kom er ook niet achter wat nu precies zoveel verbruikt. Er zijn wat losse programma's die draaien. Deze wil ik langzaamaan verplaatsen naar Docker. Twijfel nog over Plex, maar wellicht die ook.
Crashplan, WSL, Zulu verbruiken wel het meeste. Waarom Edge erbij staat is mij een raadsel. Ja, die heb ik soms open voor uitleg en dergelijke, maar nu was deze afgesloten.
Los van elkaar lijkt het allemaal niet zo heel veel, maar opgeteld loopt het wel hard op denk ik.
Maar met 16GB aan ram zou ik toch wel voldoende moeten hebben. Hiervoor had ik 8GB enkele DIMM en eigenlijk geen problemen. Alles is wel standaard geupdate.
DjoeC schreef op vrijdag 3 juli 2026 @ 13:59:
[...]
Verkijk je je misschien op wat er voor cache en andere "gebruik geheugen als beschikbaar" taken gebruikt wordt? Ik heb eenzelfde soort actieve taken lijst die niet optelt tot mijn totale geheugengebruik.....
[Afbeelding]
Dit heb ik zeg maar. Jij hebt ruim meer geheugen dan dat ik heb en qua in gebruik zitten we op hetzelfde. Alleen ik heb minder totaal geheugen. Ik zou daar toch eens verder induiken. Wellicht dat WSL onderwater toch meer geheugen gebruikt wat Windows niet goed laat zien.
Dat heb ik dus ook. Het is dat de CPU niet zo veel in gebruik is, anders zou ik denken dat ik gehacked ben en er een miner draait op de server. Maar ook daar heb ik al eens naar gezocht.Wienen schreef op vrijdag 3 juli 2026 @ 14:32:
@Arunia jouw processen gebruiken helemaal niet zoveel geheugen, ik kan me ook haast niet voorstellen dat deze bij elkaar opgeteld 95% van je RAM geheugen verbruiken. Ik zit op mijn Windows laptop met 16GB op 85% en heb vele grotere processen/apps draaien die 1,5 tot 2GB per stuk in beslag nemen.
Ik zou daar toch eens verder induiken. Wellicht dat WSL onderwater toch meer geheugen gebruikt wat Windows niet goed laat zien.
Na herstart zit ik vaak wel op 85%, maar dat loopt wel iets op. Blijf het apart vinden, mijn eigen pc staat ook veel lager, maar goed, potato, potato en niet echt te vergelijken. Of ik moet daar dezelfde dingen op draaien.
Sowieso wat ik al zei, vind ik het vreemd dat het een jaar of iets langer geleden niet zo was. Maar ja, wie weet dat het ergens een Windows update is geweest die het verbruik omhoog gooit.
Ik heb er al eens zo'n programma tegenaan gegooid, maar ook die gaf me niet echt de uitkomst.
WSL2 heb ik op max 1100MB gezet qua ram geheugen. Dus meer dan dat zal die niet moeten gebruiken en zo te zien gebeurd dat ook niet echt. Home Assistant verbruikt ook niet zoveel.
Weet niet echt hoe ik het moet troubleshooten eigenlijk. Ik weet dat het gewoon mogelijk moet zijn om ruim lager in verbruik te zitten.
[ Voor 11% gewijzigd door Arunia op 03-07-2026 15:51 ]
Misschien kun je hier iets mee? Je doet iig aan paging, het lijkt alsof je 16GB in je PC hebt met een 16GB paging file. Je hebt meer dan 16GB in gebruik en dus moet Windows ook paging gaan managen. Dan zit je ook nog met alle processen die filehandles hebben openstaan - vermoedelijk veel in R-W en niet read only waardoor ze niet vrijgegeven kunnen worden. En onder Docker zou het me niet verbazen als dat flink grotere aantallen zijn als je de Docker file structuren bekijkt......Arunia schreef op vrijdag 3 juli 2026 @ 15:50:
[...]
Dat heb ik dus ook. Het is dat de CPU niet zo veel in gebruik is, anders zou ik denken dat ik gehacked ben en er een miner draait op de server. Maar ook daar heb ik al eens naar gezocht.
Na herstart zit ik vaak wel op 85%, maar dat loopt wel iets op. Blijf het apart vinden, mijn eigen pc staat ook veel lager, maar goed, potato, potato en niet echt te vergelijken. Of ik moet daar dezelfde dingen op draaien.
Sowieso wat ik al zei, vind ik het vreemd dat het een jaar of iets langer geleden niet zo was. Maar ja, wie weet dat het ergens een Windows update is geweest die het verbruik omhoog gooit.
Ik heb er al eens zo'n programma tegenaan gegooid, maar ook die gaf me niet echt de uitkomst.
WSL2 heb ik op max 1100MB gezet qua ram geheugen. Dus meer dan dat zal die niet moeten gebruiken en zo te zien gebeurd dat ook niet echt. Home Assistant verbruikt ook niet zoveel.
Weet niet echt hoe ik het moet troubleshooten eigenlijk. Ik weet dat het gewoon mogelijk moet zijn om ruim lager in verbruik te zitten.
Maar - dit is zeker niet mijn expertise, ik draai Docker juist onder Linux omdat ik over Linux veel makkelijker inhoudelijke informatie kan vinden (en omdat een Pi met SSD veel minder verbruik heeft bij 24/7), ook daar ben ik geen specialist in.....
O ja, voor de duidelijkheid: Windows pakt al het vrije geheugen voor filecaching en read-ahead. Ook daar zit misschien nog iets om uit te zoeken? Ik denk nu ook aan "uitgestelde writes" - dat kun je uitschakelen dan wordt die ruimte vrij gegeven. Even zoeken waar die optie zit...
Per disk instelbaar: https://help.2brightspark...rror-message-from-windows
[ Voor 9% gewijzigd door DjoeC op 03-07-2026 16:06 ]
Thanks, ik zal daar ook eens in duiken. Uiteindelijk zal ik het wel vinden, dat weet ik zeker en voor nu draait het onder de 99% wat ook scheelt.DjoeC schreef op vrijdag 3 juli 2026 @ 15:58:
[...]
Misschien kun je hier iets mee? Je doet iig aan paging, het lijkt alsof je 16GB in je PC hebt met een 16GB paging file. Je hebt meer dan 16GB in gebruik en dus moet Windows ook paging gaan managen. Dan zit je ook nog met alle processen die filehandles hebben openstaan - vermoedelijk veel in R-W en niet read only waardoor ze niet vrijgegeven kunnen worden. En onder Docker zou het me niet verbazen als dat flink grotere aantallen zijn als je de Docker file structuren bekijkt......
Maar - dit is zeker niet mijn expertise, ik draai Docker juist onder Linux omdat ik over Linux veel makkelijker inhoudelijke informatie kan vinden (en omdat een Pi met SSD veel minder verbruik heeft bij 24/7), ook daar ben ik geen specialist in.....
Maar wil er nog een stuk meer dingen onder draaien en dan voorkomen dat het wel weer tegen zijn max aan loopt.
Kijken of je daar wat kan vinden.
en anders WSL tuning opzoeken.
https://devalice.jaceclub...slconfig--ramcpuswap-caps
Ik ben voor mijzelf ook is kijken, heb 100GB in cached staan dus vind het bij jou weinig...
[ Voor 16% gewijzigd door 3DDude op 03-07-2026 16:04 ]
Be nice, You Assholes :)
Aan Docker hoeft het niet te liggen... Ik draai 20+ containers op een 16GB Raspi 5 met 4TB SSD. Die deden t op een 8GB Pi4 met 2TB sata SSD ook zonder issues.Arunia schreef op vrijdag 3 juli 2026 @ 16:03:
[...]
Thanks, ik zal daar ook eens in duiken. Uiteindelijk zal ik het wel vinden, dat weet ik zeker en voor nu draait het onder de 99% wat ook scheelt.
Maar wil er nog een stuk meer dingen onder draaien en dan voorkomen dat het wel weer tegen zijn max aan loopt.
WSL lijkt toegewezen op 1.118.660KB en werkset is 360KB. Die zou ik omlaag kunnen gooien, maar dan moet ik daar goed op letten dat deze niet vol loopt en ik dat niet door heb.
:strip_exif()/f/image/kVHmYCWIKf4N5A2RFAzm6aUj.png?f=user_large)
Als ik kijk naar harde fouten, dan is dat bij memory compression vooral, maar loopt ook niet op andere vlakken hard omhoog. Maar met het geheugen wat vrij hoog ligt, is het geheugen op dit moment niet echt toereikend.
@DjoeC Ik denk inderdaad dat het ook niet aan WSL2 of Docker ligt.
[ Voor 3% gewijzigd door Arunia op 03-07-2026 16:22 ]
Be nice, You Assholes :)
Ach. Crashplan is in Java geschreven en heeft per TB aan backup weer x GB nodig aan RAM.Wienen schreef op vrijdag 3 juli 2026 @ 19:29:
Ik zou toch eens gaan onderzoeken waar die java.exe vandaan komen
Ik heb slechts 2TB aan backups en de Crashplan docker container gebruikt 22GB RAM
Material 3 Thema's | Swiss Army Knife card | Flex Horseshoe Card
Haha dan hebben we de boosdoener wellicht gevondenMars Warrior schreef op vrijdag 3 juli 2026 @ 20:45:
[...]
Ach. Crashplan is in Java geschreven en heeft per TB aan backup weer x GB nodig aan RAM.
Ik heb slechts 2TB aan backups en de Crashplan docker container gebruikt 22GB RAM
Maar wat is er zo bijzonder aan Crashplan dat je daar aan vast blijft houden als deze zoveel geheugen vreet?
Ik heb m'n backup volledig ingericht met Rustic i.c.m. XyOps voor de backup workflows, en waar Rustic enkel tijdens de backup job even wat geheugen gebruikt draait er verder buiten de job om niks. Werkt als een zonnetje.
@Wienen Zeker. Het is denk ik met de uitleg van @Mars Warrior wel duidelijk wat er precies gebeurd.
Ik heb 16TB in mijn server zitten en nee, niet alles is vol en niet alles wordt gebackupped.
Waarom ik vast blijf houden aan Crashplan is denk ik het gemak en nog niet iets anders gevonden wat simpel werkt eigenlijk. Betaal er ook maandelijks voor en buiten dat het echt takken traag is (opnieuw backup gemaakt na aangevraagd te hebben over te laten zetten naar een datacenter in Ierland en deze 2 maanden bezig is geweest
Maar zal eens kijken of real time naar alleen in de nacht overzetten het op zal lossen. In de nacht maakt het verbruik me sowieso weinig uit.
Gebruik je het voor Windows of voor Linux? Ik gebruik Backblaze Personal met onbeperkte data. De agent werkt alleen onder Windows en dus heb ik wat ingericht om de relevante Linux meuk naar een Windows disk te backuppen. Momenteel > 20TB bij hen staan, in Amsterdam. In 2024 USD 229,- betaald voor 2 jaar (incl BTW). Zal dit jaar wel een paar tientjes meer worden maar ik kan er geen schijf voor kopen. 1e backup duurde wel een dikke week, nu blijft ie op de achtergrond prima bij. Maar, er zijn een paar grotere backup topics hier in het forum.Arunia schreef op zaterdag 4 juli 2026 @ 01:33:
@3DDude Dat sorteren had ik gedaan. Vandaar deze uitkomst. Ook op naam om te zien hoeveel Java.exe onderdelen er voorbij kwamen.
@Wienen Zeker. Het is denk ik met de uitleg van @Mars Warrior wel duidelijk wat er precies gebeurd.
Ik heb 16TB in mijn server zitten en nee, niet alles is vol en niet alles wordt gebackupped.
Waarom ik vast blijf houden aan Crashplan is denk ik het gemak en nog niet iets anders gevonden wat simpel werkt eigenlijk. Betaal er ook maandelijks voor en buiten dat het echt takken traag is (opnieuw backup gemaakt na aangevraagd te hebben over te laten zetten naar een datacenter in Ierland en deze 2 maanden bezig is geweest), werkt het vrij simpel. Voor nu nog geen zin gehad om opnieuw iets uit te zoeken en gaan leren. Daarnaast is het meeste nog duurder per maand. Tja, komt vast nog wel een keer.
Maar zal eens kijken of real time naar alleen in de nacht overzetten het op zal lossen. In de nacht maakt het verbruik me sowieso weinig uit.
Aanvulling: Als je bij Backblaze eem vinkje zet bewaren ze "alle" file versies gedurende 1 jaar. Een aantal files zijn excluded maar mijn backups niet. Die bewaar ik dus een tijdje lokaal, daarna mag BB het voor mij doen. Dat scheelt bij volume backups (Acronis backup van C+D schijf) best een hoop lokale opslag.
[ Voor 8% gewijzigd door DjoeC op 04-07-2026 15:32 ]
De backup topics ken ik inderdaad. Kom er zelf ook om zo nu en dan eens te kijken of er wat nieuws is.DjoeC schreef op zaterdag 4 juli 2026 @ 12:58:
[...]
Gebruik je het voor Windows of voor Linux? Ik gebruik Backblaze Personal met onbeperkte data. De agent werkt alleen onder Windows en dus heb ik wat ingericht om de relevante Linux meuk naar een Windows disk te backuppen. Momenteel > 20TB bij hen staan, in Amsterdam. In 2024 USD 229,- betaald voor 2 jaar (incl BTW). Zal dit jaar wel een paar tientjes meer worden maar ik kan er geen schijf voor kopen. 1e backup duurde wel een dikke week, nu blijft ie op de achtergrond prima bij. Maar, er zijn een paar grotere backup topics hier in het forum.
Qua prijs zit ik nu aan de 13 euro of iets per maand.
Ik gebruik het voor Windows. Dus dat zeker een optie kunnen zijn.
Dat heeft te maken met een stukje historie. Voorheen kon je met CrashPlan gratis naar een andere server back-uppen. Dus een Remote back-up. Dan hebben ze dat uitgesloopt en moest je gaan betalen. Dat was in het begin behoorlijk goedkoop. Ik meen iets van € 60 terwijl ik iets van 10 terabyte had als back-up.Wienen schreef op vrijdag 3 juli 2026 @ 21:26:
[...]
Haha dan hebben we de boosdoener wellicht gevonden![]()
Maar wat is er zo bijzonder aan Crashplan dat je daar aan vast blijft houden als deze zoveel geheugen vreet?
Ik heb m'n backup volledig ingericht met Rustic i.c.m. XyOps voor de backup workflows, en waar Rustic enkel tijdens de backup job even wat geheugen gebruikt draait er verder buiten de job om niks. Werkt als een zonnetje.
Daarna is CP allerlei beperkingen in gaan voeren. En het is inderdaad zo traag als dikke stront. En het kost inderdaad veel ram geheugen. Maar mijn 128 GB ram stamt nog uit de tijd dat je daar € 300 voor betaalde 🫣
Dus ik zit wel naar een alternatief te kijken, maar dat heeft absoluut geen haast.
Material 3 Thema's | Swiss Army Knife card | Flex Horseshoe Card
Hier een deel van mijn compose file met één container als voorbeeld.
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
| networks: vadjnet: driver_opts: com.docker.network.bridge.name: vadjnet ipam: config: - subnet: 172.20.0.0/16 services: swag: image: lscr.io/linuxserver/swag container_name: swag cap_add: - NET_ADMIN # sysctls: # - net.ipv6.conf.all.disable_ipv6=1 environment: - PUID=${PUID} - PGID=${PGID} - TZ=${TZ} - URL=${DUCKDNSURL} - SUBDOMAINS=wildcard - VALIDATION=duckdns # - CERTPROVIDER= #optional # - DNSPLUGIN=cloudflare #optional - DUCKDNSTOKEN=${DUCKDNSTOKEN} # - EMAIL=<e-mail> #optional # - ONLY_SUBDOMAINS=false #optional # - EXTRA_DOMAINS=<extradomains> #optional # - STAGING=false #optional volumes: - ${DATA}/swag/config:/config ports: - 0.0.0.0:443:443 # - 80:80 #optional networks: vadjnet: ipv4_address: 172.20.0.2 # dns: # - 192.168.41.1 restart: unless-stopped |
Het fysieke netwerk bestaat uit een Opnsense router met DNSMasq en Unbound waardoor ik via DHCP IP-adressen uitdeel en de hostname van deze hosts FQDN zijn op het netwerk (bijvoorbeeld desk9800.home.internal).
Het probleem wat ik heb is dat hostnames van hosts op het fysieke netwerk niet op een gebruikelijke manier kunnen worden benaderd vanuit de containers. Wat ik daar mee bedoel is dat een standaard ping vanuit een container naar een host (bijvoorbeeld van de swag container naar desk9800.home.internal) resulteert in:
ping: bad address 'desk9800.home.internal'
Server: 127.0.0.11 Address: 127.0.0.11:53 Non-authoritative answer: Name: desk9800.home.internal Address: 192.168.10.103 ** server can't find desk9800.home.internal: SERVFAIL
Omdat nslookup laat zien dat DNS, ook binnen de container, lijkt te werken ging ik verder zoeken. Uiteindelijk ben ik op het idee gekomen om bij ping de "-4" optie te gebruiken. Hierdoor wordt ping gedwongen ipv4 te gebruiken. Dit resulteert in:
PING desk9800.home.internal (192.168.10.103): 56 data bytes
- "ipv6": false toevoegen aan /etc/docker/daemon.json.
- sysctls:
- net.ipv6.conf.all.disable_ipv6=1
toevoegen aan de desbetreffende container in de compose file.
Prima.
1
2
3
4
5
| networks: vadjnet: ipv4_address: 172.20.0.2 driver: bridge enable_ipv6: false |
Ik zal dat eens proberen. Bedankt.synoniem schreef op maandag 20 juli 2026 @ 23:07:
Je zou dit nog kunnen proberen:YAML:
1 2 3 4 5 networks: vadjnet: ipv4_address: 172.20.0.2 driver: bridge enable_ipv6: false
[edit]
Ik heb het bovenstaande toegevoegd aan het networks-deel:
networks:
vadjnet:
driver_opts:
com.docker.network.bridge.name: vadjnet
driver: bridge
enable_ipv6: false
ipam:
config:
- subnet: 172.20.0.0/16ping: bad address 'desk9800.home.internal'
[ Voor 43% gewijzigd door tikkietrugjaap op 21-07-2026 10:29 ]
Prima.
Start die container eens met: --dns <ip-adres van die dns server>. En probeer dan nog eens.
makes it run like clockwork