Compare commits

..

13 Commits

127 changed files with 918 additions and 227 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,69 @@
import re
from ansible.errors import AnsibleFilterError
class FilterModule(object):
"""
Custom Ansible filter plugin:
- generate_all_domains: Flatten, dedupe, sort domains with optional www prefixes
- generate_base_sld_domains: Extract unique sld.tld domains from values and redirect sources
"""
def filters(self):
return {
'generate_all_domains': self.generate_all_domains,
'generate_base_sld_domains': self.generate_base_sld_domains,
}
@staticmethod
def generate_all_domains(domains_dict, include_www=True):
"""
Transform a dict of domains (values: str, list, dict) into a flat list,
optionally add 'www.' prefixes, dedupe and sort alphabetically.
Avoids infinite loops by snapshotting initial domain list for www prefixes.
"""
try:
flat = FilterModule._flatten_domain_values(domains_dict)
if include_www:
# Snapshot original list to avoid extending while iterating
original = list(flat)
flat.extend([f"www.{d}" for d in original])
return sorted(set(flat))
except Exception as exc:
raise AnsibleFilterError(f"generate_all_domains failed: {exc}")
@staticmethod
def generate_base_sld_domains(domains_dict, redirect_mappings):
"""
Flatten domains_dict and redirect_mappings, extract second-level + top-level domains.
redirect_mappings: list of dicts with key 'source'
"""
try:
flat = FilterModule._flatten_domain_values(domains_dict)
for mapping in redirect_mappings or []:
src = mapping.get('source')
if isinstance(src, str):
flat.append(src)
elif isinstance(src, list):
flat.extend(src)
pattern = re.compile(r'^(?:.*\.)?([^.]+\.[^.]+)$')
slds = {m.group(1) for d in flat if (m := pattern.match(d))}
return sorted(slds)
except Exception as exc:
raise AnsibleFilterError(f"generate_base_sld_domains failed: {exc}")
@staticmethod
def _flatten_domain_values(domains_dict):
"""
Helper to extract domain strings from dict values (str, list, dict).
"""
flat = []
for val in (domains_dict or {}).values():
if isinstance(val, str):
flat.append(val)
elif isinstance(val, list):
flat.extend(val)
elif isinstance(val, dict):
flat.extend(val.values())
return flat

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

@ -1,8 +1,15 @@
import os
import yaml
from ansible.errors import AnsibleFilterError from ansible.errors import AnsibleFilterError
class FilterModule(object): class FilterModule(object):
""" """
Custom filters for conditional domain assignments Custom filters for conditional domain assignments, handling both direct group matches
and recursive role dependency resolution.
Determines if a given application_id (domain_key) should have its domain added by checking:
- If domain_key is explicitly listed in group_names, or
- If domain_key matches any application_id of roles reachable from active groups via dependencies.
""" """
def filters(self): def filters(self):
@ -13,17 +20,67 @@ class FilterModule(object):
@staticmethod @staticmethod
def add_domain_if_group(domains_dict, domain_key, domain_value, group_names): def add_domain_if_group(domains_dict, domain_key, domain_value, group_names):
""" """
Add {domain_key: domain_value} to domains_dict Add {domain_key: domain_value} to domains_dict if either:
only if domain_key is in group_names. 1) domain_key is in group_names (direct inclusion), or
2) domain_key is among collected application_id values of roles
reachable from any group in group_names via recursive dependencies.
Usage in Jinja: Parameters:
{{ {} domains_dict: existing dict of domains
| add_domain_if_group('akaunting', 'akaunting.' ~ primary_domain, group_names) }} domain_key: name of the application to check
domain_value: domain or dict/list of domains to assign
group_names: list of active group (role/application) names
""" """
try: try:
result = dict(domains_dict) result = dict(domains_dict)
# Direct group match: if the application name itself is in group_names
if domain_key in group_names: if domain_key in group_names:
result[domain_key] = domain_value result[domain_key] = domain_value
return result
# Setup roles directory path
plugin_dir = os.path.dirname(__file__)
project_root = os.path.abspath(os.path.join(plugin_dir, '..'))
roles_dir = os.path.join(project_root, 'roles')
# Collect all roles reachable from the active groups
def collect_roles(role_name, collected):
if role_name in collected:
return
collected.add(role_name)
meta_path = os.path.join(roles_dir, role_name, 'meta', 'main.yml')
if os.path.isfile(meta_path):
with open(meta_path) as f:
meta = yaml.safe_load(f) or {}
for dep in meta.get('dependencies', []):
if isinstance(dep, str):
dep_name = dep
elif isinstance(dep, dict):
dep_name = dep.get('role') or dep.get('name')
else:
continue
collect_roles(dep_name, collected)
included_roles = set()
for grp in group_names:
collect_roles(grp, included_roles)
# Gather application_ids from each included role
app_ids = set()
for role in included_roles:
vars_main = os.path.join(roles_dir, role, 'vars', 'main.yml')
if os.path.isfile(vars_main):
with open(vars_main) as f:
vars_data = yaml.safe_load(f) or {}
app_id = vars_data.get('application_id')
if app_id:
app_ids.add(app_id)
# Indirect inclusion: match by application_id
if domain_key in app_ids:
result[domain_key] = domain_value
return result return result
except Exception as exc: except Exception as exc:
raise AnsibleFilterError(f"add_domain_if_group failed: {exc}") raise AnsibleFilterError(f"add_domain_if_group failed: {exc}")

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:

