Added get_domain function

This commit is contained in:
Kevin Veen-Birkenbach 2025-05-17 14:53:55 +02:00
parent ad51597e2e
commit 3388d3c592
No known key found for this signature in database
GPG Key ID: 44D8F11FD62F878E
94 changed files with 288 additions and 141 deletions

View File

@ -95,7 +95,7 @@ Now that you have defined the application settings, domain, and application ID,
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -0,0 +1,60 @@
from ansible.errors import AnsibleFilterError
class FilterModule(object):
'''Ansible filter plugin to retrieve the correct domain for a given application_id.'''
def filters(self):
return {
'get_domain': self.get_domain,
}
def get_domain(self, domains, application_id):
"""
Return the domain for application_id from the domains mapping:
- If value is a string, return it.
- If value is a dict, return its first value.
- If value is a list, return its first element.
- Otherwise, raise an error.
"""
# Ensure domains is a mapping
if not isinstance(domains, dict):
raise AnsibleFilterError(f"'domains' must be a dict, got {type(domains).__name__}")
if application_id not in domains:
raise AnsibleFilterError(f"application_id '{application_id}' not found in domains mapping")
val = domains[application_id]
# String case
if isinstance(val, str):
if not val:
raise AnsibleFilterError(f"domains['{application_id}'] is an empty string")
return val
# Dict case
if isinstance(val, dict):
try:
first_val = next(iter(val.values()))
except StopIteration:
raise AnsibleFilterError(f"domains['{application_id}'] dict is empty")
if not isinstance(first_val, str) or not first_val:
raise AnsibleFilterError(
f"first value of domains['{application_id}'] must be a non-empty string, got {first_val!r}"
)
return first_val
# List case
if isinstance(val, list):
if not val:
raise AnsibleFilterError(f"domains['{application_id}'] list is empty")
first = val[0]
if not isinstance(first, str) or not first:
raise AnsibleFilterError(
f"first element of domains['{application_id}'] must be a non-empty string, got {first!r}"
)
return first
# Other types
raise AnsibleFilterError(
f"domains['{application_id}'] has unsupported type {type(val).__name__}, must be str, dict or list"
)

View File

@ -21,7 +21,7 @@ class FilterModule(object):
{{ redirect_list {{ redirect_list
| add_redirect_if_group('lam', | add_redirect_if_group('lam',
'ldap.' ~ primary_domain, 'ldap.' ~ primary_domain,
domains.lam, domains | get_domain('lam'),
group_names) }} group_names) }}
""" """
try: try:

View File

@ -9,7 +9,7 @@
## Helper Variables: ## Helper Variables:
_oidc_client_realm: "{{ oidc.client.realm if oidc.client is defined and oidc.client.realm is defined else primary_domain }}" _oidc_client_realm: "{{ oidc.client.realm if oidc.client is defined and oidc.client.realm is defined else primary_domain }}"
_oidc_client_issuer_url: "{{ web_protocol }}://{{domains.keycloak}}/realms/{{_oidc_client_realm}}" _oidc_client_issuer_url: "{{ web_protocol }}://{{domains | get_domain('keycloak')}}/realms/{{_oidc_client_realm}}"
defaults_oidc: defaults_oidc:
client: client:

View File

@ -17,15 +17,15 @@ defaults_service_provider:
favicon: "{{ applications.assets_server.url | safe_var | safe_join('favicon.ico') }}" favicon: "{{ applications.assets_server.url | safe_var | safe_join('favicon.ico') }}"
contact: contact:
bluesky: >- bluesky: >-
{{ ('@' ~ users.administrator.username ~ '.' ~ domains[application_id]['api']) {{ ('@' ~ users.administrator.username ~ '.' ~ domains.bluesky.api)
if 'bluesky' in group_names else '' }} if 'bluesky' in group_names else '' }}
email: "contact@{{ primary_domain }}" email: "contact@{{ primary_domain }}"
mastodon: "{{ '@' ~ users.administrator.username ~ '@' ~ domains.mastodon if 'mastodon' in group_names else '' }}" mastodon: "{{ '@' ~ users.administrator.username ~ '@' ~ domains | get_domain('mastodon') if 'mastodon' in group_names else '' }}"
matrix: "{{ '@' ~ users.administrator.username ~ ':' ~ domains.matrix.synapse if 'matrix' in group_names else '' }}" matrix: "{{ '@' ~ users.administrator.username ~ ':' ~ domains.matrix.synapse if 'matrix' in group_names else '' }}"
peertube: "{{ '@' ~ users.administrator.username ~ '@' ~ domains.peertube[0] if 'peertube' in group_names else '' }}" peertube: "{{ '@' ~ users.administrator.username ~ '@' ~ domains | get_domain('peertube') if 'peertube' in group_names else '' }}"
pixelfed: "{{ '@' ~ users.administrator.username ~ '@' ~ domains.pixelfed if 'pixelfed' in group_names else '' }}" pixelfed: "{{ '@' ~ users.administrator.username ~ '@' ~ domains | get_domain('pixelfed') if 'pixelfed' in group_names else '' }}"
phone: "+0 000 000 404" phone: "+0 000 000 404"
wordpress: "{{ '@' ~ users.administrator.username ~ '@' ~ domains.wordpress[0] if 'wordpress' in group_names else '' }}" wordpress: "{{ '@' ~ users.administrator.username ~ '@' ~ domains | get_domain('wordpress') if 'wordpress' in group_names else '' }}"
legal: legal:
editorial_responsible: "Johannes Gutenberg" editorial_responsible: "Johannes Gutenberg"

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "include tasks update-repository-with-files.yml" - name: "include tasks update-repository-with-files.yml"

View File

@ -1,5 +1,5 @@
# You should change this to match your reverse proxy DNS name and protocol # You should change this to match your reverse proxy DNS name and protocol
APP_URL=https://{{domains[application_id]}} APP_URL=https://{{domains | get_domain(application_id)}}
LOCALE={{ HOST_LL }} LOCALE={{ HOST_LL }}
# Don't change this unless you rename your database container or use rootless podman, in case of using rootless podman you should set it to 127.0.0.1 (NOT localhost) # Don't change this unless you rename your database container or use rootless podman, in case of using rootless podman you should set it to 127.0.0.1 (NOT localhost)

View File

@ -10,13 +10,13 @@
domain: "{{ item }}" domain: "{{ item }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
loop: loop:
- "{{ domains.mailu }}" - "{{ domains | get_domain('mailu') }}"
- "{{ domain }}" - "{{ domain }}"
- name: configure {{domains[application_id]}}.conf - name: configure {{domains | get_domain(application_id)}}.conf
template: template:
src: roles/nginx-docker-reverse-proxy/templates/vhost/basic.conf.j2 src: roles/nginx-docker-reverse-proxy/templates/vhost/basic.conf.j2
dest: "{{nginx.directories.http.servers}}{{domains[application_id]}}.conf" dest: "{{nginx.directories.http.servers}}{{domains | get_domain(application_id)}}.conf"
notify: restart nginx notify: restart nginx
- name: "include tasks update-repository-with-files.yml" - name: "include tasks update-repository-with-files.yml"

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -1,5 +1,5 @@
application_id: "baserow" application_id: "baserow"
database_password: "{{ baserow_database_password }}" database_password: "{{ baserow_database_password }}"
database_type: "postgres" database_type: "postgres"
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"

