Compare commits

...

8 Commits

Author SHA1 Message Date
ce3fe1cd51 Nextcloud: integrate Talk & Whiteboard; adjust ports & healthchecks
- Enable Spreed (Talk); signaling via /standalone-signaling/
- STUN/TURN: move STUN to 3480 (3479 occupied by BBB), keep TURN 5350 reserved
- docker-compose: expose internal WS ports; explicit TURN port mapping
- Healthchecks: add nc-based TCP checks (roles/docker-container/templates/healthcheck/nc.yml.j2)
- Nginx: location proxy to talk:8081
- Schema: add talk_* secrets (turn/signaling/internal)
- Plugins: configure spreed/whiteboard via vars/*; remove old task files
- Ports matrix (group_vars/all/09_ports.yml) updated/commented

Conversation: https://chatgpt.com/share/68b61a6a-e1dc-800f-b793-4aa600bc0166
2025-09-02 00:13:23 +02:00
7ca8b7c71d feat(nextcloud): integrate Talk & Whiteboard; refactor to NEXTCLOUD_* vars; full-stack setup
config(ports): add Nextcloud websocket port (4003); canonical domains (nextcloud/talk/whiteboard)

refactor: unify get_app_conf usage & Jinja spacing; migrate paths/handlers to new NEXTCLOUD_* vars

feat(plugins): split plugin routines; configure Whiteboard via occ (URL + JWT)

fix(oidc): use NEXTCLOUD_URL for logout; correct LDAP attribute mappings; add OIDC flavor switch

feat: Whiteboard container & reverse-proxy location; Talk STUN/WS ports; Redis URL for Whiteboard

chore: drop obsolete TODO; minor cleanups in oauth2-proxy, matrix, peertube, pgadmin, phpldapadmin, pixelfed, phpmyadmin

security(schema): Bluesky jwt_secret now base64_prefixed_32; add Nextcloud whiteboard_jwt_secret

db: normalize postgres image tag templating; central DB host checks spacing fixes

ops: add full-stack bootstrap (certs, proxy, volumes); internal nginx config reload handler update

refs: https://chatgpt.com/share/68b5f5b7-8d64-800f-b001-1241f818dc0e
2025-09-01 21:37:02 +02:00
110381e80c Refactored peertube role and implemented config volume 2025-09-01 18:19:50 +02:00
b02d88adc0 Refactored server roles for better readability 2025-09-01 18:08:35 +02:00
b7065837df MediaWiki: switch feature.css to false and add custom Vector 2022 override stylesheet
See: https://chatgpt.com/share/68b5b925-f418-800f-8f84-de744dd2d093
2025-09-01 17:18:12 +02:00
c98a2378c4 Added is defined condition 2025-09-01 17:05:30 +02:00
4ae3cee36c web-svc-logout: merge logout domains into CSP connect-src and refactor task flow
• Add tasks/01_core.yml to set applications[application_id].server.csp.whitelist['connect-src'] = LOGOUT_CONNECT_SRC_NEW.

• Switch tasks/main.yml to include 01_core.yml (run-once guard preserved).

• Update templates/env.j2 to emit LOGOUT_DOMAINS as a comma-separated list.

• Rework vars/main.yml: compute LOGOUT_DOMAINS, derive LOGOUT_ORIGINS with WEB_PROTOCOL, read connect-src via the get_app_conf filter, and merge/dedupe (unique).

Rationale: ensure CSP allows cross-domain logout requests for all configured services.

Conversation: https://chatgpt.com/share/68b5b07d-b208-800f-b6b2-f26934607c8a
2025-09-01 16:41:33 +02:00
b834f0c95c Implemented config image for pretix 2025-09-01 16:20:04 +02:00
142 changed files with 795 additions and 389 deletions

View File

@@ -80,7 +80,8 @@ ports:
svc-db-openldap: 636
stun:
web-app-bigbluebutton: 3478 # Not sure if it's right placed here or if it should be moved to localhost section
web-app-nextcloud: 3479
# Occupied by BBB: 3479
web-app-nextcloud: 3480
turn:
web-app-bigbluebutton: 5349 # Not sure if it's right placed here or if it should be moved to localhost section
web-app-nextcloud: 5350 # Not used yet

View File

@@ -111,16 +111,6 @@ roles:
description: "Developer-centric server utilities and admin toolkits."
icon: "fas fa-code"
invokable: false
srv:
title: "Server"
description: "General server roles for provisioning and managing server infrastructure—covering web servers, proxy servers, network services, and other backend components."
icon: "fas fa-server"
invokable: false
proxy:
title: "Proxy Server"
description: "Proxy-server roles for virtual-host orchestration and reverse-proxy setups."
icon: "fas fa-project-diagram"
invokable: false
web:
title: "Web Infrastructure"
description: "Roles for managing web infrastructure—covering static content services and deployable web applications."

View File

@@ -20,7 +20,7 @@ To offer a centralized, extensible system for managing containerized application
- **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-core` and other Infinito.Nexus service roles.
- **Integration Support:** Compatible with `sys-svc-proxy` and other Infinito.Nexus service roles.
## Administration Tips

View File

@@ -3,7 +3,7 @@
- "CMD"
- "curl"
- "-f"
{% if container_hostname %}
{% if container_hostname is defined %}
- "-H"
- "Host: {{ container_hostname }}"
{% endif %}

View File

@@ -0,0 +1,7 @@
healthcheck:
test: ["CMD-SHELL", "nc -z localhost {{ container_port }} || exit 1"]
interval: 30s
timeout: 3s
retries: 3
start_period: 10s
{{ "\n" }}

View File

@@ -1,4 +0,0 @@
- block:
- include_tasks: 01_core.yml
- include_tasks: utils/run_once.yml
when: run_once_srv_letsencrypt is not defined

View File

@@ -2,5 +2,5 @@ server {
listen {{ ports.public.ldaps['svc-db-openldap'] }}ssl;
proxy_pass 127.0.0.1:{{ ports.localhost.ldap['svc-db-openldap'] }};
{% include 'roles/srv-letsencrypt/templates/ssl_credentials.j2' %}
{% include 'roles/sys-svc-letsencrypt/templates/ssl_credentials.j2' %}
}

View File

@@ -3,7 +3,7 @@
name: '{{ item }}'
loop:
- sys-svc-certbot
- srv-core
- sys-svc-webserver
- sys-ctl-alm-compose
- name: install certbot

View File

@@ -41,9 +41,9 @@
when: inj_enabled.logout
- block:
- name: Include dependency 'srv-core'
- name: Include dependency 'sys-svc-webserver'
include_role:
name: srv-core
when: run_once_srv_core is not defined
name: sys-svc-webserver
when: run_once_sys_svc_webserver is not defined
- include_tasks: utils/run_once.yml
when: run_once_sys_front_inj_all is not defined

View File

@@ -1,7 +1,7 @@
- name: Include dependency 'srv-core'
- name: Include dependency 'sys-svc-webserver'
include_role:
name: srv-core
when: run_once_srv_core is not defined
name: sys-svc-webserver
when: run_once_sys_svc_webserver is not defined
- name: Generate color palette with colorscheme-generator
set_fact:

View File

@@ -1,8 +1,8 @@
- block:
- name: Include dependency 'srv-core'
- name: Include dependency 'sys-svc-webserver'
include_role:
name: srv-core
when: run_once_srv_core is not defined
name: sys-svc-webserver
when: run_once_sys_svc_webserver is not defined
- include_tasks: 01_deploy.yml
- include_tasks: utils/run_once.yml
when: run_once_sys_front_inj_desktop is not defined

View File

@@ -1,9 +1,9 @@
- block:
- name: Include dependency 'srv-core'
- name: Include dependency 'sys-svc-webserver'
include_role:
name: srv-core
when: run_once_srv_core is not defined
name: sys-svc-webserver
when: run_once_sys_svc_webserver is not defined
- include_tasks: utils/run_once.yml
when: run_once_sys_front_inj_javascript is not defined

View File

@@ -1,8 +1,8 @@
- name: Include dependency 'srv-core'
- name: Include dependency 'sys-svc-webserver'
include_role:
name: srv-core
name: sys-svc-webserver
when:
- run_once_srv_core is not defined
- run_once_sys_svc_webserver is not defined
- name: "deploy the logout.js"
include_tasks: "02_deploy.yml"

View File

@@ -1,8 +1,8 @@
- block:
- name: Include dependency 'srv-core'
- name: Include dependency 'sys-svc-webserver'
include_role:
name: srv-core
when: run_once_srv_core is not defined
name: sys-svc-webserver
when: run_once_sys_svc_webserver is not defined
- include_tasks: utils/run_once.yml
when: run_once_sys_front_inj_matomo is not defined

View File

@@ -10,7 +10,7 @@ A higher-level orchestration wrapper, *sys-stk-front-proxy* ties together severa
1. **`sys-front-inj-all`** applies global tweaks and includes.
2. **`sys-svc-certs`** obtains Lets Encrypt certificates.
3. **Domain template deployment** copies a Jinja2 vHost from *srv-proxy-core*.
3. **Domain template deployment** copies a Jinja2 vHost from *sys-svc-proxy*.
4. **`web-app-oauth2-proxy`** *(optional)* protects the site with OAuth2.
The result is a complete, reproducible domain rollout in a single playbook task.

View File

@@ -2,4 +2,4 @@
vhost_flavour: "basic" # valid: basic, ws_generic
# build the full template path from the flavour
vhost_template_src: "roles/srv-proxy-core/templates/vhost/{{ vhost_flavour }}.conf.j2"
vhost_template_src: "roles/sys-svc-proxy/templates/vhost/{{ vhost_flavour }}.conf.j2"

View File

@@ -1,8 +1,8 @@
- block:
- name: Include dependency 'srv-proxy-core'
- name: Include dependency 'sys-svc-proxy'
include_role:
name: srv-proxy-core
when: run_once_srv_proxy_core is not defined
name: sys-svc-proxy
when: run_once_sys_svc_proxy is not defined
- include_tasks: utils/run_once.yml
when: run_once_sys_stk_front_proxy is not defined
@@ -15,7 +15,7 @@
- name: "include role for {{ domain }} to receive certificates and do the modification routines"
include_role:
name: srv-composer
name: sys-util-csp-cert
- name: "Copy nginx config to {{ configuration_destination }}"
template:

View File

@@ -1 +1 @@
configuration_destination: "{{ NGINX.DIRECTORIES.HTTP.SERVERS }}{{ domain }}.conf"
configuration_destination: "{{ [ NGINX.DIRECTORIES.HTTP.SERVERS, domain ~ '.conf'] | path_join }}"

View File

@@ -7,7 +7,7 @@ The **sys-stk-front-pure** role extends a basic Nginx installation by wiring in
2. Pulls in Lets Encrypt ACME challenge handling.
3. Applies global cleanup of unused domain configs.
This role is built on top of your existing `srv-core` role, and it automates the end-to-end process of turning HTTP sites into secure HTTPS sites.
This role is built on top of your existing `sys-svc-webserver` role, and it automates the end-to-end process of turning HTTP sites into secure HTTPS sites.
---
@@ -15,9 +15,9 @@ This role is built on top of your existing `srv-core` role, and it automates the
When you apply **sys-stk-front-pure**, it will:
1. **Include** the `srv-core` role to install and configure Nginx.
1. **Include** the `sys-svc-webserver` role to install and configure Nginx.
2. **Clean up** any stale vHost files under `sys-svc-cln-domains`.
3. **Deploy** the Lets Encrypt challenge-and-redirect snippet from `srv-letsencrypt`.
3. **Deploy** the Lets Encrypt challenge-and-redirect snippet from `sys-svc-letsencrypt`.
4. **Reload** Nginx automatically when any template changes.
All tasks are idempotent—once your certificates are in place and your configuration is set, Ansible will skip unchanged steps on subsequent runs.
@@ -42,7 +42,7 @@ All tasks are idempotent—once your certificates are in place and your configur
## Requirements
- A working `srv-core` setup.
- A working `sys-svc-webserver` setup.
- DNS managed via Cloudflare (for CAA record tasks) or equivalent ACME DNS flow.
- Variables:
- `LETSENCRYPT_WEBROOT_PATH`

View File

@@ -3,8 +3,8 @@
include_role:
name: '{{ item }}'
loop:
- srv-core
- sys-svc-webserver
- sys-svc-cln-domains
- srv-letsencrypt
- sys-svc-letsencrypt
- include_tasks: utils/run_once.yml
when: run_once_sys_stk_front_pure is not defined

View File

@@ -3,7 +3,7 @@
include_role:
name: '{{ item }}'
loop:
- srv-core
- sys-svc-webserver
- name: Include task to remove deprecated nginx configs
include_tasks: remove_deprecated_nginx_configs.yml

View File

@@ -15,6 +15,6 @@
- name: Remove exact nginx config for {{ domain }}
ansible.builtin.file:
path: "{{ NGINX.DIRECTORIES.HTTP.SERVERS }}{{ domain }}.conf"
path: "{{ [ NGINX.DIRECTORIES.HTTP.SERVERS, domain ~ '.conf'] | path_join }}"
state: absent
notify: restart openresty

View File

@@ -1,5 +1,4 @@
---
- block:
- include_tasks: 01_core.yml
- include_tasks: utils/run_once.yml
when: run_once_srv_core is not defined
when: run_once_sys_svc_letsencrypt is not defined

View File

@@ -12,4 +12,4 @@ ssl_session_tickets on;
add_header Strict-Transport-Security max-age=15768000;
ssl_stapling on;
ssl_stapling_verify on;
{% include 'roles/srv-letsencrypt/templates/ssl_credentials.j2' %}
{% include 'roles/sys-svc-letsencrypt/templates/ssl_credentials.j2' %}

View File

@@ -4,6 +4,6 @@
name: '{{ item }}'
loop:
- sys-stk-front-pure
- srv-core
- sys-svc-webserver
- include_tasks: utils/run_once.yml
when: run_once_srv_proxy_core is not defined
when: run_once_sys_svc_proxy is not defined

View File

@@ -1,6 +1,6 @@
# Nginx Location Templates
This directory contains Jinja2 templates for different Nginx `location` blocks, each designed to proxy and optimize different types of web traffic. These templates are used by the `srv-proxy-core` role to modularize and standardize reverse proxy configuration across a wide variety of applications.
This directory contains Jinja2 templates for different Nginx `location` blocks, each designed to proxy and optimize different types of web traffic. These templates are used by the `sys-svc-proxy` role to modularize and standardize reverse proxy configuration across a wide variety of applications.
---

View File

@@ -15,7 +15,7 @@ location {{location}}
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port {{ WEB_PORT }};
{% include 'roles/srv-proxy-core/templates/headers/content_security_policy.conf.j2' %}
{% include 'roles/sys-svc-proxy/templates/headers/content_security_policy.conf.j2' %}
# WebSocket specific header
proxy_http_version 1.1;

View File

@@ -1,7 +1,7 @@
server
{
server_name {{ domain }};
{% include 'roles/srv-proxy-core/templates/headers/buffers.conf.j2' %}
{% include 'roles/sys-svc-proxy/templates/headers/buffers.conf.j2' %}
{% if applications | get_app_conf(application_id, 'features.oauth2', False) %}
{% include 'roles/web-app-oauth2-proxy/templates/endpoint.conf.j2'%}
@@ -14,7 +14,7 @@ server
{{ proxy_extra_configuration }}
{% endif %}
{% include 'roles/srv-letsencrypt/templates/ssl_header.j2' %}
{% include 'roles/sys-svc-letsencrypt/templates/ssl_header.j2' %}
{% if applications | get_app_conf(application_id, 'features.oauth2', False) %}
{% set acl = applications | get_app_conf(application_id, 'oauth2_proxy.acl', False, {}) %}
@@ -23,38 +23,38 @@ server
{# 1. Expose everything by default, then protect blacklisted paths #}
{% set oauth2_proxy_enabled = false %}
{% set location = "/" %}
{% include 'roles/srv-proxy-core/templates/location/html.conf.j2' %}
{% include 'roles/sys-svc-proxy/templates/location/html.conf.j2' %}
{% for loc in acl.blacklist %}
{% set oauth2_proxy_enabled = true %}
{% set location = loc %}
{% include 'roles/srv-proxy-core/templates/location/html.conf.j2' %}
{% include 'roles/sys-svc-proxy/templates/location/html.conf.j2' %}
{% endfor %}
{% elif acl.whitelist is defined %}
{# 2. Protect everything by default, then expose whitelisted paths #}
{% set oauth2_proxy_enabled = true %}
{% set location = "/" %}
{% include 'roles/srv-proxy-core/templates/location/html.conf.j2' %}
{% include 'roles/sys-svc-proxy/templates/location/html.conf.j2' %}
{% for loc in acl.whitelist %}
{% set oauth2_proxy_enabled = false %}
{% set location = loc %}
{% include 'roles/srv-proxy-core/templates/location/html.conf.j2' %}
{% include 'roles/sys-svc-proxy/templates/location/html.conf.j2' %}
{% endfor %}
{% else %}
{# 3. OAuth2 enabled but no (or empty) ACL — protect all #}
{% set oauth2_proxy_enabled = true %}
{% set location = "/" %}
{% include 'roles/srv-proxy-core/templates/location/html.conf.j2' %}
{% include 'roles/sys-svc-proxy/templates/location/html.conf.j2' %}
{% endif %}
{% else %}
{# 4. OAuth2 completely disabled — expose all #}
{% set oauth2_proxy_enabled = false %}
{% set location = "/" %}
{% include 'roles/srv-proxy-core/templates/location/html.conf.j2' %}
{% include 'roles/sys-svc-proxy/templates/location/html.conf.j2' %}
{% endif %}
}

View File

@@ -6,7 +6,7 @@ map $http_upgrade $connection_upgrade {
server {
server_name {{ domain }};
{% include 'roles/srv-letsencrypt/templates/ssl_header.j2' %}
{% include 'roles/sys-svc-letsencrypt/templates/ssl_header.j2' %}
{% include 'roles/sys-front-inj-all/templates/server.conf.j2' %}
@@ -25,10 +25,10 @@ server {
add_header Strict-Transport-Security "max-age=31536000";
{% include 'roles/srv-proxy-core/templates/location/html.conf.j2' %}
{% include 'roles/sys-svc-proxy/templates/location/html.conf.j2' %}
{% if location_ws is defined %}
{% include 'roles/srv-proxy-core/templates/location/ws.conf.j2' %}
{% include 'roles/sys-svc-proxy/templates/location/ws.conf.j2' %}
{% endif %}
error_page 500 501 502 503 504 /500.html;

View File

@@ -18,4 +18,4 @@ galaxy_info:
- performance
repository: "https://s.infinito.nexus/code"
issue_tracker_url: "https://s.infinito.nexus/issues"
documentation: "https://s.infinito.nexus/code/roles/srv-core"
documentation: "https://s.infinito.nexus/code/roles/sys-svc-webserver"

View File

@@ -49,3 +49,5 @@
- sys-ctl-hlth-csp
vars:
flush_handlers: false
- include_tasks: utils/run_once.yml

View File

@@ -0,0 +1,4 @@
---
- block:
- include_tasks: 01_core.yml
when: run_once_sys_svc_webserver is not defined

View File

@@ -1,4 +1,4 @@
# Role: srv-composer
# Role: sys-util-csp-cert
This Ansible role composes and orchestrates all necessary HTTPS-layer tasks and HTML-content injections for your webserver domains. It integrates two key sub-roles into a unified workflow:

View File

@@ -27,4 +27,4 @@ galaxy_info:
- orchestration
repository: "https://s.infinito.nexus/code"
issue_tracker_url: "https://s.infinito.nexus/issues"
documentation: "https://s.infinito.nexus/code/roles/srv-composer"
documentation: "https://s.infinito.nexus/code/roles/sys-util-csp-cert"

View File

@@ -1,4 +1,4 @@
# run_once_srv_composer: deactivated
# run_once_sys_util_csp_cert: deactivated
- name: "include role sys-front-inj-all for '{{ domain }}'"
include_role:

View File

@@ -35,7 +35,7 @@ By default, BigBlueButton is deployed with best-practice hardening, modular secr
## System Requirements
- Arch Linux with Docker, Compose, and Nginx roles pre-installed
- DNS and reverse proxy configuration using `srv-proxy-core`
- DNS and reverse proxy configuration using `sys-svc-proxy`
- Functional email system for Greenlight SMTP
## Important Resources

View File

@@ -3,7 +3,7 @@
set_fact:
proxy_extra_configuration: >-
{{ lookup('ansible.builtin.template',
playbook_dir ~ '/roles/srv-proxy-core/templates/location/html.conf.j2') | trim }}
playbook_dir ~ '/roles/sys-svc-proxy/templates/location/html.conf.j2') | trim }}
vars:
location: '^~ /html5client'
oauth2_proxy_enabled: false

View File

@@ -1,8 +1,8 @@
credentials:
jwt_secret:
description: "Secret used for JWT signing (base64, 64 bytes)"
algorithm: "plain"
validation: "^[A-Za-z0-9+/=]{86,}$" # 64 bytes base64 = ~86 characters without newline
description: "Secret used for JWT signing"
algorithm: "base64_prefixed_32"
validation: "^base64:[A-Za-z0-9+/]{43}=$"
plc_rotation_key_k256_private_key_hex:
description: "PLC rotation key in hex format (32 bytes)"
algorithm: "sha256"

View File

@@ -18,7 +18,7 @@
- name: "include role for {{ application_id }} to receive certs & do modification routines for {{ MATRIX_SYNAPSE_DOMAIN }}"
include_role:
name: srv-composer
name: sys-util-csp-cert
vars:
domain: "{{ MATRIX_SYNAPSE_DOMAIN }}"
http_port: "{{ MATRIX_SYNAPSE_PORT }}"

View File

@@ -1,6 +1,6 @@
server {
server_name {{ domain }};
{% include 'roles/srv-letsencrypt/templates/ssl_header.j2' %}
{% include 'roles/sys-svc-letsencrypt/templates/ssl_header.j2' %}
# For the federation port
listen {{ MATRIX_FEDERATION_PORT }} ssl default_server;
@@ -8,7 +8,7 @@ server {
{% include 'roles/sys-front-inj-all/templates/server.conf.j2'%}
{% include 'roles/srv-proxy-core/templates/location/html.conf.j2' %}
{% include 'roles/sys-svc-proxy/templates/location/html.conf.j2' %}
{% include 'roles/srv-proxy-core/templates/location/upload.conf.j2' %}
{% include 'roles/sys-svc-proxy/templates/location/upload.conf.j2' %}
}

View File

@@ -18,6 +18,6 @@ docker:
features:
logout: true
central_database: true
css: true
css: false
desktop: true
oidc: true

View File

@@ -0,0 +1,256 @@
/* MediaWiki (Vector 2022 + OOUI) color remap via Infinito.Nexus palette
- Keep changes scoped and variable-driven
- Prefer variables over hard values
- Avoid !important unless an inline style or strong OOUI rule requires it
*/
/* ---------- App-scoped variables (derived from global color scale) ---------- */
:root {
/* Brand & accents */
--mw-primary: var(--color-01-60);
--mw-primary-contrast: var(--color-01-99);
--mw-secondary: var(--color-01-85);
--mw-accent: var(--color-01-50);
/* Surfaces */
--mw-surface: var(--color-01-92);
--mw-surface-variant: var(--color-01-90);
--mw-surface-muted: var(--color-01-95);
/* Text */
--mw-text: var(--color-01-20);
--mw-text-muted: var(--color-01-45);
--mw-heading: var(--color-01-15);
--mw-link: var(--color-01-55);
--mw-link-hover: var(--color-01-60);
--mw-link-visited: var(--color-01-45);
/* Lines / borders / focus */
--mw-border: var(--color-01-85);
--mw-divider: var(--color-01-87);
--mw-focus: rgba(var(--color-01-rgb-65), .35);
/* Status */
--mw-success: var(--bs-success);
--mw-warning: var(--bs-warning);
--mw-danger: var(--bs-danger);
}
/* ---------- Global shell ---------- */
body.skin-vector,
.skin-vector .mw-page-container {
background-color: var(--mw-surface);
background-image: linear-gradient({{ range(0, 361) | random }}deg,
var(--mw-surface),
var(--mw-surface-variant),
var(--mw-surface-muted),
var(--mw-surface)
);
color: var(--mw-text);
}
/* ---------- Header / site chrome ---------- */
.skin-vector .vector-header,
.skin-vector .vector-header-container,
.skin-vector .mw-header {
background-color: var(--color-01-80);
background-image: linear-gradient({{ range(0, 361) | random }}deg,
var(--color-01-75), var(--color-01-80), var(--color-01-81), var(--color-01-85)
);
color: var(--color-01-17);
border-bottom: 1px solid var(--mw-divider);
}
/* Logo & title area often inherits link styles—keep readable */
.skin-vector .mw-logo a,
.skin-vector .mw-logo svg,
.skin-vector .vector-header a {
color: var(--mw-heading);
fill: currentColor;
}
/* ---------- Sidebar / menus ---------- */
.skin-vector .vector-sidebar,
.skin-vector .mw-portlet,
.skin-vector .vector-menu-content {
background-color: var(--mw-surface-variant);
border-color: var(--mw-border);
}
.skin-vector .vector-sidebar .vector-menu-heading,
.skin-vector .vector-menu-heading {
color: var(--mw-heading);
border-bottom: 1px solid var(--mw-divider);
}
/* ---------- Table of Contents ---------- */
.skin-vector .vector-toc,
.skin-vector .vector-toc .vector-toc-contents {
background-color: var(--mw-surface-muted);
border: 1px solid var(--mw-border);
}
.skin-vector .vector-toc .vector-toc-text {
color: var(--mw-text);
}
/* ---------- Content area ---------- */
.skin-vector .mw-content-container,
.skin-vector .mw-content-ltr,
.skin-vector .mw-body,
.skin-vector .mw-parser-output {
color: var(--mw-text);
}
.skin-vector .mw-parser-output h1,
.skin-vector .mw-parser-output h2,
.skin-vector .mw-parser-output h3,
.skin-vector .mw-parser-output h4,
.skin-vector .mw-parser-output h5,
.skin-vector .mw-parser-output h6 {
color: var(--mw-heading);
}
/* Links */
.skin-vector .mw-parser-output a { color: var(--mw-link); }
.skin-vector .mw-parser-output a:visited { color: var(--mw-link-visited); }
.skin-vector .mw-parser-output a:hover,
.skin-vector .mw-parser-output a:focus { color: var(--mw-link-hover); }
/* ---------- Search ---------- */
.skin-vector .vector-search-box input,
.skin-vector .vector-search-box .vector-search-input {
background-color: var(--mw-surface);
border: 1px solid var(--mw-border);
color: var(--mw-text);
}
.skin-vector .vector-search-box input:focus {
outline: 0;
box-shadow: 0 0 0 3px var(--mw-focus);
border-color: var(--mw-link);
}
/* ---------- Buttons (MediaWiki UI + OOUI) ---------- */
/* MediaWiki UI */
.mw-ui-button,
.mw-ui-button:visited {
background-color: var(--mw-surface-muted);
color: var(--mw-text);
border: 1px solid var(--mw-border);
}
.mw-ui-button:hover,
.mw-ui-button:focus {
background-color: var(--mw-surface-variant);
color: var(--mw-text);
border-color: var(--mw-link);
box-shadow: 0 0 0 3px var(--mw-focus);
}
.mw-ui-progressive,
.mw-ui-primary {
background-color: var(--mw-primary);
color: var(--mw-primary-contrast);
border-color: var(--mw-primary);
}
.mw-ui-progressive:hover,
.mw-ui-primary:hover {
filter: brightness(0.95);
}
/* OOUI (covers most modern UI widgets) */
.oo-ui-buttonElement-button {
background-color: var(--mw-surface-muted);
color: var(--mw-text);
border: 1px solid var(--mw-border);
}
.oo-ui-buttonElement-button:focus-visible {
outline: 0;
box-shadow: 0 0 0 3px var(--mw-focus);
border-color: var(--mw-link);
}
.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button,
.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button {
background-color: var(--mw-primary);
color: var(--mw-primary-contrast);
border-color: var(--mw-primary);
}
/* Inputs */
.mw-ui-input,
.oo-ui-inputWidget-input {
background-color: var(--mw-surface);
color: var(--mw-text);
border: 1px solid var(--mw-border);
}
.oo-ui-inputWidget-input:focus,
.mw-ui-input:focus {
outline: 0;
box-shadow: 0 0 0 3px var(--mw-focus);
border-color: var(--mw-link);
}
/* ---------- Tables / infoboxes ---------- */
table.wikitable,
.mw-parser-output table.infobox,
.mw-parser-output table.prettytable {
background-color: var(--color-01-99);
border: 1px solid var(--mw-border);
color: var(--mw-text);
}
table.wikitable > * > tr > th,
table.wikitable > * > tr > td {
border: 1px solid var(--mw-border);
}
table.wikitable > * > tr > th {
background-color: var(--color-01-80);
background-image: linear-gradient({{ range(0, 361) | random }}deg,
var(--color-01-75), var(--color-01-80), var(--color-01-81), var(--color-01-85)
);
color: var(--mw-heading);
}
/* ---------- Notices / boxes ---------- */
.mw-notification,
.mw-message-box,
.mw-message-box-notice {
background-color: var(--mw-surface-muted);
border-color: var(--mw-border);
color: var(--mw-text);
}
.mw-message-box-warning {
border-left: 4px solid var(--mw-warning);
}
.mw-message-box-error {
border-left: 4px solid var(--mw-danger);
}
.mw-message-box-success {
border-left: 4px solid var(--mw-success);
}
/* ---------- Footer ---------- */
.skin-vector .mw-footer {
background-color: var(--mw-surface-variant);
border-top: 1px solid var(--mw-divider);
color: var(--mw-text-muted);
}
/* ---------- Dark-mode helpers (for browser extensions honoring vars) ---------- */
@media (prefers-color-scheme: dark) {
:root {
/* Nudge contrast a bit in dark environments */
--mw-text: var(--color-01-90);
--mw-text-muted: var(--color-01-80);
--mw-heading: var(--color-01-95);
}
}