55
filter_plugins/safe.py Normal file
View File

@ -0,0 +1,55 @@
from jinja2 import Undefined
def safe_placeholders(template: str, mapping: dict = None) -> str:
"""
Format a template like "{url}/logo.png".
If mapping is provided (not None) and ANY placeholder is missing or maps to None/empty string, the function will raise KeyError.
If mapping is None, missing placeholders or invalid templates return empty string.
Numerical zero or False are considered valid values.
Any other formatting errors return an empty string.
"""
# Non-string templates yield empty
if not isinstance(template, str):
return ''
class SafeDict(dict):
def __getitem__(self, key):
val = super().get(key, None)
# Treat None or empty string as missing
if val is None or (isinstance(val, str) and val == ''):
raise KeyError(key)
return val
def __missing__(self, key):
raise KeyError(key)
silent = mapping is None
data = mapping or {}
try:
return template.format_map(SafeDict(data))
except KeyError:
if silent:
return ''
raise
except Exception:
return ''
def safe_var(value):
"""
Ansible filter: returns the value unchanged unless it's Undefined or None,
in which case returns an empty string.
Catches all exceptions and yields ''.
"""
try:
if isinstance(value, Undefined) or value is None:
return ''
return value
except Exception:
return ''
class FilterModule(object):
def filters(self):
return {
'safe_var': safe_var,
'safe_placeholders': safe_placeholders,
}

View File

@ -0,0 +1,29 @@
# file: filter_plugins/safe_join.py
"""
Ansible filter plugin that joins a base string and a tail path safely.
If the base is falsy (None, empty, etc.), returns an empty string.
"""
def safe_join(base, tail):
"""
Safely join base and tail into a path or URL.
- base: the base string. If falsy, returns ''.
- tail: the string to append. Leading/trailing slashes are handled.
- On any exception, returns ''.
"""
try:
if not base:
return ''
base_str = str(base).rstrip('/')
tail_str = str(tail).lstrip('/')
return f"{base_str}/{tail_str}"
except Exception:
return ''
class FilterModule(object):
def filters(self):
return {
'safe_join': safe_join,
}

View File

@ -21,8 +21,7 @@ defaults_domains: >-
| add_domain_if_group('mailu', 'mail.' ~ primary_domain, group_names) | add_domain_if_group('mailu', 'mail.' ~ primary_domain, group_names)
| add_domain_if_group('mastodon', ['microblog.' ~ primary_domain], group_names) | add_domain_if_group('mastodon', ['microblog.' ~ primary_domain], group_names)
| add_domain_if_group('matomo', 'matomo.' ~ primary_domain, group_names) | add_domain_if_group('matomo', 'matomo.' ~ primary_domain, group_names)
| add_domain_if_group('matrix', 'matrix.' ~ primary_domain, group_names) | add_domain_if_group('matrix', {'synapse': 'matrix.' ~ primary_domain, 'element':'element.' ~ primary_domain}, group_names)
| add_domain_if_group('matrix', 'element.' ~ primary_domain, group_names)
| add_domain_if_group('moodle', 'academy.' ~ primary_domain, group_names) | add_domain_if_group('moodle', 'academy.' ~ primary_domain, group_names)
| add_domain_if_group('mediawiki', 'wiki.' ~ primary_domain, group_names) | add_domain_if_group('mediawiki', 'wiki.' ~ primary_domain, group_names)
| add_domain_if_group('nextcloud', 'cloud.' ~ primary_domain, group_names) | add_domain_if_group('nextcloud', 'cloud.' ~ primary_domain, group_names)

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

@ -9,23 +9,31 @@ defaults_service_provider:
city: "Cybertown" city: "Cybertown"
postal_code: "00001" postal_code: "00001"
country: "Nexusland" country: "Nexusland"
logo: "{{applications.assets_server.url}}/logo.png" logo: "{{ applications.assets_server.url | safe_var | safe_join('logo.png') }}"
platform: platform:
titel: "CyMaIS Demo" titel: "CyMaIS Demo"
subtitel: "The Future of Self-Hosted Infrastructure. Secure. Automated. Sovereign." subtitel: "The Future of Self-Hosted Infrastructure. Secure. Automated. Sovereign."
logo: "{{applications.assets_server.url}}/img/logo.png" logo: "{{ applications.assets_server.url | safe_var | safe_join('logo.png') }}"
favicon: "{{applications.assets_server.url}}/img/favicon.ico" favicon: "{{ applications.assets_server.url | safe_var | safe_join('favicon.ico') }}"
contact: contact:
bluesky: "{{ '@' ~ users.administrator.username ~ '.' ~ domains.[application_id]['api'] if 'bluesky' in group_names else '' }}" bluesky: >-
{{ ('@' ~ users.administrator.username ~ '.' ~ domains.bluesky.api)
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.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"
source_code: "https://github.com/kevinveenbirkenbach/cymais" source_code: "https://github.com/kevinveenbirkenbach/cymais"
imprint: "{{ web_protocol }}://{{domains.html_server}}/imprint.html" imprint: >-
{{ "{protocol}://{domain}/imprint.html"
| safe_placeholders({
'protocol': web_protocol,
'domain': domains.html_server
})
}}

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

@ -10,8 +10,8 @@
domain: "{{ item.domain }}" domain: "{{ item.domain }}"
http_port: "{{ item.http_port }}" http_port: "{{ item.http_port }}"
loop: loop:
- { domain: domains.[application_id]['api'], http_port: ports.localhost.http.bluesky_api } - { domain: domains.[application_id].api, http_port: ports.localhost.http.bluesky_api }
- { domain: domains.[application_id]['web'], http_port: ports.localhost.http.bluesky_web } - { domain: domains.[application_id].web, http_port: ports.localhost.http.bluesky_web }
# The following lines should be removed when the following issue is closed: # The following lines should be removed when the following issue is closed:
# https://github.com/bluesky-social/pds/issues/52 # https://github.com/bluesky-social/pds/issues/52

View File

@ -22,8 +22,8 @@ services:
dockerfile: Dockerfile dockerfile: Dockerfile
# It doesn't compile yet with this parameters. @todo Fix it # It doesn't compile yet with this parameters. @todo Fix it
args: args:
REACT_APP_PDS_URL: "{{ web_protocol }}://{{domains.[application_id]['api']}}" # URL des PDS REACT_APP_PDS_URL: "{{ web_protocol }}://{{domains.[application_id].api}}" # URL des PDS
REACT_APP_API_URL: "{{ web_protocol }}://{{domains.[application_id]['api']}}" # API-URL des PDS REACT_APP_API_URL: "{{ web_protocol }}://{{domains.[application_id].api}}" # API-URL des PDS
REACT_APP_SITE_NAME: "{{primary_domain | upper}} - Bluesky" REACT_APP_SITE_NAME: "{{primary_domain | upper}} - Bluesky"
REACT_APP_SITE_DESCRIPTION: "Decentral Social " REACT_APP_SITE_DESCRIPTION: "Decentral Social "
ports: ports:

View File

@ -1,6 +1,6 @@
PDS_HOSTNAME="{{domains.[application_id]['api']}}" PDS_HOSTNAME="{{domains.[application_id].api}}"
PDS_ADMIN_EMAIL="{{applications.bluesky.users.administrator.email}}" PDS_ADMIN_EMAIL="{{applications.bluesky.users.administrator.email}}"
PDS_SERVICE_DID="did:web:{{domains.[application_id]['api']}}" PDS_SERVICE_DID="did:web:{{domains.[application_id].api}}"
# See https://mattdyson.org/blog/2024/11/self-hosting-bluesky-pds/ # See https://mattdyson.org/blog/2024/11/self-hosting-bluesky-pds/
PDS_SERVICE_HANDLE_DOMAINS=".{{primary_domain}}" PDS_SERVICE_HANDLE_DOMAINS=".{{primary_domain}}"
@ -15,7 +15,7 @@ PDS_BLOBSTORE_DISK_LOCATION=/opt/pds/blocks
PDS_DATA_DIRECTORY: /opt/pds PDS_DATA_DIRECTORY: /opt/pds
PDS_BLOB_UPLOAD_LIMIT: 52428800 PDS_BLOB_UPLOAD_LIMIT: 52428800
PDS_DID_PLC_URL=https://plc.directory PDS_DID_PLC_URL=https://plc.directory
PDS_BSKY_APP_VIEW_URL=https://{{domains.[application_id]['web']}} PDS_BSKY_APP_VIEW_URL=https://{{domains.[application_id].web}}
PDS_BSKY_APP_VIEW_DID=did:web:{{domains.[application_id]['web']}} PDS_BSKY_APP_VIEW_DID=did:web:{{domains.[application_id].web}}
PDS_REPORT_SERVICE_URL=https://mod.bsky.app PDS_REPORT_SERVICE_URL=https://mod.bsky.app
PDS_REPORT_SERVICE_DID=did:plc:ar7c4by46qjdydhdevvrndac PDS_REPORT_SERVICE_DID=did:plc:ar7c4by46qjdydhdevvrndac

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")
@ -51,8 +51,10 @@ env:
DISCOURSE_DEVELOPER_EMAILS: {{users.administrator.email}} DISCOURSE_DEVELOPER_EMAILS: {{users.administrator.email}}
# Set Logo # Set Logo
{% if service_provider.platform.logo | bool %}
DISCOURSE_LOGO_URL: "{{ service_provider.platform.logo }}" DISCOURSE_LOGO_URL: "{{ service_provider.platform.logo }}"
DISCOURSE_LOGO_SMALL_URL: "{{ service_provider.platform.logo }}" DISCOURSE_LOGO_SMALL_URL: "{{ service_provider.platform.logo }}"
{% endif %}
# SMTP ADDRESS, username, and password are required # SMTP ADDRESS, username, and password are required
# WARNING the char '#' in SMTP password can cause problems! # WARNING the char '#' in SMTP password can cause problems!
@ -135,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 }}"
@ -65,8 +65,9 @@ listmonk_settings:
# - key: "messengers" # - key: "messengers"
# value: '[]' # value: '[]'
- key: "app.logo_url" - key: "app.logo_url"
value: '"{{ service_provider.platform.logo }}"' value: '"{{ service_provider.platform.logo }}"'
when: service_provider.platform.logo | bool
- key: "app.site_name" - key: "app.site_name"
value: '"{{ service_provider.company.titel }} Mailing list"' value: '"{{ service_provider.company.titel }} Mailing list"'
@ -115,8 +116,9 @@ listmonk_settings:
# - key: "app.concurrency" # - key: "app.concurrency"
# value: '10' # value: '10'
- key: "app.favicon_url" - key: "app.favicon_url"
value: '"{{ service_provider.platform.favicon }}"' value: '"{{ service_provider.platform.favicon }}"'
when: service_provider.platform.favicon | bool
# - key: "bounce.postmark" # - key: "bounce.postmark"
# value: '{"enabled": false, "password": "", "username": ""}' # value: '{"enabled": false, "password": "", "username": ""}'

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