View File

@ -54,7 +54,7 @@
- name: Wait for BigBlueButton - name: Wait for BigBlueButton
wait_for: wait_for:
host: "{{ domains.bigbluebutton }}" host: "{{ domains | get_domain('bigbluebutton') }}"
port: 80 port: 80
delay: 5 delay: 5
timeout: 600 timeout: 600

View File

@ -37,7 +37,7 @@ FSESL_PASSWORD={{applications[application_id].credentials.fsesl_password}}
# CONNECTION # CONNECTION
# ==================================== # ====================================
DOMAIN={{domains[application_id]}} DOMAIN={{domains | get_domain(application_id)}}
EXTERNAL_IPv4={{networks.internet.ip4}} EXTERNAL_IPv4={{networks.internet.ip4}}
# The following line is not tested and could lead to bugs: # The following line is not tested and could lead to bugs:
@ -50,7 +50,7 @@ STUN_PORT={{ ports.public.stun[application_id] }}
# TURN SERVER # TURN SERVER
# uncomment and adjust following two lines to add an external TURN server # uncomment and adjust following two lines to add an external TURN server
TURN_SERVER=turns:{{domains[application_id]}}:{{ ports.public.turn[application_id] }}?transport=tcp TURN_SERVER=turns:{{domains | get_domain(application_id)}}:{{ ports.public.turn[application_id] }}?transport=tcp
TURN_SECRET={{applications[application_id].credentials.turn_secret}} TURN_SECRET={{applications[application_id].credentials.turn_secret}}
# Allowed SIP IPs # Allowed SIP IPs
@ -290,6 +290,6 @@ DEFAULT_REGISTRATION=invite
OPENID_CONNECT_CLIENT_ID={{oidc.client.id}} OPENID_CONNECT_CLIENT_ID={{oidc.client.id}}
OPENID_CONNECT_CLIENT_SECRET={{oidc.client.secret}} OPENID_CONNECT_CLIENT_SECRET={{oidc.client.secret}}
OPENID_CONNECT_ISSUER={{oidc.client.issuer_url}} OPENID_CONNECT_ISSUER={{oidc.client.issuer_url}}
OPENID_CONNECT_REDIRECT=https://{{domains[application_id]}} OPENID_CONNECT_REDIRECT=https://{{domains | get_domain(application_id)}}
# OPENID_CONNECT_UID_FIELD=sub default # OPENID_CONNECT_UID_FIELD=sub default
{% endif %} {% endif %}

View File

@ -11,7 +11,7 @@ database:
name: "multiple_databases" name: "multiple_databases"
username: "postgres2" username: "postgres2"
urls: urls:
api: "{{ web_protocol }}://{{domains.bigbluebutton}}/bigbluebutton/" # API Address used by Nextcloud Integration api: "{{ web_protocol }}://{{domains | get_domain('bigbluebutton')}}/bigbluebutton/" # API Address used by Nextcloud Integration
features: features:
matomo: true matomo: true
css: true css: true

View File

@ -7,7 +7,7 @@ docker_compose_file_final: "{{ docker_compose.directories.instance }}docker-c
database_type: "postgres" database_type: "postgres"
database_password: "{{ applications.bigbluebutton.credentials.postgresql_secret }}" database_password: "{{ applications.bigbluebutton.credentials.postgresql_secret }}"
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
bbb_env_file_link: "{{ docker_compose.directories.instance }}.env" bbb_env_file_link: "{{ docker_compose.directories.instance }}.env"
bbb_env_file_origine: "{{ bbb_repository_directory }}.env" bbb_env_file_origine: "{{ bbb_repository_directory }}.env"

View File

@ -16,7 +16,7 @@
- CMD-SHELL - CMD-SHELL
- > - >
if [ ! -f /tmp/email_sent ]; then if [ ! -f /tmp/email_sent ]; then
echo 'Subject: testmessage from {{domains[application_id]}}\n\nSUCCESSFULL' | msmtp -t {{users.blackhole.email}} && touch /tmp/email_sent; echo 'Subject: testmessage from {{domains | get_domain(application_id)}}\n\nSUCCESSFULL' | msmtp -t {{users.blackhole.email}} && touch /tmp/email_sent;
fi && fi &&
curl -f http://localhost:80/ || exit 1 curl -f http://localhost:80/ || exit 1
interval: 1m interval: 1m

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -16,7 +16,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
when: run_once_docker_discourse is not defined when: run_once_docker_discourse is not defined

View File

@ -41,7 +41,7 @@ env:
UNICORN_WORKERS: 8 UNICORN_WORKERS: 8
## Required. Discourse will not work with a bare IP number. ## Required. Discourse will not work with a bare IP number.
DISCOURSE_HOSTNAME: {{domains[application_id]}} DISCOURSE_HOSTNAME: {{domains | get_domain(application_id)}}
## Uncomment if you want the container to be started with the same ## Uncomment if you want the container to be started with the same
## hostname (-h option) as specified above (default "$hostname-$config") ## hostname (-h option) as specified above (default "$hostname-$config")
@ -137,7 +137,7 @@ run:
- exec: rails r "SiteSetting.openid_connect_discovery_document = '{{oidc.client.discovery_document}}'" - exec: rails r "SiteSetting.openid_connect_discovery_document = '{{oidc.client.discovery_document}}'"
- exec: rails r "SiteSetting.openid_connect_client_id = '{{oidc.client.id}}'" - exec: rails r "SiteSetting.openid_connect_client_id = '{{oidc.client.id}}'"
- exec: rails r "SiteSetting.openid_connect_client_secret = '{{oidc.client.secret}}'" - exec: rails r "SiteSetting.openid_connect_client_secret = '{{oidc.client.secret}}'"
- exec: rails r "SiteSetting.openid_connect_rp_initiated_logout_redirect = 'https://{{domains[application_id]}}'" - exec: rails r "SiteSetting.openid_connect_rp_initiated_logout_redirect = 'https://{{domains | get_domain(application_id)}}'"
- exec: rails r "SiteSetting.openid_connect_allow_association_change = false" - exec: rails r "SiteSetting.openid_connect_allow_association_change = false"
- exec: rails r "SiteSetting.openid_connect_rp_initiated_logout = true" - exec: rails r "SiteSetting.openid_connect_rp_initiated_logout = true"
{% endif %} {% endif %}

View File

@ -4,7 +4,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: create elasticsearch-sysctl.conf - name: create elasticsearch-sysctl.conf

View File

@ -11,7 +11,7 @@
ws_port: "{{ ports.localhost.websocket[application_id] }}" ws_port: "{{ ports.localhost.websocket[application_id] }}"
client_max_body_size: "100m" client_max_body_size: "100m"
vhost_flavour: "ws_generic" vhost_flavour: "ws_generic"
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -31,7 +31,7 @@ services:
driver: journald driver: journald
environment: environment:
- ESPOCRM_CONFIG_USE_WEB_SOCKET=true - ESPOCRM_CONFIG_USE_WEB_SOCKET=true
- ESPOCRM_CONFIG_WEB_SOCKET_URL=ws://{{ domains[application_id] }}/ws - ESPOCRM_CONFIG_WEB_SOCKET_URL=ws://{{ domains | get_domain(application_id) }}/ws
- ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBSCRIBER_DSN=tcp://*:7777 - ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBSCRIBER_DSN=tcp://*:7777
- ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBMISSION_DSN=tcp://websocket:7777 - ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBMISSION_DSN=tcp://websocket:7777
entrypoint: docker-websocket.sh entrypoint: docker-websocket.sh

