General optimations and debugging

This commit is contained in:
Kevin Veen-Birkenbach 2025-07-08 13:50:23 +02:00
parent cb29a479b3
commit 36ff93e64e
No known key found for this signature in database
GPG Key ID: 44D8F11FD62F878E
69 changed files with 425 additions and 290 deletions

View File

@ -39,7 +39,7 @@ def compare_application_keys(applications, defaults, source_file):
default_keys = recursive_keys(default_conf)
for key in app_keys:
if key.startswith("credentials."):
if key.startswith("credentials"):
continue # explicitly ignore credentials
if key not in default_keys:
errors.append(f"{source_file}: Missing default for {app_id}: {key}")

View File

@ -62,6 +62,7 @@ ports:
collabora: 8042
mobilizon: 8043
simpleicons: 8044
libretranslate: 8055
bigbluebutton: 48087 # This port is predefined by bbb. @todo Try to change this to a 8XXX port
# Ports which are exposed to the World Wide Web
public:

View File

@ -88,6 +88,8 @@ defaults_networks:
subnet: 192.168.103.96/28
simpleicons:
subnet: 192.168.103.112/28
libretranslate:
subnet: 192.168.103.128/28
# /24 Networks / 254 Usable Clients
bigbluebutton:

View File

@ -11,8 +11,8 @@ defaults_service_provider:
country: "Nexusland"
logo: "{{ applications['assets-server'].url ~ '/img/logo.png' }}"
platform:
titel: "CyMaIS Demo"
subtitel: "The Future of Self-Hosted Infrastructure. Secure. Automated. Sovereign."
titel: "CyMaIS"
subtitel: "One login. Infinite applications."
logo: "{{ applications['assets-server'].url ~ '/img/logo.png' }}"
favicon: "{{ applications['assets-server'].url ~ '/img/favicon.ico' }}"
contact:

View File

@ -13,7 +13,7 @@
environment:
- AKAUNTING_SETUP
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
data:

View File

@ -15,4 +15,5 @@ docker:
services:
database:
enabled: true
credentials: {}

View File

@ -7,7 +7,7 @@
volumes:
- .:/usr/share/nginx/html
- .:/var/www
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_incl.yml.j2' %}
maildev:
worker:
env_file:
@ -16,7 +16,7 @@
worker:
image: "{{ applications[application_id].images.worker }}"
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_incl.yml.j2' %}
maildev:
{% include 'roles/docker-container/templates/networks.yml.j2' %}
volumes:

View File

@ -9,7 +9,7 @@
ports:
- "{{ports.localhost.http[application_id]}}:80"
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
data:

View File

@ -20,3 +20,4 @@ csp:
unsafe-inline: true
style-src:
unsafe-inline: true
credentials: {}

View File

@ -1,6 +1,6 @@
# This template needs to be included in docker-compose.yml, which depend on a mariadb database
{% if not applications | is_feature_enabled('central_database',application_id) %}
database:
{{ database_host }}:
container_name: {{application_id}}-database
logging:
driver: journald

View File

@ -1,6 +1,6 @@
# This template needs to be included in docker-compose.yml, which depend on a postgres database
{% if not applications | is_feature_enabled('central_database',application_id) %}
database:
{{ database_host }}:
image: postgres:{{applications.postgres.version}}-alpine
container_name: {{application_id}}-database
env_file:

View File

@ -7,7 +7,7 @@
- "127.0.0.1:{{ports.localhost.http[application_id]}}:80"
{% include 'roles/docker-container/templates/base.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-compose/templates/networks.yml.j2' %}

View File

@ -26,3 +26,4 @@ galaxy_info:
documentation: https://s.veen.world/cymais
dependencies:
- nginx-docker-reverse-proxy
- docker-container # Necessary for template use

View File

@ -17,7 +17,7 @@ The following templates are available under `roles/docker-container/templates/`:
- `central_ldap` when LDAP feature and network are enabled
- `default`
- **depends_on_dmbs.j2**
- **depends_on_dmbs.yml.j2**
Builds a `depends_on:` block automatically:
- If `central_database` is **off**, renders an empty list `depends_on: []`
- Otherwise, includes `database` and/or `redis` with healthcheck conditions

View File

@ -0,0 +1,8 @@
{% if not applications | is_feature_enabled('central_database',application_id) %}
{{ database_host }}:
condition: service_healthy
{% endif %}
{% if applications[application_id].docker.services.redis.enabled | default(false) | bool %}
redis:
condition: service_healthy
{% endif %}

View File