View File

@@ -1,2 +0,0 @@
# Todo
- Implement Collabora and Talk Supper . [See](https://www.youtube.com/watch?v=7cRmvTyt1ik)

View File

@@ -18,7 +18,6 @@ server:
domains:
canonical:
- "cloud.{{ PRIMARY_DOMAIN }}"
# talk: "talk.{{ PRIMARY_DOMAIN }}" @todo needs to be activated
docker:
volumes:
data: nextcloud_data
@@ -45,8 +44,14 @@ docker:
name: "nextcloud-talk"
image: "nextcloud/aio-talk"
version: "latest"
enabled: false # Not enabled yet, because just implemented during refactoring and not tested yet. if tested activate
oidc:
backup:
no_stop_required: false
whiteboard:
name: "nextcloud-whiteboard"
image: "ghcr.io/nextcloud-releases/whiteboard"
version: "latest"
backup:
no_stop_required: true
enabled: "{{ applications | get_app_conf('web-app-nextcloud', 'features.oidc', False, True) }}" # Activate OIDC for Nextcloud
# floavor decides which OICD plugin should be used.
# Available options: oidc_login, sociallogin
@@ -72,7 +77,8 @@ performance:
opcache_memory_consumption: "{{ ((ansible_memtotal_mb | int) / 30)|int }}M" # Dynamic set memory consumption
plugins_enabled: true # Implemented for speeding up testing and debugging process. For productive environments keep it true and steer the apps via the plugins config
oidc:
flavor: "{{ _applications_nextcloud_oidc_flavor }}"
plugins:
# List for Nextcloud Plugin Routine
# Decides if plugins should be activated or deactivated
@@ -234,7 +240,7 @@ plugins:
- oidc_login # Will be disabled
spreed:
# Nextcloud Spreed: offers video conferencing and chat functionalities (https://apps.nextcloud.com/apps/spreed)
enabled: false # @todo to activate it first implement web-svc-coturn and activate it
enabled: true
tables:
# Nextcloud tables: allows creation and editing of tables within the interface (https://apps.nextcloud.com/apps/tables)
enabled: true

View File

@@ -1,6 +1,6 @@
---
- name: restart nextcloud nginx service
command:
cmd: "docker exec {{ nextcloud_proxy_name }} nginx -s reload"
cmd: "docker exec {{ NEXTCLOUD_PROXY_CONTAINER }} nginx -s reload"
listen: restart nextcloud nginx service
ignore_errors: true # Ignoring if container is restarting

View File

@@ -1,6 +1,21 @@
credentials:
whiteboard_jwt_secret:
description: "Secret used for JWT signing"
algorithm: "base64_prefixed_32"
validation: "^base64:[A-Za-z0-9+/]{43}=$"
administrator_password:
description: "Initial password for the Nextcloud administrator (change immediately and enable 2FA)"
algorithm: "sha256"
validation: "^[a-f0-9]{64}$"
talk_turn_secret:
description: "TURN REST secret for coturn"
algorithm: "base64_prefixed_32"
validation: "^base64:[A-Za-z0-9+/]{43}=$"
talk_signaling_secret:
description: "Secret for Talk signaling"
algorithm: "base64_prefixed_32"
validation: "^base64:[A-Za-z0-9+/]{43}=$"
talk_internal_secret:
description: "Internal secret for AIO Talk"
algorithm: "base64_prefixed_32"
validation: "^base64:[A-Za-z0-9+/]{43}=$"

View File

@@ -0,0 +1,37 @@
- name: "include role for {{ application_id }} to receive certs & do modification routines for '{{ domain }}:{{ port }}'"
include_role:
name: sys-util-csp-cert
- name: create nextcloud proxy configuration file
template:
src: "nginx/host.conf.j2"
dest: "{{ NEXTCLOUD_HOST_NGINX_PATH }}"
notify: restart openresty
- name: "load docker and db for {{ application_id }}"
include_role:
name: sys-stk-back-stateful
vars:
docker_compose_flush_handlers: false
- name: "create {{ NEXTCLOUD_HOST_CONF_ADD_PATH }}"
file:
path: "{{ NEXTCLOUD_HOST_CONF_ADD_PATH }}"
state: directory
mode: "0755"
- name: "Create config files at {{ NEXTCLOUD_HOST_CONF_ADD_PATH }}"
template:
src: "{{ item }}"
dest: "{{ NEXTCLOUD_HOST_CONF_ADD_PATH }}/{{ item | basename | regex_replace('\\.j2$', '') }}"
owner: "{{ NEXTCLOUD_DOCKER_USER_id }}"
group: "{{ NEXTCLOUD_DOCKER_USER_id }}"
loop: "{{ lookup('fileglob', role_path ~ '/templates/config/*.j2', wantlist=True) }}"
# Not all type of changes take instantly place. Due to this reason a rebuild is required.
notify: docker compose up
- name: create internal nextcloud nginx configuration
template:
src: "nginx/docker.conf.j2"
dest: "{{ [docker_compose.directories.volumes, 'nginx.conf'] | path_join }}"
notify: restart nextcloud nginx service

View File

@@ -3,7 +3,7 @@
- name: Add dynamic config merging from Jinja template
template:
src: include.php.j2
dest: "{{ nextcloud_host_include_instructions_file }}"
dest: "{{ NEXTCLOUD_HOST_INCL_PATH }}"
notify: docker compose restart
- name: Flush handlers so Nextcloud container is restarted and ready
@@ -19,11 +19,11 @@
- name: Copy include instructions to the container
command: >
docker cp {{ nextcloud_host_include_instructions_file }} {{ NEXTCLOUD_CONTAINER }}:{{ nextcloud_docker_include_instructions_file }}
docker cp {{ NEXTCLOUD_HOST_INCL_PATH }} {{ NEXTCLOUD_CONTAINER }}:{{ NEXTCLOUD_DOCKER_INCL_PATH }}
- name: Append generated config to config.php only if not present
command: >
docker exec -u {{ NEXTCLOUD_DOCKER_USER }} {{ NEXTCLOUD_CONTAINER }} sh -c "
grep -q '{{ nextcloud_docker_config_additives_directory }}' {{ nextcloud_docker_config_file }} ||
cat {{ nextcloud_docker_include_instructions_file }} >> {{ nextcloud_docker_config_file }}"
grep -q '{{ NEXTCLOUD_DOCKER_CONF_ADD_PATH }}' {{ NEXTCLOUD_DOCKER_CONFIG_FILE }} ||
cat {{ NEXTCLOUD_DOCKER_INCL_PATH }} >> {{ NEXTCLOUD_DOCKER_CONFIG_FILE }}"
notify: docker compose restart

View File

@@ -1,7 +1,7 @@
- name: Ensure Nextcloud administrator is in the 'admin' group
command: >
docker exec -u {{ NEXTCLOUD_DOCKER_USER }} {{ NEXTCLOUD_CONTAINER }}
php occ group:adduser admin {{ nextcloud_administrator_username }}
php occ group:adduser admin {{ NEXTCLOUD_ADMINISTRATOR_USERNAME }}
register: add_admin_to_group
changed_when: "not ASYNC_ENABLED and 'Added user' in (add_admin_to_group.stdout | default(''))"
failed_when: >

View File

@@ -1,5 +1,5 @@
- block:
- include_tasks: 06_plugin_routines.yml
- include_tasks: _plugin_a_routines.yml
when: plugin_value.enabled | bool
- name: disable {{ plugin_key }} nextcloud plugin

View File

@@ -35,9 +35,12 @@
and
("already installed" not in install_result.stdout)
- include_tasks: 07_plugin_enable_and_configure.yml
- include_tasks: _plugin_b_enable_and_configure.yml
when:
- install_result is defined
- >
install_result.rc == 0
or "already installed" in install_result.stdout
vars:
plugin_task_path: "{{ NEXTCLOUD_CNODE_PLUGIN_TASKS_PATH }}{{ plugin_key }}.yml"
plugin_vars_path: "{{ NEXTCLOUD_CNODE_PLUGIN_VARS_PATH }}{{ plugin_key }}.yml"

View File

@@ -3,16 +3,16 @@
register: enable_result
changed_when: enable_result.rc == 0 and ("already enabled" not in enable_result.stdout)
- name: Check if {{ nextcloud_control_node_plugin_vars_directory }}{{ plugin_key }}.yml exists
- name: Check if {{ plugin_vars_path }} exists
stat:
path: "{{ nextcloud_control_node_plugin_vars_directory }}{{ plugin_key }}.yml"
path: "{{ plugin_vars_path }}"
delegate_to: localhost
become: false
register: plugin_vars_file
- name: "Load {{ plugin_key }} configuration variables"
include_vars:
file: "{{ nextcloud_control_node_plugin_vars_directory }}{{ plugin_key }}.yml"
file: "{{ plugin_vars_path }}"
when: plugin_vars_file.stat.exists
- name: "Set plugin configuration (batched shell, no async)"
@@ -34,14 +34,15 @@
failed_when: not ASYNC_ENABLED and config_set_shell.rc != 0
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | default(true) | bool }}"
- name: Check if {{ nextcloud_control_node_plugin_tasks_directory }}{{ plugin_key }}.yml exists
- name: Check if {{ plugin_task_path }} exists
stat:
path: "{{ nextcloud_control_node_plugin_tasks_directory }}{{ plugin_key }}.yml"
path: "{{ plugin_task_path }}"
delegate_to: localhost
become: false
register: plugin_tasks_file
- name: "include {{ nextcloud_control_node_plugin_tasks_directory }}{{ plugin_key }}.yml"
include_tasks: "{{ nextcloud_control_node_plugin_tasks_directory }}{{ plugin_key }}.yml"
- name: "include {{ plugin_task_path }}"
include_tasks: "{{ plugin_task_path }}"
when: plugin_tasks_file.stat.exists

