Confluence/Jira roles: add READMEs, switch to custom images, proxy/JVM envs, and integer-safe heap sizing

Confluence: README added; demo disables OIDC/LDAP; Dockerfile overlay; docker-compose now uses CONFLUENCE_CUSTOM_IMAGE and DB depends include; env.j2 adds ATL_* and JVM_*; vars use integer math (//) for Xmx/Xms and expose CUSTOM_IMAGE.

Jira: initial role skeleton with README, config/meta/tasks; Dockerfile overlay; docker-compose using JIRA_CUSTOM_IMAGE and DB depends include; env.j2 with proxy + JVM envs; vars with integer-safe memory sizing.

Context: https://chatgpt.com/share/68b6b592-2250-800f-b68e-b37ae98dbe70
This commit is contained in:
2025-09-02 12:07:34 +02:00
parent bc56940e55
commit 188b098503
15 changed files with 265 additions and 29 deletions

View File

@@ -0,0 +1,25 @@
# Confluence
## Description
Confluence is Atlassians enterprise wiki and collaboration platform. This role deploys Confluence via Docker Compose, wires it to PostgreSQL, and integrates proxy awareness, optional OIDC SSO, health checks, and production-friendly defaults for Infinito.Nexus.
## Overview
The role builds a minimal custom image on top of the official Confluence image, prepares persistent volumes, and exposes the app behind your reverse proxy. Configuration is driven by variables (image, version, volumes, domains, OIDC). JVM heap sizing is auto-derived from host RAM with safe caps to avoid `Xms > Xmx`.
## Features
* **Fully Dockerized:** Compose stack with a dedicated data volume (`confluence_data`) and a slim overlay image for future add-ons.
* **Reverse-Proxy Ready:** Sets `ATL_PROXY_NAME/PORT/SCHEME/SECURE` so Confluence generates correct external URLs behind HTTPS.
* **OIDC SSO (Optional):** Pre-templated vars for issuer, client, scopes, JWKS; compatible with Atlassian DC SSO/OIDC marketplace apps.
* **Central Database:** PostgreSQL integration (local or central DB) with bootstrap credentials from role vars.
* **JVM Auto-Tuning:** `JVM_MINIMUM_MEMORY` / `JVM_MAXIMUM_MEMORY` computed from host memory with upper bounds.
* **Health Checks:** Curl-based container healthcheck for early failure detection.
* **CSP & Canonical Domains:** Hooks into platform CSP/SSL/domain management to keep policies strict and URLs stable.
* **Backup Friendly:** Data isolated under `/var/atlassian/application-data/confluence`.
## Further Resources
* Product page: [Atlassian Confluence](https://www.atlassian.com/software/confluence)
* Docker Hub (official image): [atlassian/confluence](https://hub.docker.com/r/atlassian/confluence)

View File

@@ -15,7 +15,8 @@ features:
desktop: true
central_database: true
logout: true
oidc: true
oidc: false # Not enabled for demo version
ldap: false # Not enabled for demo version
server:
csp:
whitelist: {}

View File

@@ -0,0 +1,8 @@
FROM "{{ CONFLUENCE_IMAGE }}:{{ CONFLUENCE_VERSION }}"
# Optional: install OIDC SSO app (example path/name)
# COPY ./plugins/atlassian-sso-dc-latest.obr /opt/atlassian/confluence/confluence/WEB-INF/atlassian-bundled-plugins/
# Ensure proper permissions for app data
RUN mkdir -p /var/atlassian/application-data/confluence && \
chown -R 2001:2001 /var/atlassian/application-data/confluence

View File

@@ -3,9 +3,7 @@
build:
context: .
dockerfile: Dockerfile
args:
CONFLUENCE_BASE_IMAGE: "{{ CONFLUENCE_IMAGE }}:{{ CONFLUENCE_VERSION }}"
image: "{{ CONFLUENCE_IMAGE }}:{{ CONFLUENCE_VERSION }}-oidc"
image: "{{ CONFLUENCE_CUSTOM_IMAGE }}"
container_name: "{{ CONFLUENCE_CONTAINER }}"
hostname: '{{ CONFLUENCE_HOSTNAME}}'
ports:
@@ -14,8 +12,7 @@
- 'data:/var/atlassian/application-data/confluence'
{% include 'roles/docker-container/templates/healthcheck/curl.yml.j2' %}
{% include 'roles/docker-container/templates/base.yml.j2' %}
depends_on:
- database
{% 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

@@ -1,6 +1,13 @@
## Confluence core
CONFLUENCE_URL="{{ CONFLUENCE_URL }}"
ATL_PROXY_NAME={{ CONFLUENCE_HOSTNAME }}
ATL_PROXY_PORT={{ WEB_PORT }}
ATL_TOMCAT_SCHEME={{ WEB_PROTOCOL }}
ATL_TOMCAT_SECURE={{ (WEB_PORT == 443) | lower }}
JVM_MINIMUM_MEMORY={{ CONFLUENCE_JVM_MIN }}
JVM_MAXIMUM_MEMORY={{ CONFLUENCE_JVM_MAX }}
## Database
CONFLUENCE_DATABASE_NAME="{{ database_name }}"
CONFLUENCE_DATABASE_USER="{{ database_username }}"

View File

@@ -1,27 +1,41 @@
application_id: "web-app-confluence"
database_type: "postgres"
container_port: 8090 # Standardport Confluence
# General
application_id: "web-app-confluence"
database_type: "postgres"
# URLs
CONFLUENCE_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
CONFLUENCE_HOSTNAME: "{{ domains | get_domain(application_id) }}"
# Container
container_port: 8090
container_hostname: "{{ domains | get_domain(application_id) }}"
# OIDC
CONFLUENCE_OIDC_ENABLED: "{{ applications | get_app_conf(application_id, 'features.oidc') }}"
CONFLUENCE_OIDC_LABEL: "{{ OIDC.BUTTON_TEXT }}"
CONFLUENCE_OIDC_CLIENT_ID: "{{ OIDC.CLIENT.ID }}"
CONFLUENCE_OIDC_CLIENT_SECRET: "{{ OIDC.CLIENT.SECRET }}"
CONFLUENCE_OIDC_ISSUER: "{{ OIDC.CLIENT.ISSUER_URL }}"
CONFLUENCE_OIDC_AUTH_URL: "{{ OIDC.CLIENT.AUTHORIZE_URL }}"
CONFLUENCE_OIDC_TOKEN_URL: "{{ OIDC.CLIENT.TOKEN_URL }}"
CONFLUENCE_OIDC_USERINFO_URL: "{{ OIDC.CLIENT.USER_INFO_URL }}"
CONFLUENCE_OIDC_LOGOUT_URL: "{{ OIDC.CLIENT.LOGOUT_URL }}"
CONFLUENCE_OIDC_JWKS_URL: "{{ OIDC.CLIENT.CERTS }}"
CONFLUENCE_OIDC_SCOPES: "openid,email,profile"
# Confluence
## URLs
CONFLUENCE_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
CONFLUENCE_HOSTNAME: "{{ container_hostname }}"
## OIDC
CONFLUENCE_OIDC_ENABLED: "{{ applications | get_app_conf(application_id, 'features.oidc') }}"
CONFLUENCE_OIDC_LABEL: "{{ OIDC.BUTTON_TEXT }}"
CONFLUENCE_OIDC_CLIENT_ID: "{{ OIDC.CLIENT.ID }}"
CONFLUENCE_OIDC_CLIENT_SECRET: "{{ OIDC.CLIENT.SECRET }}"
CONFLUENCE_OIDC_ISSUER: "{{ OIDC.CLIENT.ISSUER_URL }}"
CONFLUENCE_OIDC_AUTH_URL: "{{ OIDC.CLIENT.AUTHORIZE_URL }}"
CONFLUENCE_OIDC_TOKEN_URL: "{{ OIDC.CLIENT.TOKEN_URL }}"
CONFLUENCE_OIDC_USERINFO_URL: "{{ OIDC.CLIENT.USER_INFO_URL }}"
CONFLUENCE_OIDC_LOGOUT_URL: "{{ OIDC.CLIENT.LOGOUT_URL }}"
CONFLUENCE_OIDC_JWKS_URL: "{{ OIDC.CLIENT.CERTS }}"
CONFLUENCE_OIDC_SCOPES: "openid,email,profile"
CONFLUENCE_OIDC_UNIQUE_ATTRIBUTE: "{{ OIDC.ATTRIBUTES.USERNAME }}"
# Docker
CONFLUENCE_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.application.version') }}"
CONFLUENCE_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.application.image') }}"
CONFLUENCE_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.application.name') }}"
CONFLUENCE_DATA_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"
## Docker
CONFLUENCE_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.application.version') }}"
CONFLUENCE_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.application.image') }}"
CONFLUENCE_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.application.name') }}"
CONFLUENCE_DATA_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"
CONFLUENCE_CUSTOM_IMAGE: "{{ CONFLUENCE_IMAGE }}_custom"
## Performance
CONFLUENCE_TOTAL_MB: "{{ ansible_memtotal_mb | int }}"
CONFLUENCE_JVM_MAX_MB: "{{ [ (CONFLUENCE_TOTAL_MB // 2), 12288 ] | min }}"
CONFLUENCE_JVM_MIN_MB: "{{ [ (CONFLUENCE_TOTAL_MB // 4), CONFLUENCE_JVM_MAX_MB ] | min }}"
CONFLUENCE_JVM_MIN: "{{ CONFLUENCE_JVM_MIN_MB }}m"
CONFLUENCE_JVM_MAX: "{{ CONFLUENCE_JVM_MAX_MB }}m"

View File

@@ -0,0 +1,25 @@
# Jira
## Description
Jira Software is Atlassians issue and project-tracking platform. This role deploys Jira via Docker Compose, connects it to PostgreSQL, and adds proxy awareness, optional OIDC SSO, health checks, and production-oriented defaults for Infinito.Nexus.
## Overview
The role builds a lean custom image on top of the official Jira Software image, provisions persistent volumes, and exposes the app behind your reverse proxy. Variables control image/version/volumes/domains/SSO. JVM heap sizing is auto-derived from host RAM with safe caps to prevent `Xms > Xmx`.
## Features
* **Fully Dockerized:** Compose stack with a dedicated data volume (`jira_data`) and a minimal overlay image to enable future plugins/config.
* **Reverse-Proxy/HTTPS Ready:** Preconfigured Atlassian Tomcat proxy envs so Jira respects external scheme/host/port.
* **OIDC SSO (Optional):** Pre-templated vars for issuer, client, endpoints, scopes; compatible with Atlassian DC SSO/OIDC marketplace apps.
* **Central Database:** PostgreSQL integration (local or central) with credentials sourced from role configuration.
* **JVM Auto-Tuning:** Safe calculation of `JVM_MINIMUM_MEMORY` / `JVM_MAXIMUM_MEMORY` with caps to avoid VM init errors.
* **Health Checks:** Container healthcheck for quicker failure detection and stable automation.
* **CSP & Canonical Domains:** Integrates with platform CSP and domain management.
* **Backup Ready:** Persistent data under `/var/atlassian/application-data/jira`.
## Further Resources
* Product page: [Atlassian Jira Software](https://www.atlassian.com/software/jira)
* Docker Hub (official image): [atlassian/jira-software](https://hub.docker.com/r/atlassian/jira-software)

View File

@@ -0,0 +1,29 @@
credentials: {}
docker:
services:
database:
enabled: true
application:
image: atlassian/jira-software
version: latest
name: jira
volumes:
data: "jira_data"
features:
matomo: true
css: true
desktop: true
central_database: true
logout: true
oidc: false # Not enabled for demo version
ldap: false # Not enabled for demo version
server:
csp:
whitelist: {}
flags: {}
domains:
canonical:
- "jira.{{ PRIMARY_DOMAIN }}"
rbac:
roles: {}

View File

@@ -0,0 +1,20 @@
galaxy_info:
author: "Kevin Veen-Birkenbach"
description: "Jira Software is Atlassians issue & project tracking platform. This role deploys Jira in Docker, adds optional OIDC support, and integrates with the Infinito.Nexus ecosystem."
license: "Infinito.Nexus NonCommercial License"
license_url: "https://s.infinito.nexus/license"
company: |
Kevin Veen-Birkenbach
Consulting & Coaching Solutions
https://www.veen.world
galaxy_tags: []
repository: "https://s.infinito.nexus/code"
issue_tracker_url: "https://s.infinito.nexus/issues"
documentation: "https://s.infinito.nexus/code/"
logo:
class: "fas fa-diagram-project"
run_after:
- web-app-matomo
- web-app-keycloak
- web-app-mailu
dependencies: []

View File

View File

@@ -0,0 +1,7 @@
---
- block:
- name: "load docker, db and proxy for {{ application_id }}"
include_role:
name: sys-stk-full-stateful
- include_tasks: utils/run_once.yml
when: run_once_web_app_jira is not defined

View File

@@ -0,0 +1,8 @@
FROM "{{ JIRA_IMAGE }}:{{ JIRA_VERSION }}"
# Optional: install OIDC SSO app (example path/name)
# COPY ./plugins/atlassian-sso-dc-latest.obr /opt/atlassian/jira/atlassian-bundled-plugins/
# Ensure proper permissions for app data
RUN mkdir -p /var/atlassian/application-data/jira && \
chown -R 2001:2001 /var/atlassian/application-data/jira

View File

@@ -0,0 +1,23 @@
{% include 'roles/docker-compose/templates/base.yml.j2' %}
application:
build:
context: .
dockerfile: Dockerfile
image: "{{ JIRA_CUSTOM_IMAGE }}"
container_name: "{{ JIRA_CONTAINER }}"
hostname: '{{ JIRA_HOSTNAME }}'
ports:
- "127.0.0.1:{{ ports.localhost.http[application_id] }}:8080"
volumes:
- 'data:/var/atlassian/application-data/jira'
{% 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' %}
data:
name: {{ JIRA_DATA_VOLUME }}
{% include 'roles/docker-compose/templates/networks.yml.j2' %}

View File

@@ -0,0 +1,31 @@
## Jira core
JIRA_URL="{{ JIRA_URL }}"
## Database
JIRA_DATABASE_NAME="{{ database_name }}"
JIRA_DATABASE_USER="{{ database_username }}"
JIRA_DATABASE_PASSWORD="{{ database_password }}"
JIRA_DATABASE_HOST="{{ database_host }}"
JIRA_DATABASE_PORT="{{ database_port }}"
ATL_PROXY_NAME={{ JIRA_HOSTNAME }}
ATL_PROXY_PORT={{ WEB_PORT }}
ATL_TOMCAT_SCHEME={{ WEB_PROTOCOL }}
ATL_TOMCAT_SECURE={{ (WEB_PORT == 443) | lower }}
JVM_MINIMUM_MEMORY={{ JIRA_JVM_MIN }}
JVM_MAXIMUM_MEMORY={{ JIRA_JVM_MAX }}
## OIDC
{% if JIRA_OIDC_ENABLED %}
JIRA_OIDC_TITLE="{{ JIRA_OIDC_LABEL | replace('\"','\\\"') }}"
JIRA_OIDC_ISSUER="{{ JIRA_OIDC_ISSUER }}"
JIRA_OIDC_AUTHORIZATION_ENDPOINT="{{ JIRA_OIDC_AUTH_URL }}"
JIRA_OIDC_TOKEN_ENDPOINT="{{ JIRA_OIDC_TOKEN_URL }}"
JIRA_OIDC_USERINFO_ENDPOINT="{{ JIRA_OIDC_USERINFO_URL }}"
JIRA_OIDC_END_SESSION_ENDPOINT="{{ JIRA_OIDC_LOGOUT_URL }}"
JIRA_OIDC_JWKS_URI="{{ JIRA_OIDC_JWKS_URL }}"
JIRA_OIDC_CLIENT_ID="{{ JIRA_OIDC_CLIENT_ID }}"
JIRA_OIDC_CLIENT_SECRET="{{ JIRA_OIDC_CLIENT_SECRET }}"
JIRA_OIDC_SCOPES="{{ JIRA_OIDC_SCOPES }}"
JIRA_OIDC_UNIQUE_ATTRIBUTE="{{ JIRA_OIDC_UNIQUE_ATTRIBUTE }}"
{% endif %}

View File

@@ -0,0 +1,41 @@
# General
application_id: "web-app-jira"
database_type: "postgres"
# Container
container_port: 8080 # Standardport Jira
container_hostname: "{{ domains | get_domain(application_id) }}"
# Jira
## URLs
JIRA_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
JIRA_HOSTNAME: "{{ container_hostname }}"
## OIDC
JIRA_OIDC_ENABLED: "{{ applications | get_app_conf(application_id, 'features.oidc') }}"
JIRA_OIDC_LABEL: "{{ OIDC.BUTTON_TEXT }}"
JIRA_OIDC_CLIENT_ID: "{{ OIDC.CLIENT.ID }}"
JIRA_OIDC_CLIENT_SECRET: "{{ OIDC.CLIENT.SECRET }}"
JIRA_OIDC_ISSUER: "{{ OIDC.CLIENT.ISSUER_URL }}"
JIRA_OIDC_AUTH_URL: "{{ OIDC.CLIENT.AUTHORIZE_URL }}"
JIRA_OIDC_TOKEN_URL: "{{ OIDC.CLIENT.TOKEN_URL }}"
JIRA_OIDC_USERINFO_URL: "{{ OIDC.CLIENT.USER_INFO_URL }}"
JIRA_OIDC_LOGOUT_URL: "{{ OIDC.CLIENT.LOGOUT_URL }}"
JIRA_OIDC_JWKS_URL: "{{ OIDC.CLIENT.CERTS }}"
JIRA_OIDC_SCOPES: "openid,email,profile"
JIRA_OIDC_UNIQUE_ATTRIBUTE: "{{ OIDC.ATTRIBUTES.USERNAME }}"
## Docker
JIRA_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.application.version') }}"
JIRA_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.application.image') }}"
JIRA_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.application.name') }}"
JIRA_DATA_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"
JIRA_CUSTOM_IMAGE: "{{ JIRA_IMAGE }}_custom"
## Performance (auto-derive from host memory)
JIRA_TOTAL_MB: "{{ ansible_memtotal_mb | int }}"
JIRA_JVM_MAX_MB: "{{ [ (JIRA_TOTAL_MB // 2), 12288 ] | min }}"
JIRA_JVM_MIN_MB: "{{ [ (JIRA_TOTAL_MB // 4), JIRA_JVM_MAX_MB ] | min }}"
JIRA_JVM_MIN: "{{ JIRA_JVM_MIN_MB }}m"
JIRA_JVM_MAX: "{{ JIRA_JVM_MAX_MB }}m"