@ -3,8 +3,8 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
loop: loop:
- "{{domains.element}}" - "{{domains.matrix.element}}"
- "{{domains.synapse}}" - "{{domains.matrix.synapse}}"
loop_control: loop_control:
loop_var: domain loop_var: domain
@ -129,13 +129,13 @@
#- name: add log.config #- name: add log.config
# template: # template:
# src: "log.config.j2" # src: "log.config.j2"
# dest: "{{docker_compose.directories.instance}}{{domains.synapse}}.log.config" # dest: "{{docker_compose.directories.instance}}{{domains.matrix.synapse}}.log.config"
# notify: recreate matrix # notify: recreate matrix
# #
## https://github.com/matrix-org/synapse/issues/6303 ## https://github.com/matrix-org/synapse/issues/6303
#- name: set correct folder permissions #- name: set correct folder permissions
# command: # command:
# cmd: "docker run --rm --mount type=volume,src=matrix_synapse_data,dst=/data -e SYNAPSE_SERVER_NAME={{domains.synapse}} -e SYNAPSE_REPORT_STATS=no --entrypoint /bin/sh matrixdotorg/synapse:latest -c 'chown -vR 991:991 /data'" # cmd: "docker run --rm --mount type=volume,src=matrix_synapse_data,dst=/data -e SYNAPSE_SERVER_NAME={{domains.matrix.synapse}} -e SYNAPSE_REPORT_STATS=no --entrypoint /bin/sh matrixdotorg/synapse:latest -c 'chown -vR 991:991 /data'"
# #
#- name: add docker-compose.yml #- name: add docker-compose.yml
# template: # template:

View File

@ -8,7 +8,7 @@
# because you can't change the Domain after deployment. # because you can't change the Domain after deployment.
# #
# Example value: example.com # Example value: example.com
matrix_domain: "{{domains.synapse}}" matrix_domain: "{{domains.matrix.synapse}}"
# The Matrix homeserver software to install. # The Matrix homeserver software to install.
# See: # See:

View File

@ -16,7 +16,7 @@
include_role: include_role:
name: nginx-https-get-cert-modify-all name: nginx-https-get-cert-modify-all
vars: vars:
domain: "{{domains.synapse}}" domain: "{{domains.matrix.synapse}}"
http_port: "{{ports.localhost.http.synapse}}" http_port: "{{ports.localhost.http.synapse}}"
- name: create {{well_known_directory}} - name: create {{well_known_directory}}
@ -30,12 +30,12 @@
src: "well-known.j2" src: "well-known.j2"
dest: "{{well_known_directory}}server" dest: "{{well_known_directory}}server"
- name: create {{domains.synapse}}.conf - name: create {{domains.matrix.synapse}}.conf
template: template:
src: "templates/nginx.conf.j2" src: "templates/nginx.conf.j2"
dest: "{{nginx.directories.http.servers}}{{domains.synapse}}.conf" dest: "{{nginx.directories.http.servers}}{{domains.matrix.synapse}}.conf"
vars: vars:
domain: "{{domains.synapse}}" # Didn't work in the past. May it works now. This does not seem to work @todo Check how to solve without declaring set_fact, seems a bug at templates domain: "{{domains.matrix.synapse}}" # Didn't work in the past. May it works now. This does not seem to work @todo Check how to solve without declaring set_fact, seems a bug at templates
http_port: "{{ports.localhost.http.synapse}}" http_port: "{{ports.localhost.http.synapse}}"
notify: restart nginx notify: restart nginx
@ -43,7 +43,7 @@
include_role: include_role:
name: nginx-domain-setup name: nginx-domain-setup
vars: vars:
domain: "{{domains.element}}" domain: "{{domains.matrix.element}}"
http_port: "{{ports.localhost.http.element}}" http_port: "{{ports.localhost.http.element}}"
- name: include create-and-seed-database.yml for multiple bridges - name: include create-and-seed-database.yml for multiple bridges
@ -94,13 +94,13 @@
- name: add synapse log configuration - name: add synapse log configuration
template: template:
src: "synapse/log.config.j2" src: "synapse/log.config.j2"
dest: "{{docker_compose.directories.instance}}{{domains.synapse}}.log.config" dest: "{{docker_compose.directories.instance}}{{domains.matrix.synapse}}.log.config"
notify: docker compose project setup notify: docker compose project setup
# https://github.com/matrix-org/synapse/issues/6303 # https://github.com/matrix-org/synapse/issues/6303
- name: set correct folder permissions - name: set correct folder permissions
command: command:
cmd: "docker run --rm --mount type=volume,src=matrix_synapse_data,dst=/data -e SYNAPSE_SERVER_NAME={{domains.synapse}} -e SYNAPSE_REPORT_STATS=no --entrypoint /bin/sh matrixdotorg/synapse:latest -c 'chown -vR 991:991 /data'" cmd: "docker run --rm --mount type=volume,src=matrix_synapse_data,dst=/data -e SYNAPSE_SERVER_NAME={{domains.matrix.synapse}} -e SYNAPSE_REPORT_STATS=no --entrypoint /bin/sh matrixdotorg/synapse:latest -c 'chown -vR 991:991 /data'"
- name: add docker-compose.yml - name: add docker-compose.yml
template: template:

View File

@ -11,12 +11,12 @@ services:
volumes: volumes:
- synapse_data:/data - synapse_data:/data
- ./homeserver.yaml:/data/homeserver.yaml:ro - ./homeserver.yaml:/data/homeserver.yaml:ro
- ./{{domains.synapse}}.log.config:/data/{{domains.synapse}}.log.config:ro - ./{{domains.matrix.synapse}}.log.config:/data/{{domains.matrix.synapse}}.log.config:ro
{% for item in bridges %} {% for item in bridges %}
- {{docker_compose.directories.instance}}mautrix/{{item.bridge_name}}/registration.yaml:{{registration_file_folder}}{{item.bridge_name}}.registration.yaml:ro - {{docker_compose.directories.instance}}mautrix/{{item.bridge_name}}/registration.yaml:{{registration_file_folder}}{{item.bridge_name}}.registration.yaml:ro
{% endfor %} {% endfor %}
environment: environment:
- SYNAPSE_SERVER_NAME={{domains.synapse}} - SYNAPSE_SERVER_NAME={{domains.matrix.synapse}}
- SYNAPSE_REPORT_STATS=no - SYNAPSE_REPORT_STATS=no
ports: ports:
- "127.0.0.1:{{ports.localhost.http.synapse}}:8008" - "127.0.0.1:{{ports.localhost.http.synapse}}:8008"
@ -91,7 +91,7 @@ services:
KEYV_URL: '' KEYV_URL: ''
KEYV_BOT_ENCRYPTION: 'false' KEYV_BOT_ENCRYPTION: 'false'
KEYV_BOT_STORAGE: 'true' KEYV_BOT_STORAGE: 'true'
MATRIX_HOMESERVER_URL: 'https://{{domains.synapse}}' MATRIX_HOMESERVER_URL: 'https://{{domains.matrix.synapse}}'
MATRIX_BOT_USERNAME: '@chatgptbot:{{applications[application_id].server_name}}' MATRIX_BOT_USERNAME: '@chatgptbot:{{applications[application_id].server_name}}'
MATRIX_ACCESS_TOKEN: '{{ applications[application_id].credentials.chatgpt_bridge_access_token | default('') }}' MATRIX_ACCESS_TOKEN: '{{ applications[application_id].credentials.chatgpt_bridge_access_token | default('') }}'
MATRIX_BOT_PASSWORD: '{{applications[application_id].credentials.chatgpt_bridge_user_password}}' MATRIX_BOT_PASSWORD: '{{applications[application_id].credentials.chatgpt_bridge_user_password}}'

View File