View File

@ -23,7 +23,7 @@ ESPOCRM_ADMIN_USERNAME={{ applications[application_id].users.administrator.usern
ESPOCRM_ADMIN_PASSWORD={{ applications[application_id].credentials.administrator_password }} ESPOCRM_ADMIN_PASSWORD={{ applications[application_id].credentials.administrator_password }}
# Public base URL of the EspoCRM instance # Public base URL of the EspoCRM instance
ESPOCRM_SITE_URL={{ web_protocol }}://{{ domains[application_id] }} ESPOCRM_SITE_URL={{ web_protocol }}://{{ domains | get_domain(application_id) }}
# ------------------------------------------------ # ------------------------------------------------
# General UI & locale settings # General UI & locale settings
@ -94,7 +94,7 @@ ESPOCRM_CONFIG_OIDC_TOKEN_ENDPOINT={{ oidc.client.token_url }}
ESPOCRM_CONFIG_OIDC_USER_INFO_ENDPOINT={{ oidc.client.user_info_url }} ESPOCRM_CONFIG_OIDC_USER_INFO_ENDPOINT={{ oidc.client.user_info_url }}
ESPOCRM_CONFIG_OIDC_JWKS_ENDPOINT={{ oidc.client.certs }} ESPOCRM_CONFIG_OIDC_JWKS_ENDPOINT={{ oidc.client.certs }}
ESPOCRM_CONFIG_OIDC_AUTHORIZATION_REDIRECT_URI=https://{{ domains[application_id] }}/oidc/callback ESPOCRM_CONFIG_OIDC_AUTHORIZATION_REDIRECT_URI=https://{{ domains | get_domain(application_id) }}/oidc/callback
#ESPOCRM_CONFIG_OIDC_SCOPES=openid,profile,email # Defined in main.yml #ESPOCRM_CONFIG_OIDC_SCOPES=openid,profile,email # Defined in main.yml
ESPOCRM_CONFIG_OIDC_CREATE_USER=true ESPOCRM_CONFIG_OIDC_CREATE_USER=true

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -1,8 +1,8 @@
# The configuration options can be found here: # The configuration options can be found here:
# @see https://hub.docker.com/_/friendica # @see https://hub.docker.com/_/friendica
FRIENDICA_URL= https://{{domains[application_id]}} FRIENDICA_URL= https://{{domains | get_domain(application_id)}}
HOSTNAME= {{domains[application_id]}} HOSTNAME= {{domains | get_domain(application_id)}}
FRIENDICA_NO_VALIDATION={{no_validation | lower}} FRIENDICA_NO_VALIDATION={{no_validation | lower}}
# Debugging # Debugging

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -40,7 +40,7 @@ FUNKWHALE_WEB_WORKERS=4
# Replace this by the definitive, public domain you will use for # Replace this by the definitive, public domain you will use for
# your instance. It cannot be changed after initial deployment # your instance. It cannot be changed after initial deployment
# without breaking your instance. # without breaking your instance.
FUNKWHALE_HOSTNAME={{domains[application_id]}} FUNKWHALE_HOSTNAME={{domains | get_domain(application_id)}}
FUNKWHALE_PROTOCOL=https FUNKWHALE_PROTOCOL=https
# Log level (debug, info, warning, error, critical) # Log level (debug, info, warning, error, critical)

View File

@ -6,7 +6,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -10,10 +10,10 @@ DB_USER={{database_username}}
DB_PASSWD={{database_password}} DB_PASSWD={{database_password}}
SSH_PORT={{ports.public.ssh[application_id]}} SSH_PORT={{ports.public.ssh[application_id]}}
SSH_LISTEN_PORT=22 SSH_LISTEN_PORT=22
DOMAIN={{domains[application_id]}} DOMAIN={{domains | get_domain(application_id)}}
SSH_DOMAIN={{domains[application_id]}} SSH_DOMAIN={{domains | get_domain(application_id)}}
RUN_MODE="{{ 'dev' if (CYMAIS_ENVIRONMENT | lower) == 'development' else 'prod' }}" RUN_MODE="{{ 'dev' if (CYMAIS_ENVIRONMENT | lower) == 'development' else 'prod' }}"
ROOT_URL="{{ web_protocol }}://{{domains[application_id]}}/" ROOT_URL="{{ web_protocol }}://{{domains | get_domain(application_id)}}/"
# Mail Configuration # Mail Configuration
# @see https://docs.gitea.com/next/installation/install-with-docker#managing-deployments-with-environment-variables # @see https://docs.gitea.com/next/installation/install-with-docker#managing-deployments-with-environment-variables

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -6,7 +6,7 @@ services:
web: web:
image: "gitlab/gitlab-ee:{{applications.gitlab.version}}" image: "gitlab/gitlab-ee:{{applications.gitlab.version}}"
hostname: '{{domains[application_id]}}' hostname: '{{domains | get_domain(application_id)}}'
{% include 'roles/docker-compose/templates/services/base.yml.j2' %} {% include 'roles/docker-compose/templates/services/base.yml.j2' %}
ports: ports:
- "127.0.0.1:{{ports.localhost.http[application_id]}}:80" - "127.0.0.1:{{ports.localhost.http[application_id]}}:80"

View File

@ -2,7 +2,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "docker jenkins" - name: "docker jenkins"

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
loop: "{{ domains }}" loop: "{{ domains }}"
loop_control: loop_control:

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -14,7 +14,7 @@ services:
{% include 'templates/docker/container/depends-on-just-database.yml.j2' %} {% include 'templates/docker/container/depends-on-just-database.yml.j2' %}
{% include 'templates/docker/container/networks.yml.j2' %} {% include 'templates/docker/container/networks.yml.j2' %}
healthcheck: healthcheck:
test: ["CMD", "sh", "-c", "exec 3<>/dev/tcp/localhost/9000 && echo -e 'GET /health/live HTTP/1.1\\r\\nHost: {{domains.keycloak}}\\r\\nConnection: close\\r\\n\\r\\n' >&3 && cat <&3"] test: ["CMD", "sh", "-c", "exec 3<>/dev/tcp/localhost/9000 && echo -e 'GET /health/live HTTP/1.1\\r\\nHost: {{domains | get_domain('keycloak')}}\\r\\nConnection: close\\r\\n\\r\\n' >&3 && cat <&3"]
interval: 30s interval: 30s
timeout: 10s timeout: 10s
retries: 3 retries: 3

View File

@ -2,7 +2,7 @@
# Documentation can be found here: # Documentation can be found here:
# @see https://www.keycloak.org/server/containers # @see https://www.keycloak.org/server/containers
KC_HOSTNAME= https://{{domains[application_id]}} KC_HOSTNAME= https://{{domains | get_domain(application_id)}}
KC_HTTP_ENABLED= true KC_HTTP_ENABLED= true
# Health Checks # Health Checks

View File

@ -517,7 +517,7 @@
"/realms/{{realm}}/account/*" "/realms/{{realm}}/account/*"
], ],
"webOrigins": [ "webOrigins": [
"{{ web_protocol }}://{{domains.keycloak}}" "{{ web_protocol }}://{{domains | get_domain('keycloak')}}"
], ],
"notBefore": 0, "notBefore": 0,
"bearerOnly": false, "bearerOnly": false,
@ -1663,7 +1663,7 @@
"replyTo": "", "replyTo": "",
"host": "{{system_email.host}}", "host": "{{system_email.host}}",
"from": "{{ users['no-reply'].email }}", "from": "{{ users['no-reply'].email }}",
"fromDisplayName": "Keycloak Authentification System - {{domains.keycloak}}", "fromDisplayName": "Keycloak Authentification System - {{domains | get_domain('keycloak')}}",
"envelopeFrom": "", "envelopeFrom": "",
"ssl": "true", "ssl": "true",
"user": "{{ users['no-reply'].email }}" "user": "{{ users['no-reply'].email }}"