View File

@@ -1,76 +1,39 @@
---
- name: "Install Collabora Dependency"
- name: "load docker, db and proxy for {{ application_id }}"
include_role:
name: web-svc-collabora
name: sys-stk-full-stateful
vars:
flush_handlers: true
when:
- run_once_web_svc_collabora is not defined
- NEXTCLOUD_COLLABORA_ENABLED | bool
- name: "include role for {{ application_id }} to receive certs & do modification routines"
include_role:
name: srv-composer
- name: create nextcloud proxy configuration file
template:
src: "nginx/host.conf.j2"
dest: "{{ nextcloud_host_nginx_path }}"
notify: restart openresty
- name: "load docker and db for {{ application_id }}"
include_role:
name: sys-stk-back-stateful
- name: Setup the full docker stack
include_tasks: 01_fullstack.yml
vars:
docker_compose_flush_handlers: false
- name: "create {{ nextcloud_host_config_additives_directory }}"
file:
path: "{{ nextcloud_host_config_additives_directory }}"
state: directory
mode: "0755"
- name: "Create config files at {{ nextcloud_host_config_additives_directory }}"
template:
src: "{{ item }}"
dest: "{{ nextcloud_host_config_additives_directory }}/{{ item | basename | regex_replace('\\.j2$', '') }}"
owner: "{{ NEXTCLOUD_DOCKER_USER_id }}"
group: "{{ NEXTCLOUD_DOCKER_USER_id }}"
loop: "{{ lookup('fileglob', role_path ~ '/templates/config/*.j2', wantlist=True) }}"
# Not all type of changes take instantly place. Due to this reason a rebuild is required.
notify: docker compose up
- name: create internal nextcloud nginx configuration
template:
src: "nginx/docker.conf.j2"
dest: "{{ docker_compose.directories.volumes }}nginx.conf"
notify: restart nextcloud nginx service
domain: "{{ NEXTCLOUD_DOMAIN }}"
http_port: "{{ NEXTCLOUD_PORT }}"
- name: Setup config.php
include_tasks: 01_config.yml
include_tasks: 02_config.yml
- name: Flush all handlers immediately so that occ can be used
meta: flush_handlers
- name: Update\Upgrade Nextcloud
include_tasks: 02_upgrade.yml
include_tasks: 03_upgrade.yml
when: MODE_UPDATE | bool
- name: Load system configuration steps
include_tasks: "{{ item }}"
loop:
- 03_admin.yml
- 04_system_config.yml
- 04_admin.yml
- 05_system_config.yml
- name: Setup Nextcloud Plugins
include_tasks: 05_plugin.yml
loop: "{{ applications | get_app_conf(application_id, 'plugins', True) | dict2items }}"
include_tasks: 06_setup_plugin.yml
loop: "{{ NEXTCLOUD_PLUGIN_ITEMS }}"
loop_control:
loop_var: plugin_item
vars:
plugin_key: "{{ plugin_item.key }}"
plugin_value: "{{ plugin_item.value }}"
when: nextcloud_plugins_enabled
when: NEXTCLOUD_PLUGINS_ENABLED

