Renamed general and mode constants and implemented a check to verify that constants are just defined ones over the whole repository

This commit is contained in:
Kevin Veen-Birkenbach 2025-08-13 19:10:44 +02:00
parent 004507e233
commit db0e030900
No known key found for this signature in database
GPG Key ID: 44D8F11FD62F878E
171 changed files with 474 additions and 345 deletions

View File

@ -189,7 +189,7 @@ def parse_args():
def main():
args = parse_args()
primary_domain = '{{ primary_domain }}'
primary_domain = '{{ PRIMARY_DOMAIN }}'
become_pwd = '{{ lookup("password", "/dev/null length=42 chars=ascii_letters,digits") }}'
try:

View File

@ -191,13 +191,13 @@ def main():
validate_application_ids(args.inventory, args.id)
modes = {
"mode_reset": args.reset,
"mode_test": args.test,
"mode_update": args.update,
"mode_backup": args.backup,
"mode_cleanup": args.cleanup,
"mode_logs": args.logs,
"enable_debug": args.debug,
"MODE_RESET": args.reset,
"MODE_TEST": args.test,
"MODE_UPDATE": args.update,
"MODE_BACKUP": args.backup,
"MODE_CLEANUP": args.cleanup,
"MODE_LOGS": args.logs,
"MODE_DEBUG": args.debug,
"host_type": args.host_type
}

View File

@ -4,7 +4,7 @@ class FilterModule(object):
def filters(self):
return {'alias_domains_map': self.alias_domains_map}
def alias_domains_map(self, apps, primary_domain):
def alias_domains_map(self, apps, PRIMARY_DOMAIN):
"""
Build a map of application IDs to their alias domains.
@ -42,7 +42,7 @@ class FilterModule(object):
domains_cfg = cfg.get('server',{}).get('domains',{})
entry = domains_cfg.get('canonical')
if entry is None:
canonical_map[app_id] = [default_domain(app_id, primary_domain)]
canonical_map[app_id] = [default_domain(app_id, PRIMARY_DOMAIN)]
elif isinstance(entry, dict):
canonical_map[app_id] = list(entry.values())
elif isinstance(entry, list):
@ -69,7 +69,7 @@ class FilterModule(object):
# otherwise, compute aliases
aliases = parse_entry(domains_cfg, 'aliases', app_id) or []
default = default_domain(app_id, primary_domain)
default = default_domain(app_id, PRIMARY_DOMAIN)
has_aliases = 'aliases' in domains_cfg
has_canon = 'canonical' in domains_cfg

View File

@ -9,7 +9,7 @@ class FilterModule(object):
def filters(self):
return {'canonical_domains_map': self.canonical_domains_map}
def canonical_domains_map(self, apps, primary_domain):
def canonical_domains_map(self, apps, PRIMARY_DOMAIN):
"""
Maps applications to their canonical domains, checking for conflicts
and ensuring all domains are valid and unique across applications.
@ -30,7 +30,7 @@ class FilterModule(object):
domains_cfg = cfg.get('server',{}).get('domains',{})
if not domains_cfg or 'canonical' not in domains_cfg:
self._add_default_domain(app_id, primary_domain, seen_domains, result)
self._add_default_domain(app_id, PRIMARY_DOMAIN, seen_domains, result)
continue
canonical_domains = domains_cfg['canonical']
@ -38,13 +38,13 @@ class FilterModule(object):
return result
def _add_default_domain(self, app_id, primary_domain, seen_domains, result):
def _add_default_domain(self, app_id, PRIMARY_DOMAIN, seen_domains, result):
"""
Add the default domain for an application if no canonical domains are defined.
Ensures the domain is unique across applications.
"""
entity_name = get_entity_name(app_id)
default_domain = f"{entity_name}.{primary_domain}"
default_domain = f"{entity_name}.{PRIMARY_DOMAIN}"
if default_domain in seen_domains:
raise AnsibleFilterError(
f"Domain '{default_domain}' is already configured for "

View File

@ -7,7 +7,7 @@ class FilterModule(object):
def filters(self):
return {'domain_mappings': self.domain_mappings}
def domain_mappings(self, apps, primary_domain):
def domain_mappings(self, apps, PRIMARY_DOMAIN):
"""
Build a flat list of redirect mappings for all apps:
- source: each alias domain
@ -43,7 +43,7 @@ class FilterModule(object):
domains_cfg = cfg.get('server',{}).get('domains',{})
entry = domains_cfg.get('canonical')
if entry is None:
canonical_map[app_id] = [default_domain(app_id, primary_domain)]
canonical_map[app_id] = [default_domain(app_id, PRIMARY_DOMAIN)]
elif isinstance(entry, dict):
canonical_map[app_id] = list(entry.values())
elif isinstance(entry, list):
@ -61,11 +61,11 @@ class FilterModule(object):
alias_map[app_id] = []
continue
if isinstance(domains_cfg, dict) and not domains_cfg:
alias_map[app_id] = [default_domain(app_id, primary_domain)]
alias_map[app_id] = [default_domain(app_id, PRIMARY_DOMAIN)]
continue
aliases = parse_entry(domains_cfg, 'aliases', app_id) or []
default = default_domain(app_id, primary_domain)
default = default_domain(app_id, PRIMARY_DOMAIN)
has_aliases = 'aliases' in domains_cfg
has_canonical = 'canonical' in domains_cfg
@ -84,7 +84,7 @@ class FilterModule(object):
mappings = []
for app_id, sources in alias_map.items():
canon_list = canonical_map.get(app_id, [])
target = canon_list[0] if canon_list else default_domain(app_id, primary_domain)
target = canon_list[0] if canon_list else default_domain(app_id, PRIMARY_DOMAIN)
for src in sources:
if src == target:
# skip self-redirects

View File

@ -19,7 +19,7 @@ class FilterModule(object):
Usage in Jinja:
{{ redirect_list
| add_redirect_if_group('lam',
'ldap.' ~ primary_domain,
'ldap.' ~ PRIMARY_DOMAIN,
domains | get_domain('web-app-lam'),
group_names) }}
"""

View File

@ -1,4 +1,4 @@
INFINITO_ENVIRONMENT: "production" # Possible values: production, development
ENVIRONMENT: "production" # Possible values: production, development
# If true, sensitive credentials will be masked or hidden from all Ansible task logs
# Recommendet to set to true
@ -19,49 +19,46 @@ HOST_THOUSAND_SEPARATOR: "."
HOST_DECIMAL_MARK: ","
# Deployment mode
deployment_mode: "single" # Use single, if you deploy on one server. Use cluster if you setup in cluster mode.
DEPLOYMENT_MODE: "single" # Use single, if you deploy on one server. Use cluster if you setup in cluster mode.
# Web
WEB_PROTOCOL: "https" # Web protocol type. Use https or http. If you run local you need to change it to http
WEB_PORT: "{{ 443 if WEB_PROTOCOL == 'https' else 80 }}" # Default port web applications will listen to
## Domain
primary_domain_tld: "localhost" # Top Level Domain of the server
primary_domain_sld: "infinito" # Second Level Domain of the server
primary_domain: "{{primary_domain_sld}}.{{primary_domain_tld}}" # Primary Domain of the server
# Domain
PRIMARY_DOMAIN: "localhost" # Primary Domain of the server
PRIMARY_DOMAIN_tld: "{{ (PRIMARY_DOMAIN == 'localhost') | ternary('localhost', PRIMARY_DOMAIN.split('.')[-1]) }}" # Top Level Domain of the server
PRIMARY_DOMAIN_SLD: "{{ (PRIMARY_DOMAIN == 'localhost') | ternary('localhost', PRIMARY_DOMAIN.split('.')[-2]) }}" # Second Level Domain of the server
# Server Tact Variables
## Ours in which the server is "awake" (100% working). Rest of the time is reserved for maintanance
hours_server_awake: "0..23"
HOURS_SERVER_AWAKE: "0..23"
## Random delay for systemd timers to avoid peak loads.
randomized_delay_sec: "5min"
RANDOMIZED_DELAY_SEC: "5min"
# Runtime Variables for Process Control
activate_all_timers: false # Activates all timers, independend if the handlers had been triggered
ACTIVATE_ALL_TIMERS: false # Activates all timers, independend if the handlers had been triggered
# This enables debugging in ansible and in the apps
# You SHOULD NOT enable this on production servers
enable_debug: false
dns_provider: cloudflare # The DNS Provider\Registrar for the domain
DNS_PROVIDER: cloudflare # The DNS Provider\Registrar for the domain
# Which ACME method to use: webroot, cloudflare, or hetzner
certbot_acme_challenge_method: "cloudflare"
certbot_credentials_dir: /etc/certbot
certbot_credentials_file: "{{ certbot_credentials_dir }}/{{ certbot_acme_challenge_method }}.ini"
certbot_dns_api_token: "" # Define in inventory file: More information here: group_vars/all/docs/CLOUDFLARE_API_TOKEN.md
certbot_dns_propagation_wait_seconds: 300 # How long should the script wait for DNS propagation before continuing
certbot_flavor: san # Possible options: san (recommended, with a dns flavor like cloudflare, or hetzner), wildcard(doesn't function with www redirect), dedicated
CERTBOT_ACME_CHALLENGE_METHOD: "cloudflare"
CERTBOT_CREDENTIALS_DIR: /etc/certbot
CERTBOT_CREDENTIALS_FILE: "{{ CERTBOT_CREDENTIALS_DIR }}/{{ CERTBOT_ACME_CHALLENGE_METHOD }}.ini"
CERTBOT_DNS_API_TOKEN: "" # Define in inventory file: More information here: group_vars/all/docs/CLOUDFLARE_API_TOKEN.md
CERTBOT_DNS_PROPAGATION_WAIT_SECONDS: 300 # How long should the script wait for DNS propagation before continuing
CERTBOT_FLAVOR: san # Possible options: san (recommended, with a dns flavor like cloudflare, or hetzner), wildcard(doesn't function with www redirect), dedicated
# Path where Certbot stores challenge webroot files
letsencrypt_webroot_path: "/var/lib/letsencrypt/"
LETSENCRYPT_WEBROOT_PATH: "/var/lib/letsencrypt/"
# Base directory containing Certbot configuration, account data, and archives
letsencrypt_base_path: "/etc/letsencrypt/"
LETSENCRYPT_BASE_PATH: "/etc/letsencrypt/"
# Symlink directory for the current active certificate and private key
letsencrypt_live_path: "{{ letsencrypt_base_path }}live/"
LETSENCRYPT_LIVE_PATH: "{{ LETSENCRYPT_BASE_PATH }}live/"
## Docker Role Specific Parameters
DOCKER_RESTART_POLICY: "unless-stopped"

View File

@ -1,8 +1,9 @@
# Mode
# The following modes can be combined with each other
mode_reset: false # Cleans up all Infinito.Nexus files. It's necessary to run to whole playbook and not particial roles when using this function.
mode_test: false # Executes test routines instead of productive routines
mode_update: true # Executes updates
mode_backup: true # Activates the backup before the update procedure
mode_cleanup: true # Cleanup unused files and configurations
MODE_RESET: false # Cleans up all Infinito.Nexus files. It's necessary to run to whole playbook and not particial roles when using this function.
MODE_TEST: false # Executes test routines instead of productive routines
MODE_UPDATE: true # Executes updates
MODE_BACKUP: true # Activates the backup before the update procedure
MODE_CLEANUP: true # Cleanup unused files and configurations
MODE_DEBUG: false # This enables debugging in ansible and in the apps, You SHOULD NOT enable this on production servers

View File

@ -1,7 +1,7 @@
# Email Configuration
default_system_email:
domain: "{{primary_domain}}"
host: "mail.{{primary_domain}}"
domain: "{{PRIMARY_DOMAIN}}"
host: "mail.{{PRIMARY_DOMAIN}}"
port: 465
tls: true # true for TLS and false for SSL
start_tls: false

View File

@ -3,10 +3,10 @@
on_calendar_health_btrfs: "*-*-* 00:00:00" # Check once per day the btrfs for errors
on_calendar_health_journalctl: "*-*-* 00:00:00" # Check once per day the journalctl for errors
on_calendar_health_disc_space: "*-*-* 06,12,18,00:00:00" # Check four times per day if there is sufficient disc space
on_calendar_health_docker_container: "*-*-* {{ hours_server_awake }}:00:00" # Check once per hour if the docker containers are healthy
on_calendar_health_docker_volumes: "*-*-* {{ hours_server_awake }}:15:00" # Check once per hour if the docker volumes are healthy
on_calendar_health_csp_crawler: "*-*-* {{ hours_server_awake }}:30:00" # Check once per hour if all CSP are fullfilled available
on_calendar_health_nginx: "*-*-* {{ hours_server_awake }}:45:00" # Check once per hour if all webservices are available
on_calendar_health_docker_container: "*-*-* {{ HOURS_SERVER_AWAKE }}:00:00" # Check once per hour if the docker containers are healthy
on_calendar_health_docker_volumes: "*-*-* {{ HOURS_SERVER_AWAKE }}:15:00" # Check once per hour if the docker volumes are healthy
on_calendar_health_csp_crawler: "*-*-* {{ HOURS_SERVER_AWAKE }}:30:00" # Check once per hour if all CSP are fullfilled available
on_calendar_health_nginx: "*-*-* {{ HOURS_SERVER_AWAKE }}:45:00" # Check once per hour if all webservices are available
on_calendar_health_msmtp: "*-*-* 00:00:00" # Check once per day SMTP Server
## Schedule for Cleanup Tasks
@ -19,7 +19,7 @@ on_calendar_backup_docker_to_local: "*-*-* 03:30:00"
on_calendar_backup_remote_to_local: "*-*-* 21:30:00"
## Schedule for Maintenance Tasks
on_calendar_heal_docker: "*-*-* {{ hours_server_awake }}:30:00" # Heal unhealthy docker instances once per hour
on_calendar_heal_docker: "*-*-* {{ HOURS_SERVER_AWAKE }}:30:00" # Heal unhealthy docker instances once per hour
on_calendar_renew_lets_encrypt_certificates: "*-*-* 12,00:30:00" # Renew Mailu certificates twice per day
on_calendar_deploy_certificates: "*-*-* 13,01:30:00" # Deploy letsencrypt certificates twice per day to docker containers
on_calendar_msi_keyboard_color: "*-*-* *:*:00" # Change the keyboard color every minute

View File

@ -8,7 +8,7 @@
# @see https://en.wikipedia.org/wiki/OpenID_Connect
## 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_url: "{{
(oidc.url
if (oidc is defined and oidc.url is defined)
@ -16,7 +16,7 @@ _oidc_url: "{{
)
}}"
_oidc_client_issuer_url: "{{ _oidc_url }}/realms/{{_oidc_client_realm}}"
_oidc_client_id: "{{ oidc.client.id if oidc.client is defined and oidc.client.id is defined else primary_domain }}"
_oidc_client_id: "{{ oidc.client.id if oidc.client is defined and oidc.client.id is defined else PRIMARY_DOMAIN }}"
defaults_oidc:
url: "{{ _oidc_url }}"
@ -33,7 +33,7 @@ defaults_oidc:
change_credentials: "{{_oidc_client_issuer_url}}account/account-security/signing-in" # URL for managing or changing user credentials
certs: "{{_oidc_client_issuer_url}}/protocol/openid-connect/certs" # JSON Web Key Set (JWKS)
reset_credentials: "{{_oidc_client_issuer_url}}/login-actions/reset-credentials?client_id={{ _oidc_client_id }}" # Password reset url
button_text: "SSO Login ({{primary_domain | upper}})" # Default button text
button_text: "SSO Login ({{PRIMARY_DOMAIN | upper}})" # Default button text
attributes:
# Attribut to identify the user
username: "preferred_username"

View File

@ -5,12 +5,12 @@
# Helper Variables:
# Keep in mind to mapp this variables if there is ever the possibility for the user to define them in the inventory
_ldap_dn_base: "dc={{primary_domain_sld}},dc={{primary_domain_tld}}"
_ldap_dn_base: "dc={{PRIMARY_DOMAIN_SLD}},dc={{PRIMARY_DOMAIN_tld}}"
_ldap_docker_network_enabled: "{{ applications | get_app_conf('svc-db-openldap', 'network.docker') }}"
_ldap_protocol: "{{ 'ldap' if _ldap_docker_network_enabled else 'ldaps' }}"
_ldap_server_port: "{{ ports.localhost[_ldap_protocol]['svc-db-openldap'] }}"
_ldap_name: "{{ applications | get_app_conf('svc-db-openldap', 'docker.services.openldap.name') }}"
_ldap_domain: "{{ primary_domain }}" # LDAP is jsut listening to a port not to a dedicated domain, so primary domain should be sufficient
_ldap_domain: "{{ PRIMARY_DOMAIN }}" # LDAP is jsut listening to a port not to a dedicated domain, so primary domain should be sufficient
_ldap_user_id: "uid"
_ldap_filters_users_all: "(|(objectclass=inetOrgPerson))"

View File