View File

@ -6,7 +6,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -3,16 +3,16 @@
include_role: include_role:
name: docker-compose name: docker-compose
- name: Create {{domains[application_id]}}.conf if LDAP is exposed to internet - name: Create {{domains | get_domain(application_id)}}.conf if LDAP is exposed to internet
template: template:
src: "nginx.stream.conf.j2" src: "nginx.stream.conf.j2"
dest: "{{nginx.directories.streams}}{{domains[application_id]}}.conf" dest: "{{nginx.directories.streams}}{{domains | get_domain(application_id)}}.conf"
notify: restart nginx notify: restart nginx
when: applications[application_id].network.public | bool when: applications[application_id].network.public | bool
- name: Remove {{domains[application_id]}}.conf if LDAP is not exposed to internet - name: Remove {{domains | get_domain(application_id)}}.conf if LDAP is not exposed to internet
file: file:
path: "{{ nginx.directories.streams }}{{ domains[application_id] }}.conf" path: "{{ nginx.directories.streams }}{{ domains | get_domain(application_id) }}.conf"
state: absent state: absent
when: not applications[application_id].network.public | bool when: not applications[application_id].network.public | bool

View File

@ -16,7 +16,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: add config.toml - name: add config.toml

View File

@ -3,7 +3,7 @@ database_type: "postgres"
listmonk_settings: listmonk_settings:
- key: "app.root_url" - key: "app.root_url"
value: '"{{ web_protocol }}://{{ domains[application_id] }}"' value: '"{{ web_protocol }}://{{ domains | get_domain(application_id) }}"'
- key: "app.notify_emails" - key: "app.notify_emails"
value: "{{ [ users.administrator.email ] | to_json }}" value: "{{ [ users.administrator.email ] | to_json }}"

View File

@ -8,7 +8,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
nginx_docker_reverse_proxy_extra_configuration: "client_max_body_size 31M;" nginx_docker_reverse_proxy_extra_configuration: "client_max_body_size 31M;"
when: run_once_docker_mailu is not defined when: run_once_docker_mailu is not defined

View File

@ -20,7 +20,7 @@ SUBNET={{networks.local.mailu.subnet}}
DOMAIN={{applications.mailu.domain}} DOMAIN={{applications.mailu.domain}}
# Hostnames for this server, separated with comas # Hostnames for this server, separated with comas
HOSTNAMES={{domains[application_id]}} HOSTNAMES={{domains | get_domain(application_id)}}
# Postmaster local part (will append the main mail domain) # Postmaster local part (will append the main mail domain)
POSTMASTER=admin POSTMASTER=admin
@ -105,7 +105,7 @@ WEB_WEBMAIL=/webmail
SITENAME=Mailservices SITENAME=Mailservices
# Linked Website URL # Linked Website URL
WEBSITE=https://{{domains[application_id]}} WEBSITE=https://{{domains | get_domain(application_id)}}

View File

@ -10,5 +10,5 @@ cert_mount_directory: "{{docker_compose.directories.volumes}}certs/"
# @see https://github.com/heviat/Mailu-OIDC/tree/2024.06 # @see https://github.com/heviat/Mailu-OIDC/tree/2024.06
docker_source: "{{ 'ghcr.io/heviat' if applications[application_id].features.oidc | bool else 'ghcr.io/mailu' }}" docker_source: "{{ 'ghcr.io/heviat' if applications[application_id].features.oidc | bool else 'ghcr.io/mailu' }}"
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"

View File

@ -3,7 +3,7 @@
# @see https://github.com/mastodon/mastodon/blob/main/.env.production.sample # @see https://github.com/mastodon/mastodon/blob/main/.env.production.sample
LOCAL_DOMAIN={{domains[application_id]}} LOCAL_DOMAIN={{domains | get_domain(application_id)}}
ALTERNATE_DOMAINS="{{ domains.mastodon[1:] | join(',') }}" ALTERNATE_DOMAINS="{{ domains.mastodon[1:] | join(',') }}"
SINGLE_USER_MODE={{applications.mastodon.single_user_mode}} SINGLE_USER_MODE={{applications.mastodon.single_user_mode}}
@ -67,7 +67,7 @@ OIDC_SCOPE="openid,profile,email"
# @see https://stackoverflow.com/questions/72108087/how-to-set-the-username-of-mastodon-by-log-in-via-keycloak # @see https://stackoverflow.com/questions/72108087/how-to-set-the-username-of-mastodon-by-log-in-via-keycloak
OIDC_UID_FIELD={{oidc.attributes.username}} OIDC_UID_FIELD={{oidc.attributes.username}}
OIDC_CLIENT_ID={{oidc.client.id}} OIDC_CLIENT_ID={{oidc.client.id}}
OIDC_REDIRECT_URI=https://{{domains[application_id]}}/auth/auth/openid_connect/callback OIDC_REDIRECT_URI=https://{{domains | get_domain(application_id)}}/auth/auth/openid_connect/callback
OIDC_SECURITY_ASSUME_EMAIL_IS_VERIFIED=true OIDC_SECURITY_ASSUME_EMAIL_IS_VERIFIED=true
OIDC_CLIENT_SECRET={{oidc.client.secret}} OIDC_CLIENT_SECRET={{oidc.client.secret}}
# uncomment to only use OIDC for login / registration buttons # uncomment to only use OIDC for login / registration buttons

View File

@ -8,7 +8,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
when: run_once_docker_matomo is not defined when: run_once_docker_matomo is not defined

View File

@ -3,4 +3,4 @@ application_id: "matomo"
database_type: "mariadb" database_type: "mariadb"
# I don't know if this is still necessary # I don't know if this is still necessary
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: add docker-compose.yml - name: add docker-compose.yml

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "Transfer Dockerfile to {{ docker_compose.directories.instance }}" - name: "Transfer Dockerfile to {{ docker_compose.directories.instance }}"

View File

@ -3,7 +3,7 @@
include_role: include_role:
name: docker-central-database name: docker-central-database
- name: "include tasks setup-domain.yml with {{domains[application_id]}}" - name: "include tasks setup-domain.yml with {{domains | get_domain(application_id)}}"
include_tasks: setup-domain.yml include_tasks: setup-domain.yml
loop: "{{ mybb_domains + [source_domain] }}" loop: "{{ mybb_domains + [source_domain] }}"
loop_control: loop_control:

View File

@ -4,12 +4,12 @@
include_role: include_role:
name: nginx-https-get-cert name: nginx-https-get-cert
vars: vars:
domain: "{{domains[application_id]}}" domain: "{{domains | get_domain(application_id)}}"
- name: configure {{domains[application_id]}}.conf - name: configure {{domains | get_domain(application_id)}}.conf
template: template:
src: "roles/nginx-docker-reverse-proxy/templates/vhost/basic.conf.j2" src: "roles/nginx-docker-reverse-proxy/templates/vhost/basic.conf.j2"
dest: "{{nginx.directories.http.servers}}{{domains[application_id]}}.conf" dest: "{{nginx.directories.http.servers}}{{domains | get_domain(application_id)}}.conf"
notify: restart nginx notify: restart nginx
vars: vars:
nginx_docker_reverse_proxy_extra_configuration: "sub_filter '{{source_domain}}' '{{domains[application_id]}}';" nginx_docker_reverse_proxy_extra_configuration: "sub_filter '{{source_domain}}' '{{domains | get_domain(application_id)}}';"

View File

@ -26,7 +26,7 @@
- name: create nextcloud nginx proxy configuration file - name: create nextcloud nginx proxy configuration file
template: template:
src: "nginx/host.conf.j2" src: "nginx/host.conf.j2"
dest: "{{nginx.directories.http.servers}}{{domains[application_id]}}.conf" dest: "{{nginx.directories.http.servers}}{{domains | get_domain(application_id)}}.conf"
notify: restart nginx notify: restart nginx
- name: create internal nextcloud nginx configuration - name: create internal nextcloud nginx configuration

View File

@ -21,7 +21,7 @@ return array (
'oidc_login_auto_redirect' => true, 'oidc_login_auto_redirect' => true,
// Redirect to this page after logging out the user // Redirect to this page after logging out the user
'oidc_login_logout_url' => 'https://{{domains[application_id]}}', 'oidc_login_logout_url' => 'https://{{domains | get_domain(application_id)}}',
// If set to true the user will be redirected to the // If set to true the user will be redirected to the
// logout endpoint of the OIDC provider after logout // logout endpoint of the OIDC provider after logout

View File

@ -29,10 +29,10 @@ NEXTCLOUD_ADMIN_PASSWORD= "{{applications[application_id].credentials.admi
# Security # Security
NEXTCLOUD_TRUSTED_DOMAINS= "{{domains[application_id]}}" NEXTCLOUD_TRUSTED_DOMAINS= "{{domains | get_domain(application_id)}}"
# Whitelist local docker gateway in Nextcloud to prevent brute-force throtteling # Whitelist local docker gateway in Nextcloud to prevent brute-force throtteling
TRUSTED_PROXIES= "192.168.102.65" TRUSTED_PROXIES= "192.168.102.65"
OVERWRITECLIURL= "{{ web_protocol }}://{{domains[application_id]}}" OVERWRITECLIURL= "{{ web_protocol }}://{{domains | get_domain(application_id)}}"
OVERWRITEPROTOCOL= "https" OVERWRITEPROTOCOL= "https"
# Redis Configuration # Redis Configuration

View File

@ -7,7 +7,7 @@ database_password: "{{applications.nextcloud.cr
database_type: "mariadb" # Database flavor database_type: "mariadb" # Database flavor
# Networking # Networking
domain: "{{ domains[application_id] }}" # Public domain at which Nextcloud will be accessable domain: "{{ domains | get_domain(application_id) }}" # Public domain at which Nextcloud will be accessable
http_port: "{{ ports.localhost.http[application_id] }}" # Port at which nextcloud is reachable in the local network http_port: "{{ ports.localhost.http[application_id] }}" # Port at which nextcloud is reachable in the local network
# Control Node # Control Node

View File

@ -25,7 +25,7 @@ plugin_configuration:
configkey: "custom_providers" configkey: "custom_providers"
configvalue: configvalue:
custom_oidc: custom_oidc:
- name: "{{ domains.keycloak }}" - name: "{{ domains | get_domain('keycloak') }}"
title: "keycloak" title: "keycloak"
style: "keycloak" style: "keycloak"
authorizeUrl: "{{ oidc.client.authorize_url }}" authorizeUrl: "{{ oidc.client.authorize_url }}"

View File

@ -15,7 +15,7 @@ nextcloud_system_config:
value: "{{ HOST_LL | upper }}" value: "{{ HOST_LL | upper }}"
- parameter: "trusted_domains 0" - parameter: "trusted_domains 0"
value: "{{domains[application_id]}}" value: "{{domains | get_domain(application_id)}}"
- parameter: "overwrite.cli.url" - parameter: "overwrite.cli.url"
value: "{{ web_protocol }}://{{domains[application_id]}}" value: "{{ web_protocol }}://{{domains | get_domain(application_id)}}"

View File

@ -3,7 +3,7 @@ cookie_secret = "{{ applications[oauth2_proxy_application_id].creden
email_domains = "{{ primary_domain }}" email_domains = "{{ primary_domain }}"
cookie_secure = "true" # True is necessary to force the cookie set via https cookie_secure = "true" # True is necessary to force the cookie set via https
upstreams = "http://{{ applications[oauth2_proxy_application_id].oauth2_proxy.application }}:{{ applications[oauth2_proxy_application_id].oauth2_proxy.port }}" upstreams = "http://{{ applications[oauth2_proxy_application_id].oauth2_proxy.application }}:{{ applications[oauth2_proxy_application_id].oauth2_proxy.port }}"
cookie_domains = ["{{ domains[oauth2_proxy_application_id] }}", "{{ domains.keycloak }}"] # Required so cookie can be read on all subdomains. cookie_domains = ["{{ domains[oauth2_proxy_application_id] }}", "{{ domains | get_domain('keycloak') }}"] # Required so cookie can be read on all subdomains.
whitelist_domains = [".{{ primary_domain }}"] # Required to allow redirection back to original requested target. whitelist_domains = [".{{ primary_domain }}"] # Required to allow redirection back to original requested target.
# keycloak provider # keycloak provider

View File

@ -1,6 +1,6 @@
configuration_file: "oauth2-proxy-keycloak.cfg" # Needs to be set true in the roles which use it configuration_file: "oauth2-proxy-keycloak.cfg" # Needs to be set true in the roles which use it
version: "latest" # Docker Image version version: "latest" # Docker Image version
redirect_url: "{{ web_protocol }}://{{domains.keycloak}}/auth/realms/{{primary_domain}}/protocol/openid-connect/auth" # The redirect URL for the OAuth2 flow. It should match the redirect URL configured in Keycloak. redirect_url: "{{ web_protocol }}://{{domains | get_domain('keycloak')}}/auth/realms/{{primary_domain}}/protocol/openid-connect/auth" # The redirect URL for the OAuth2 flow. It should match the redirect URL configured in Keycloak.
allowed_roles: admin # Restrict it default to admin role. Use the vars/main.yml to open the specific role for other groups allowed_roles: admin # Restrict it default to admin role. Use the vars/main.yml to open the specific role for other groups
features: features:
matomo: true matomo: true

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "Create {{openproject_plugins_service}}" - name: "Create {{openproject_plugins_service}}"

View File

@ -7,7 +7,7 @@
# https://www.openproject.org/docs/installation-and-operations/configuration/environment/ # https://www.openproject.org/docs/installation-and-operations/configuration/environment/
# #
OPENPROJECT_HTTPS=true OPENPROJECT_HTTPS=true
OPENPROJECT_HOST__NAME={{domains[application_id]}} OPENPROJECT_HOST__NAME={{domains | get_domain(application_id)}}
OPENPROJECT_RAILS__RELATIVE__URL__ROOT= OPENPROJECT_RAILS__RELATIVE__URL__ROOT=
IMAP_ENABLED=false IMAP_ENABLED=false
POSTGRES_PASSWORD="{{ database_password }}" POSTGRES_PASSWORD="{{ database_password }}"

View File

@ -8,7 +8,7 @@ PEERTUBE_DB_SSL=false
PEERTUBE_DB_HOSTNAME={{database_host}} PEERTUBE_DB_HOSTNAME={{database_host}}
# PeerTube server configuration # PeerTube server configuration
PEERTUBE_WEBSERVER_HOSTNAME={{domains[application_id]}} PEERTUBE_WEBSERVER_HOSTNAME={{domains | get_domain(application_id)}}
PEERTUBE_TRUST_PROXY=["127.0.0.1", "loopback"] PEERTUBE_TRUST_PROXY=["127.0.0.1", "loopback"]
PEERTUBE_SECRET={{applications[application_id].credentials.secret}} PEERTUBE_SECRET={{applications[application_id].credentials.secret}}

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "configure pgadmin servers" - name: "configure pgadmin servers"

View File

@ -6,7 +6,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -1,3 +1,3 @@
# @See https://github.com/leenooks/phpLDAPadmin/wiki/Docker-Container # @See https://github.com/leenooks/phpLDAPadmin/wiki/Docker-Container
APP_URL= https://{{domains[application_id]}} APP_URL= https://{{domains | get_domain(application_id)}}
LDAP_HOST= {{ldap.server.domain}} LDAP_HOST= {{ldap.server.domain}}

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -5,10 +5,10 @@ APP_KEY={{applications[application_id].credentials.app_key}}
APP_NAME="{{applications.pixelfed.titel}}" APP_NAME="{{applications.pixelfed.titel}}"
APP_ENV=production APP_ENV=production
APP_DEBUG={{enable_debug | string | lower }} APP_DEBUG={{enable_debug | string | lower }}
APP_URL=https://{{domains[application_id]}} APP_URL=https://{{domains | get_domain(application_id)}}
APP_DOMAIN="{{domains[application_id]}}" APP_DOMAIN="{{domains | get_domain(application_id)}}"
ADMIN_DOMAIN="{{domains[application_id]}}" ADMIN_DOMAIN="{{domains | get_domain(application_id)}}"
SESSION_DOMAIN="{{domains[application_id]}}" SESSION_DOMAIN="{{domains | get_domain(application_id)}}"
OPEN_REGISTRATION=false OPEN_REGISTRATION=false
ENFORCE_EMAIL_VERIFICATION=false ENFORCE_EMAIL_VERIFICATION=false

View File

@ -21,7 +21,7 @@ class LookupModule(LookupBase):
- Retrieves the description from galaxy_info.description in meta/main.yml - Retrieves the description from galaxy_info.description in meta/main.yml
- Retrieves the icon class from galaxy_info.logo.class - Retrieves the icon class from galaxy_info.logo.class
- Retrieves the tags from galaxy_info.galaxy_tags - Retrieves the tags from galaxy_info.galaxy_tags
- Builds the URL using the 'domains' variable (e.g. domains[application_id]) - Builds the URL using the 'domains' variable (e.g. domains | get_domain(application_id))
- Sets the iframe flag from applications[application_id].features.iframe - Sets the iframe flag from applications[application_id].features.iframe
Only cards whose application_id is included in the variable group_names are returned. Only cards whose application_id is included in the variable group_names are returned.

View File

@ -8,7 +8,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
when: run_once_docker_portfolio is not defined when: run_once_docker_portfolio is not defined

View File

@ -36,19 +36,19 @@
description: Access the central admin console description: Access the central admin console
icon: icon:
class: fa-solid fa-shield-halved class: fa-solid fa-shield-halved
url: https://{{domains.keycloak}}/admin url: https://{{domains | get_domain('keycloak')}}/admin
iframe: {{ applications | is_feature_enabled('portfolio_iframe','keycloak') }} iframe: {{ applications | is_feature_enabled('portfolio_iframe','keycloak') }}
- name: Profile - name: Profile
description: Update your personal admin settings description: Update your personal admin settings
icon: icon:
class: fa-solid fa-user-gear class: fa-solid fa-user-gear
url: https://{{ domains.keycloak }}/realms/{{oidc.client.id}}/account url: https://{{ domains | get_domain('keycloak') }}/realms/{{oidc.client.id}}/account
iframe: {{ applications | is_feature_enabled('portfolio_iframe','keycloak') }} iframe: {{ applications | is_feature_enabled('portfolio_iframe','keycloak') }}
- name: Logout - name: Logout
description: End your admin session securely description: End your admin session securely
icon: icon:
class: fa-solid fa-right-from-bracket class: fa-solid fa-right-from-bracket
url: https://{{ domains.keycloak }}/realms/{{oidc.client.id}}/protocol/openid-connect/logout url: https://{{ domains | get_domain('keycloak') }}/realms/{{oidc.client.id}}/protocol/openid-connect/logout
iframe: false iframe: false
{% endif %} {% endif %}

View File

@ -23,7 +23,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -5,7 +5,7 @@ APP_ENV=production
APP_DEBUG={{enable_debug | string | lower }} APP_DEBUG={{enable_debug | string | lower }}
# Please regenerate the APP_KEY value by calling `docker compose run --rm app php artisan key:generate --show`. Copy paste the value here # Please regenerate the APP_KEY value by calling `docker compose run --rm app php artisan key:generate --show`. Copy paste the value here
APP_KEY={{applications[application_id].credentials.app_key}} APP_KEY={{applications[application_id].credentials.app_key}}
APP_URL=https://{{domains[application_id]}} APP_URL=https://{{domains | get_domain(application_id)}}
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones - TZ identifier # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones - TZ identifier
APP_TIMEZONE='{{ HOST_TIMEZONE }}' APP_TIMEZONE='{{ HOST_TIMEZONE }}'
APP_LOCALE={{ HOST_LL }} APP_LOCALE={{ HOST_LL }}

View File

@ -19,7 +19,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -13,7 +13,7 @@ services:
environment: environment:
SPRING_PROFILES_ACTIVE: docker,postgresql,saml2 SPRING_PROFILES_ACTIVE: docker,postgresql,saml2
OPENJPA_REMOTE_COMMIT: sjvm OPENJPA_REMOTE_COMMIT: sjvm
SERVICE_DISCOVERY_ADDRESS: {{ web_protocol }}://{{ domains[application_id] }}/{{syncope_paths[rest]}}/ SERVICE_DISCOVERY_ADDRESS: {{ web_protocol }}://{{ domains | get_domain(application_id) }}/{{syncope_paths[rest]}}/
# database variablen auslesen # database variablen auslesen
console: console:
@ -25,7 +25,7 @@ services:
restart: always restart: always
environment: environment:
SPRING_PROFILES_ACTIVE: docker,saml2 SPRING_PROFILES_ACTIVE: docker,saml2
SERVICE_DISCOVERY_ADDRESS: {{ web_protocol }}://{{ domains[application_id] }}/{{syncope_paths[console]}}/ SERVICE_DISCOVERY_ADDRESS: {{ web_protocol }}://{{ domains | get_domain(application_id) }}/{{syncope_paths[console]}}/
enduser: enduser:
depends_on: depends_on:
@ -36,5 +36,5 @@ services:
restart: always restart: always
environment: environment:
SPRING_PROFILES_ACTIVE: docker,saml2 SPRING_PROFILES_ACTIVE: docker,saml2
SERVICE_DISCOVERY_ADDRESS: {{ web_protocol }}://{{ domains[application_id] }}/{{syncope_paths[enduser]}}/ SERVICE_DISCOVERY_ADDRESS: {{ web_protocol }}://{{ domains | get_domain(application_id) }}/{{syncope_paths[enduser]}}/

View File

@ -16,7 +16,7 @@ server
{% include 'roles/letsencrypt/templates/ssl_header.j2' %} {% include 'roles/letsencrypt/templates/ssl_header.j2' %}
{% for path in syncope_paths.values() %} {% for path in syncope_paths.values() %}
{% set location = web_protocol ~ '://' ~ domains[application_id] ~ '/' ~ path ~ '/' %} {% set location = web_protocol ~ '://' ~ domains | get_domain(application_id) ~ '/' ~ path ~ '/' %}
{% include 'roles/nginx-docker-reverse-proxy/templates/location/proxy_basic.conf.j2'%} {% include 'roles/nginx-docker-reverse-proxy/templates/location/proxy_basic.conf.j2'%}
{% endfor %} {% endfor %}
} }

View File

@ -1,7 +1,7 @@
# General Configuration # General Configuration
application_id: syncope application_id: syncope
database_type: "postgres" database_type: "postgres"
database_password: "{{ domains[application_id].credentials.database_password }}" database_password: "{{ domains | get_domain(application_id).credentials.database_password }}"
# Application Specific # Application Specific
syncope_keymaster_address: http://localhost:8080/syncope/rest/keymaster syncope_keymaster_address: http://localhost:8080/syncope/rest/keymaster
@ -10,8 +10,8 @@ syncope_paths:
console: console console: console
enduser: enduser enduser: enduser
syncope_anonymous_user: "{{ domains[application_id].users.anonymous.username }}" syncope_anonymous_user: "{{ domains | get_domain(application_id).users.anonymous.username }}"
syncope_anonymous_password: "{{ domains[application_id].credentials.anonymous.password }}" syncope_anonymous_password: "{{ domains | get_domain(application_id).credentials.anonymous.password }}"
syncope_administrator_user: "{{ domains[application_id].users.administrator.username }}" syncope_administrator_user: "{{ domains | get_domain(application_id).users.administrator.username }}"
syncope_administrator_password: "{{ domains[application_id].credentials.administrator_password }}" syncope_administrator_password: "{{ domains | get_domain(application_id).credentials.administrator_password }}"

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "include role docker-repository-setup for {{application_id}}" - name: "include role docker-repository-setup for {{application_id}}"

View File

@ -1,6 +1,6 @@
# Taiga's URLs - Variables to define where Taiga should be served # Taiga's URLs - Variables to define where Taiga should be served
TAIGA_SITES_SCHEME = https # serve Taiga using "http" or "https" (secured) connection TAIGA_SITES_SCHEME = https # serve Taiga using "http" or "https" (secured) connection
TAIGA_SITES_DOMAIN = "{{domains[application_id]}}" # Taiga's base URL TAIGA_SITES_DOMAIN = "{{domains | get_domain(application_id)}}" # Taiga's base URL
TAIGA_SUBPATH = "" # it'll be appended to the TAIGA_DOMAIN (use either "" or a "/subpath") TAIGA_SUBPATH = "" # it'll be appended to the TAIGA_DOMAIN (use either "" or a "/subpath")
WEBSOCKETS_SCHEME = wss # events connection protocol (use either "ws" or "wss") WEBSOCKETS_SCHEME = wss # events connection protocol (use either "ws" or "wss")

View File

@ -2,7 +2,7 @@
command: > command: >
docker-compose exec -T -u www-data application docker-compose exec -T -u www-data application
wp core install wp core install
--url="{{ web_protocol }}://{{ domains[application_id][0] }}" --url="{{ web_protocol }}://{{ domains | get_domain(application_id)[0] }}"
--title="{{ applications[application_id].title }}" --title="{{ applications[application_id].title }}"
--admin_user="{{ applications[application_id].users.administrator.username }}" --admin_user="{{ applications[application_id].users.administrator.username }}"
--admin_password="{{ applications[application_id].credentials.administrator_password }}" --admin_password="{{ applications[application_id].credentials.administrator_password }}"

View File

@ -5,7 +5,7 @@
- name: Wait for Discourse API - name: Wait for Discourse API
wait_for: wait_for:
host: "{{ domains.discourse }}" host: "{{ domains | get_domain('discourse') }}"
port: 80 port: 80
delay: 5 delay: 5
timeout: 600 timeout: 600

View File

@ -31,6 +31,6 @@ csp:
- "https://fonts.bunny.net" - "https://fonts.bunny.net"
script-src: script-src:
- "https://cdn.gtranslate.net" - "https://cdn.gtranslate.net"
- "{{ domains.wordpress[0] }}" - "{{ domains | get_domain('wordpress') }}"
style-src: style-src:
- "https://fonts.bunny.net" - "https://fonts.bunny.net"

View File

@ -11,7 +11,7 @@ discourse_settings:
- name: discourse_connect - name: discourse_connect
key: url key: url
value: "{{ web_protocol }}://{{ domains.discourse }}" value: "{{ web_protocol }}://{{ domains | get_domain('discourse') }}"
- name: discourse_connect - name: discourse_connect
key: api-key key: api-key
value: "{{ vault_discourse_api_key }}" value: "{{ vault_discourse_api_key }}"

View File

@ -7,7 +7,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "copy docker-compose.yml and env file" - name: "copy docker-compose.yml and env file"

View File

@ -2,6 +2,6 @@ YOURLS_DB_HOST: "{{database_host}}"
YOURLS_DB_USER: "{{database_username}}" YOURLS_DB_USER: "{{database_username}}"
YOURLS_DB_PASS: "{{database_password}}" YOURLS_DB_PASS: "{{database_password}}"
YOURLS_DB_NAME: "{{database_name}}" YOURLS_DB_NAME: "{{database_name}}"
YOURLS_SITE: "{{ web_protocol }}://{{domains[application_id]}}" YOURLS_SITE: "{{ web_protocol }}://{{domains | get_domain(application_id)}}"
YOURLS_USER: "{{applications.yourls.users.administrator.username}}" YOURLS_USER: "{{applications.yourls.users.administrator.username}}"
YOURLS_PASS: "{{applications[application_id].credentials.administrator_password}}" YOURLS_PASS: "{{applications[application_id].credentials.administrator_password}}"

