Compare commits

..

7 Commits

Author SHA1 Message Date
uumas
c2fd6236fe service: samll improvements 2026-03-28 06:05:37 +02:00
uumas
edb803f3c1 nextcloud: Add support for additional networks 2026-03-28 06:04:48 +02:00
uumas
500bba84b4 windmill: Run worker outside of pinp 2026-03-26 04:11:50 +02:00
uumas
351ef2c5d4 service: Allow additional dependencies for additional containers 2026-03-26 04:06:26 +02:00
uumas
1d180106d6 service: Use saner defaults for additional containers 2026-03-25 19:29:30 +02:00
uumas
9eaa306aa4 lint 2026-03-25 19:28:40 +02:00
uumas
f8e67b12d7 windmill: fix entrypoint script 2026-03-24 19:56:09 +02:00
10 changed files with 179 additions and 76 deletions

View File

@@ -1,3 +1,4 @@
--- ---
nextcloud_tag: stable nextcloud_tag: stable
nextcloud_install_harp: false nextcloud_install_harp: false
nextcloud_additional_networks: []

View File

@@ -22,3 +22,9 @@ argument_specs:
type: bool type: bool
required: false required: false
default: false default: false
nextcloud_additional_networks:
description: Additional docker networks to add nextcloud container to
type: list
elements: str
required: false
default: []

View File

@@ -29,3 +29,4 @@
NEXTCLOUD_ADMIN_PASSWORD_FILE: /run/secrets/admin-password NEXTCLOUD_ADMIN_PASSWORD_FILE: /run/secrets/admin-password
service_additional_containers: "{{ _nextcloud_additional_containers }}" service_additional_containers: "{{ _nextcloud_additional_containers }}"
service_vhost_locations: "{{ _nextcloud_vhost_locations }}" service_vhost_locations: "{{ _nextcloud_vhost_locations }}"
service_container_additional_networks: "{{ nextcloud_additional_networks }}"

View File