@ -19,7 +19,7 @@ defaults_service_provider:
web-app-bluesky: >-
{{ ('@' ~ users.contact.username ~ '.' ~ domains['web-app-bluesky'].api)
if 'web-app-bluesky' in group_names else '' }}
email: "{{ users.contact.username ~ '@' ~ primary_domain if 'web-app-mailu' in group_names else '' }}"
email: "{{ users.contact.username ~ '@' ~ PRIMARY_DOMAIN if 'web-app-mailu' in group_names else '' }}"
mastodon: "{{ '@' ~ users.contact.username ~ '@' ~ domains | get_domain('web-app-mastodon') if 'web-app-mastodon' in group_names else '' }}"
matrix: "{{ '@' ~ users.contact.username ~ ':' ~ domains['web-app-matrix'].synapse if 'web-app-matrix' in group_names else '' }}"
peertube: "{{ '@' ~ users.contact.username ~ '@' ~ domains | get_domain('web-app-peertube') if 'web-app-peertube' in group_names else '' }}"

View File

@ -1,10 +1,10 @@
# Cloudflare API Token for Ansible (`certbot_dns_api_token`)
# Cloudflare API Token for Ansible (`CERTBOT_DNS_API_TOKEN`)
This document explains how to generate and use a Cloudflare API Token for DNS automation and certificate operations in Ansible (e.g., with Certbot).
## Purpose
The `certbot_dns_api_token` variable must contain a valid Cloudflare API Token.
The `CERTBOT_DNS_API_TOKEN` variable must contain a valid Cloudflare API Token.
This token is used for all DNS operations and ACME (SSL/TLS certificate) challenges that require access to your Cloudflare-managed domains.
**Never commit your API token to a public repository. Always keep it secure!**
@ -58,4 +58,4 @@ Add the following permissions:
Set the token in your Ansible inventory or secrets file:
```yaml
certbot_dns_api_token: "cf_your_generated_token_here"
CERTBOT_DNS_API_TOKEN: "cf_your_generated_token_here"

View File

@ -15,7 +15,7 @@
- name: Warn if repo is not reachable
debug:
msg: "Warning: Repository is not reachable."
when: git_result.failed and enable_debug | bool
when: git_result.failed and MODE_DEBUG | bool
- name: Ensure systemd user directory exists
file:

View File

@ -8,7 +8,7 @@ Refer to the [Docker Compose documentation](https://docs.docker.com/compose/), t
## Overview
This role creates a flexible directory layout for managing Docker Compose projects across environments. It ensures directories are initialized, optionally reset, and kept clean using internal flags like `mode_reset` or `mode_cleanup`.
This role creates a flexible directory layout for managing Docker Compose projects across environments. It ensures directories are initialized, optionally reset, and kept clean using internal flags like `MODE_RESET` or `MODE_CLEANUP`.
## Purpose
@ -17,7 +17,7 @@ To offer a centralized, extensible system for managing containerized application
## Features
- **Dynamic Directory Structure:** Creates per-application instance folders for Compose setups.
- **Reset Logic:** Cleans previous Compose project files and data when `mode_reset` is enabled.
- **Reset Logic:** Cleans previous Compose project files and data when `MODE_RESET` is enabled.
- **Handlers for Runtime Control:** Automatically builds, sets up, or restarts containers based on handlers.
- **Template-ready Service Files:** Predefined service base and health check templates.
- **Integration Support:** Compatible with `srv-proxy-7-4-core` and other Infinito.Nexus service roles.

View File

@ -10,7 +10,7 @@
- name: "reset (if enabled)"
include_tasks: 01_reset.yml
when: mode_reset | bool
when: MODE_RESET | bool
# This could lead to problems in docker-compose directories which are based on a git repository
# @todo Verify that this isn't the case. E.g. in accounting

View File

@ -16,7 +16,7 @@
url: "{{ cf_api_url }}?name={{ domain | to_primary_domain }}"
method: GET
headers:
Authorization: "Bearer {{ certbot_dns_api_token }}"
Authorization: "Bearer {{ CERTBOT_DNS_API_TOKEN }}"
Content-Type: "application/json"
return_content: yes
register: cf_zone_lookup_dev
@ -43,8 +43,8 @@
- name: activate cloudflare cache development mode
include_tasks: "cloudflare/02_enable_cf_dev_mode.yml"
when: (INFINITO_ENVIRONMENT | lower) == 'development'
when: (ENVIRONMENT | lower) == 'development'
- name: purge cloudflare domain cache
include_tasks: "cloudflare/01_cleanup.yml"
when: mode_cleanup | bool
when: MODE_CLEANUP | bool

View File

@ -3,7 +3,7 @@
url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/purge_cache"
method: POST
headers:
Authorization: "Bearer {{ certbot_dns_api_token }}"
Authorization: "Bearer {{ CERTBOT_DNS_API_TOKEN }}"
Content-Type: "application/json"
body:
purge_everything: true

View File

@ -1,7 +1,7 @@
# roles/srv-proxy-6-6-domain/tasks/02_enable_cf_dev_mode.yml
---
# Enables Cloudflare Development Mode (bypasses cache for ~3 hours).
# Uses the same auth token as in 01_cleanup.yml: certbot_dns_api_token
# Uses the same auth token as in 01_cleanup.yml: CERTBOT_DNS_API_TOKEN
# Assumes `domain` and (optionally) `cf_zone_id` are available.
# Safe to run repeatedly; only changes when the mode is not already "on".
@ -10,7 +10,7 @@
url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/settings/development_mode"
method: GET
headers:
Authorization: "Bearer {{ certbot_dns_api_token }}"
Authorization: "Bearer {{ CERTBOT_DNS_API_TOKEN }}"
Content-Type: "application/json"
return_content: yes
register: cf_dev_mode_current
@ -20,7 +20,7 @@
url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/settings/development_mode"
method: PATCH
headers:
Authorization: "Bearer {{ certbot_dns_api_token }}"
Authorization: "Bearer {{ CERTBOT_DNS_API_TOKEN }}"
Content-Type: "application/json"
body:
value: "on"

View File

@ -7,7 +7,7 @@
when: run_once_srv_proxy_6_6_domain is not defined
- include_tasks: "01_cloudflare.yml"
when: dns_provider == "cloudflare"
when: DNS_PROVIDER == "cloudflare"
- include_tasks: "{{ playbook_dir }}/tasks/utils/load_handlers.yml"
vars:

View File

@ -49,7 +49,7 @@ This script:
**Usage:**
```sh
sh srv-proxy-6-6-tls-deploy.sh primary_domain /path/to/docker/compose
sh srv-proxy-6-6-tls-deploy.sh PRIMARY_DOMAIN /path/to/docker/compose
```
---

View File

@ -4,33 +4,33 @@ If you enabled `enable_wildcard_certificate`, follow these steps to manually req
### **1⃣ Run the Certbot Command 🖥️**
```sh
certbot certonly --manual --preferred-challenges=dns --agree-tos \
--email administrator@primary_domain -d primary_domain -d "*.primary_domain"
--email administrator@PRIMARY_DOMAIN -d PRIMARY_DOMAIN -d "*.PRIMARY_DOMAIN"
```
### **2⃣ Add DNS TXT Record for Validation 📜**
Certbot will prompt you to add a DNS TXT record:
```
Please create a TXT record under the name:
_acme-challenge.primary_domain.
_acme-challenge.PRIMARY_DOMAIN.
with the following value:
9oVizYIYVGlZ3VtWQIKRS5UghyXiqGoUNlCtIE7LiA
```
**Go to your DNS provider** and create a new **TXT record**:
- **Host:** `_acme-challenge.primary_domain`
- **Host:** `_acme-challenge.PRIMARY_DOMAIN`
- **Value:** `"9oVizYIYVGlZ3VtWQIKRS5UghyXiqGoUNlCtIE7LiA"`
- **TTL:** Set to **300 seconds (or lowest possible)**
**Verify the DNS record** before continuing:
```sh
dig TXT _acme-challenge.primary_domain @8.8.8.8
dig TXT _acme-challenge.PRIMARY_DOMAIN @8.8.8.8
```
### **3⃣ Complete the Certificate Request ✅**
Once the DNS changes have propagated, **press Enter** in the Certbot terminal.
If successful, Certbot will save the certificates under:
```
/etc/letsencrypt/live/primary_domain/
/etc/letsencrypt/live/PRIMARY_DOMAIN/
```
- **fullchain.pem** → The certificate
- **privkey.pem** → The private key

View File

@ -12,11 +12,11 @@ docker_compose_instance_directory="$2"
docker_compose_cert_directory="$docker_compose_instance_directory/volumes/certs"
# Copy certificates
cp -RvL "{{ letsencrypt_live_path }}/$ssl_cert_folder/"* "$docker_compose_cert_directory" || exit 1
cp -RvL "{{ LETSENCRYPT_LIVE_PATH }}/$ssl_cert_folder/"* "$docker_compose_cert_directory" || exit 1
# This code is optimized for mailu
cp -v "{{ letsencrypt_live_path }}/$ssl_cert_folder/privkey.pem" "$docker_compose_cert_directory/key.pem" || exit 1
cp -v "{{ letsencrypt_live_path }}/$ssl_cert_folder/fullchain.pem" "$docker_compose_cert_directory/cert.pem" || exit 1
cp -v "{{ LETSENCRYPT_LIVE_PATH }}/$ssl_cert_folder/privkey.pem" "$docker_compose_cert_directory/key.pem" || exit 1
cp -v "{{ LETSENCRYPT_LIVE_PATH }}/$ssl_cert_folder/fullchain.pem" "$docker_compose_cert_directory/cert.pem" || exit 1
# Set correct reading rights
chmod a+r -v "$docker_compose_cert_directory/"*

View File

@ -24,7 +24,7 @@ The Nginx HTTPS Certificate Retrieval role ensures that your Nginx-served domain
- **ACME Challenge Selection:** Supports DNS plugins or webroot method automatically.
- **Wildcard Certificate Management:** Issues wildcard certificates when configured, saving effort for subdomain-heavy deployments.
- **Safe Cleanup:** Ensures that no unused certificates are left behind.
- **Flexible Control:** Supports `mode_test` for staging environment testing and `mode_cleanup` for cert cleanup operations.
- **Flexible Control:** Supports `MODE_TEST` for staging environment testing and `MODE_CLEANUP` for cert cleanup operations.
## 🔗 Learn More

View File

@ -1,7 +1,7 @@
- name: "Check if certificate already exists for {{ domain }}"
cert_check_exists:
domain: "{{ domain }}"
cert_base_path: "{{ letsencrypt_live_path }}"
cert_base_path: "{{ LETSENCRYPT_LIVE_PATH }}"
register: cert_check
- name: "receive certificate for {{ domain }}"
@ -10,21 +10,21 @@
--agree-tos
--email {{ users.administrator.email }}
--non-interactive
{% if certbot_acme_challenge_method != "webroot" %}
--dns-{{ certbot_acme_challenge_method }}
--dns-{{ certbot_acme_challenge_method }}-credentials {{ certbot_credentials_file }}
--dns-{{ certbot_acme_challenge_method }}-propagation-seconds {{ certbot_dns_propagation_wait_seconds }}
{% if CERTBOT_ACME_CHALLENGE_METHOD != "webroot" %}
--dns-{{ CERTBOT_ACME_CHALLENGE_METHOD }}
--dns-{{ CERTBOT_ACME_CHALLENGE_METHOD }}-credentials {{ CERTBOT_CREDENTIALS_FILE }}
--dns-{{ CERTBOT_ACME_CHALLENGE_METHOD }}-propagation-seconds {{ CERTBOT_DNS_PROPAGATION_WAIT_SECONDS }}
{% else %}
--webroot
-w {{ letsencrypt_webroot_path }}
-w {{ LETSENCRYPT_WEBROOT_PATH }}
{% endif %}
{% if wildcard_domain is defined and ( wildcard_domain | bool ) %}
-d {{ primary_domain }}
-d *.{{ primary_domain }}
-d {{ PRIMARY_DOMAIN }}
-d *.{{ PRIMARY_DOMAIN }}
{% else %}
-d {{ domain }}
{% endif %}
{{ '--test-cert' if mode_test | bool else '' }}
{{ '--test-cert' if MODE_TEST | bool else '' }}
register: certbot_result
changed_when: "'Certificate not yet due for renewal' not in certbot_result.stdout"
when: not cert_check.exists

View File

@ -10,15 +10,15 @@
certbundle
--domains "{{ current_play_domains_all | join(',') }}"
--certbot-email "{{ users.administrator.email }}"
--certbot-acme-challenge-method "{{ certbot_acme_challenge_method }}"
--certbot-acme-challenge-method "{{ CERTBOT_ACME_CHALLENGE_METHOD }}"
--chunk-size 100
{% if certbot_acme_challenge_method != 'webroot' %}
--certbot-credentials-file "{{ certbot_credentials_file }}"
--certbot-dns-propagation-seconds "{{ certbot_dns_propagation_wait_seconds }}"
{% if CERTBOT_ACME_CHALLENGE_METHOD != 'webroot' %}
--certbot-credentials-file "{{ CERTBOT_CREDENTIALS_FILE }}"
--certbot-dns-propagation-seconds "{{ CERTBOT_DNS_PROPAGATION_WAIT_SECONDS }}"
{% else %}
--letsencrypt-webroot-path "{{ letsencrypt_webroot_path }}"
--letsencrypt-webroot-path "{{ LETSENCRYPT_WEBROOT_PATH }}"
{% endif %}
{{ '--mode-test' if mode_test | bool else '' }}
{{ '--mode-test' if MODE_TEST | bool else '' }}
register: certbundle_result
changed_when: "'Certificate not yet due for renewal' not in certbundle_result.stdout"
failed_when: >

View File

@ -3,7 +3,7 @@
vars:
wildcard_domain: true
when:
- domain.split('.') | length == (primary_domain.split('.') | length + 1) and domain.endswith(primary_domain)
- domain.split('.') | length == (PRIMARY_DOMAIN.split('.') | length + 1) and domain.endswith(PRIMARY_DOMAIN)
- run_once_receive_certificate is not defined
- name: "Load dedicated certificate for domain"
@ -11,7 +11,7 @@
vars:
wildcard_domain: false
when:
- not (domain.split('.') | length == (primary_domain.split('.') | length + 1) and domain.endswith(primary_domain))
- not (domain.split('.') | length == (PRIMARY_DOMAIN.split('.') | length + 1) and domain.endswith(PRIMARY_DOMAIN))
- name: run the receive_certificate tasks once
set_fact:

View File

@ -6,20 +6,20 @@
- include_tasks: utils/run_once.yml
when: run_once_srv_web_6_6_tls_core is not defined
- name: "Include flavor '{{ certbot_flavor }}' for '{{ domain }}'"
include_tasks: "{{ role_path }}/tasks/flavors/{{ certbot_flavor }}.yml"
- name: "Include flavor '{{ CERTBOT_FLAVOR }}' for '{{ domain }}'"
include_tasks: "{{ role_path }}/tasks/flavors/{{ CERTBOT_FLAVOR }}.yml"
#- name: "Cleanup dedicated cert for {{ domain }}"
# command: >-
# certbot delete --cert-name {{ domain }} --non-interactive
# when:
# - mode_cleanup | bool
# - MODE_CLEANUP | bool
# # Cleanup mode is enabled
# - certbot_flavor != 'dedicated'
# - CERTBOT_FLAVOR != 'dedicated'
# # Wildcard certificate is enabled
# - domain.split('.') | length == (primary_domain.split('.') | length + 1) and domain.endswith(primary_domain)
# - domain.split('.') | length == (PRIMARY_DOMAIN.split('.') | length + 1) and domain.endswith(PRIMARY_DOMAIN)
# # AND: The domain is a direct first-level subdomain of the primary domain
# - domain != primary_domain
# - domain != PRIMARY_DOMAIN
# # The domain is not the primary domain
# register: certbot_result
# failed_when: certbot_result.rc != 0 and ("No certificate found with name" not in certbot_result.stderr)
@ -28,8 +28,8 @@
- name: "Find SSL cert folder for '{{ domain }}'"
cert_folder_find:
domain: "{{ domain }}"
cert_base_path: "{{ letsencrypt_live_path }}"
debug: "{{ enable_debug | default(false) }}"
cert_base_path: "{{ LETSENCRYPT_LIVE_PATH }}"
debug: "{{ MODE_DEBUG | default(false) }}"
register: cert_folder_result
delegate_to: "{{ inventory_hostname }}"
changed_when: false

View File

@ -14,11 +14,11 @@ This Ansible role installs and configures **Nginx** as a core HTTP/stream server
* **Configurable reset and cleanup** modes to purge and recreate directories.
* **Custom `nginx.conf`** template with sensible defaults for performance and security.
* **Stream proxy support**: includes `stream` block for TCP/UDP proxies.
* **Cache directory management**: cleanup and recreation based on `mode_cleanup`.
* **Cache directory management**: cleanup and recreation based on `MODE_CLEANUP`.
## Debugging Tips
* **General logs**: `journalctl -f -u nginx`
* **Filter by host**: `journalctl -u nginx -f | grep "{{ inventory_hostname }}"`
* **Enable detailed format**: set `enable_debug: true` and reload Nginx.
* **Enable detailed format**: set `MODE_DEBUG: true` and reload Nginx.

View File

@ -20,7 +20,7 @@
- name: "reset (if enabled)"
include_tasks: 02_reset.yml
when: mode_reset | bool
when: MODE_RESET | bool
- name: Ensure nginx configuration directories are present
file:

View File

@ -1,4 +1,4 @@
- name: "Delete {{nginx.directories.configuration}} directory, when mode_reset"
- name: "Delete {{nginx.directories.configuration}} directory, when MODE_RESET"
file:
path: "{{ nginx.directories.configuration }}"
state: absent

View File

@ -4,7 +4,7 @@
path: "{{ item.value }}"
state: absent
when:
- mode_cleanup | bool
- MODE_CLEANUP | bool
- run_once_nginx_reverse_proxy is not defined
loop: "{{ nginx.directories.cache | dict2items }}"
loop_control:

View File

@ -24,7 +24,7 @@ http
# --------------------------------------------------------------------------------
{# logging and debugging #}
{% if enable_debug | bool %}
{% if MODE_DEBUG | bool %}
{# individual log format for better debugging #}
log_format debug '$host - $remote_addr [$time_local] '
'"$request" $status $body_bytes_sent '

View File

@ -45,8 +45,8 @@ All tasks are idempotent—once your certificates are in place and your configur
- A working `srv-web-7-4-core` setup.
- DNS managed via Cloudflare (for CAA record tasks) or equivalent ACME DNS flow.
- Variables:
- `letsencrypt_webroot_path`
- `letsencrypt_live_path`
- `LETSENCRYPT_WEBROOT_PATH`
- `LETSENCRYPT_LIVE_PATH`
- `on_calendar_renew_lets_encrypt_certificates`
---

View File

@ -6,34 +6,34 @@
- name: install certbot DNS plugin
community.general.pacman:
name: "certbot-dns-{{ certbot_acme_challenge_method }}"
name: "certbot-dns-{{ CERTBOT_ACME_CHALLENGE_METHOD }}"
state: present
when:
- run_once_srv_web_7_7_certbot is not defined
- certbot_acme_challenge_method != 'webroot'
- CERTBOT_ACME_CHALLENGE_METHOD != 'webroot'
- name: Ensure /etc/certbot directory exists
file:
path: "{{ certbot_credentials_dir }}"
path: "{{ CERTBOT_CREDENTIALS_DIR }}"
state: directory
owner: root
group: root
mode: '0755'
when:
- run_once_srv_web_7_7_certbot is not defined
- certbot_acme_challenge_method != 'webroot'
- CERTBOT_ACME_CHALLENGE_METHOD != 'webroot'
- name: Install plugin credentials file
copy:
dest: "{{ certbot_credentials_file }}"
dest: "{{ CERTBOT_CREDENTIALS_FILE }}"
content: |
dns_{{ certbot_acme_challenge_method }}_api_token = {{ certbot_dns_api_token }}
dns_{{ CERTBOT_ACME_CHALLENGE_METHOD }}_api_token = {{ CERTBOT_DNS_API_TOKEN }}
owner: root
group: root
mode: '0600'
when:
- run_once_srv_web_7_7_certbot is not defined
- certbot_acme_challenge_method != 'webroot'
- CERTBOT_ACME_CHALLENGE_METHOD != 'webroot'
- name: run the certbot role once
set_fact:

View File

@ -10,7 +10,7 @@ Looping over a provided list of domains (`cloudflare_domains`), this role:
- Determines the zone name by extracting the last two labels of each domain.
- Ensures an A-record for each domain points to the specified IP (`cloudflare_target_ip`).
- Honors the `proxied` flag to switch between DNS-only and Cloudflare-proxied modes.
- Provides an optional debug task (`enable_debug`) to output the domain list before changes.
- Provides an optional debug task (`MODE_DEBUG`) to output the domain list before changes.
Ideal for environments where bulk or dynamic DNS updates are needed, this role abstracts away the complexity of Cloudflares zone and record API.
@ -23,7 +23,7 @@ Cloudflare DNS Records delivers an idempotent, scalable solution for managing A-
- **Automatic Zone Detection:** Parses each domain to derive its zone (`example.com`) without manual intervention.
- **Bulk Record Management:** Creates or updates A-records for all entries in `cloudflare_domains`.
- **Proxy Toggle:** Configure `proxied: true` or `false` per record to switch between DNS-only and proxied modes.
- **Debug Support:** Enable `enable_debug` to print the domain list for validation before execution.
- **Debug Support:** Enable `MODE_DEBUG` to print the domain list for validation before execution.
- **Flexible Authentication:** Supports both API token (`api_token`) and Global API key + email.
- **Low-TTL Option:** Use `ttl: 1` for rapid DNS propagation during dynamic updates.

View File

@ -2,7 +2,7 @@
- name: Create or update Cloudflare A-record for {{ item }}
community.general.cloudflare_dns:
api_token: "{{ certbot_dns_api_token }}"
api_token: "{{ CERTBOT_DNS_API_TOKEN }}"
zone: "{{ item.split('.')[-2:] | join('.') }}"
state: present
type: A

View File

@ -10,7 +10,7 @@
set_fact:
inj_enabled:
javascript: "{{ applications | get_app_conf(application_id, 'features.javascript', False) }}"
logout: "{{ (applications | get_app_conf(application_id, 'features.logout', False) or domain == primary_domain) }}"
logout: "{{ (applications | get_app_conf(application_id, 'features.logout', False) or domain == PRIMARY_DOMAIN) }}"
css: "{{ applications | get_app_conf(application_id, 'features.css', False) }}"
matomo: "{{ applications | get_app_conf(application_id, 'features.matomo', False) }}"
port_ui: "{{ applications | get_app_conf(application_id, 'features.port-ui-desktop', False) }}"
@ -39,7 +39,7 @@
set_fact:
inj_enabled:
javascript: "{{ applications | get_app_conf(application_id, 'features.javascript', False) }}"
logout: "{{ (applications | get_app_conf(application_id, 'features.logout', False) or domain == primary_domain) }}"
logout: "{{ (applications | get_app_conf(application_id, 'features.logout', False) or domain == PRIMARY_DOMAIN) }}"
css: "{{ applications | get_app_conf(application_id, 'features.css', False) }}"
matomo: "{{ applications | get_app_conf(application_id, 'features.matomo', False) }}"
port_ui: "{{ applications | get_app_conf(application_id, 'features.port-ui-desktop', False) }}"

View File

@ -16,7 +16,7 @@ This Ansible role injects a custom JavaScript snippet into all HTML responses se
Activates only when you enable the `javascript` feature for a given application, keeping your server blocks clean and performant.
- **Debug Mode**
Supports an `enable_debug` flag that appends optional `console.log` statements for easier troubleshooting in staging or development.
Supports an `MODE_DEBUG` flag that appends optional `console.log` statements for easier troubleshooting in staging or development.
## Author

View File

@ -2,6 +2,6 @@ document.addEventListener('DOMContentLoaded', function() {
initLogoutPatch(
'{{ oidc.client.logout_url }}',
'{{ WEB_PROTOCOL }}',
'{{ primary_domain }}'
'{{ PRIMARY_DOMAIN }}'
);
});

View File

@ -12,7 +12,7 @@
domain: "{{ domain }}"
base_domain: "{{ base_domain }}"
matomo_verification_url: "{{ matomo_verification_url }}"
when: enable_debug | bool
when: MODE_DEBUG | bool
- name: "Check if site {{ domain }} is allready registered at Matomo"
uri:

View File

@ -14,6 +14,6 @@ _paq.push(["enableLinkTracking"]);
g.async=true; g.src=u+"matomo.js"; s.parentNode.insertBefore(g,s);
})();
{% if enable_debug | bool %}
{% if MODE_DEBUG | bool %}
console.log("Matomo is loaded.");
{% endif %}

View File

@ -1,5 +1,5 @@
(function() {
var primary = "{{ primary_domain }}";
var primary = "{{ PRIMARY_DOMAIN }}";
var allowedOrigin = "https://{{ domains | get_domain('web-app-port-ui') }}";
function notifyParent() {
@ -43,6 +43,6 @@
};
})();
{% if enable_debug | bool %}
{% if MODE_DEBUG | bool %}
console.log("[iframe-sync] Sender for iframe messages is active.");
{% endif %}

View File

@ -11,4 +11,4 @@
- name: "Set CAA records for all base domains"
include_tasks: 01_set-caa-records.yml
when: dns_provider == 'cloudflare'
when: DNS_PROVIDER == 'cloudflare'

View File

@ -1,14 +1,14 @@
---
- name: "Validate certbot_dns_api_token"
- name: "Validate CERTBOT_DNS_API_TOKEN"
fail:
msg: >
The variable "certbot_dns_api_token" must be defined and cannot be empty!
when: (certbot_dns_api_token|default('')|trim) == ''
The variable "CERTBOT_DNS_API_TOKEN" must be defined and cannot be empty!
when: (CERTBOT_DNS_API_TOKEN|default('')|trim) == ''
- name: "Ensure all CAA records are present"
community.general.cloudflare_dns:
api_token: "{{ certbot_dns_api_token }}"
api_token: "{{ CERTBOT_DNS_API_TOKEN }}"
zone: "{{ item.0 }}"
record: "@"
type: CAA

View File

@ -9,7 +9,7 @@ server
#letsencrypt
location ^~ /.well-known/acme-challenge/ {
allow all;
root {{ letsencrypt_webroot_path }};
root {{ LETSENCRYPT_WEBROOT_PATH }};
default_type "text/plain";
try_files $uri =404;
}

View File

@ -1,3 +1,3 @@
ssl_certificate {{ [ letsencrypt_live_path, ssl_cert_folder] | path_join }}/fullchain.pem;
ssl_certificate_key {{ [ letsencrypt_live_path, ssl_cert_folder] | path_join }}/privkey.pem;
ssl_trusted_certificate {{ [ letsencrypt_live_path, ssl_cert_folder] | path_join }}/chain.pem;
ssl_certificate {{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder] | path_join }}/fullchain.pem;
ssl_certificate_key {{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder] | path_join }}/privkey.pem;
ssl_trusted_certificate {{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder] | path_join }}/chain.pem;

View File

@ -10,6 +10,6 @@
- {{ nginx.directories.configuration }}:{{ nginx.directories.configuration }}:ro
- {{ nginx.directories.data.www }}:{{ nginx.directories.data.www }}:ro
- {{ nginx.directories.data.well_known }}:{{ nginx.directories.data.well_known }}:ro
- {{ letsencrypt_webroot_path }}:{{ letsencrypt_webroot_path }}:ro
- {{ letsencrypt_base_path }}:{{ letsencrypt_base_path }}:ro
- {{ LETSENCRYPT_WEBROOT_PATH }}:{{ LETSENCRYPT_WEBROOT_PATH }}:ro
- {{ LETSENCRYPT_BASE_PATH }}:{{ LETSENCRYPT_BASE_PATH }}:ro
command: ["openresty", "-g", "daemon off;"]

View File

@ -12,7 +12,7 @@
- name: "reset (if enabled)"
include_tasks: 03_reset.yml
when: mode_reset | bool
when: MODE_RESET | bool
- name: configure sys-bkp-docker-2-loc-everything.infinito.service
template:

View File

@ -11,7 +11,7 @@
database_host: "{{ database_host | default('undefined') }}"
database_username: "{{ database_username | default('undefined') }}"
database_password: "{{ database_password | default('undefined') }}"
when: enable_debug | bool
when: MODE_DEBUG | bool
- name: "fail if not all required database variables are defined"
fail:

View File

@ -14,7 +14,7 @@
vars:
domain: "{{ item }}"
when:
- mode_cleanup | bool
- MODE_CLEANUP | bool
## The revoking just works for the base domain
#- name: "Revoke Certbot certificate for {{ item }}"
@ -25,7 +25,7 @@
# loop_control:
# label: "{{ item }}"
# when:
# - mode_cleanup | bool
# - MODE_CLEANUP | bool
# - run_once_sys_cln_domains is not defined
# register: certbot_revoke_result
# failed_when: >
@ -43,7 +43,7 @@
# loop_control:
# label: "{{ item }}"
# when:
# - mode_cleanup | bool
# - MODE_CLEANUP | bool
# - run_once_sys_cln_domains is not defined
# register: certbot_delete_result
# failed_when: >

View File

@ -4,7 +4,7 @@ This Ansible role handles resetting and cleaning up “Infinito.Nexus” systemd
## Description
When enabled via the `mode_reset` flag, this role will:
When enabled via the `MODE_RESET` flag, this role will:
1. Run its reset tasks exactly once per play (`run_once_sys_rst_daemon` guard).
2. Find all `/etc/systemd/system/*.infinito.service` units.

View File

@ -1,6 +1,6 @@
- name: "reset (if enabled)"
include_tasks: reset.yml
when: mode_reset | bool and run_once_sys_rst_daemon is not defined
when: MODE_RESET | bool and run_once_sys_rst_daemon is not defined
- name: run {{ role_name }} once
set_fact:

View File

@ -19,7 +19,7 @@ This Ansible role configures the OpenSSH daemon (`sshd`) by deploying a template
- **Security Defaults**
- Disables password (`PasswordAuthentication no`) and root login (`PermitRootLogin no`)
- Enforces public-key authentication (`PubkeyAuthentication yes`)
- Conditionally sets `LogLevel` to `DEBUG3` when `enable_debug` is true
- Conditionally sets `LogLevel` to `DEBUG3` when `MODE_DEBUG` is true
- **Systemd Integration**
Handles daemon reload and service restart seamlessly on configuration changes.

View File

@ -25,7 +25,7 @@
# Logging
#SyslogFacility AUTH
LogLevel {% if enable_debug | bool %}DEBUG3{% else %}INFO{% endif %}
LogLevel {% if MODE_DEBUG | bool %}DEBUG3{% else %}INFO{% endif %}
# Authentication:

View File

@ -9,7 +9,7 @@ This role configures a systemd timer to periodically start a corresponding servi
Optimized for automated task scheduling in a [systemd](https://en.wikipedia.org/wiki/Systemd) environment, this role:
- Generates a timer unit file for a given service (using the `service_name` variable).
- Reloads and restarts the timer using systemd to ensure that changes take effect.
- Supports dynamic configuration of scheduling parameters via variables like `on_calendar` and `randomized_delay_sec`.
- Supports dynamic configuration of scheduling parameters via variables like `on_calendar` and `RANDOMIZED_DELAY_SEC`.
## Purpose

View File

@ -1,7 +1,7 @@
- name: "reset (if enabled)"
include_tasks: 01_reset.yml
when: mode_reset | bool and run_once_sys_timer is not defined
when: MODE_RESET | bool and run_once_sys_timer is not defined
- name: run {{ role_name }} once
set_fact:
@ -20,5 +20,5 @@
name: "{{ sys_timer_file }}"
state: restarted
enabled: yes
when: dummy_timer.changed or activate_all_timers | bool
when: dummy_timer.changed or ACTIVATE_ALL_TIMERS | bool

View File

@ -3,7 +3,7 @@ Description=Timer to start {{service_name}}.infinito.service
[Timer]
OnCalendar={{on_calendar}}
RandomizedDelaySec={{randomized_delay_sec}}
RandomizedDelaySec={{RANDOMIZED_DELAY_SEC}}
Persistent={{ persistent | default('false') }}
[Install]

View File

@ -8,7 +8,7 @@
name: sys-bkp-docker-2-loc-everything.infinito.service
state: started
when:
- mode_backup | bool
- MODE_BACKUP | bool
- name: create {{update_docker_script}}
template:

View File

@ -149,7 +149,7 @@ def update_mastodon():
Runs the database migration for Mastodon to ensure all required tables are up to date.
"""
print("Starting Mastodon database migration.")
run_command("docker compose exec -T web bash -c 'RAILS_ENV={{ INFINITO_ENVIRONMENT | lower }} bin/rails db:migrate'")
run_command("docker compose exec -T web bash -c 'RAILS_ENV={{ ENVIRONMENT | lower }} bin/rails db:migrate'")
print("Mastodon database migration complete.")
def upgrade_listmonk():

View File

@ -2,7 +2,7 @@ users:
administrator:
description: "System Administrator"
username: "administrator"
email: "administrator@{{ primary_domain }}"
email: "administrator@{{ PRIMARY_DOMAIN }}"
password: "{{ ansible_become_password }}"
uid: 1001
gid: 1001

View File

@ -2,10 +2,10 @@
users:
sld:
description: "Auto Generated Account to reserve the SLD"
username: "{{ primary_domain.split('.')[0] }}"
username: "{{ PRIMARY_DOMAIN.split('.')[0] }}"
tld:
description: "Auto Generated Account to reserve the TLD"
username: "{{ primary_domain.split('.')[1] }}"
username: "{{ PRIMARY_DOMAIN.split('.')[1] }}"
root:
username: root
uid: 0

View File

@ -1,5 +1,5 @@
company:
name: "Akaunting on {{ primary_domain | upper }}" # @todo load automatic based on service_provider infos, this will fail
name: "Akaunting on {{ PRIMARY_DOMAIN | upper }}" # @todo load automatic based on service_provider infos, this will fail
email: "{{ users.administrator.email }}" # @todo load automatic based on service_provider infos, this will fail
setup_admin_email: "{{ users.administrator.email }}"
features:
@ -11,7 +11,7 @@ features:
server:
domains:
canonical:
- "accounting.{{ primary_domain }}"
- "accounting.{{ PRIMARY_DOMAIN }}"
docker:
services:
database:

View File

@ -16,4 +16,4 @@ docker:
server:
domains:
canonical:
- "tickets.{{ primary_domain }}"
- "tickets.{{ PRIMARY_DOMAIN }}"

View File

@ -21,4 +21,4 @@ docker:
server:
domains:
canonical:
- baserow.{{ primary_domain }}
- baserow.{{ PRIMARY_DOMAIN }}

View File

@ -18,7 +18,7 @@ server:
unsafe-inline: true
domains:
canonical:
- "meet.{{ primary_domain }}"
- "meet.{{ PRIMARY_DOMAIN }}"
credentials: {}
docker:

View File

@ -1,6 +1,6 @@
ENABLE_COTURN=true
COTURN_TLS_CERT_PATH={{ [ letsencrypt_live_path, ssl_cert_folder] | path_join }}/fullchain.pem
COTURN_TLS_KEY_PATH={{ [ letsencrypt_live_path, ssl_cert_folder] | path_join }}/privkey.pem
COTURN_TLS_CERT_PATH={{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder] | path_join }}/fullchain.pem
COTURN_TLS_KEY_PATH={{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder] | path_join }}/privkey.pem
ENABLE_GREENLIGHT={{ applications | get_app_conf(application_id, 'enable_greenlight', True) }}
# Enable Webhooks

View File

@ -1,3 +1,3 @@
users:
administrator:
email: "administrator@{{ primary_domain }}"
email: "administrator@{{ PRIMARY_DOMAIN }}"

View File

@ -11,8 +11,8 @@ features:
server:
domains:
canonical:
web: "bskyweb.{{ primary_domain }}"
api: "bluesky.{{ primary_domain }}"
web: "bskyweb.{{ PRIMARY_DOMAIN }}"
api: "bluesky.{{ PRIMARY_DOMAIN }}"
docker:
services:
database:

View File

@ -24,7 +24,7 @@
args:
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_SITE_NAME: "{{primary_domain | upper}} - Bluesky"
REACT_APP_SITE_NAME: "{{PRIMARY_DOMAIN | upper}} - Bluesky"
REACT_APP_SITE_DESCRIPTION: "Decentral Social "
ports:
- "127.0.0.1:{{ports.localhost.http['web-app-bluesky_web']}}:8100"

View File

@ -3,7 +3,7 @@ PDS_ADMIN_EMAIL="{{applications.bluesky.users.administrator.email}}"
PDS_SERVICE_DID="did:web:{{domains[application_id].api}}"
# See https://mattdyson.org/blog/2024/11/self-hosting-bluesky-pds/
PDS_SERVICE_HANDLE_DOMAINS=".{{primary_domain}}"
PDS_SERVICE_HANDLE_DOMAINS=".{{PRIMARY_DOMAIN}}"
PDS_JWT_SECRET="{{ bluesky_jwt_secret }}"
PDS_ADMIN_PASSWORD="{{bluesky_admin_password}}"
PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX="{{ bluesky_rotation_key }}"

View File

@ -1,3 +1,3 @@
users:
administrator:
email: "administrator@{{ primary_domain }}"
email: "administrator@{{ PRIMARY_DOMAIN }}"

View File

@ -1,7 +1,7 @@
server:
domains:
canonical:
- "collabora.{{ primary_domain }}"
- "collabora.{{ PRIMARY_DOMAIN }}"
docker:
services:
redis:

View File

@ -16,10 +16,10 @@ server:
unsafe-inline: true
whitelist:
font-src:
- "http://*.{{primary_domain}}"
- "http://*.{{PRIMARY_DOMAIN}}"
domains:
canonical:
- "forum.{{ primary_domain }}"
- "forum.{{ PRIMARY_DOMAIN }}"
docker:
services:
database:

View File

@ -1,6 +1,6 @@
- name: "reset (if enabled)"
include_tasks: 02_reset.yml
when: mode_reset | bool
when: MODE_RESET | bool
# Necessary for building: https://chat.openai.com/share/99d258cc-294b-4924-8eef-02fe419bb838
- name: install which

View File

@ -3,4 +3,4 @@ features:
server:
domains:
canonical:
- elk.{{ primary_domain }}
- elk.{{ PRIMARY_DOMAIN }}

View File

@ -18,17 +18,17 @@ server:
unsafe-eval: true
whitelist:
connect-src:
- wss://espocrm.{{ primary_domain }}
- wss://espocrm.{{ PRIMARY_DOMAIN }}
- "data:"
frame-src:
- https://s.espocrm.com/
domains:
aliases:
- "crm.{{ primary_domain }}"
- "crm.{{ PRIMARY_DOMAIN }}"
canonical:
- espocrm.{{ primary_domain }}
- espocrm.{{ PRIMARY_DOMAIN }}
email:
from_name: "Customer Relationship Management ({{ primary_domain }})"
from_name: "Customer Relationship Management ({{ PRIMARY_DOMAIN }})"
docker:
services:
database:

View File

@ -41,7 +41,7 @@ ESPOCRM_CONFIG_DEFAULT_CURRENCY={{ HOST_CURRENCY }}
# ------------------------------------------------
# Logger
# ------------------------------------------------
ESPOCRM_CONFIG_LOGGER_LEVEL={{ 'DEBUG' if enable_debug | bool else 'INFO' }}
ESPOCRM_CONFIG_LOGGER_LEVEL={{ 'DEBUG' if MODE_DEBUG | bool else 'INFO' }}
ESPOCRM_CONFIG_LOGGER_PATH=php://stdout
ESPOCRM_CONFIG_LOGGER_ROTATION=false

View File

@ -12,7 +12,7 @@ features:
server:
domains:
canonical:
- "social.{{ primary_domain }}"
- "social.{{ PRIMARY_DOMAIN }}"
csp:
flags:
script-src-elem:

View File

@ -6,8 +6,8 @@ HOSTNAME={{domains | get_domain(application_id)}}
FRIENDICA_NO_VALIDATION={{friendica_no_validation | lower}}
# Debugging
FRIENDICA_DEBUGGING={{ (enable_debug | bool) | lower }}{{"\n"}}
FRIENDICA_LOGLEVEL={% if enable_debug | bool %}9{% else %}5{% endif %}{{"\n"}}
FRIENDICA_DEBUGGING={{ (MODE_DEBUG | bool) | lower }}{{"\n"}}
FRIENDICA_LOGLEVEL={% if MODE_DEBUG | bool %}9{% else %}5{% endif %}{{"\n"}}
FRIENDICA_LOGGER=syslog
# Database Configuration

View File

@ -23,10 +23,10 @@ features:
server:
domains:
canonical:
- "audio.{{ primary_domain }}"
- "audio.{{ PRIMARY_DOMAIN }}"
aliases:
- "music.{{ primary_domain }}"
- "sound.{{ primary_domain }}"
- "music.{{ PRIMARY_DOMAIN }}"
- "sound.{{ PRIMARY_DOMAIN }}"
csp:
flags:
style-src:

View File

@ -40,10 +40,10 @@ FUNKWHALE_HOSTNAME={{domains | get_domain(application_id)}}
FUNKWHALE_PROTOCOL={{ WEB_PROTOCOL }}
# Log level (debug, info, warning, error, critical)
LOGLEVEL={% if enable_debug | bool %}debug{% else %}error{% endif %}
LOGLEVEL={% if MODE_DEBUG | bool %}debug{% else %}error{% endif %}
# Could be that this is redundant
DJANGO_LOGLEVEL={% if enable_debug | bool %}debug{% else %}error{% endif %}
DJANGO_LOGLEVEL={% if MODE_DEBUG | bool %}debug{% else %}error{% endif %}
# Configure e-mail sending using this variale
# By default, funkwhale will output e-mails sent to stdout

View File

@ -36,9 +36,9 @@ server:
- "data:"
domains:
aliases:
- "git.{{ primary_domain }}"
- "git.{{ PRIMARY_DOMAIN }}"
canonical:
- gitea.{{ primary_domain }}
- gitea.{{ PRIMARY_DOMAIN }}
docker:
services:
database:

View File

@ -2,7 +2,7 @@
shell: |
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
gitea admin auth list \
| awk -v name="LDAP ({{ primary_domain }})" '$0 ~ name {print $1; exit}'
| awk -v name="LDAP ({{ PRIMARY_DOMAIN }})" '$0 ~ name {print $1; exit}'
args:
chdir: "{{ docker_compose.directories.instance }}"
register: ldap_source_id_raw

View File

@ -54,14 +54,14 @@
- name: Execute Cleanup Routines
include_tasks: 03_cleanup.yml
when: mode_cleanup
when: MODE_CLEANUP
- name: Include DNS role to register Gitea domain(s)
include_role:
name: srv-web-7-7-dns-records
vars:
cloudflare_api_token: "{{ certbot_dns_api_token }}"
cloudflare_api_token: "{{ CERTBOT_DNS_API_TOKEN }}"
cloudflare_domains: "{{ [ domains | get_domain(application_id) ] }}"
cloudflare_target_ip: "{{ networks.internet.ip4 }}"
cloudflare_proxied: false
when: dns_provider == 'cloudflare'
when: DNS_PROVIDER == 'cloudflare'

View File

@ -13,7 +13,7 @@
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
gitea admin auth list \
| tail -n +2 \
| grep -F "LDAP ({{ primary_domain }})" \
| grep -F "LDAP ({{ PRIMARY_DOMAIN }})" \
| awk '{print $1; exit}'
args:
chdir: "{{ docker_compose.directories.instance }}"

View File

@ -3,7 +3,7 @@
# General
DOMAIN={{domains | get_domain(application_id)}}
RUN_MODE="{{ 'dev' if (INFINITO_ENVIRONMENT | lower) == 'development' else 'prod' }}"
RUN_MODE="{{ 'dev' if (ENVIRONMENT | lower) == 'development' else 'prod' }}"
ROOT_URL="{{ domains | get_url(application_id, WEB_PROTOCOL) }}/"
APP_NAME="{{ applications | get_app_conf(application_id, 'title', True) }}"
USER_UID=1000
@ -11,7 +11,7 @@ USER_GID=1000
# Logging configuration
GITEA__log__MODE=console
GITEA__log__LEVEL={% if enable_debug | bool %}Debug{% else %}Info{% endif %}
GITEA__log__LEVEL={% if MODE_DEBUG | bool %}Debug{% else %}Info{% endif %}
# Database
DB_TYPE=mysql

View File

@ -1,7 +1,7 @@
application_id: "web-app-gitea"
database_type: "mariadb"
gitea_ldap_auth_args:
- '--name "LDAP ({{ primary_domain }})"'
- '--name "LDAP ({{ PRIMARY_DOMAIN }})"'
- '--host "{{ ldap.server.domain }}"'
- '--port {{ ldap.server.port }}'
- '--security-protocol "{{ ldap.server.security | trim or "unencrypted" }}"'

View File

@ -18,4 +18,4 @@ credentials:
server:
domains:
canonical:
- gitlab.{{ primary_domain }}
- gitlab.{{ PRIMARY_DOMAIN }}

View File

@ -3,4 +3,4 @@ features:
server:
domains:
canonical:
- jenkins.{{ primary_domain }}
- jenkins.{{ PRIMARY_DOMAIN }}

View File

@ -9,7 +9,7 @@ features:
server:
domains:
canonical:
- "cms.{{ primary_domain }}"
- "cms.{{ PRIMARY_DOMAIN }}"
docker:
services:
database:

View File

@ -28,7 +28,7 @@ server:
- "*" # For frontend channel logout it's necessary that iframes can be loaded
domains:
canonical:
- "auth.{{ primary_domain }}"
- "auth.{{ PRIMARY_DOMAIN }}"
scopes:
rbac_roles: rbac_roles
nextcloud: nextcloud

View File

@ -25,7 +25,7 @@ KC_BOOTSTRAP_ADMIN_USERNAME= "{{applications | get_app_conf(application_id, '
KC_BOOTSTRAP_ADMIN_PASSWORD= "{{applications | get_app_conf(application_id, 'credentials.administrator_password', True)}}"
# Enable detailed logs
{% if enable_debug | bool %}
{% if MODE_DEBUG | bool %}
KC_LOG_LEVEL=DEBUG
KC_LOG_CONSOLE_ENABLED=true
{% endif %}

View File

@ -836,7 +836,7 @@
{# The following line should be covered by 02_update_client_redirects.yml #}
"redirectUris": {{ domains | redirect_uris(applications, WEB_PROTOCOL) | tojson }},
"webOrigins": [
"{{ WEB_PROTOCOL }}://*.{{primary_domain}}"
"{{ WEB_PROTOCOL }}://*.{{PRIMARY_DOMAIN}}"
],
"notBefore": 0,
"bearerOnly": false,
@ -853,7 +853,7 @@
"oidc.ciba.grant.enabled": "false",
"client.secret.creation.time": "0",
"backchannel.logout.session.required": "true",
"post.logout.redirect.uris": "{{ WEB_PROTOCOL }}://{{primary_domain}}/*##+",
"post.logout.redirect.uris": "{{ WEB_PROTOCOL }}://{{PRIMARY_DOMAIN}}/*##+",
"frontchannel.logout.session.required": "true",
"oauth2.device.authorization.grant.enabled": "false",
"display.on.consent.screen": "false",

View File

@ -5,7 +5,7 @@ database_type: "postgres"
# Keycloak
keycloak_container: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.name') }}" # Name of the keycloak docker container
keycloak_docker_import_directory: "/opt/keycloak/data/import/" # Directory in which keycloak import files are placed in the running docker container
keycloak_realm: "{{ primary_domain}}" # This is the name of the default realm which is used by the applications
keycloak_realm: "{{ PRIMARY_DOMAIN}}" # This is the name of the default realm which is used by the applications
keycloak_master_api_user: "{{ applications | get_app_conf(application_id, 'users.administrator') }}" # Master Administrator
keycloak_master_api_user_name: "{{ keycloak_master_api_user.username }}" # Master Administrator Username
keycloak_master_api_user_password: "{{ keycloak_master_api_user.password }}" # Master Administrator Password
@ -15,7 +15,7 @@ keycloak_server_host: "127.0.0.1:{{ ports.localhost.http[applicati
keycloak_server_host_url: "http://{{ keycloak_server_host }}"
keycloak_image: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.image') }}" # Keycloak docker image
keycloak_version: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.version') }}" # Keycloak docker version
keycloak_debug_enabled: "{{ enable_debug }}"
keycloak_debug_enabled: "{{ MODE_DEBUG }}"
keycloak_redirect_features: ["features.oauth2","features.oidc"]
keycloak_client_id: "{{ oidc.client.id }}"
keycloak_ldap_component_name: "{{ ldap.server.domain }}" # Name of the LDAP User Federation component in Keycloak (as shown in UI)

View File

@ -27,7 +27,7 @@ server:
unsafe-inline: true
domains:
aliases:
- "ldap.{{primary_domain}}"
- "ldap.{{PRIMARY_DOMAIN}}"
canonical:
- lam.{{ primary_domain }}
- lam.{{ PRIMARY_DOMAIN }}

View File

@ -24,7 +24,7 @@ server:
flags: {} # Flags which should be set
domains:
canonical:
- "libretranslate.{{ primary_domain }}"
- "libretranslate.{{ PRIMARY_DOMAIN }}"
aliases: [] # Alias redirections to the first element of the canonical domains
rbac:
roles: {}

View File

@ -9,7 +9,7 @@ features:
server:
domains:
canonical:
- "newsletter.{{ primary_domain }}"
- "newsletter.{{ PRIMARY_DOMAIN }}"
docker:
services:
database:

View File

@ -1,7 +1,7 @@
oidc:
email_by_username: true # If true, then the mail is set by the username. If wrong then the OIDC user email is used
enable_user_creation: true # Users will be created if not existing
domain: "{{ primary_domain }}" # The main domain from which mails will be send \ email suffix behind @
domain: "{{ PRIMARY_DOMAIN }}" # The main domain from which mails will be send \ email suffix behind @
features:
matomo: true
css: false
@ -12,7 +12,7 @@ features:
server:
domains:
canonical:
- "mail.{{ primary_domain }}"
- "mail.{{ PRIMARY_DOMAIN }}"
csp:
flags:
style-src:

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