View File

@ -3,6 +3,31 @@ import requests
import sys import sys
import re import re
def get_expected_statuses(domain: str, parts: list[str], redirected_domains: set[str]) -> list[int]:
"""
Determine the expected HTTP status codes based on the domain name.
Args:
domain: The full domain string (e.g. 'example.com').
parts: The domain split into its subcomponents (e.g. ['www', 'example', 'com']).
redirected_domains: A set of domains that should trigger a redirect.
Returns:
A list of expected HTTP status codes.
"""
{%- if domains | get_domain('listmonk') | safe_var | bool %}
if domain == '{{domains | get_domain('listmonk')}}':
return [404]
{%- endif %}
if (parts and parts[0] == 'www') or (domain in redirected_domains):
return [301]
{%- if domains | get_domain('yourls') | safe_var | bool %}
if domain == '{{domains | get_domain('yourls')}}':
return [403]
{%- endif %}
# Default: Expect status code 200 or 302 for a domain
return [200,302]
# file in which fqdn server configs are deposit # file in which fqdn server configs are deposit
config_path = '{{nginx.directories.http.servers}}' config_path = '{{nginx.directories.http.servers}}'
@ -22,19 +47,12 @@ for filename in os.listdir(config_path):
# Prepare the URL and expected status codes # Prepare the URL and expected status codes
url = f"{{ web_protocol }}://{domain}" url = f"{{ web_protocol }}://{domain}"
# Default: Expect status code 200 or 302 for a domain
expected_statuses = [200,302]
redirected_domains = [domain['source'] for domain in {{redirect_domain_mappings}}] redirected_domains = [domain['source'] for domain in {{redirect_domain_mappings}}]
redirected_domains.append("{{domains.mailu}}") {%- if domains | get_domain('mailu') | safe_var | bool %}
redirected_domains.append("{{domains | get_domain('mailu')}}")
{%- endif %}
# Determine expected status codes based on the domain expected_statuses = get_expected_statuses(domain, parts, redirected_domains)
if domain == '{{domains.listmonk}}':
expected_statuses = [404]
elif parts[0] == 'www' or domain in redirected_domains:
expected_statuses = [301]
elif domain == '{{domains.yourls}}':
expected_statuses = [403]
try: try:
# Send a HEAD request to get only the response header # Send a HEAD request to get only the response header

View File

@ -3,11 +3,11 @@
include_role: include_role:
name: nginx-https-get-cert-modify-all name: nginx-https-get-cert-modify-all
vars: vars:
domain: "{{domains[application_id]}}" domain: "{{domains | get_domain(application_id)}}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "generate {{domains[application_id]}}.conf" - name: "generate {{domains | get_domain(application_id)}}.conf"
template: template:
src: "nginx.conf.j2" src: "nginx.conf.j2"
dest: "{{nginx.directories.http.servers}}{{domains[application_id]}}.conf" dest: "{{nginx.directories.http.servers}}{{domains | get_domain(application_id)}}.conf"
notify: restart nginx notify: restart nginx

View File

@ -1,6 +1,6 @@
server server
{ {
server_name {{domains[application_id]}}; server_name {{domains | get_domain(application_id)}};
{% include 'roles/letsencrypt/templates/ssl_header.j2' %} {% include 'roles/letsencrypt/templates/ssl_header.j2' %}

View File

@ -1,2 +1,2 @@
application_id: "file_server" application_id: "file_server"
domain: "{{ domains[application_id] }}" domain: "{{ domains | get_domain(application_id) }}"

View File

@ -3,11 +3,11 @@
include_role: include_role:
name: nginx-https-get-cert-modify-all name: nginx-https-get-cert-modify-all
vars: vars:
domain: "{{domains[application_id]}}" domain: "{{domains | get_domain(application_id)}}"
http_port: "{{ ports.localhost.http[application_id] }}" http_port: "{{ ports.localhost.http[application_id] }}"
- name: "generate {{domains[application_id]}}.conf" - name: "generate {{domains | get_domain(application_id)}}.conf"
template: template:
src: "nginx.conf.j2" src: "nginx.conf.j2"
dest: "{{nginx.directories.http.servers}}{{domains[application_id]}}.conf" dest: "{{nginx.directories.http.servers}}{{domains | get_domain(application_id)}}.conf"
notify: restart nginx notify: restart nginx

View File

@ -1,6 +1,6 @@
server server
{ {
server_name {{domains[application_id]}}; server_name {{domains | get_domain(application_id)}};
{% include 'roles/letsencrypt/templates/ssl_header.j2' %} {% include 'roles/letsencrypt/templates/ssl_header.j2' %}

View File

@ -1,2 +1,2 @@
application_id: "html_server" application_id: "html_server"
domain: "{{domains[application_id]}}" domain: "{{domains | get_domain(application_id)}}"

View File

@ -0,0 +1,69 @@
# tests/unit/test_get_domain_filter.py
import unittest
import sys
import os
# Ensure filter_plugins directory is on the path
sys.path.insert(
0,
os.path.abspath(
os.path.join(os.path.dirname(__file__), '../../filter_plugins')
)
)
from get_domain_filter import FilterModule
from ansible.errors import AnsibleFilterError
class TestGetDomainFilter(unittest.TestCase):
def setUp(self):
# Retrieve the get_domain filter function
self.get_domain = FilterModule().filters()['get_domain']
def test_string_value(self):
domains = {'app': 'example.com'}
self.assertEqual(self.get_domain(domains, 'app'), 'example.com')
def test_dict_value(self):
domains = {'app': {'primary': 'primary.com', 'secondary': 'secondary.com'}}
self.assertEqual(self.get_domain(domains, 'app'), 'primary.com')
def test_list_value(self):
domains = {'app': ['first.com', 'second.com']}
self.assertEqual(self.get_domain(domains, 'app'), 'first.com')
def test_missing_application_id(self):
domains = {'app': 'example.com'}
with self.assertRaises(AnsibleFilterError):
self.get_domain(domains, 'missing')
def test_domains_not_dict(self):
with self.assertRaises(AnsibleFilterError):
self.get_domain(['not', 'a', 'dict'], 'app')
def test_empty_string(self):
domains = {'app': ''}
with self.assertRaises(AnsibleFilterError):
self.get_domain(domains, 'app')
def test_empty_dict(self):
domains = {'app': {}}
with self.assertRaises(AnsibleFilterError):
self.get_domain(domains, 'app')
def test_empty_list(self):
domains = {'app': []}
with self.assertRaises(AnsibleFilterError):
self.get_domain(domains, 'app')
def test_non_string_in_dict(self):
domains = {'app': {'key': 123}}
with self.assertRaises(AnsibleFilterError):
self.get_domain(domains, 'app')
def test_non_string_in_list(self):
domains = {'app': [123]}
with self.assertRaises(AnsibleFilterError):
self.get_domain(domains, 'app')
if __name__ == '__main__':
unittest.main()