@@ -29,7 +29,7 @@ argument_specs:
service_container_http_port: service_container_http_port:
description: description:
- Port inside the container where http requests are proxied to. - Port inside the container where http requests are proxied to.
- If set to 0, http requests are proxied to /run/<service name>.sock inside the container - If set to 0, http requests are proxied to fd:3 inside the container
type: int type: int
required: false required: false
default: 0 default: 0
@@ -340,9 +340,10 @@ argument_specs:
service_additional_containers: service_additional_containers:
description: description:
- List of additional containers for the service. - List of additional containers for the service.
- > - >-
Will inherit most options from main service container. All options can be overridden If image is not specified, will use service container image and
per-container. inherit most options from main service container.
- All options can be overridden per-container.
type: list type: list
required: false required: false
default: [] default: []
@@ -363,26 +364,30 @@ argument_specs:
required: false required: false
default: "{{ service_container_image }}" default: "{{ service_container_image }}"
user: user:
description: The UID to run as inside the container description:
- The UID to run as inside the container.
- Defaults to <service_container_user> if same image, "" otherwise.
type: str type: str
required: false required: false
default: "{{ service_container_user }}"
command: command:
description: Command to start the container with. description:
- Command to start the container with.
- Defaults to <service_container_command> if same image, [] otherwise.
type: list type: list
required: false required: false
default: []
elements: str elements: str
entrypoint: entrypoint:
description: Entrypoint to use in the container description:
- Entrypoint to use in the container
- Defaults to <service_container_entrypoint> if same image, "" otherwise.
type: str type: str
required: false required: false
default: ""
mounts: mounts:
description: List of bind mounts or volumes to be mounted inside the container. description:
- List of bind mounts or volumes to be mounted inside the container.
- Defaults to <service_container_mounts> if same image, [] otherwise.
type: list type: list
required: false required: false
default: "{{ service_container_mounts }}"
elements: dict elements: dict
options: options:
type: type:
@@ -450,10 +455,11 @@ argument_specs:
required: false required: false
default: [] default: []
devices: devices:
description: List of devices to be added inside the container. description:
- List of devices to be added inside the container.
- Defaults to <service_container_devices> if same image, [] otherwise.
type: list type: list
required: false required: false
default: "{{ service_container_devices }}"
elements: dict elements: dict
options: options:
source: source:
@@ -476,7 +482,7 @@ argument_specs:
- Name of the port. - Name of the port.
- >- - >-
If type is socket, the socket will be created at If type is socket, the socket will be created at
/run/<service name>-<additional container name>-<port name>.sock on the host. /run/<service name>-<port name>-socat.sock on the host.
- If type is not socket, this is just informative. - If type is not socket, this is just informative.
type: str type: str
required: true required: true
@@ -506,15 +512,17 @@ argument_specs:
type: int type: int
required: false required: false
env: env:
description: A dict of environment variables for the container description:
- A dict of environment variables for the container
- Defaults to <service_container_env> if same image, {} otherwise.
type: dict type: dict
required: false required: false
default: "{{ service_container_env }}"
add_capabilities: add_capabilities:
description: List of capabilities to add to the container description:
- List of capabilities to add to the container
- Defaults to <service_container_add_capabilities> if same image, [] otherwise.
type: list type: list
required: false required: false
default: "{{ service_container_add_capabilities }}"
elements: str elements: str
secrets: secrets:
description: description:
@@ -525,9 +533,9 @@ argument_specs:
A dict of secrets and their values (including autogenerated values) is available as A dict of secrets and their values (including autogenerated values) is available as
`service_podman_secrets` for use in templates. This should only be used if the `service_podman_secrets` for use in templates. This should only be used if the
container doesn't support reading the secret from file or environment variable. container doesn't support reading the secret from file or environment variable.
- Defaults to <service_container_secrets> if same image, [] otherwise.
type: list type: list
required: false required: false
default: "{{ service_container_secrets }}"
elements: dict elements: dict
options: options:
name: name:
@@ -563,6 +571,23 @@ argument_specs:
the name of the environment variable. Defaults to secret name. the name of the environment variable. Defaults to secret name.
type: str type: str
required: false required: false
requires:
description: >-
List of systemd units this container depends on, in addition to
service-wide requires.
type: list
required: false
default: []
elements: str
wants:
description: >-
List of systemd units this container weakly depends on, in addition to
service-wide wants.
type: list
required: false
default: []
elements: str
service_requires: service_requires:
description: List of systemd units this service container depends on. description: List of systemd units this service container depends on.

View File

@@ -4,19 +4,19 @@
name: container name: container
vars: vars:
container_name: "{{ _service_additional_container.name }}" container_name: "{{ _service_additional_container.name }}"
container_image: "{{ _service_additional_container.image | default(service_container_image) }}" container_image: "{{ _service_additional_container.image }}"
container_command: "{{ _service_additional_container.command | default([]) }}" container_command: "{{ _service_additional_container.command }}"
container_entrypoint: "{{ _service_additional_container.entrypoint | default('') }}" container_entrypoint: "{{ _service_additional_container.entrypoint }}"
container_user: "{{ _service_additional_container.user | default(service_container_user) }}" container_user: "{{ _service_additional_container.user }}"
container_mounts: "{{ _service_additional_container_mounts }}" container_mounts: "{{ _service_additional_container_mounts }}"
container_devices: "{{ _service_additional_container.devices | default(service_container_devices) }}" container_devices: "{{ _service_additional_container.devices }}"
container_publish_ports: "{{ _service_additional_container_publish_ports }}" container_publish_ports: "{{ _service_additional_container_publish_ports }}"
container_networks: "{{ _service_additional_container_networks }}" container_networks: "{{ _service_additional_container_networks }}"
container_hostname: "{{ _service_additional_container.name | regex_replace('^' ~ service_name ~ '-', '') }}" container_hostname: "{{ _service_additional_container.name | regex_replace('^' ~ service_name ~ '-', '') }}"
container_secrets: "{{ _service_additional_container_secrets }}" container_secrets: "{{ _service_additional_container_secrets }}"
container_env: "{{ _service_additional_container.env | default(service_container_env) }}" container_env: "{{ _service_additional_container.env }}"
container_add_capabilities: "{{ _service_additional_container.add_capabilities | default(service_container_add_capabilities) }}" container_add_capabilities: "{{ _service_additional_container.add_capabilities }}"
container_requires: "{{ _service_container_requires }}" container_requires: "{{ _service_additional_container_requires }}"
container_wants: "{{ _service_additional_container_wants }}" container_wants: "{{ _service_additional_container_wants }}"
container_auto_update: "{{ service_auto_update }}" container_auto_update: "{{ service_auto_update }}"
loop: "{{ _service_additional_containers }}" loop: "{{ _service_additional_containers }}"

View File

@@ -8,5 +8,9 @@
container_networks: container_networks:
- name: "{{ service_name }}" - name: "{{ service_name }}"
ip: "{{ service_container_ip | ansible.utils.ipmath(2) if _service_static_ip else '' }}" ip: "{{ service_container_ip | ansible.utils.ipmath(2) if _service_static_ip else '' }}"
container_mounts:
- type: volume
source: redis
destination: /data
container_hostname: redis container_hostname: redis
container_auto_update: "{{ service_auto_update }}" container_auto_update: "{{ service_auto_update }}"

View File

@@ -1,9 +1,72 @@
--- ---
_service_additional_container_defaults:
image: "{{ service_container_image }}"
requires: []
wants: []
_service_additional_containers_with_default_image: >-
{{
([_service_additional_container_defaults] * service_additional_containers | length)
| zip(service_additional_containers)
| map('combine')
}}
_service_additional_container_same_image_defaults:
user: "{{ service_container_user }}"
command: "{{ service_container_command }}"
entrypoint: "{{ service_container_entrypoint }}"
devices: "{{ service_container_devices }}"
env: "{{ service_container_env }}"
add_capabilities: "{{ service_container_add_capabilities }}"
_service_additional_container_different_image_defaults:
user: ""
command: []
entrypoint: ""
mounts: []
devices: []
publish_ports: []
env: {}
add_capabilities: []
secrets: []
_service_additional_same_image_containers: >-
{{
_service_additional_containers_with_default_image
| selectattr('image', '==', service_container_image)
}}
_service_additional_different_image_containers: >-
{{
_service_additional_containers_with_default_image
| selectattr('image', '!=', service_container_image)
}}
_service_additional_containers: >- _service_additional_containers: >-
{{ {{
service_additional_containers (
(
(
[_service_additional_container_same_image_defaults] *
(_service_additional_same_image_containers | length)
)
| zip(_service_additional_same_image_containers)
| map('combine')
) +
(
(
[_service_additional_container_different_image_defaults] *
(_service_additional_different_image_containers | length)
)
| zip(_service_additional_different_image_containers)
| map('combine')
)
)
| zip( | zip(
service_additional_containers (
_service_additional_same_image_containers +
_service_additional_different_image_containers
)
| map(attribute='name') | map(attribute='name')
| map('regex_replace', '^', service_name ~ '-') | map('regex_replace', '^', service_name ~ '-')
| map('community.general.dict_kv', 'name') | map('community.general.dict_kv', 'name')
@@ -11,15 +74,19 @@ _service_additional_containers: >-
| map('combine') | map('combine')
}} }}
_service_additional_container_wants: >- _service_additional_container_wants: >-
{{ {{
service_wants service_wants + _service_additional_container.wants +
+ _service_additional_container_publish_socket_ports _service_additional_container_publish_socket_ports
| map(attribute='name') | map(attribute='name')
| map('regex_replace', '^', service_name ~ '-') | map('regex_replace', '^', service_name ~ '-')
| map('regex_replace', '$', '-socat.socket') | map('regex_replace', '$', '-socat.socket')
}} }}
_service_additional_container_requires: >-
{{ _service_container_requires + _service_additional_container.requires }}
_service_additional_container_networks: >- _service_additional_container_networks: >-
{{ {{
[{ [{

View File

@@ -22,7 +22,12 @@ _service_container_secrets: >-
+ ( + (
[{ [{
'name': _service_database_name ~ '-url', 'name': _service_database_name ~ '-url',
'value': 'postgres://' ~ service_name | replace('-', '_') ~ ':' ~ service_podman_secrets[service_name ~ '-postgres'] ~ '@postgres/' ~ service_name | replace('-', '_') ~ '?sslmode=disable', 'value':
'postgres://'
~ service_name | replace('-', '_')
~ ':' ~ service_podman_secrets[service_name ~ '-postgres']
~ '@postgres/' ~ service_name | replace('-', '_')
~ '?sslmode=disable',
'type': service_database_secret_type, 'type': service_database_secret_type,
'target': service_database_secret_target ~ '-url' 'target': service_database_secret_target ~ '-url'
}] if service_podman_secrets[service_name ~ '-postgres'] is defined else [] }] if service_podman_secrets[service_name ~ '-postgres'] is defined else []

View File

@@ -17,26 +17,46 @@
DATABASE_URL_FILE: /run/secrets/postgres-url DATABASE_URL_FILE: /run/secrets/postgres-url
MODE: server MODE: server
service_additional_containers: service_additional_containers:
- name: worker - name: worker-pinp
image: quay.io/podman/stable:latest image: quay.io/podman/stable:latest
user: podman user: podman
entrypoint: /entrypoint.sh command:
- podman
- system
- service
- --time
- "0"
mounts:
- type: volume
source: worker-pinp-containers
destination: /home/podman/.local/share/containers
- type: volume
source: worker-pinp-tmp
destination: /tmp/storage-run-1000
- type: volume
source: worker-pinp-run
destination: /tmp/storage-run-1000/podman
- name: worker
mounts: mounts:
- type: volume - type: volume
source: worker-logs source: worker-logs
destination: /worker-logs destination: /tmp/windmill/logs
- type: volume - type: volume
source: worker-dependency-cache source: worker-dependency-cache
destination: /worker-dependency-cache destination: /tmp/windmill/cache
- type: template
source: worker_entrypoint.sh.j2
destination: /entrypoint.sh
mode: "0755"
- type: volume - type: volume
source: worker-containers source: worker-pinp-run
destination: /home/podman/.local/share/containers destination: /run/podman
publish_ports: [] readonly: true
env: {} env:
DATABASE_URL_FILE: /run/secrets/postgres-url
DOCKER_HOST: unix:///run/podman/podman.sock
MODE: worker
WORKER_GROUP: default
ENABLE_UNSHARE_PID: "true"
UNSHARE_ISOLATION_FLAGS: "--user --map-root-user --pid --fork"
wants:
- windmill-worker-pinp.service
- name: worker-native - name: worker-native
env: env:
DATABASE_URL_FILE: /run/secrets/postgres-url DATABASE_URL_FILE: /run/secrets/postgres-url

View File

@@ -1,26 +0,0 @@
#!/bin/bash
# {{ ansible_managed }}
_term() {
echo "Received SIGTERM, stopping all containers"
kill "$child"
}
podman system service -t 0 &
podman run \
--rm \
-v /run/secrets/postgres-url:/run/secrets/postgres-url:ro \
-e DATABASE_URL_FILE=/run/secrets/postgres-url \
-e MODE=worker \
-e WORKER_GROUP=default \
-e ENABLE_UNSHARE_PID="true" \
-v /tmp/storage-run-1000/podman/podman.sock:/var/run/docker.sock \
-v /worker-logs:/tmp/windmill/logs \
-v /worker-dependency-cache:/tmp/windmill/cache \
--name worker \
--network host \
ghcr.io/windmill-labs/windmill:main &
child=$!
trap _term SIGTERM
wait $!