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.
72 lines
2.7 KiB
Django/Jinja
72 lines
2.7 KiB
Django/Jinja
services:
|
|
{{ send_service_name }}:
|
|
image: {{ send_image }}
|
|
container_name: {{ send_service_name }}
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- {{ send_redis_service_name }}
|
|
networks:
|
|
- {{ send_traefik_network }}
|
|
- {{ send_internal_network }}
|
|
{% if send_extra_hosts is defined and send_extra_hosts | length > 0 %}
|
|
extra_hosts:
|
|
{% for host in send_extra_hosts %}
|
|
- "{{ host }}"
|
|
{% endfor %}
|
|
{% endif %}
|
|
environment:
|
|
{% if send_use_ssl %}
|
|
BASE_URL: "https://{{ send_domains[0] }}"
|
|
{% else %}
|
|
BASE_URL: "http://{{ send_domains[0] }}"
|
|
{% endif %}
|
|
REDIS_HOST: "{{ send_redis_service_name }}"
|
|
REDIS_PORT: "6379"
|
|
MAX_FILE_SIZE: "{{ send_max_file_size }}"
|
|
DEFAULT_DOWNLOADS: "{{ send_default_downloads }}"
|
|
MAX_DOWNLOADS: "{{ send_max_downloads }}"
|
|
DEFAULT_EXPIRE_SECONDS: "{{ send_default_expire_seconds }}"
|
|
MAX_EXPIRE_SECONDS: "{{ send_max_expire_seconds }}"
|
|
MAX_FILES_PER_ARCHIVE: "{{ send_max_files_per_archive }}"
|
|
DOWNLOAD_COUNTS: "{{ send_download_counts }}"
|
|
EXPIRE_TIMES_SECONDS: "{{ send_expire_times_seconds }}"
|
|
{% if send_storage_backend == "s3" %}
|
|
S3_BUCKET: "{{ send_s3_bucket }}"
|
|
S3_ENDPOINT: "{{ send_s3_endpoint }}"
|
|
S3_USE_PATH_STYLE_ENDPOINT: "{{ 'true' if send_s3_use_path_style else 'false' }}"
|
|
AWS_ACCESSKEYID: "{{ send_s3_access_key }}"
|
|
AWS_SECRETACCESSKEY: "{{ send_s3_secret_key }}"
|
|
AWS_REGION: "{{ send_s3_region }}"
|
|
{% else %}
|
|
FILE_DIR: "/uploads"
|
|
volumes:
|
|
- {{ send_docker_volume_dir }}/uploads:/uploads
|
|
{% endif %}
|
|
labels:
|
|
- traefik.enable=true
|
|
- traefik.docker.network={{ send_traefik_network }}
|
|
- traefik.http.routers.{{ send_service_name }}.rule={% for d in send_domains %}Host(`{{ d }}`){% if not loop.last %} || {% endif %}{% endfor +%}
|
|
- traefik.http.services.{{ send_service_name }}.loadbalancer.server.port={{ send_port }}
|
|
{% if send_use_ssl %}
|
|
- traefik.http.routers.{{ send_service_name }}.entrypoints=websecure
|
|
- traefik.http.routers.{{ send_service_name }}.tls=true
|
|
{% if traefik_cert_mode | default('selfsigned') == 'acme' %}
|
|
- traefik.http.routers.{{ send_service_name }}.tls.certresolver={{ traefik_ssl_cert_resolver | default('dns') }}
|
|
{% endif %}
|
|
{% else %}
|
|
- traefik.http.routers.{{ send_service_name }}.entrypoints=web
|
|
{% endif %}
|
|
|
|
{{ send_redis_service_name }}:
|
|
image: {{ send_redis_image }}
|
|
container_name: {{ send_redis_service_name }}
|
|
restart: unless-stopped
|
|
networks:
|
|
- {{ send_internal_network }}
|
|
volumes:
|
|
- {{ send_docker_volume_dir }}/redis:/data
|
|
|
|
networks:
|
|
{{ send_internal_network }}:
|
|
{{ send_traefik_network }}:
|
|
external: true
|