@ -1,8 +1,8 @@
{ {
"default_server_config": { "default_server_config": {
"m.homeserver": { "m.homeserver": {
"base_url": "{{ web_protocol }}://{{domains.synapse}}", "base_url": "{{ web_protocol }}://{{domains.matrix.synapse}}",
"server_name": "{{domains.synapse}}" "server_name": "{{domains.matrix.synapse}}"
}, },
"m.identity_server": { "m.identity_server": {
"base_url": "{{ web_protocol }}://{{primary_domain}}" "base_url": "{{ web_protocol }}://{{primary_domain}}"

View File

@ -143,7 +143,7 @@ bridge:
sync_direct_chat_list: false sync_direct_chat_list: false
# Servers to always allow double puppeting from # Servers to always allow double puppeting from
double_puppet_server_map: double_puppet_server_map:
{{applications[application_id].server_name}}: {{domains.synapse}} {{applications[application_id].server_name}}: {{domains.matrix.synapse}}
# Allow using double puppeting from any server with a valid client .well-known file. # Allow using double puppeting from any server with a valid client .well-known file.
double_puppet_allow_discovery: false double_puppet_allow_discovery: false
# Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth # Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth

View File

@ -134,7 +134,7 @@ bridge:
double_puppet_allow_discovery: false double_puppet_allow_discovery: false
# Servers to allow double puppeting from, even if double_puppet_allow_discovery is false. # Servers to allow double puppeting from, even if double_puppet_allow_discovery is false.
double_puppet_server_map: double_puppet_server_map:
{{applications[application_id].server_name}}: https://{{domains.synapse}} {{applications[application_id].server_name}}: https://{{domains.matrix.synapse}}
# Shared secret for https://github.com/devture/matrix-synapse-shared-secret-auth # Shared secret for https://github.com/devture/matrix-synapse-shared-secret-auth
# #
# If set, custom puppets will be enabled automatically for local users # If set, custom puppets will be enabled automatically for local users

View File

@ -141,7 +141,7 @@ bridge:
federate_rooms: true federate_rooms: true
# Servers to always allow double puppeting from # Servers to always allow double puppeting from
double_puppet_server_map: double_puppet_server_map:
{{applications[application_id].server_name}}: https://{{domains.synapse}} {{applications[application_id].server_name}}: https://{{domains.matrix.synapse}}
# Allow using double puppeting from any server with a valid client .well-known file. # Allow using double puppeting from any server with a valid client .well-known file.
double_puppet_allow_discovery: false double_puppet_allow_discovery: false
# Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth # Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth

View File

@ -118,7 +118,7 @@ bridge:
# Servers to always allow double puppeting from # Servers to always allow double puppeting from
double_puppet_server_map: double_puppet_server_map:
{{applications[application_id].server_name}}: https://{{domains.synapse}} {{applications[application_id].server_name}}: https://{{domains.matrix.synapse}}
# Allow using double puppeting from any server with a valid client .well-known file. # Allow using double puppeting from any server with a valid client .well-known file.
double_puppet_allow_discovery: false double_puppet_allow_discovery: false
# Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth # Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth

View File

@ -198,7 +198,7 @@ bridge:
sync_direct_chat_list: false sync_direct_chat_list: false
# Servers to always allow double puppeting from # Servers to always allow double puppeting from
double_puppet_server_map: double_puppet_server_map:
{{applications[application_id].server_name}}: https://{{domains.synapse}} {{applications[application_id].server_name}}: https://{{domains.matrix.synapse}}
# Allow using double puppeting from any server with a valid client .well-known file. # Allow using double puppeting from any server with a valid client .well-known file.
double_puppet_allow_discovery: false double_puppet_allow_discovery: false
# Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth # Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth

View File

@ -236,7 +236,7 @@ bridge:
force_active_delivery_receipts: false force_active_delivery_receipts: false
# Servers to always allow double puppeting from # Servers to always allow double puppeting from
double_puppet_server_map: double_puppet_server_map:
{{applications[application_id].server_name}}: https://{{domains.synapse}} {{applications[application_id].server_name}}: https://{{domains.matrix.synapse}}
# Allow using double puppeting from any server with a valid client .well-known file. # Allow using double puppeting from any server with a valid client .well-known file.
double_puppet_allow_discovery: false double_puppet_allow_discovery: false
# Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth # Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth

View File

@ -1,10 +1,10 @@
server { server {
{# Somehow .j2 doesn't interpretate the passed variable right. For this reasons this redeclaration is necessary #} {# Somehow .j2 doesn't interpretate the passed variable right. For this reasons this redeclaration is necessary #}
{# Could be that this is related to the set_fact use #} {# Could be that this is related to the set_fact use #}
{% set domain = domains.synapse %} {% set domain = domains.matrix.synapse %}
{% set http_port = ports.localhost.http.synapse %} {% set http_port = ports.localhost.http.synapse %}
server_name {{domains.synapse}}; server_name {{domains.matrix.synapse}};
{% include 'roles/letsencrypt/templates/ssl_header.j2' %} {% include 'roles/letsencrypt/templates/ssl_header.j2' %}
# For the federation port # For the federation port

View File

@ -17,15 +17,15 @@ database:
host: "{{database_host}}" host: "{{database_host}}"
cp_min: 5 cp_min: 5
cp_max: 10 cp_max: 10
log_config: "/data/{{domains.synapse}}.log.config" log_config: "/data/{{domains.matrix.synapse}}.log.config"
media_store_path: "/data/media_store" media_store_path: "/data/media_store"
registration_shared_secret: "{{applications[application_id].credentials.registration_shared_secret}}" registration_shared_secret: "{{applications[application_id].credentials.registration_shared_secret}}"
report_stats: true report_stats: true
macaroon_secret_key: "{{applications[application_id].credentials.macaroon_secret_key}}" macaroon_secret_key: "{{applications[application_id].credentials.macaroon_secret_key}}"
form_secret: "{{applications[application_id].credentials.form_secret}}" form_secret: "{{applications[application_id].credentials.form_secret}}"
signing_key_path: "/data/{{domains.synapse}}.signing.key" signing_key_path: "/data/{{domains.matrix.synapse}}.signing.key"
web_client_location: "{{ web_protocol }}://{{domains.element}}" web_client_location: "{{ web_protocol }}://{{domains.matrix.element}}"
public_baseurl: "{{ web_protocol }}://{{domains.synapse}}" public_baseurl: "{{ web_protocol }}://{{domains.matrix.synapse}}"
trusted_key_servers: trusted_key_servers:
- server_name: "matrix.org" - server_name: "matrix.org"
admin_contact: 'mailto:{{users.administrator.email}}' admin_contact: 'mailto:{{users.administrator.email}}'
@ -39,10 +39,10 @@ email:
#require_transport_security: true #require_transport_security: true
enable_tls: "{{ system_email.tls | upper }}" enable_tls: "{{ system_email.tls | upper }}"
notif_from: "Your Friendly %(app)s homeserver <{{ users['no-reply'].email }}>" notif_from: "Your Friendly %(app)s homeserver <{{ users['no-reply'].email }}>"
app_name: "Matrix on {{domains.synapse}}" app_name: "Matrix on {{domains.matrix.synapse}}"
enable_notifs: true enable_notifs: true
notif_for_new_users: false notif_for_new_users: false
client_base_url: "{{domains.synapse}}" client_base_url: "{{domains.matrix.synapse}}"
validation_token_lifetime: 15m validation_token_lifetime: 15m
{% if applications | is_feature_enabled('oidc',application_id) %} {% if applications | is_feature_enabled('oidc',application_id) %}

View File

@ -8,7 +8,7 @@ handlers:
file: file:
class: logging.handlers.RotatingFileHandler class: logging.handlers.RotatingFileHandler
formatter: precise formatter: precise
filename: /data/{{domains.synapse}}.homeserver.log filename: /data/{{domains.matrix.synapse}}.homeserver.log
maxBytes: 10485760 maxBytes: 10485760
backupCount: 3 backupCount: 3
console: console:

View File

@ -1,3 +1,3 @@
{ {
"m.server": "{{domains.synapse}}:443" "m.server": "{{domains.matrix.synapse}}:443"
} }

View File

@ -25,9 +25,9 @@ csp:
whitelist: whitelist:
connect-src: connect-src:
- "{{ primary_domain }}" - "{{ primary_domain }}"
- "{{ domains.matrix }}" - "{{ domains.matrix.synapse | safe_var }}"
script-src: script-src:
- "{{ domains.matrix }}" - "{{ domains.matrix.synapse | safe_var }}"
- "https://cdn.jsdelivr.net" - "https://cdn.jsdelivr.net"
plugins: plugins:
# You need to enable them in the inventory file # You need to enable them in the inventory 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: 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.
@ -90,15 +90,16 @@ class LookupModule(LookupBase):
applications = variables.get("applications", {}) applications = variables.get("applications", {})
domain_url = domains.get(application_id, "") domain_url = domains.get(application_id, "")
# Check if domain_url is a list. If so, select the first element.
if isinstance(domain_url, list): if isinstance(domain_url, list):
domain_url = domain_url[0] domain_url = domain_url[0]
elif isinstance(domain_url, dict):
domain_url = next(iter(domain_url.values()))
# Construct the URL using the domain_url if available. # Construct the URL using the domain_url if available.
url = "https://" + domain_url if domain_url else "" url = "https://" + domain_url if domain_url else ""
app_data = applications.get(application_id, {}) app_data = applications.get(application_id, {})
iframe = app_data.get("features", {}).get("iframe", False) iframe = app_data.get("features", {}).get("portfolio_iframe", False)
# Build card dictionary # Build card dictionary
card = { card = {

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]}}/

Some files were not shown because too many files have changed in this diff Show More