Bundle of cross-role changes for the gymb services deployment: - Traefik routers: OR-combine opnform/homarr/bookstack Host rules with new *_extra_domains (internal *.int.* FQDNs for a DMZ reverseproxy), and emit tls.certresolver only when traefik_cert_mode == acme (drawio, homarr, opnform, send). - Split-horizon: bookstack_extra_hosts / opnform_extra_hosts add container /etc/hosts overrides so containers reach the IdP public FQDN over the LAN. - bookstack: assert the OIDC issuer resolves concretely (reject "//v2.0"), allowing non-Entra IdPs that override bookstack_oidc_issuer. - homarr: derive the bcrypt salt from the password digest so the admin hash is idempotent — no spurious template changes / container restarts. - opnform: PATCH an existing OIDC connection instead of skipping (applies corrected inventory on re-run); add OIDC_FORCE_LOGIN (enabled only after bootstrap) and an optional direct-SSO ingress entrypoint. Docs: READMEs and meta/argument_specs.yml updated for all new variables.
93 lines
3.7 KiB
Django/Jinja
93 lines
3.7 KiB
Django/Jinja
#---------------------------------------------------------------------#
|
|
# BookStack - Self-hosted wiki / knowledge base. #
|
|
#---------------------------------------------------------------------#
|
|
---
|
|
services:
|
|
{{ bookstack_service_name }}:
|
|
image: {{ bookstack_image }}
|
|
container_name: {{ bookstack_service_name }}
|
|
restart: unless-stopped
|
|
environment:
|
|
PUID: "{{ bookstack_puid }}"
|
|
PGID: "{{ bookstack_pgid }}"
|
|
TZ: "{{ bookstack_tz }}"
|
|
APP_URL: "{{ bookstack_base_url }}"
|
|
APP_KEY: "{{ bookstack_resolved_app_key }}"
|
|
DB_HOST: "{{ bookstack_service_name }}-db"
|
|
DB_PORT: "3306"
|
|
DB_DATABASE: "{{ bookstack_db_name }}"
|
|
DB_USERNAME: "{{ bookstack_db_user }}"
|
|
DB_PASSWORD: "{{ bookstack_db_password }}"
|
|
MAIL_DRIVER: "{{ bookstack_mail_driver }}"
|
|
MAIL_HOST: "{{ bookstack_mail_host }}"
|
|
MAIL_PORT: "{{ bookstack_mail_port }}"
|
|
MAIL_USERNAME: "{{ bookstack_mail_username }}"
|
|
MAIL_PASSWORD: "{{ bookstack_mail_password }}"
|
|
MAIL_ENCRYPTION: "{{ bookstack_mail_encryption }}"
|
|
MAIL_FROM: "{{ bookstack_mail_from }}"
|
|
MAIL_FROM_NAME: "{{ bookstack_mail_from_name }}"
|
|
{% if bookstack_oidc_enabled %}
|
|
AUTH_METHOD: "oidc"
|
|
AUTH_AUTO_INITIATE: "{{ bookstack_oidc_auto_initiate | string | lower }}"
|
|
OIDC_NAME: "{{ bookstack_oidc_name }}"
|
|
OIDC_DISPLAY_NAME_CLAIMS: "name"
|
|
OIDC_CLIENT_ID: "{{ bookstack_oidc_client_id }}"
|
|
OIDC_CLIENT_SECRET: "{{ bookstack_oidc_client_secret }}"
|
|
OIDC_ISSUER: "{{ bookstack_oidc_issuer }}"
|
|
OIDC_ISSUER_DISCOVER: "true"
|
|
OIDC_END_SESSION_ENDPOINT: "true"
|
|
OIDC_ADDITIONAL_SCOPES: "{{ bookstack_oidc_additional_scopes }}"
|
|
OIDC_USER_TO_GROUPS: "{{ bookstack_oidc_user_to_groups | string | lower }}"
|
|
OIDC_GROUPS_CLAIM: "{{ bookstack_oidc_groups_claim }}"
|
|
{% endif %}
|
|
volumes:
|
|
- {{ bookstack_appdata_dir }}:/config
|
|
networks:
|
|
- {{ bookstack_traefik_network }}
|
|
- internal
|
|
{% if bookstack_extra_hosts | length > 0 %}
|
|
extra_hosts:
|
|
{% for host in bookstack_extra_hosts %}
|
|
- "{{ host }}"
|
|
{% endfor %}
|
|
{% endif %}
|
|
depends_on:
|
|
{{ bookstack_service_name }}-db:
|
|
condition: service_healthy
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.docker.network={{ bookstack_traefik_network }}"
|
|
- "traefik.http.routers.{{ bookstack_service_name }}.rule={% set _all_domains = [bookstack_domain] + (bookstack_extra_domains | default([])) %}{% for d in _all_domains %}Host(`{{ d }}`){% if not loop.last %} || {% endif %}{% endfor +%}"
|
|
- "traefik.http.routers.{{ bookstack_service_name }}.entrypoints=websecure"
|
|
- "traefik.http.routers.{{ bookstack_service_name }}.tls=true"
|
|
- "traefik.http.routers.{{ bookstack_service_name }}.tls.certresolver={{ bookstack_traefik_certresolver }}"
|
|
- "traefik.http.services.{{ bookstack_service_name }}.loadbalancer.server.port=80"
|
|
|
|
{{ bookstack_service_name }}-db:
|
|
image: {{ bookstack_db_image }}
|
|
container_name: {{ bookstack_service_name }}-db
|
|
restart: unless-stopped
|
|
environment:
|
|
PUID: "{{ bookstack_puid }}"
|
|
PGID: "{{ bookstack_pgid }}"
|
|
TZ: "{{ bookstack_tz }}"
|
|
MYSQL_ROOT_PASSWORD: "{{ bookstack_db_root_password }}"
|
|
MYSQL_DATABASE: "{{ bookstack_db_name }}"
|
|
MYSQL_USER: "{{ bookstack_db_user }}"
|
|
MYSQL_PASSWORD: "{{ bookstack_db_password }}"
|
|
volumes:
|
|
- {{ bookstack_db_data_dir }}:/config
|
|
networks:
|
|
- internal
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "mariadb-admin ping -h 127.0.0.1 -u root --password=\"$$MYSQL_ROOT_PASSWORD\" --silent"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 12
|
|
start_period: 60s
|
|
|
|
networks:
|
|
{{ bookstack_traefik_network }}:
|
|
external: true
|
|
internal:
|
|
driver: bridge
|