View File

@@ -0,0 +1,7 @@
- name: "Install Collabora Dependency"
include_role:
name: web-svc-collabora
vars:
flush_handlers: true
when:
- run_once_web_svc_collabora is not defined

View File

@@ -1,7 +1,7 @@
<?php
# Implementing OICD configuration
{% if applications | get_app_conf(application_id, 'oidc.flavor', True) == "oidc_login" %}
{% if applications | get_app_conf(application_id, 'oidc.flavor') == "oidc_login" %}
# Check out: https://github.com/pulsejet/nextcloud-oidc-login
@@ -21,7 +21,7 @@ return array (
'oidc_login_auto_redirect' => true,
// Redirect to this page after logging out the user
'oidc_login_logout_url' => 'https://{{ domains | get_domain(application_id) }}',
'oidc_login_logout_url' => '{{ NEXTCLOUD_URL }}',
// If set to true the user will be redirected to the
// logout endpoint of the OIDC provider after logout

View File

@@ -1,40 +1,8 @@
{% include 'roles/docker-compose/templates/base.yml.j2' %}
application:
image: "{{ nextcloud_image }}:{{ nextcloud_version }}"
container_name: {{ NEXTCLOUD_CONTAINER }}
volumes:
- data:{{ NEXTCLOUD_DOCKER_WORK_DIRECTORY }}
- {{ nextcloud_host_config_additives_directory }}:{{ nextcloud_docker_config_additives_directory }}:ro
healthcheck:
test: ["CMD", "su", "www-data", "-s", "/bin/sh", "-c", "php {{ NEXTCLOUD_DOCKER_WORK_DIRECTORY }}occ status"]
interval: 1m
timeout: 10s
retries: 3
{% 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' %}
ipv4_address: 192.168.102.69
{% if nextcloud_talk_enabled %}
talk:
{% include 'roles/docker-container/templates/base.yml.j2' %}
image: "{{ nextcloud_talk_image }}:{{ nextcloud_talk_version }}"
container_name: {{ nextcloud_talk_name }}
hostname: hpb_yt
init: true
ports:
- {{ networks.internet.ip4 }}:{{ nextcloud_talk_stun_port }}:3478/tcp #TURN TCP
- {{ networks.internet.ip4 }}:{{ nextcloud_talk_stun_port }}:3478/udp #TURN UDP
- {{ networks.internet.ip4 }}:8181:8081/tcp #Signaling @todo needs to be optimized
networks:
default:
ipv4_address: 192.168.102.68
{% endif %}
proxy:
image: "{{ nextcloud_proxy_image }}:{{ nextcloud_proxy_version }}"
container_name: "{{ nextcloud_proxy_name }}"
image: "{{ NEXTCLOUD_PROXY_IMAGE }}:{{ NEXTCLOUD_PROXY_VERSION }}"
container_name: "{{ NEXTCLOUD_PROXY_CONTAINER }}"
logging:
driver: journald
restart: {{ DOCKER_RESTART_POLICY }}
@@ -50,9 +18,57 @@
default:
ipv4_address: 192.168.102.67
application:
image: "{{ NEXTCLOUD_IMAGE }}:{{ NEXTCLOUD_VERSION }}"
container_name: {{ NEXTCLOUD_CONTAINER }}
volumes:
- data:{{ NEXTCLOUD_DOCKER_WORK_DIRECTORY }}
- {{ NEXTCLOUD_HOST_CONF_ADD_PATH }}:{{ NEXTCLOUD_DOCKER_CONF_ADD_PATH }}:ro
healthcheck:
test: ["CMD", "su", "www-data", "-s", "/bin/sh", "-c", "php {{ NEXTCLOUD_DOCKER_WORK_DIRECTORY }}occ status"]
interval: 1m
timeout: 10s
retries: 3
{% 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' %}
ipv4_address: 192.168.102.69
{% if NEXTCLOUD_TALK_ENABLED %}
talk:
{% set container_port = NEXTCLOUD_TALK_INTERNAL_PORT %}
{% include 'roles/docker-container/templates/base.yml.j2' %}
{% include 'roles/docker-container/templates/healthcheck/tcp.yml.j2' %}
image: "{{ NEXTCLOUD_TALK_IMAGE }}:{{ NEXTCLOUD_TALK_VERSION }}"
container_name: {{ NEXTCLOUD_TALK_CONTAINER }}
init: true
ports:
- {{ networks.internet.ip4 }}:{{ NEXTCLOUD_TALK_STUN_PORT }}:{{ NEXTCLOUD_TALK_INT_TURN_PORT }}/tcp #TURN TCP
- {{ networks.internet.ip4 }}:{{ NEXTCLOUD_TALK_STUN_PORT }}:{{ NEXTCLOUD_TALK_INT_TURN_PORT }}/udp #TURN UDP
expose:
- "{{ container_port }}"
networks:
default:
ipv4_address: 192.168.102.68
{% endif %}
{% if NEXTCLOUD_WHITEBOARD_ENABLED %}
whiteboard:
{% set container_port = NEXTCLOUD_WHITEBOARD_INTERNAL_PORT %}
{% include 'roles/docker-container/templates/base.yml.j2' %}
{% include 'roles/docker-container/templates/healthcheck/nc.yml.j2' %}
image: "{{ NEXTCLOUD_WHITEBOARD_IMAGE }}:{{ NEXTCLOUD_WHITEBOARD_VERSION }}"
container_name: {{ NEXTCLOUD_WHITEBOARD_CONTAINER }}
expose:
- "{{ container_port }}"
networks:
default:
ipv4_address: 192.168.102.71
{% endif %}
cron:
container_name: "{{ nextcloud_cron_name }}"
image: "{{ nextcloud_image }}:{{ nextcloud_version }}"
container_name: "{{ NEXTCLOUD_CRON_CONTAINER }}"
image: "{{ NEXTCLOUD_IMAGE }}:{{ NEXTCLOUD_VERSION }}"
restart: {{ DOCKER_RESTART_POLICY }}
logging:
driver: journald
@@ -70,6 +86,6 @@
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
data:
name: {{ nextcloud_volume }}
name: {{ NEXTCLOUD_VOLUME }}
{% include 'roles/docker-compose/templates/networks.yml.j2' %}

View File

@@ -24,30 +24,37 @@ MAIL_FROM_ADDRESS= "{{ users['no-reply'].username }}"
MAIL_DOMAIN= "{{ SYSTEM_EMAIL.DOMAIN }}"
# Initial Admin Data
NEXTCLOUD_ADMIN_USER= "{{applications | get_app_conf(application_id, 'users.administrator.username')}}"
NEXTCLOUD_ADMIN_PASSWORD= "{{applications | get_app_conf(application_id, 'credentials.administrator_password')}}"
NEXTCLOUD_ADMIN_USER= "{{ NEXTCLOUD_ADMINISTRATOR_USER }}"
NEXTCLOUD_ADMIN_PASSWORD= "{{ NEXTCLOUD_ADMINISTRATOR_PASSWORD }}"
# Security
NEXTCLOUD_TRUSTED_DOMAINS= "{{ domains[application_id] | select | join(',') }}"
NEXTCLOUD_TRUSTED_DOMAINS= "{{ NEXTCLOUD_DOMAIN }}"
# Whitelist local docker gateway in Nextcloud to prevent brute-force throtteling
TRUSTED_PROXIES= "{{ networks.internet.values() | select | join(',') }}"
OVERWRITECLIURL= "{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
OVERWRITEPROTOCOL= "https"
OVERWRITECLIURL= "{{ NEXTCLOUD_URL }}"
OVERWRITEPROTOCOL= "{{ WEB_PROTOCOL }}"
# Redis Configuration
REDIS_HOST= redis
REDIS_PORT= 6379
{% if nextcloud_talk_enabled %}
{% if NEXTCLOUD_TALK_ENABLED %}
# Talk Configuration
# This code was just moved here during refactoring and isn't tested yet.
# @todo move it to an own env file for encapsulation reasons
NC_DOMAIN=cloud.yourdomain.tld
TALK_HOST=signaling.yourdomain.tld
TURN_SECRET=${TURN_SECRET}
SIGNALING_SECRET=${SIGNALING_SECRET}
TZ=Europe/Berlin
NC_DOMAIN={{ NEXTCLOUD_DOMAIN }}
TALK_HOST={{ NEXTCLOUD_TALK_DOMAIN }}
TURN_SECRET={{ applications | get_app_conf(application_id, 'credentials.talk_turn_secret') }}
SIGNALING_SECRET={{ applications | get_app_conf(application_id, 'credentials.talk_signaling_secret') }}
INTERNAL_SECRET={{ applications | get_app_conf(application_id, 'credentials.talk_internal_secret') }}
TZ={{ HOST_TIMEZONE }}
TALK_PORT=3478
INTERNAL_SECRET=${INTERNAL_SECRET}
{% endif %}
{% if NEXTCLOUD_WHITEBOARD_ENABLED %}
# @todo move it to an own env file for encapsuling reasons
NEXTCLOUD_URL= "{{ NEXTCLOUD_URL }}"
JWT_SECRET_KEY= "{{ NEXTCLOUD_WHITEBOARD_JWT }}"
STORAGE_STRATEGY=redis
REDIS_URL=redis://redis:6379/0
{% endif %}

View File

@@ -3,7 +3,7 @@
$CONFIG_EXTRA = [];
foreach (glob("{% endraw %}{{ nextcloud_docker_config_additives_directory }}{% raw %}*.php") as $file) {
foreach (glob("{% endraw %}{{ NEXTCLOUD_DOCKER_CONF_ADD_PATH }}{% raw %}*.php") as $file) {
$CONFIG_EXTRA = array_merge($CONFIG_EXTRA, include $file);
}

View File

@@ -179,5 +179,24 @@ http {
location / {
try_files $uri $uri/ /index.php$request_uri;
}
location {{ NEXTCLOUD_WHITEBOARD_LOCATION }} {
proxy_pass http://whiteboard:{{ NEXTCLOUD_WHITEBOARD_INTERNAL_PORT }}/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600;
}
location {{ NEXTCLOUD_TALK_LOCATION }} {
proxy_pass http://talk:{{ NEXTCLOUD_TALK_INTERNAL_PORT }}/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600;
}
}
}

View File

@@ -2,7 +2,7 @@ server
{
server_name {{ domain }};
{% include 'roles/srv-letsencrypt/templates/ssl_header.j2' %}
{% include 'roles/sys-svc-letsencrypt/templates/ssl_header.j2' %}
{% include 'roles/sys-front-inj-all/templates/server.conf.j2'%}
@@ -17,7 +17,7 @@ server
client_body_buffer_size 400M;
fastcgi_buffers 64 4K;
{% include 'roles/srv-proxy-core/templates/location/html.conf.j2' %}
{% include 'roles/sys-svc-proxy/templates/location/html.conf.j2' %}
location ^~ /.well-known {
rewrite ^/\.well-known/host-meta\.json /public.php?service=host-meta-json last;

View File

@@ -3,70 +3,89 @@
application_id: "web-app-nextcloud" # Application identifier
container_port: 80
# Networking
domain: "{{ domains | get_domain(application_id) }}" # Public domain at which Nextcloud will be accessable
http_port: "{{ ports.localhost.http[application_id] }}" # Port at which nextcloud is reachable in the local network
# Database
database_password: "{{ applications | get_app_conf(application_id, 'credentials.database_password', True)}}"
database_password: "{{ applications | get_app_conf(application_id, 'credentials.database_password') }}"
database_type: "mariadb" # Database flavor
nextcloud_plugins_enabled: "{{ applications | get_app_conf(application_id, 'plugins_enabled') }}"
nextcloud_administrator_username: "{{ applications | get_app_conf(application_id, 'users.administrator.username') }}"
# Nextcloud
## General
NEXTCLOUD_DOMAIN: "{{ domains | get_domain(application_id) }}"
NEXTCLOUD_PORT: "{{ ports.localhost.http[application_id] }}"
NEXTCLOUD_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
# Control Node
nextcloud_control_node_plugin_vars_directory: "{{role_path}}/vars/plugins/" # Folder in which the files for the plugin configuration are stored
nextcloud_control_node_plugin_tasks_directory: "{{role_path}}/tasks/plugins/" # Folder which contains the files for extra plugin configuration tasks
NEXTCLOUD_PLUGINS_ENABLED: "{{ applications | get_app_conf(application_id, 'plugins_enabled') }}"
NEXTCLOUD_ADMINISTRATOR_USERNAME: "{{ applications | get_app_conf(application_id, 'users.administrator.username') }}"
# Host
## Plugins
NEXTCLOUD_PLUGIN_ITEMS: "{{ applications | get_app_conf(application_id, 'plugins') | dict2items }}"
## Host Paths
nextcloud_host_config_additives_directory: "{{ docker_compose.directories.volumes }}infinito/" # This folder is the path to which the additive configurations will be copied
nextcloud_host_include_instructions_file: "{{ docker_compose.directories.volumes }}includes.php" # Path to the instruction file on the host. Responsible for loading the additional configurations
nextcloud_host_nginx_path: "{{ NGINX.DIRECTORIES.HTTP.SERVERS }}{{ domains | get_domain(application_id) }}.conf" # Nginx path for proxy conf
## Paths
# Docker
### Host
NEXTCLOUD_HOST_CONF_ADD_PATH: "{{ [ docker_compose.directories.volumes, 'infinito' ] | path_join }}" # This folder is the path to which the additive configurations will be copied
NEXTCLOUD_HOST_INCL_PATH: "{{ [ docker_compose.directories.volumes, 'includes.php' ] | path_join }}" # Path to the instruction file on the host. Responsible for loading the additional configurations
NEXTCLOUD_HOST_NGINX_PATH: "{{ [ NGINX.DIRECTORIES.HTTP.SERVERS, NEXTCLOUD_DOMAIN ~ '.conf' ] | path_join }}" # Nginx path for proxy conf
nextcloud_volume: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"
## Control Node
NEXTCLOUD_CNODE_PLUGIN_VARS_PATH: "{{ [role_path, 'vars/plugins/'] | path_join }}" # Folder in which the files for the plugin configuration are stored
NEXTCLOUD_CNODE_PLUGIN_TASKS_PATH: "{{ [role_path, 'tasks/plugins/'] | path_join }}" # Folder which contains the files for extra plugin configuration tasks
nextcloud_version: "{{ applications | get_app_conf(application_id, 'docker.services.nextcloud.version') }}"
nextcloud_image: "{{ applications | get_app_conf(application_id, 'docker.services.nextcloud.image') }}"
## Internal Paths
NEXTCLOUD_DOCKER_WORK_DIRECTORY: "/var/www/html/" # Name of the workdir in which the application is stored
NEXTCLOUD_DOCKER_CONF_DIRECTORY: "{{ NEXTCLOUD_DOCKER_WORK_DIRECTORY }}config/" # Folder in which the Nextcloud configurations are stored
NEXTCLOUD_DOCKER_CONFIG_FILE: "{{ NEXTCLOUD_DOCKER_CONF_DIRECTORY }}config.php" # Path to the Nextcloud configuration file
NEXTCLOUD_DOCKER_CONF_ADD_PATH: "{{ NEXTCLOUD_DOCKER_CONF_DIRECTORY }}infinito/" # Path to the folder which contains additional configurations
NEXTCLOUD_DOCKER_INCL_PATH: "/tmp/includes.php" # Path to the temporary file which will be included to the config.php to load the additional configurations
## Administrator
NEXTCLOUD_ADMINISTRATOR_USER: "{{ applications | get_app_conf(application_id, 'users.administrator.username') }}"
NEXTCLOUD_ADMINISTRATOR_PASSWORD: "{{ applications | get_app_conf(application_id, 'credentials.administrator_password') }}"
## Docker
### Base
NEXTCLOUD_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"
NEXTCLOUD_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.nextcloud.version') }}"
NEXTCLOUD_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.nextcloud.image') }}"
NEXTCLOUD_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.nextcloud.name') }}"
nextcloud_proxy_name: "{{ applications | get_app_conf(application_id, 'docker.services.proxy.name') }}"
nextcloud_proxy_image: "{{ applications | get_app_conf(application_id, 'docker.services.proxy.image') }}"
nextcloud_proxy_version: "{{ applications | get_app_conf(application_id, 'docker.services.proxy.version') }}"
### Proxy
NEXTCLOUD_PROXY_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.proxy.name') }}"
NEXTCLOUD_PROXY_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.proxy.image') }}"
NEXTCLOUD_PROXY_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.proxy.version') }}"
nextcloud_cron_name: "{{ applications | get_app_conf(application_id, 'docker.services.cron.name') }}"
### Cron
NEXTCLOUD_CRON_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.cron.name') }}"
# Plugins
### Talk
NEXTCLOUD_TALK_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.talk.name') }}"
NEXTCLOUD_TALK_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.talk.image') }}"
NEXTCLOUD_TALK_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.talk.version') }}"
NEXTCLOUD_TALK_ENABLED: "{{ applications | get_app_conf(application_id, 'plugins.spreed.enabled') }}"
NEXTCLOUD_TALK_STUN_PORT: "{{ ports.public.stun[application_id] }}"
NEXTCLOUD_TALK_DOMAIN: "{{ NEXTCLOUD_DOMAIN }}"
NEXTCLOUD_TALK_LOCATION: "/standalone-signaling/"
NEXTCLOUD_TALK_URL: "{{ [ NEXTCLOUD_URL, NEXTCLOUD_TALK_LOCATION ] | url_join }}"
NEXTCLOUD_TALK_INTERNAL_PORT: "8081"
NEXTCLOUD_TALK_INT_TURN_PORT: "3478"
## Talk
nextcloud_talk_name: "{{ applications | get_app_conf(application_id, 'docker.services.talk.name') }}"
nextcloud_talk_image: "{{ applications | get_app_conf(application_id, 'docker.services.talk.image') }}"
nextcloud_talk_version: "{{ applications | get_app_conf(application_id, 'docker.services.talk.version') }}"
nextcloud_talk_enabled: "{{ applications | is_docker_service_enabled(application_id, 'talk') }}"
nextcloud_talk_stun_port: "{{ ports.public.stun[application_id] }}"
# nextcloud_talk_domain: "{{ domains[application_id].talk }}"
### Whiteboard
NEXTCLOUD_WHITEBOARD_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.whiteboard.name') }}"
NEXTCLOUD_WHITEBOARD_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.whiteboard.image') }}"
NEXTCLOUD_WHITEBOARD_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.whiteboard.version') }}"
NEXTCLOUD_WHITEBOARD_ENABLED: "{{ applications | get_app_conf(application_id, 'plugins.whiteboard.enabled') }}"
NEXTCLOUD_WHITEBOARD_INTERNAL_PORT: "3002"
NEXTCLOUD_WHITEBOARD_JWT: "{{ applications | get_app_conf(application_id, 'credentials.whiteboard_jwt_secret') }}"
NEXTCLOUD_WHITEBOARD_LOCATION: "/whiteboard/"
NEXTCLOUD_WHITEBOARD_URL: "{{ [ NEXTCLOUD_URL, NEXTCLOUD_WHITEBOARD_LOCATION ] | url_join }}"
# Collabora
#nextcloud_collabora_name: "{{ applications | get_app_conf(application_id, 'docker.services.collabora.name') }}"
### Collabora
NEXTCLOUD_COLLABORA_URL: "{{ domains | get_url('web-svc-collabora', WEB_PROTOCOL) }}"
#NEXTCLOUD_COLLABORA_DOMAIN: "{{ domains | get_domain('web-svc-collabora') }}"
NEXTCLOUD_COLLABORA_ENABLED: "{{ applications | get_app_conf(application_id, 'plugins.richdocuments.enabled') }}"
## User Configuration
NEXTCLOUD_DOCKER_USER_id: 82 # UID of the www-data user
NEXTCLOUD_DOCKER_USER: "www-data" # Name of the www-data user (Set here to easy change it in the future)
## Internal Paths
NEXTCLOUD_DOCKER_WORK_DIRECTORY: "/var/www/html/" # Name of the workdir in which the application is stored
NEXTCLOUD_DOCKER_CONFIG_DIRECTORY: "{{ NEXTCLOUD_DOCKER_WORK_DIRECTORY }}config/" # Folder in which the Nextcloud configurations are stored
nextcloud_docker_config_file: "{{ NEXTCLOUD_DOCKER_CONFIG_DIRECTORY }}config.php" # Path to the Nextcloud configuration file
nextcloud_docker_config_additives_directory: "{{ NEXTCLOUD_DOCKER_CONFIG_DIRECTORY }}infinito/" # Path to the folder which contains additional configurations
nextcloud_docker_include_instructions_file: "/tmp/includes.php" # Path to the temporary file which will be included to the config.php to load the additional configurations
## Execution
NEXTCLOUD_DOCKER_EXEC: "docker exec -u {{ NEXTCLOUD_DOCKER_USER }} {{ NEXTCLOUD_CONTAINER }}" # General execute composition
NEXTCLOUD_DOCKER_EXEC_OCC: "{{NEXTCLOUD_DOCKER_EXEC}} {{ NEXTCLOUD_DOCKER_WORK_DIRECTORY }}occ" # Execute docker occ command
# NEXTCLOUD_COLLOBORA_CONF_EXEC: "docker exec {{ applications | get_app_conf('web-svc-collabora', 'docker.services.collabora.name') }} coolconfig"

View File

@@ -0,0 +1,23 @@
plugin_configuration:
- appid: "spreed"
configkey: "signaling_servers"
configvalue:
- server: "{{ NEXTCLOUD_TALK_URL }}"
verify: true
# optional:
alias: "primary"
# STUN
- appid: "spreed"
configkey: "stun_servers"
configvalue:
- "stun:{{ NEXTCLOUD_TALK_DOMAIN }}:{{ NEXTCLOUD_TALK_STUN_PORT }}"
# TURN with REST-Secret (used by Talk/Coturn)
- appid: "spreed"
configkey: "turn_servers"
configvalue:
- server: "turn:{{ NEXTCLOUD_TALK_DOMAIN }}:{{ NEXTCLOUD_TALK_STUN_PORT }}?transport=udp"
secret: "{{ applications | get_app_conf(application_id, 'credentials.talk_turn_secret') }}"
ttl: 86400
protocols: "udp,tcp"

View File

@@ -0,0 +1,8 @@
plugin_configuration:
- appid: "whiteboard"
configkey: "collabBackendUrl"
configvalue: "{{ NEXTCLOUD_WHITEBOARD_URL }}"
- appid: "whiteboard"
configkey: "jwt_secret_key"
configvalue: "{{ NEXTCLOUD_WHITEBOARD_JWT }}"

View File

@@ -15,7 +15,7 @@ nextcloud_system_config:
value: "{{ HOST_LL | upper }}"
- parameter: "trusted_domains 0"
value: "{{ domains | get_domain(application_id) }}"
value: "{{ NEXTCLOUD_DOMAIN }}"
- parameter: "overwrite.cli.url"
value: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
value: "{{ NEXTCLOUD_URL }}"

View File

@@ -40,3 +40,4 @@ docker:
no_stop_required: true
volumes:
data: peertube_data
config: peertube_config

View File

@@ -4,15 +4,15 @@
- name: Check if OIDC plugin is already installed
command: >
docker exec {{ peertube_name }} test -d /data/plugins/data/peertube-plugin-auth-openid-connect
docker exec {{ PEERTUBE_CONTAINER }} test -d /data/plugins/data/peertube-plugin-auth-openid-connect
register: peertube_oidc_plugin_check
failed_when: false
changed_when: false
- name: "Install auth-openid-connect plugin for Peertube"
command: >
docker exec {{ peertube_name }} \
npm run plugin:install -- --npm-name {{oidc_plugin}}
docker exec {{ PEERTUBE_CONTAINER }} \
npm run plugin:install -- --npm-name {{ PEERTUBE_OIDC_PLUGIN }}
when: peertube_oidc_plugin_check.rc != 0
notify: docker compose up

View File

@@ -0,0 +1,5 @@
- name: "Uninstall auth-openid-connect plugin for Peertube"
command: >
docker exec {{ PEERTUBE_CONTAINER }} \
npm run plugin:uninstall -- --npm-name {{ PEERTUBE_OIDC_PLUGIN }}
ignore_errors: true

View File

@@ -1,9 +1,9 @@
- name: "include role for {{ application_id }} to receive certs & do modification routines"
include_role:
name: srv-composer
name: sys-util-csp-cert
- name: configure {{ domain }}.conf
template:
src: "templates/peertube.conf.j2"
dest: "{{ NGINX.DIRECTORIES.HTTP.SERVERS }}{{ domain }}.conf"
dest: "{{ [ NGINX.DIRECTORIES.HTTP.SERVERS, domain ~ '.conf'] | path_join }}"
notify: restart openresty

View File

@@ -1,5 +0,0 @@
- name: "Uninstall auth-openid-connect plugin for Peertube"
command: >
docker exec {{ peertube_name }} \
npm run plugin:uninstall -- --npm-name {{oidc_plugin}}
ignore_errors: true

View File

@@ -1,7 +1,7 @@
---
- name: "include create-domains.yml for peertube"
include_tasks: create-domains.yml
loop: "{{ domains['web-app-peertube'] }}"
- name: "include _create-domains.yml for peertube"
include_tasks: _create-domains.yml
loop: "{{ domains[application_id] }}"
loop_control:
loop_var: domain
vars:
@@ -14,9 +14,9 @@
name: sys-stk-back-stateful
- name: "Install and activate auth-openid-connect plugin if OIDC is enabled"
include_tasks: enable-oidc.yml
when: applications | get_app_conf(application_id, 'features.oidc', False)
include_tasks: 01_enable-oidc.yml
when: PEERTUBE_OIDC_ENABLED
- name: "Deinstall and disable auth-openid-connect plugin if OIDC is enabled"
include_tasks: disable-oidc.yml
when: applications | get_app_conf(application_id, 'features.oidc', False)
include_tasks: 02_disable-oidc.yml
when: PEERTUBE_OIDC_ENABLED

View File

@@ -2,8 +2,8 @@
application:
{% set container_port = 9000 %}
image: {{ peertube_image }}:{{ peertube_version }}
container_name: {{ peertube_name }}
image: {{ PEERTUBE_IMAGE }}:{{ PEERTUBE_VERSION }}
container_name: {{ PEERTUBE_CONTAINER }}
{% include 'roles/docker-container/templates/base.yml.j2' %}
ports:
- "1935:1935" # @todo Add to ports
@@ -18,7 +18,8 @@
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
assets:
data:
name: {{ peertube_volume }}
name: {{ PEERTUBE_DATA_VOLUME }}
config:
name: {{ PEERTUBE_CONFIG_VOLUME }}
{% include 'roles/docker-compose/templates/networks.yml.j2' %}

View File

@@ -1,18 +1,18 @@
server {
server_name {{ domain }};
{% include 'roles/srv-letsencrypt/templates/ssl_header.j2' %}
{% include 'roles/sys-svc-letsencrypt/templates/ssl_header.j2' %}
{% include 'roles/sys-front-inj-all/templates/server.conf.j2'%}
{% include 'roles/srv-proxy-core/templates/headers/content_security_policy.conf.j2' %}
{% include 'roles/sys-svc-proxy/templates/headers/content_security_policy.conf.j2' %}
##
# Application
##
{% set location = "@html" %}
{% include 'roles/srv-proxy-core/templates/location/html.conf.j2' %}
{% include 'roles/sys-svc-proxy/templates/location/html.conf.j2' %}
location / {
try_files /dev/null {{ location }};
@@ -45,7 +45,7 @@ server {
##
{% set location_ws = "@websocket" %}
{% include 'roles/srv-proxy-core/templates/location/ws.conf.j2' %}
{% include 'roles/sys-svc-proxy/templates/location/ws.conf.j2' %}
location /socket.io {
try_files /dev/null {{ location_ws }};

View File

@@ -6,10 +6,12 @@ database_type: "postgres"
docker_compose_flush_handlers: true
# Role variables
peertube_version: "{{ applications | get_app_conf(application_id, 'docker.services.peertube.version', True) }}"
peertube_image: "{{ applications | get_app_conf(application_id, 'docker.services.peertube.image', True) }}"
peertube_name: "{{ applications | get_app_conf(application_id, 'docker.services.peertube.name', True) }}"
peertube_volume: "{{ applications | get_app_conf(application_id, 'docker.volumes.data', True) }}"
PEERTUBE_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.peertube.version') }}"
PEERTUBE_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.peertube.image') }}"
PEERTUBE_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.peertube.name') }}"
PEERTUBE_DATA_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"
PEERTUBE_CONFIG_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.config') }}"
# OIDC
oidc_plugin: "peertube-plugin-auth-openid-connect"
PEERTUBE_OIDC_PLUGIN: "peertube-plugin-auth-openid-connect"
PEERTUBE_OIDC_ENABLED: "{{ applications | get_app_conf(application_id, 'features.oidc', False) }}"

View File

@@ -9,8 +9,11 @@ docker:
image: pretix/standalone
version: stable
name: pretix
backup:
no_stop_required: true
volumes:
data: "pretix_data"
config: "pretix_config"
features:
matomo: true
css: true

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