diff --git a/roles/authentik/defaults/main.yml b/roles/authentik/defaults/main.yml index 3ff71be..9b2ca9a 100644 --- a/roles/authentik/defaults/main.yml +++ b/roles/authentik/defaults/main.yml @@ -12,11 +12,7 @@ authentik_docker_compose_dir: "{{ docker_compose_base_dir }}/{{ authentik_servic authentik_docker_volume_dir: "{{ docker_volume_base_dir }}/{{ authentik_service_name }}" # Authentik service configuration -# FQDNs the authentik router accepts. The first entry is the canonical -# domain; further entries cover internal *.int.* names used for -# server-to-server traffic so backend calls don't hairpin via DMZ. -authentik_domains: - - "authentik.local.test" +authentik_domain: "authentik.local.test" authentik_image: "ghcr.io/goauthentik/server:2026.2.2" authentik_port: 9000 authentik_secret_key: "changeme-generate-a-random-string" diff --git a/roles/authentik/templates/blueprints/blueprint-login-sources.yaml.j2 b/roles/authentik/templates/blueprints/blueprint-login-sources.yaml.j2 index 8bddb41..acbb635 100644 --- a/roles/authentik/templates/blueprints/blueprint-login-sources.yaml.j2 +++ b/roles/authentik/templates/blueprints/blueprint-login-sources.yaml.j2 @@ -16,10 +16,8 @@ entries: {% for field in authentik_login_user_fields %} - {{ field }} {% endfor %} -{% if authentik_login_sources %} # OAuth/social login sources (use !Find to reference sources from other blueprints) sources: {% for src in authentik_login_sources %} - !Find [authentik_sources_oauth.oauthsource, [slug, {{ src.slug }}]] {% endfor %} -{% endif %} diff --git a/roles/authentik/templates/docker-compose.yml.j2 b/roles/authentik/templates/docker-compose.yml.j2 index f0193ec..c9796a2 100644 --- a/roles/authentik/templates/docker-compose.yml.j2 +++ b/roles/authentik/templates/docker-compose.yml.j2 @@ -48,13 +48,10 @@ services: labels: - traefik.enable=true - traefik.docker.network={{ authentik_traefik_network }} - - traefik.http.routers.{{ authentik_service_name }}.rule={% for d in authentik_domains %}Host(`{{ d }}`){% if not loop.last %} || {% endif %}{% endfor +%} + - traefik.http.routers.{{ authentik_service_name }}.rule=Host(`{{ authentik_domain }}`) {% if authentik_use_ssl %} - traefik.http.routers.{{ authentik_service_name }}.entrypoints=websecure - traefik.http.routers.{{ authentik_service_name }}.tls=true -{% if traefik_cert_mode | default('selfsigned') == 'acme' %} - - traefik.http.routers.{{ authentik_service_name }}.tls.certresolver={{ traefik_ssl_cert_resolver | default('dns') }} -{% endif %} {% else %} - traefik.http.routers.{{ authentik_service_name }}.entrypoints=web {% endif %} diff --git a/roles/collabora/defaults/main.yml b/roles/collabora/defaults/main.yml index 11aa468..3cfb559 100644 --- a/roles/collabora/defaults/main.yml +++ b/roles/collabora/defaults/main.yml @@ -12,11 +12,7 @@ collabora_docker_compose_dir: "{{ docker_compose_base_dir }}/{{ collabora_servic collabora_docker_volume_dir: "{{ docker_volume_base_dir }}/{{ collabora_service_name }}" # Service configuration -# FQDNs the collabora router accepts. The first entry is the canonical -# domain; further entries cover internal *.int.* names used for -# server-to-server WOPI discovery. -collabora_domains: - - "office.local.test" +collabora_domain: "office.local.test" collabora_image: "collabora/code:latest" collabora_port: 9980 collabora_extra_hosts: [] diff --git a/roles/collabora/handlers/main.yml b/roles/collabora/handlers/main.yml index 3364bcc..bfd2b02 100644 --- a/roles/collabora/handlers/main.yml +++ b/roles/collabora/handlers/main.yml @@ -5,4 +5,4 @@ - name: restart collabora community.docker.docker_compose_v2: project_src: "{{ collabora_docker_compose_dir }}" - state: present \ No newline at end of file + state: restarted \ No newline at end of file diff --git a/roles/collabora/templates/docker-compose.yml.j2 b/roles/collabora/templates/docker-compose.yml.j2 index 353a08b..c0f589e 100644 --- a/roles/collabora/templates/docker-compose.yml.j2 +++ b/roles/collabora/templates/docker-compose.yml.j2 @@ -20,14 +20,11 @@ services: labels: - traefik.enable=true - traefik.docker.network={{ collabora_traefik_network }} - - traefik.http.routers.{{ collabora_service_name }}.rule={% for d in collabora_domains %}Host(`{{ d }}`){% if not loop.last %} || {% endif %}{% endfor +%} + - traefik.http.routers.{{ collabora_service_name }}.rule=Host(`{{ collabora_domain }}`) - traefik.http.services.{{ collabora_service_name }}.loadbalancer.server.port={{ collabora_port }} {% if collabora_use_ssl %} - traefik.http.routers.{{ collabora_service_name }}.entrypoints=websecure - traefik.http.routers.{{ collabora_service_name }}.tls=true -{% if traefik_cert_mode | default('selfsigned') == 'acme' %} - - traefik.http.routers.{{ collabora_service_name }}.tls.certresolver={{ traefik_ssl_cert_resolver | default('dns') }} -{% endif %} {% else %} - traefik.http.routers.{{ collabora_service_name }}.entrypoints=web {% endif %} diff --git a/roles/drawio/handlers/main.yml b/roles/drawio/handlers/main.yml index b68633d..f1ef0da 100644 --- a/roles/drawio/handlers/main.yml +++ b/roles/drawio/handlers/main.yml @@ -5,4 +5,4 @@ - name: restart drawio community.docker.docker_compose_v2: project_src: "{{ drawio_docker_compose_dir }}" - state: present \ No newline at end of file + state: restarted \ No newline at end of file diff --git a/roles/garage/defaults/main.yml b/roles/garage/defaults/main.yml index 091e318..495317e 100644 --- a/roles/garage/defaults/main.yml +++ b/roles/garage/defaults/main.yml @@ -13,11 +13,7 @@ garage_docker_volume_dir: "{{ docker_volume_base_dir }}/{{ garage_service_name } # Garage service configuration garage_image: "dxflrs/garage:v2.1.0" -# FQDNs the garage S3 router accepts. The first entry is the canonical -# domain and is also used as the virtual-hosted-style root_domain in -# garage.toml; further entries cover internal *.int.* names. -garage_s3_domains: - - "storage.local.test" +garage_s3_domain: "storage.local.test" garage_web_domain: "web.storage.local.test" garage_webui_domain: "console.storage.local.test" diff --git a/roles/garage/templates/docker-compose.yml.j2 b/roles/garage/templates/docker-compose.yml.j2 index d344e5f..9e3e862 100644 --- a/roles/garage/templates/docker-compose.yml.j2 +++ b/roles/garage/templates/docker-compose.yml.j2 @@ -14,13 +14,10 @@ services: - traefik.enable=true - traefik.docker.network={{ garage_traefik_network }} # S3 API endpoint - - traefik.http.routers.{{ garage_service_name }}.rule={% for d in garage_s3_domains %}Host(`{{ d }}`){% if not loop.last %} || {% endif %}{% endfor +%} + - traefik.http.routers.{{ garage_service_name }}.rule=Host(`{{ garage_s3_domain }}`) {% if garage_use_ssl %} - traefik.http.routers.{{ garage_service_name }}.entrypoints=websecure - traefik.http.routers.{{ garage_service_name }}.tls=true -{% if traefik_cert_mode | default('selfsigned') == 'acme' %} - - traefik.http.routers.{{ garage_service_name }}.tls.certresolver={{ traefik_ssl_cert_resolver | default('dns') }} -{% endif %} {% else %} - traefik.http.routers.{{ garage_service_name }}.entrypoints=web {% endif %} @@ -51,9 +48,6 @@ services: {% if garage_use_ssl %} - traefik.http.routers.{{ garage_service_name }}-console.entrypoints=websecure - traefik.http.routers.{{ garage_service_name }}-console.tls=true -{% if traefik_cert_mode | default('selfsigned') == 'acme' %} - - traefik.http.routers.{{ garage_service_name }}-console.tls.certresolver={{ traefik_ssl_cert_resolver | default('dns') }} -{% endif %} {% else %} - traefik.http.routers.{{ garage_service_name }}-console.entrypoints=web {% endif %} diff --git a/roles/garage/templates/garage.toml.j2 b/roles/garage/templates/garage.toml.j2 index 06b1164..897ebcd 100644 --- a/roles/garage/templates/garage.toml.j2 +++ b/roles/garage/templates/garage.toml.j2 @@ -14,7 +14,7 @@ rpc_secret = "{{ garage_rpc_secret }}" [s3_api] s3_region = "{{ garage_s3_region }}" api_bind_addr = "[::]:{{ garage_s3_api_port }}" -root_domain = ".s3.{{ garage_s3_domains[0] }}" +root_domain = ".s3.{{ garage_s3_domain }}" [s3_web] bind_addr = "[::]:{{ garage_s3_web_port }}" diff --git a/roles/homarr/handlers/main.yml b/roles/homarr/handlers/main.yml index da74ed4..dedb949 100644 --- a/roles/homarr/handlers/main.yml +++ b/roles/homarr/handlers/main.yml @@ -5,4 +5,4 @@ - name: restart homarr community.docker.docker_compose_v2: project_src: "{{ homarr_docker_compose_dir }}" - state: present \ No newline at end of file + state: restarted \ No newline at end of file diff --git a/roles/nextcloud/defaults/main.yml b/roles/nextcloud/defaults/main.yml index b60dbc3..7535b5a 100644 --- a/roles/nextcloud/defaults/main.yml +++ b/roles/nextcloud/defaults/main.yml @@ -9,12 +9,7 @@ nextcloud_service_name: nextcloud nextcloud_docker_compose_dir: "{{ docker_compose_base_dir }}/{{ nextcloud_service_name }}" nextcloud_docker_volume_dir: "{{ docker_volume_base_dir }}/{{ nextcloud_service_name }}" -# FQDNs the nextcloud router accepts. The first entry is the canonical -# domain (used for OVERWRITEHOST and the notify_push setup); further -# entries cover internal *.int.* names so collabora's WOPI callback -# hits us on a name with a valid cert. -nextcloud_domains: - - "nextcloud.local.test" +nextcloud_domain: "nextcloud.local.test" nextcloud_image: "nextcloud:fpm" nextcloud_redis_image: "redis:latest" nextcloud_port: 80 @@ -65,12 +60,6 @@ nextcloud_trusted_proxies: "172.16.0.0/12" # File locking and real-time push notifications nextcloud_enable_notify_push: false nextcloud_notify_push_image: "icewind1991/notify_push:1.3.1" -# Domain used when calling `occ notify_push:setup`. Defaults to the -# first nextcloud_domains entry (the canonical public name). Override -# with an internal FQDN to avoid hairpinning the setup check through -# the DMZ; the FQDN must also be in nextcloud_domains so the push -# router matches it. -# nextcloud_notify_push_domain: "cloud.int.example.com" # Non-default apps to install and enable nextcloud_apps_to_install: diff --git a/roles/nextcloud/tasks/collabora.yml b/roles/nextcloud/tasks/collabora.yml index 2a7bd82..05c56e4 100644 --- a/roles/nextcloud/tasks/collabora.yml +++ b/roles/nextcloud/tasks/collabora.yml @@ -1,17 +1,11 @@ #SPDX-License-Identifier: MIT-0 --- # tasks file for configuring Collabora in Nextcloud -- name: Configure Collabora WOPI URL (server-to-server) +- name: Configure Collabora WOPI URL community.docker.docker_container_exec: container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1" command: php /var/www/html/occ config:app:set richdocuments wopi_url --value=https://{{ nextcloud_collabora_domain }} -- name: Configure Collabora public WOPI URL (browser-facing) - community.docker.docker_container_exec: - container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1" - command: php /var/www/html/occ config:app:set richdocuments public_wopi_url --value=https://{{ nextcloud_collabora_public_domain }} - when: nextcloud_collabora_public_domain is defined and nextcloud_collabora_public_domain != nextcloud_collabora_domain - - name: Configure certificate verification for Collabora community.docker.docker_container_exec: container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1" diff --git a/roles/nextcloud/tasks/notify_push.yml b/roles/nextcloud/tasks/notify_push.yml index 1497c68..18dbb8b 100644 --- a/roles/nextcloud/tasks/notify_push.yml +++ b/roles/nextcloud/tasks/notify_push.yml @@ -5,4 +5,4 @@ - name: Configure notify_push base endpoint community.docker.docker_container_exec: container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1" - command: php /var/www/html/occ notify_push:setup https://{{ nextcloud_notify_push_domain | default(nextcloud_domains[0]) }}/push \ No newline at end of file + command: php /var/www/html/occ notify_push:setup https://{{ nextcloud_domain }}/push \ No newline at end of file diff --git a/roles/nextcloud/templates/docker-compose.yml.j2 b/roles/nextcloud/templates/docker-compose.yml.j2 index 365a766..9f15760 100644 --- a/roles/nextcloud/templates/docker-compose.yml.j2 +++ b/roles/nextcloud/templates/docker-compose.yml.j2 @@ -35,13 +35,10 @@ services: labels: - traefik.enable=true - traefik.docker.network={{ nextcloud_traefik_network }} - - traefik.http.routers.{{ nextcloud_service_name }}.rule={% for d in nextcloud_domains %}Host(`{{ d }}`){% if not loop.last %} || {% endif %}{% endfor +%} + - traefik.http.routers.{{ nextcloud_service_name }}.rule=Host(`{{ nextcloud_domain }}`) {% if nextcloud_use_ssl %} - traefik.http.routers.{{ nextcloud_service_name }}.entrypoints=websecure - traefik.http.routers.{{ nextcloud_service_name }}.tls=true -{% if traefik_cert_mode | default('selfsigned') == 'acme' %} - - traefik.http.routers.{{ nextcloud_service_name }}.tls.certresolver={{ traefik_ssl_cert_resolver | default('dns') }} -{% endif %} {% else %} - traefik.http.routers.{{ nextcloud_service_name }}.entrypoints=web {% endif %} @@ -63,7 +60,7 @@ services: PHP_MEMORY_LIMIT: {{ nextcloud_memory_limit_mb }}M PHP_UPLOAD_LIMIT: {{ nextcloud_upload_limit_mb }}M OVERWRITEPROTOCOL: https - OVERWRITEHOST: {{ nextcloud_domains[0] }} + OVERWRITEHOST: {{ nextcloud_domain }} TRUSTED_PROXIES: "{{ nextcloud_trusted_proxies }}" volumes: - {{ nextcloud_docker_volume_dir }}/nextcloud/:/var/www/html @@ -72,12 +69,6 @@ services: {% for net in nextcloud_extra_networks %} - {{ net }} {% endfor %} -{% if nextcloud_extra_hosts is defined and nextcloud_extra_hosts | length > 0 %} - extra_hosts: -{% for host in nextcloud_extra_hosts %} - - "{{ host }}" -{% endfor %} -{% endif %} nextcloud: image: {{ nextcloud_image }} @@ -97,7 +88,7 @@ services: PHP_MEMORY_LIMIT: {{ nextcloud_memory_limit_mb }}M PHP_UPLOAD_LIMIT: {{ nextcloud_upload_limit_mb }}M OVERWRITEPROTOCOL: https - OVERWRITEHOST: {{ nextcloud_domains[0] }} + OVERWRITEHOST: {{ nextcloud_domain }} TRUSTED_PROXIES: "{{ nextcloud_trusted_proxies }}" {% if nextcloud_use_s3_storage %} OBJECTSTORE_S3_KEY: {{ nextcloud_s3_key }} @@ -136,7 +127,7 @@ services: environment: PORT: "7867" REDIS_URL: "redis://redis:6379" - DATABASE_URL: "postgres://{{ nextcloud_postgres_user | urlencode | replace('/', '%2F') }}:{{ nextcloud_postgres_password | urlencode | replace('/', '%2F') }}@db:5432/{{ nextcloud_postgres_db }}" + DATABASE_URL: "postgres://{{ nextcloud_postgres_user }}:{{ nextcloud_postgres_password }}@db:5432/{{ nextcloud_postgres_db }}" DATABASE_PREFIX: "oc_" NEXTCLOUD_URL: "http://nginx" networks: @@ -145,14 +136,11 @@ services: labels: - traefik.enable=true - traefik.docker.network={{ nextcloud_traefik_network }} - - traefik.http.routers.{{ nextcloud_service_name }}-push.rule=({% for d in nextcloud_domains %}Host(`{{ d }}`){% if not loop.last %} || {% endif %}{% endfor %}) && PathPrefix(`/push`) + - traefik.http.routers.{{ nextcloud_service_name }}-push.rule=Host(`{{ nextcloud_domain }}`) && PathPrefix(`/push`) - traefik.http.services.{{ nextcloud_service_name }}-push.loadbalancer.server.port=7867 {% if nextcloud_use_ssl %} - traefik.http.routers.{{ nextcloud_service_name }}-push.entrypoints=websecure - traefik.http.routers.{{ nextcloud_service_name }}-push.tls=true -{% if traefik_cert_mode | default('selfsigned') == 'acme' %} - - traefik.http.routers.{{ nextcloud_service_name }}-push.tls.certresolver={{ traefik_ssl_cert_resolver | default('dns') }} -{% endif %} {% else %} - traefik.http.routers.{{ nextcloud_service_name }}-push.entrypoints=web {% endif %} diff --git a/roles/opencloud/handlers/main.yml b/roles/opencloud/handlers/main.yml index 7cbc094..95b6986 100644 --- a/roles/opencloud/handlers/main.yml +++ b/roles/opencloud/handlers/main.yml @@ -5,4 +5,4 @@ - name: restart opencloud community.docker.docker_compose_v2: project_src: "{{ opencloud_docker_compose_dir }}" - state: present \ No newline at end of file + state: restarted \ No newline at end of file diff --git a/roles/traefik/defaults/main.yml b/roles/traefik/defaults/main.yml index eea7391..3e43412 100644 --- a/roles/traefik/defaults/main.yml +++ b/roles/traefik/defaults/main.yml @@ -33,18 +33,6 @@ traefik_acme_tsig_secret: "" # TSIG secret traefik_acme_propagation_timeout: "120" traefik_acme_polling_interval: "2" traefik_acme_ttl: "60" -# Force lego's DNS lookups (SOA resolution, propagation checks) onto -# TCP instead of UDP. Useful when container egress can reach the -# nameserver on TCP/53 but UDP/53 is blocked or unreliable. Sets the -# upstream env var LEGO_EXPERIMENTAL_DNS_TCP_ONLY=true on the -# traefik container. -traefik_acme_tcp_only: false -# Disable lego's propagation check against the zone's authoritative -# nameservers. Use when the SOA-listed NS hostname resolves to an -# address that isn't reachable from this traefik host (e.g. a DMZ -# box that can only see the internal NS IP, not the public one). -# lego still polls via the configured `resolvers:` list. -traefik_acme_disable_ans_checks: false # Self-signed certificate configuration (for vagrant/testing) traefik_selfsigned_cert_dir: "{{ docker_volume_dir }}/certs" diff --git a/roles/traefik/handlers/main.yml b/roles/traefik/handlers/main.yml index 8af7aac..4abd95a 100644 --- a/roles/traefik/handlers/main.yml +++ b/roles/traefik/handlers/main.yml @@ -5,4 +5,4 @@ - name: restart traefik community.docker.docker_compose_v2: project_src: "{{ docker_compose_dir }}" - state: present + state: restarted diff --git a/roles/traefik/tasks/main.yml b/roles/traefik/tasks/main.yml index 8934037..159ba8f 100644 --- a/roles/traefik/tasks/main.yml +++ b/roles/traefik/tasks/main.yml @@ -9,18 +9,7 @@ - name: Build service registry from backend servers (DMZ mode) set_fact: - # Two-step merge so a service entry's own `backend_host` wins: - # entries that set it pass through unchanged, entries that don't - # get the backend host's ansible_host as fallback. The override - # lets a route target an internal FQDN covered by the backend - # cert's SANs instead of the raw IP (which would fail backend - # TLS verification at the proxy hop). - proxied_services: >- - {{ - proxied_services | default([]) - + (hostvars[item].traefik_dmz_exposed_services | default([]) | selectattr('backend_host', 'defined') | list) - + (hostvars[item].traefik_dmz_exposed_services | default([]) | rejectattr('backend_host', 'defined') | map('combine', {'backend_host': hostvars[item].ansible_host | default(item)}) | list) - }} + proxied_services: "{{ proxied_services | default([]) + hostvars[item].traefik_dmz_exposed_services | default([]) | map('combine', {'backend_host': hostvars[item].ansible_host | default(item)}) | list }}" loop: "{{ _backend_servers | default([]) }}" when: traefik_mode == 'dmz' diff --git a/roles/traefik/templates/docker-compose.yml.j2 b/roles/traefik/templates/docker-compose.yml.j2 index 6dbb9ec..e45578b 100644 --- a/roles/traefik/templates/docker-compose.yml.j2 +++ b/roles/traefik/templates/docker-compose.yml.j2 @@ -12,9 +12,6 @@ services: RFC2136_PROPAGATION_TIMEOUT: "{{ traefik_acme_propagation_timeout }}" RFC2136_POLLING_INTERVAL: "{{ traefik_acme_polling_interval }}" RFC2136_TTL: "{{ traefik_acme_ttl }}" -{% if traefik_acme_tcp_only | default(false) %} - LEGO_EXPERIMENTAL_DNS_TCP_ONLY: "true" -{% endif %} {% endif %} ports: - "80:80" diff --git a/roles/traefik/templates/traefik.yml.j2 b/roles/traefik/templates/traefik.yml.j2 index 1900bbb..64bf351 100644 --- a/roles/traefik/templates/traefik.yml.j2 +++ b/roles/traefik/templates/traefik.yml.j2 @@ -48,10 +48,6 @@ certificatesResolvers: provider: rfc2136 resolvers: - "{{ traefik_acme_dns_nameserver }}" -{% if traefik_acme_disable_ans_checks | default(false) %} - propagation: - disableANSChecks: true -{% endif %} {% endif %} {% if traefik_use_ssl %}