@ -0,0 +1,9 @@
{# This template needs to be included in docker-compose.yml containers, which depend on a database, redis and optional additional volumes #}
{% if
(applications[application_id].docker.services.redis.enabled | default(false)| bool) or
not applications | is_feature_enabled('central_database',application_id)
%}
depends_on:
{% include "roles/docker-container/templates/depends_on/dbms_base.yml.j2" %}
{% endif %}
{{ "\n" }}

View File

@ -0,0 +1,4 @@
{# This template needs to be included in docker-compose.yml containers, which depend on a database, redis and optional additional volumes #}
depends_on:
{% include "roles/docker-container/templates/depends_on/dbms_base.yml.j2" %}
{{ "\n" }}

View File

@ -1,18 +0,0 @@
{# This template needs to be included in docker-compose.yml containers, which depend on a database, redis and optional additional volumes #}
{% if applications | is_feature_enabled('central_database', application_id)
and not (applications[application_id].docker.services.redis.enabled
| default(false)
| bool) %}
depends_on: []
{% else %}
depends_on:
{% if not applications | is_feature_enabled('central_database', application_id) %}
database:
condition: service_healthy
{% endif %}
{% if applications[application_id].docker.services.redis.enabled | default(false) | bool %}
redis:
condition: service_healthy
{% endif %}
{% endif %}
{{ "\n" }}

View File

@ -12,7 +12,7 @@
{% include 'roles/docker-container/templates/healthcheck/curl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
data:

View File

@ -8,7 +8,7 @@
listen: recreate discourse
- name: "add central database temporary to {{application_id}}_default"
command: docker network connect {{applications[application_id].network}} central-{{ database_type }}
command: docker network connect {{applications[application_id].network}} {{ database_host }}
failed_when: >
result.rc != 0 and
'already exists in network' not in result.stderr

View File

@ -22,7 +22,7 @@
- name: "cleanup central database from {{application_id}}_default network"
command:
cmd: "docker network disconnect {{applications[application_id].network}} central-{{ database_type }}"
cmd: "docker network disconnect {{applications[application_id].network}} {{ database_host }}"
ignore_errors: true
when:
- mode_reset | bool
@ -88,7 +88,7 @@
- name: "remove central database from {{application_id}}_default"
command:
cmd: "docker network disconnect {{applications[application_id].network}} central-{{ database_type }}"
cmd: "docker network disconnect {{applications[application_id].network}} {{ database_host }}"
ignore_errors: true
when:
- applications | is_feature_enabled('central_database',application_id)

View File

@ -5,7 +5,7 @@
{% include 'roles/docker-container/templates/healthcheck/curl.yml.j2' %}
ports:
- "127.0.0.1:{{ ports.localhost.http[application_id] }}:80"
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
volumes:
- data:/var/www/html
@ -31,7 +31,7 @@
- ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBSCRIBER_DSN=tcp://*:7777
- ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBMISSION_DSN=tcp://websocket:7777
entrypoint: docker-websocket.sh
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
volumes:
- data:/var/www/html

View File

@ -11,7 +11,7 @@
{% include 'roles/docker-container/templates/healthcheck/msmtp_curl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
data:

View File

@ -16,14 +16,14 @@
volumes:
- "data:{{funkwhale_media_root}}"
- "music:{{funkwhale_music_directory_path}}:ro"
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
celerybeat:
{% include 'roles/docker-container/templates/base.yml.j2' %}
image: "{{ applications | get_docker_image(application_id,'api') }}"
command: celery -A funkwhale_api.taskapp beat --pidfile= -l INFO
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
api:
@ -35,7 +35,7 @@
- "funkwhale_static_root:{{funkwhale_static_root}}"
ports:
- "{{ funkwhale_docker_api_port }}"
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
front:

View File

@ -12,7 +12,7 @@
- /etc/localtime:/etc/localtime:ro
{% include 'roles/docker-container/templates/healthcheck/curl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
data:

View File

@ -12,7 +12,7 @@
- 'logs:/var/log/gitlab'
- 'data:/var/opt/gitlab'
shm_size: '256m'
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}

View File

@ -7,7 +7,7 @@
ports:
- "127.0.0.1:{{ports.localhost.http[application_id]}}:80"
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
data:

View File

@ -9,7 +9,7 @@
- "{{ keycloak_server_host }}:8080"
volumes:
- "{{import_directory_host}}:{{import_directory_docker}}"
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% set container_port = 9000 %}
{% set container_healthcheck = 'health/live' %}

View File

@ -0,0 +1,19 @@
# Docker Role Template
This folder contains a template to setup docker roles.
## Description
* Put a description here.
## Overview
Put an overview here.
## Features
Put a feature list here
## Further Resources
* Put more ressources here

View File

@ -0,0 +1,19 @@
---
galaxy_info:
author: "Kevin Veen-Birkenbach"
description: ""
license: "CyMaIS NonCommercial License (CNCL)"
license_url: "https://s.veen.world/cncl"
company: |
Kevin Veen-Birkenbach
Consulting & Coaching Solutions
https://www.veen.world
galaxy_tags: []
repository: "https://github.com/kevinveenbirkenbach/cymais"
issue_tracker_url: "https://github.com/kevinveenbirkenbach/cymais/issues"
documentation: "https://github.com/kevinveenbirkenbach/cymais/"
logo:
class: ""
run_after: []
dependencies: []

View File

@ -0,0 +1,27 @@
---
- name: "include docker-compose role"
include_role:
name: docker-compose
when: run_once_docker_libretranslate is not defined
- name: "include role nginx-domain-setup for {{application_id}}"
include_role:
name: nginx-domain-setup
vars:
domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}"
when: run_once_docker_libretranslate is not defined
- name: run the libretranslate tasks once
set_fact:
run_once_docker_libretranslate: true
when: run_once_docker_libretranslate is not defined

View File

@ -0,0 +1,19 @@
services:
{% include 'roles/docker-compose/templates/base.yml.j2' %}
application:
image: "{{ applications[application_id].images[application_id] }}"
volumes: []
ports:
- "127.0.0.1:{{ ports.localhost.http[application_id] }}:{{ container_port }}"
{% include 'roles/docker-container/templates/healthcheck/curl.yml.j2' %}
{% include 'roles/docker-container/templates/base.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
{% include 'roles/docker-compose/templates/networks.yml.j2' %}

View File

@ -0,0 +1 @@
alert('Custom JS loaded');

View File

@ -0,0 +1,28 @@
credentials: {}
docker:
images: {} # @todo Move under services
versions: {} # @todo Move under services
services:
redis:
enabled: false # Enable Redis
database:
enabled: false # Enable the database
features:
matomo: true # Enable Matomo Tracking
css: true # Enable Global CSS Styling
portfolio_iframe: true # Enable loading of app in iframe
ldap: false # Enable LDAP Network
central_database: false # Enable Central Database Network
recaptcha: false # Enable ReCaptcha
oauth2: false # Enable the OAuth2-Proy
javascript: false # Enables the custom JS in the javascript.js.j2 file
csp:
whitelist: {} # URL's which should be whitelisted
flags: {} # Flags which should be set
domains:
canonical: {} # Urls under which the domain should be directly accessible
aliases: [] # Alias redirections to the first element of the canonical domains
rbac:
roles: {}

View File

@ -0,0 +1,2 @@
application_id: libretranslate # ID of the application
database_type: 0 # Database type [postgres, mariadb]

View File

@ -8,7 +8,7 @@
volumes:
- {{docker_compose.directories.config}}config.toml:/listmonk/config.toml
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/healthcheck/wget.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes-just-database.yml.j2' %}

View File

@ -23,7 +23,7 @@
volumes:
- "{{docker_compose.directories.volumes}}overrides/nginx:/overrides:ro"
- "{{cert_mount_directory}}:/certs:ro"
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_incl.yml.j2' %}
resolver:
condition: service_started
{% include 'roles/docker-container/templates/networks.yml.j2' %}
@ -38,7 +38,7 @@
volumes:
- "admin_data:/data"
- "dkim:/dkim"
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_incl.yml.j2' %}
resolver:
condition: service_started
front:

View File

@ -9,7 +9,7 @@
{% include 'roles/docker-container/templates/healthcheck/wget.yml.j2' %}
ports:
- "127.0.0.1:{{ports.localhost.http[application_id]}}:{{ container_port }}"
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
volumes:
- data:/mastodon/public/system
{% include 'roles/docker-container/templates/networks.yml.j2' %}
@ -23,14 +23,14 @@
{% include 'roles/docker-container/templates/healthcheck/wget.yml.j2' %}
ports:
- "127.0.0.1:{{ports.localhost.websocket[application_id]}}:{{ container_port }}"
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
sidekiq:
image: "{{ applications[application_id].images.mastodon }}"
{% include 'roles/docker-container/templates/base.yml.j2' %}
command: bundle exec sidekiq
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
volumes:
- data:/mastodon/public/system
healthcheck:

View File

@ -7,7 +7,7 @@
- "127.0.0.1:{{ports.localhost.http[application_id]}}:{{ container_port }}"
volumes:
- data:/var/www/html
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/healthcheck/tcp.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}

View File

@ -26,7 +26,7 @@
{% endfor %}
{% else %}
{% endif %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
element:
{% set container_port = 80 %}

View File

@ -10,7 +10,7 @@
ports:
- "127.0.0.1:{{ports.localhost.http[application_id]}}:80"
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
data:

View File

@ -8,7 +8,7 @@
- "127.0.0.1:{{ ports.localhost.http[application_id] }}:{{ container_port }}"
{% include 'roles/docker-container/templates/healthcheck/curl.yml.j2' %}
{% include 'roles/docker-container/templates/base.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}

View File

@ -14,7 +14,7 @@
- 'code:{{ bitnami_code_link }}'
- 'data:{{ bitnami_data_dir }}'
{% include 'roles/docker-container/templates/healthcheck/tcp.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}

View File

@ -8,7 +8,7 @@
restart: {{docker_restart_policy}}
volumes:
- data:/var/www/html
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
server:

View File

@ -12,7 +12,7 @@
timeout: 10s
retries: 3
{% include 'roles/docker-container/templates/base.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
ipv4_address: 192.168.102.69
@ -70,7 +70,7 @@
interval: 1m
timeout: 10s
retries: 3
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
ipv4_address: 192.168.102.70

View File

@ -35,7 +35,7 @@ x-op-app: &app
command: "./docker/prod/web"
container_name: openproject-web
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_incl.yml.j2' %}
cache:
condition: service_started
seeder:
@ -53,7 +53,7 @@ x-op-app: &app
command: "./docker/prod/worker"
container_name: openproject-worker
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_incl.yml.j2' %}
cache:
condition: service_started
seeder:
@ -69,7 +69,7 @@ x-op-app: &app
command: "./docker/prod/cron"
container_name: openproject-cron
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_incl.yml.j2' %}
cache:
condition: service_started
seeder:

View File

@ -12,10 +12,8 @@
- assets:/app/client/dist
- data:/data
- config:/config
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
healthcheck:
# This just tests if the service is running on port 9000. It doesn't check if there is an 200 or e.g. an 404 response
{% include 'roles/docker-container/templates/healthcheck/tcp.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
assets:

View File

@ -7,7 +7,7 @@
{% include 'roles/docker-container/templates/base.yml.j2' %}
ports:
- "127.0.0.1:{{ports.localhost.http[application_id]}}:80"
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/healthcheck/wget.yml.j2' %}
volumes:

View File

@ -7,7 +7,7 @@
{% include 'roles/docker-container/templates/base.yml.j2' %}
ports:
- "127.0.0.1:{{ports.localhost.http[application_id]}}:{{ container_port }}"
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/healthcheck/tcp.yml.j2' %}

View File

@ -8,7 +8,7 @@
- "./env:/var/www/.env"
ports:
- "{{ports.localhost.http[application_id]}}:80"
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
worker:
image: "{{ applications[application_id].images.pixelfed }}"
@ -22,7 +22,7 @@
interval: 60s
timeout: 5s
retries: 1
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_incl.yml.j2' %}
application:
condition: service_started
{% include 'roles/docker-container/templates/networks.yml.j2' %}

View File

@ -107,7 +107,7 @@ class LookupModule(LookupBase):
"title": title,
"text": description,
"url": url,
"link_text": "Discover {} Now!".format(title),
"link_text": "Explore {}".format(title),
"iframe": iframe,
"tags": tags,
}

View File

@ -1,89 +1,13 @@
{# The Linebreak here are intentional due to tab bugs #}
---
accounts:
name: Online Presence
description: Discover {{ 'our' if service_provider.type == 'legal' else 'my' }} online presence.
icon:
class: fa-solid fa-users
children:
- name: Follow Us
description: Follow us to stay up to recieve the newest CyMaIS updates
icon:
class: fas fa-newspaper
{% if ["mastodon", "bluesky"] | any_in(group_names) %}
children:
- name: Microblogs
description: Stay updated with {{ 'our' if service_provider.type == 'legal' else 'my' }} microblogs.
icon:
class: fa-solid fa-pen-nib
children:
{% if service_provider.contact.mastodon is defined and service_provider.contact.mastodon != "" %}
- name: Mastodon
description: Follow {{ 'our' if service_provider.type == 'legal' else 'my' }} updates on Mastodon.
icon:
class: fa-brands fa-mastodon
url: "{{ web_protocol }}://{{ service_provider.contact.mastodon.split('@')[2] }}/@{{ service_provider.contact.mastodon.split('@')[1] }}"
identifier: "{{service_provider.contact.mastodon}}"
iframe: {{ applications | is_feature_enabled('portfolio_iframe','mastodon') }}
{% endif %}
{% if service_provider.contact.bluesky is defined and service_provider.contact.bluesky != "" %}
- name: Bluesky
description: Follow {{ 'our' if service_provider.type == 'legal' else 'my' }} on Bluesky.
icon:
class: fa-brands fa-bluesky
alternatives:
- link: accounts.followus.microblogs.mastodon
identifier: "{{service_provider.contact.bluesky}}"
{% endif %}
{% endif %}
{% if service_provider.contact.pixelfed is defined and service_provider.contact.pixelfed != "" %}
- name: Pictures
description: Explore {{ 'our' if service_provider.type == 'legal' else 'my' }} photo gallery on Pixelfed.
icon:
class: fa-solid fa-camera
identifier: "{{service_provider.contact.pixelfed}}"
url: "{{ web_protocol }}://{{ service_provider.contact.pixelfed.split('@')[2] }}/@{{ service_provider.contact.pixelfed.split('@')[1] }}"
iframe: {{ applications | is_feature_enabled('portfolio_iframe','pixelfed') }}
{% endif %}
{% if service_provider.contact.peertube is defined and service_provider.contact.peertube != "" %}
- name: Videos
description: Discover {{ 'our' if service_provider.type == 'legal' else 'my' }} videos on Peertube.
icon:
class: fa-solid fa-video
identifier: "{{service_provider.contact.peertube}}"
url: "{{ web_protocol }}://{{ service_provider.contact.peertube.split('@')[2] }}/@{{ service_provider.contact.peertube.split('@')[1] }}"
iframe: {{ applications | is_feature_enabled('portfolio_iframe','peertube') }}
{% endif %}
{% if service_provider.contact.wordpress is defined and service_provider.contact.wordpress != "" %}
- name: Blog
description: Read {{ 'our' if service_provider.type == 'legal' else 'my' }} articles and stories.
icon:
class: fa-solid fa-blog
identifier: "{{service_provider.contact.wordpress}}"
url: "{{ web_protocol }}://{{ service_provider.contact.wordpress.split('@')[2] }}/@{{ service_provider.contact.wordpress.split('@')[1] }}"
iframe: {{ applications | is_feature_enabled('portfolio_iframe','wordpress') }}
{% endif %}
{% if service_provider.legal.source_code is defined and service_provider.legal.source_code != "" %}
- name: Source Code
description: Explore {{ 'our' if service_provider.type == 'legal' else 'my' }} code.
icon:
class: fa-solid fa-code
url: "{{service_provider.legal.source_code}}"
{% endif %}
{% if service_provider.contact.friendica is defined and service_provider.contact.friendica != "" %}
- name: Social Network
description: Visit {{ 'our' if service_provider.type == 'legal' else 'my' }} friendica profile
icon:
class: fas fa-network-wired
identifier: "{{service_provider.contact.friendica}}"
url: "{{ web_protocol }}://{{ service_provider.contact.friendica.split('@')[2] }}/@{{ service_provider.contact.friendica.split('@')[1] }}"
iframe: {{ applications | is_feature_enabled('portfolio_iframe','friendica') }}
{% endif %}
- link: navigation.header.contact
cards:
{{ portfolio_cards | to_nice_yaml(indent=2) }}
{% include 'menu/applications.yml.j2' %}
{% include 'menu/followus.yml.j2' %}
{% include 'menu/contact.yml.j2' %}
{% include 'menu/support.yml.j2' %}
platform:
titel: {{service_provider.platform.titel}}
subtitel: {{service_provider.platform.subtitel}}
@ -100,55 +24,7 @@ company:
{{ service_provider.company.address | to_nice_yaml(indent=4) | indent(4, true) }}
imprint_url: {{service_provider.legal.imprint}}
navigation:
header:
children:
- name: Contact
description: Get in touch with {{ 'us' if service_provider.type == 'legal' else 'me' }}
icon:
class: fa-solid fa-envelope
children:
{% if service_provider.contact.email is defined %}
{% include 'menu/header.yml.j2' %}
- name: Email
description: Send {{ 'us' if service_provider.type == 'legal' else 'me' }} an email
icon:
class: fa-solid fa-envelope
url: mailto:{{service_provider.contact.email}}
identifier: {{service_provider.contact.email}}
{% endif %}
{% if service_provider.contact.phone is defined %}
- name: Mobile
description: Call {{ 'us' if service_provider.type == 'legal' else 'me' }}
icon:
class: fa-solid fa-phone
url: "tel:{{service_provider.contact.phone}}"
identifier: "{{service_provider.contact.phone}}"
target: _top
{% endif %}
{% if service_provider.contact.matrix is defined %}
- name: Matrix
description: Chat with {{ 'us' if service_provider.type == 'legal' else 'me' }} on Matrix
icon:
class: fa-solid fa-cubes
identifier: "{{service_provider.contact.matrix}}"
{% endif %}
- name: Toggle Fullscreen
description: Enter or exit fullscreen mode
icon:
class: fa-solid fa-expand-arrows-alt
onclick: "toggleFullscreen()"
- name: Open in new tab
description: Open the currently embedded iframe URL in a fresh browser tab
icon:
class: fa-solid fa-up-right-from-square
onclick: openIframeInNewTab()
{% include 'footer_menu.yaml.j2' %}
{% include 'menu/footer.yml.j2' %}

View File

@ -1,15 +1,11 @@
footer:
children:
- link: accounts
applications:
{% if (portfolio_menu_data.categorized is mapping and portfolio_menu_data.categorized | length > 0)
or (portfolio_menu_data.uncategorized is sequence and portfolio_menu_data.uncategorized | length > 0) %}
- name: Solution Hub
description: Curated collection of self hosted tools
- name: Applications
description: Browse, configure and launch all available applications
icon:
class: fa-solid fa-network-wired
class: fa fa-th-large
children:
{# Render all categories #}
@ -79,64 +75,3 @@
{% endif %}
{% endif %}
- name: Support Us
description: "Discover all the ways you can support our work."
icon:
class: fa-solid fa-hands-helping
children:
- name: Buy me a Coffee
description: "Support our work with a coffee every cup helps!"
icon:
class: fa-solid fa-mug-hot
url: https://s.veen.world/buymeacoffee
- name: Patreon
description: "Become a member and support me monthly with exclusive content."
icon:
class: fa-brands fa-patreon
url: https://s.veen.world/patreon
- name: PayPal
description: "Donate to our open source projects with a one-time or monthly PayPal contribution."
icon:
class: fa-brands fa-paypal
url: https://s.veen.world/paypaldonate
- name: GitHub Sponsors
description: "Directly support our projects through GitHub Sponsors."
icon:
class: fa-brands fa-github
url: https://s.veen.world/githubsponsors
{% if "sphinx" in group_names %}
- name: Documentation
description: Access our comprehensive documentation and support resources to help you get the most out of the software.
icon:
class: fas fa-book
url: https://{{domains | get_domain('sphinx')}}
iframe: {{ applications | is_feature_enabled('portfolio_iframe','sphinx') }}
{% endif %}
{% if "presentation" in group_names %}
- name: Slides
description: Checkout the presentation
icon:
class: "fas fa-chalkboard-teacher"
url: https://{{domains | get_domain('presentation')}}
iframe: {{ applications | is_feature_enabled('portfolio_iframe','presentation') }}
{% endif %}
- name: Solutions
description: "Software and IT Infrastructure Solutions by Kevin Veen-Birkenbach"
icon:
class: fa-solid fa-rocket
url: "https://cybermaster.space/"
iframe: false
- name: Imprint
description: Check out the imprint information
icon:
class: fa-solid fa-scale-balanced
url: "{{service_provider.legal.imprint}}"
iframe: true

View File

@ -0,0 +1,37 @@
contact:
name: Contact
description: Get in touch with {{ 'us' if service_provider.type == 'legal' else 'me' }}
icon:
class: fa-solid fa-envelope
children:
{% if service_provider.contact.email is defined %}
- name: Email
description: Send {{ 'us' if service_provider.type == 'legal' else 'me' }} an email
icon:
class: fa-solid fa-envelope
url: mailto:{{service_provider.contact.email}}
identifier: {{service_provider.contact.email}}
{% endif %}
{% if service_provider.contact.phone is defined %}
- name: Mobile
description: Call {{ 'us' if service_provider.type == 'legal' else 'me' }}
icon:
class: fa-solid fa-phone
url: "tel:{{service_provider.contact.phone}}"
identifier: "{{service_provider.contact.phone}}"
target: _top
{% endif %}
{% if service_provider.contact.matrix is defined %}
- name: Matrix
description: Chat with {{ 'us' if service_provider.type == 'legal' else 'me' }} on Matrix
icon:
class: fa-solid fa-cubes
identifier: "{{service_provider.contact.matrix}}"
{% endif %}

View File

@ -0,0 +1,62 @@
followus:
name: Follow Us
description: Follow us to stay up to recieve the newest CyMaIS updates
icon:
class: fas fa-newspaper
{% if ["mastodon", "bluesky"] | any_in(group_names) %}
children:
{% if service_provider.contact.mastodon is defined and service_provider.contact.mastodon != "" %}
- name: Mastodon
description: Follow {{ 'our' if service_provider.type == 'legal' else 'my' }} updates on Mastodon.
icon:
class: fa-brands fa-mastodon
url: "{{ web_protocol }}://{{ service_provider.contact.mastodon.split('@')[2] }}/@{{ service_provider.contact.mastodon.split('@')[1] }}"
identifier: "{{service_provider.contact.mastodon}}"
iframe: {{ applications | is_feature_enabled('portfolio_iframe','mastodon') }}
{% endif %}
{% if service_provider.contact.bluesky is defined and service_provider.contact.bluesky != "" %}
- name: Bluesky
description: Follow {{ 'our' if service_provider.type == 'legal' else 'my' }} on Bluesky.
icon:
class: fa-brands fa-bluesky
alternatives:
- link: followus.microblogs.mastodon
identifier: "{{service_provider.contact.bluesky}}"
{% endif %}
{% endif %}
{% if service_provider.contact.pixelfed is defined and service_provider.contact.pixelfed != "" %}
- name: Pixelfed
description: Explore {{ 'our' if service_provider.type == 'legal' else 'my' }} photo gallery on Pixelfed.
icon:
class: fa-solid fa-camera
identifier: "{{service_provider.contact.pixelfed}}"
url: "{{ web_protocol }}://{{ service_provider.contact.pixelfed.split('@')[2] }}/@{{ service_provider.contact.pixelfed.split('@')[1] }}"
iframe: {{ applications | is_feature_enabled('portfolio_iframe','pixelfed') }}
{% endif %}
{% if service_provider.contact.peertube is defined and service_provider.contact.peertube != "" %}
- name: Peertube
description: Discover {{ 'our' if service_provider.type == 'legal' else 'my' }} videos on Peertube.
icon:
class: fa-solid fa-video
identifier: "{{service_provider.contact.peertube}}"
url: "{{ web_protocol }}://{{ service_provider.contact.peertube.split('@')[2] }}/@{{ service_provider.contact.peertube.split('@')[1] }}"
iframe: {{ applications | is_feature_enabled('portfolio_iframe','peertube') }}
{% endif %}
{% if service_provider.contact.wordpress is defined and service_provider.contact.wordpress != "" %}
- name: Wordpress
description: Read {{ 'our' if service_provider.type == 'legal' else 'my' }} articles and stories.
icon:
class: fa-solid fa-blog
identifier: "{{service_provider.contact.wordpress}}"
url: "{{ web_protocol }}://{{ service_provider.contact.wordpress.split('@')[2] }}/@{{ service_provider.contact.wordpress.split('@')[1] }}"
iframe: {{ applications | is_feature_enabled('portfolio_iframe','wordpress') }}
{% endif %}
{% if service_provider.contact.friendica is defined and service_provider.contact.friendica != "" %}
- name: Friendica
description: Visit {{ 'our' if service_provider.type == 'legal' else 'my' }} friendica profile
icon:
class: fas fa-network-wired
identifier: "{{service_provider.contact.friendica}}"
url: "{{ web_protocol }}://{{ service_provider.contact.friendica.split('@')[2] }}/@{{ service_provider.contact.friendica.split('@')[1] }}"
iframe: {{ applications | is_feature_enabled('portfolio_iframe','friendica') }}
{% endif %}

View File

@ -0,0 +1,48 @@
footer:
children:
# - link: support
{% if "sphinx" in group_names %}
- name: Documentation
description: Access our comprehensive documentation and support resources to help you get the most out of the software.
icon:
class: fas fa-book
url: https://{{domains | get_domain('sphinx')}}
iframe: {{ applications | is_feature_enabled('portfolio_iframe','sphinx') }}
{% endif %}
{% if "presentation" in group_names %}
- name: Slides
description: Checkout the presentation
icon:
class: "fas fa-chalkboard-teacher"
url: https://{{domains | get_domain('presentation')}}
iframe: {{ applications | is_feature_enabled('portfolio_iframe','presentation') }}
{% endif %}
- name: Solutions
description: "Software and IT Infrastructure Solutions by Kevin Veen-Birkenbach"
icon:
class: fa-solid fa-rocket
url: "https://cybermaster.space/"
iframe: false
{% if service_provider.legal.source_code is defined and service_provider.legal.source_code != "" %}
- name: Source Code
description: Explore {{ 'our' if service_provider.type == 'legal' else 'my' }} code.
icon:
class: fa-solid fa-code
url: "{{service_provider.legal.source_code}}"
{% endif %}
- link: followus
- link: contact
- name: Imprint
description: Check out the imprint information
icon:
class: fa-solid fa-scale-balanced
url: "{{service_provider.legal.imprint}}"
iframe: true

View File

@ -0,0 +1,14 @@
header:
children:
- link: applications
- name: Toggle
description: Enter or exit fullscreen mode
icon:
class: fa-solid fa-expand-arrows-alt
onclick: "toggleFullscreen()"
- name: Tab
description: Open the currently embedded iframe URL in a fresh browser tab
icon:
class: fa-solid fa-up-right-from-square
onclick: openIframeInNewTab()

View File

@ -0,0 +1,26 @@
support:
name: Support Us
description: "Discover all the ways you can support our work."
icon:
class: fa-solid fa-hands-helping
children:
- name: Buy me a Coffee
description: "Support our work with a coffee every cup helps!"
icon:
class: fa-solid fa-mug-hot
url: https://s.veen.world/buymeacoffee
- name: Patreon
description: "Become a member and support me monthly with exclusive content."
icon:
class: fa-brands fa-patreon
url: https://s.veen.world/patreon
- name: PayPal
description: "Donate to our open source projects with a one-time or monthly PayPal contribution."
icon:
class: fa-brands fa-paypal
url: https://s.veen.world/paypaldonate
- name: GitHub Sponsors
description: "Directly support our projects through GitHub Sponsors."
icon:
class: fa-brands fa-github
url: https://s.veen.world/

View File

@ -8,7 +8,7 @@
- data:/var/lib/snipeit
ports:
- "127.0.0.1:{{ports.localhost.http[application_id]}}:{{ container_port }}"
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/healthcheck/tcp.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}

View File

@ -3,7 +3,7 @@ services:
image: taigaio/taiga-back:latest
environment:
CELERY_ENABLED: "False"
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
entrypoint: "python manage.py"
volumes:

View File

@ -17,7 +17,7 @@
{% include 'roles/docker-container/templates/networks.yml.j2' %}
taiga:
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_incl.yml.j2' %}
taiga-events-rabbitmq:
condition: service_started
taiga-async-rabbitmq:
@ -52,7 +52,7 @@
{% include 'roles/docker-container/templates/networks.yml.j2' %}
taiga:
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_incl.yml.j2' %}
taiga-events-rabbitmq:
condition: service_started
taiga-async-rabbitmq:

View File

@ -11,7 +11,7 @@
- data:{{ wordpress_docker_html_path }}
{% include 'roles/docker-container/templates/healthcheck/msmtp_curl.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-compose/templates/networks.yml.j2' %}

View File

@ -9,7 +9,7 @@
- "127.0.0.1:{{ports.localhost.http[application_id]}}:{{ container_port }}"
{% include 'roles/docker-container/templates/healthcheck/curl.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes-just-database.yml.j2' %}

View File

@ -1,7 +1,7 @@
{% raw %}
services:
{% include 'roles/docker-central-database/templates/services/main.yml.j2' %}
{% include 'roles/docker-compose/templates/base.yml.j2' %}
application:
image: "{{ applications[application_id].images[application_id] }}"
@ -10,7 +10,7 @@ services:
- "127.0.0.1:{{ ports.localhost.http[application_id] }}:{{ container_port }}"
{% include 'roles/docker-container/templates/healthcheck/curl.yml.j2' %}
{% include 'roles/docker-container/templates/base.yml.j2' %}
{% include 'roles/docker-container/templates/depends_on_dmbs.j2' %}
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}

View File

@ -21,8 +21,8 @@ csp:
whitelist: {} # URL's which should be whitelisted
flags: {} # Flags which should be set
domains:
canonical: # Urls under which the domain should be directly accessible
aliases: # Alias redirections to the first element of the canonical domains
canonical: {} # Urls under which the domain should be directly accessible
aliases: [] # Alias redirections to the first element of the canonical domains
rbac:
roles: {}

View File

@ -7,12 +7,11 @@ class TestJinjaIncludePaths(unittest.TestCase):
Verifies that in all .j2 files in the project (root + subfolders):
- Every {% include 'string/path' %} or {% include "string/path" %} refers to an existing file.
- Any include using a variable or concatenation is ignored.
- Includes are resolved relative to project root, template directory, or file's parent.
"""
PROJECT_ROOT = Path(__file__).resolve().parents[2]
# Fängt jede include-Direktive ein (den gesamten Ausdruck zwischen include und %})
INCLUDE_STMT_RE = re.compile(r"{%\s*include\s+(.+?)\s*%}")
# Erlaubt nur ein einzelnes String-Literal (Gänse- oder einfache Anführungszeichen)
LITERAL_PATH_RE = re.compile(r"^['\"]([^'\"]+)['\"]$")
LITERAL_PATH_RE = re.compile(r"^[\'\"]([^\'\"]+)[\'\"]$")
def test_all_jinja_includes_exist(self):
template_paths = list(self.PROJECT_ROOT.glob("**/*.j2"))
@ -28,17 +27,33 @@ class TestJinjaIncludePaths(unittest.TestCase):
expr = stmt.group(1).strip()
m = self.LITERAL_PATH_RE.match(expr)
if not m:
continue # Variable-based includes ignorieren
continue # ignore variable-based includes
include_path = m.group(1)
abs_target = self.PROJECT_ROOT / include_path
rel_target = tpl.parent / include_path
# check absolute project-relative path
abs_target = self.PROJECT_ROOT / include_path
# check path relative to the template file
rel_target = tpl.parent / include_path
if not (abs_target.exists() or rel_target.exists()):
# check path relative to role's templates directory
role_templates_root = None
for parent in tpl.parents:
if parent.name == 'templates':
role_templates_root = parent
break
role_target = None
if role_templates_root:
role_target = role_templates_root / include_path
if not (
abs_target.exists() or
rel_target.exists() or
(role_target and role_target.exists())
):
rel_tpl = tpl.relative_to(self.PROJECT_ROOT)
missing.append(
f"{rel_tpl}: included file '{include_path}' not found "
f"(neither in PROJECT_ROOT nor in {tpl.parent.relative_to(self.PROJECT_ROOT)})"
f"(checked in project root, {tpl.parent.relative_to(self.PROJECT_ROOT)} or templates folder)"
)
if missing: