mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-12-02 15:39:57 +00:00
Added suitecrm draft - See https://chatgpt.com/share/69274924-9dec-800f-8653-345aa2c25664
This commit is contained in:
@@ -118,6 +118,8 @@ defaults_networks:
|
|||||||
subnet: 192.168.104.80/28
|
subnet: 192.168.104.80/28
|
||||||
web-svc-onlyoffice:
|
web-svc-onlyoffice:
|
||||||
subnet: 192.168.104.96/28
|
subnet: 192.168.104.96/28
|
||||||
|
web-app-suitecrm:
|
||||||
|
subnet: 192.168.104.112/28
|
||||||
|
|
||||||
# /24 Networks / 254 Usable Clients
|
# /24 Networks / 254 Usable Clients
|
||||||
web-app-bigbluebutton:
|
web-app-bigbluebutton:
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ ports:
|
|||||||
web-app-mini-qr: 8059
|
web-app-mini-qr: 8059
|
||||||
web-app-shopware: 8060
|
web-app-shopware: 8060
|
||||||
web-svc-onlyoffice: 8061
|
web-svc-onlyoffice: 8061
|
||||||
|
web-app-suitecrm: 8062
|
||||||
web-app-bigbluebutton: 48087 # This port is predefined by bbb. @todo Try to change this to a 8XXX port
|
web-app-bigbluebutton: 48087 # This port is predefined by bbb. @todo Try to change this to a 8XXX port
|
||||||
public:
|
public:
|
||||||
# The following ports should be changed to 22 on the subdomain via stream mapping
|
# The following ports should be changed to 22 on the subdomain via stream mapping
|
||||||
|
|||||||
48
roles/web-app-suitecrm/README.md
Normal file
48
roles/web-app-suitecrm/README.md
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# SuiteCRM
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Manage your customer relationships with SuiteCRM, a powerful open-source CRM platform extending SugarCRM with advanced modules, workflows, and integrations. This role integrates SuiteCRM into the Infinito.Nexus ecosystem with centralized database, mail, LDAP and OIDC-ready SSO support. 🚀💼
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This Ansible role deploys SuiteCRM using Docker and the Infinito.Nexus shared stack. It handles:
|
||||||
|
|
||||||
|
- MariaDB database provisioning via the `sys-svc-rdbms` role
|
||||||
|
- Nginx domain and reverse-proxy configuration
|
||||||
|
- Environment variable management through Jinja2 templates
|
||||||
|
- Docker Compose orchestration for the **SuiteCRM** application container
|
||||||
|
- Native **LDAP** authentication via Symfony’s LDAP configuration
|
||||||
|
- OIDC-ready wiring for integration with Keycloak or other OIDC providers (via reverse proxy or plugin)
|
||||||
|
|
||||||
|
With this role, you get a production-ready CRM environment that plugs into your existing IAM stack.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Sales & Service CRM:** Accounts, Contacts, Leads, Opportunities, Cases, Campaigns and more 📊
|
||||||
|
- **Workflow Engine:** Automate business processes and notifications 🛠️
|
||||||
|
- **LDAP Authentication:** Centralize user authentication against OpenLDAP 🔐
|
||||||
|
- **OIDC-Ready SSO:** Preconfigured OIDC environment variables for use with plugins or an OIDC reverse proxy 🌐
|
||||||
|
- **Config via Templates:** Fully customizable `.env` and `docker-compose.yml` rendered via Jinja2 ⚙️
|
||||||
|
- **Health Checks & Logging:** Integrates with Infinito.Nexus health checking and journald logging 📈
|
||||||
|
- **Modular Role Composition:** Uses shared roles for DB, proxy and monitoring to keep your stack consistent 🔄
|
||||||
|
|
||||||
|
## Further Resources
|
||||||
|
|
||||||
|
- [SuiteCRM Official Website](https://suitecrm.com/) 🌍
|
||||||
|
- [SuiteCRM Documentation](https://docs.suitecrm.com/) 📖
|
||||||
|
- [Infinito.Nexus Project Repository](https://s.infinito.nexus/code) 🔗
|
||||||
|
|
||||||
|
## OIDC & LDAP Notes
|
||||||
|
|
||||||
|
- **LDAP** is configured using Symfony’s environment variables (`AUTH_TYPE=ldap`, `LDAP_*`) so SuiteCRM 8+ can authenticate directly against your OpenLDAP service.
|
||||||
|
- **OIDC** is provided at the platform level (e.g. Keycloak + oauth2-proxy or a SuiteCRM OIDC plugin).
|
||||||
|
This role exposes OIDC client, issuer and endpoint settings as environment variables, so plugins or
|
||||||
|
sidecar components can consume them without duplicating configuration.
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
Developed and maintained by **Kevin Veen-Birkenbach**.
|
||||||
|
Consulting & Coaching Solutions: [veen.world](https://www.veen.world) 🌟
|
||||||
|
Part of the [Infinito.Nexus Project](https://s.infinito.nexus/code) 📂
|
||||||
|
License: [Infinito.Nexus NonCommercial License](https://s.infinito.nexus/license) ⚖️
|
||||||
40
roles/web-app-suitecrm/config/main.yml
Normal file
40
roles/web-app-suitecrm/config/main.yml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
features:
|
||||||
|
matomo: true
|
||||||
|
css: true
|
||||||
|
desktop: true
|
||||||
|
ldap: true
|
||||||
|
oidc: true # OIDC via Keycloak + reverse proxy / plugin
|
||||||
|
central_database: true
|
||||||
|
logout: true
|
||||||
|
|
||||||
|
server:
|
||||||
|
csp:
|
||||||
|
flags: {}
|
||||||
|
whitelist:
|
||||||
|
# Allow data URIs for icons etc.
|
||||||
|
connect-src:
|
||||||
|
- "data:"
|
||||||
|
domains:
|
||||||
|
aliases: []
|
||||||
|
canonical:
|
||||||
|
- suite.crm.{{ PRIMARY_DOMAIN }}
|
||||||
|
|
||||||
|
email:
|
||||||
|
from_name: "Customer Relationship Management (SuiteCRM, {{ PRIMARY_DOMAIN }})"
|
||||||
|
|
||||||
|
docker:
|
||||||
|
services:
|
||||||
|
database:
|
||||||
|
enabled: true
|
||||||
|
suitecrm:
|
||||||
|
image: "bitnami/suitecrm"
|
||||||
|
version: "8"
|
||||||
|
name: "suitecrm"
|
||||||
|
cpus: 1.5
|
||||||
|
mem_reservation: 1.2g
|
||||||
|
mem_limit: 2g
|
||||||
|
pids_limit: 768
|
||||||
|
volumes:
|
||||||
|
data: suitecrm_data
|
||||||
|
|
||||||
|
maintenance_mode: false
|
||||||
23
roles/web-app-suitecrm/meta/main.yml
Normal file
23
roles/web-app-suitecrm/meta/main.yml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
galaxy_info:
|
||||||
|
author: "Kevin Veen-Birkenbach"
|
||||||
|
description: >
|
||||||
|
Power your sales and service processes with SuiteCRM.
|
||||||
|
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:
|
||||||
|
- suitecrm
|
||||||
|
- crm
|
||||||
|
- sales
|
||||||
|
repository: "https://s.infinito.nexus/code"
|
||||||
|
issue_tracker_url: "https://s.infinito.nexus/issues"
|
||||||
|
documentation: "https://docs.infinito.nexus"
|
||||||
|
logo:
|
||||||
|
class: "fa-solid fa-phone"
|
||||||
|
run_after:
|
||||||
|
- web-app-keycloak
|
||||||
|
- web-app-mailu
|
||||||
|
- web-app-mastodon
|
||||||
0
roles/web-app-suitecrm/schema/main.yml
Normal file
0
roles/web-app-suitecrm/schema/main.yml
Normal file
6
roles/web-app-suitecrm/tasks/main.yml
Normal file
6
roles/web-app-suitecrm/tasks/main.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
- name: "Load docker, db and proxy for {{ application_id }}"
|
||||||
|
include_role:
|
||||||
|
name: sys-stk-full-stateful
|
||||||
|
vars:
|
||||||
|
docker_compose_flush_handlers: true
|
||||||
1
roles/web-app-suitecrm/templates/Dockerfile.j2
Normal file
1
roles/web-app-suitecrm/templates/Dockerfile.j2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
FROM "{{ SUITECRM_IMAGE }}:{{ SUITECRM_VERSION }}"
|
||||||
24
roles/web-app-suitecrm/templates/docker-compose.yml.j2
Normal file
24
roles/web-app-suitecrm/templates/docker-compose.yml.j2
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{% include 'roles/docker-compose/templates/base.yml.j2' %}
|
||||||
|
|
||||||
|
{% set service_name = SUITECRM_SERVICE %}
|
||||||
|
{{ service_name }}:
|
||||||
|
{{ lookup('template', 'roles/docker-container/templates/build.yml.j2') | indent(4) }}
|
||||||
|
container_name: {{ SUITECRM_CONTAINER }}
|
||||||
|
image: "{{ SUITECRM_CUSTOM_IMAGE }}"
|
||||||
|
init: true
|
||||||
|
stop_signal: SIGTERM
|
||||||
|
stop_grace_period: 30s
|
||||||
|
{% include 'roles/docker-container/templates/base.yml.j2' %}
|
||||||
|
{% 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_excl.yml.j2' %}
|
||||||
|
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
||||||
|
volumes:
|
||||||
|
- data:/bitnami/suitecrm
|
||||||
|
|
||||||
|
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
|
||||||
|
data:
|
||||||
|
name: {{ SUITECRM_DATA_VOLUME }}
|
||||||
|
|
||||||
|
{% include 'roles/docker-compose/templates/networks.yml.j2' %}
|
||||||
83
roles/web-app-suitecrm/templates/env.j2
Normal file
83
roles/web-app-suitecrm/templates/env.j2
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#############################################
|
||||||
|
# SuiteCRM Docker Environment (.env) – ENGLISH
|
||||||
|
# Based on bitnami/suitecrm environment variables
|
||||||
|
#############################################
|
||||||
|
|
||||||
|
# ------------------------------------------------
|
||||||
|
# Database connection (Bitnami-style)
|
||||||
|
# ------------------------------------------------
|
||||||
|
MARIADB_HOST={{ database_host }}
|
||||||
|
MARIADB_PORT={{ database_port }}
|
||||||
|
MARIADB_USER={{ database_username }}
|
||||||
|
MARIADB_PASSWORD={{ database_password }}
|
||||||
|
|
||||||
|
# ------------------------------------------------
|
||||||
|
# Initial admin account
|
||||||
|
# ------------------------------------------------
|
||||||
|
SUITECRM_USERNAME={{ applications | get_app_conf(application_id, 'users.administrator.username') }}
|
||||||
|
SUITECRM_PASSWORD={{ applications | get_app_conf(application_id, 'credentials.administrator_password') }}
|
||||||
|
SUITECRM_EMAIL={{ users['contact'].email }}
|
||||||
|
SUITECRM_HOST={{ domains | get_domain(application_id) }}
|
||||||
|
|
||||||
|
# ------------------------------------------------
|
||||||
|
# Logger / basic options
|
||||||
|
# (SuiteCRM/Bitnami will log to stdout/stderr by default)
|
||||||
|
# ------------------------------------------------
|
||||||
|
|
||||||
|
# ------------------------------------------------
|
||||||
|
# System SMTP settings
|
||||||
|
# ------------------------------------------------
|
||||||
|
SUITECRM_SMTP_HOST={{ SYSTEM_EMAIL.HOST }}
|
||||||
|
SUITECRM_SMTP_PORT={{ SYSTEM_EMAIL.PORT }}
|
||||||
|
SUITECRM_SMTP_USER={{ users['contact'].email }}
|
||||||
|
SUITECRM_SMTP_PASSWORD={{ users['contact'].mailu_token }}
|
||||||
|
SUITECRM_SMTP_PROTOCOL={{ "TLS" if SYSTEM_EMAIL.START_TLS else "SSL" }}
|
||||||
|
|
||||||
|
# ------------------------------------------------
|
||||||
|
# LDAP settings (native SuiteCRM 8+ via Symfony)
|
||||||
|
# Applied only if the feature flag is true
|
||||||
|
# ------------------------------------------------
|
||||||
|
{% if applications | get_app_conf(application_id, 'features.ldap') %}
|
||||||
|
AUTH_TYPE=ldap
|
||||||
|
|
||||||
|
# Base LDAP connection
|
||||||
|
LDAP_HOST={{ LDAP.SERVER.DOMAIN }}
|
||||||
|
LDAP_PORT={{ LDAP.SERVER.PORT }}
|
||||||
|
# Allowed values: none, tls, ssl (see SuiteCRM docs)
|
||||||
|
LDAP_ENCRYPTION={{ LDAP.SERVER.SECURITY | lower if LDAP.SERVER.SECURITY else "none" }}
|
||||||
|
LDAP_PROTOCOL_VERSION=3
|
||||||
|
LDAP_REFERRALS=false
|
||||||
|
|
||||||
|
# DN / search configuration
|
||||||
|
LDAP_DN_STRING='{{ LDAP.USER.ATTRIBUTES.ID }}={username},{{ LDAP.DN.OU.USERS }}'
|
||||||
|
LDAP_QUERY_STRING=''
|
||||||
|
LDAP_SEARCH_DN={{ LDAP.DN.ADMINISTRATOR.DATA }}
|
||||||
|
LDAP_SEARCH_PASSWORD={{ LDAP.BIND_CREDENTIAL }}
|
||||||
|
|
||||||
|
# Auto-create SuiteCRM users from LDAP
|
||||||
|
LDAP_AUTO_CREATE=enabled
|
||||||
|
LDAP_PROVIDER_BASE_DN={{ LDAP.DN.OU.USERS }}
|
||||||
|
LDAP_PROVIDER_SEARCH_DN={{ LDAP.DN.ADMINISTRATOR.DATA }}
|
||||||
|
LDAP_PROVIDER_SEARCH_PASSWORD={{ LDAP.BIND_CREDENTIAL }}
|
||||||
|
LDAP_PROVIDER_DEFAULT_ROLES=ROLE_USER
|
||||||
|
LDAP_PROVIDER_UID_KEY={{ LDAP.USER.ATTRIBUTES.ID }}
|
||||||
|
LDAP_PROVIDER_FILTER='({{ LDAP.USER.ATTRIBUTES.ID }}={username})'
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# ------------------------------------------------
|
||||||
|
# OpenID Connect settings (platform / plugin level)
|
||||||
|
# Applied only if the feature flag is true
|
||||||
|
# ------------------------------------------------
|
||||||
|
{% if SUITECRM_OIDC_ENABLED | bool %}
|
||||||
|
SUITECRM_OIDC_CLIENT_ID={{ OIDC.CLIENT.ID }}
|
||||||
|
SUITECRM_OIDC_CLIENT_SECRET={{ OIDC.CLIENT.SECRET }}
|
||||||
|
|
||||||
|
SUITECRM_OIDC_ISSUER_URL={{ OIDC.CLIENT.ISSUER_URL }}
|
||||||
|
SUITECRM_OIDC_AUTHORIZATION_ENDPOINT={{ OIDC.CLIENT.AUTHORIZE_URL }}
|
||||||
|
SUITECRM_OIDC_TOKEN_ENDPOINT={{ OIDC.CLIENT.TOKEN_URL }}
|
||||||
|
SUITECRM_OIDC_USER_INFO_ENDPOINT={{ OIDC.CLIENT.USER_INFO_URL }}
|
||||||
|
SUITECRM_OIDC_JWKS_ENDPOINT={{ OIDC.CLIENT.CERTS }}
|
||||||
|
|
||||||
|
SUITECRM_OIDC_REDIRECT_URI={{ SUITECRM_URL }}/oidc/callback
|
||||||
|
SUITECRM_OIDC_SCOPES=openid,profile,email
|
||||||
|
{% endif %}
|
||||||
7
roles/web-app-suitecrm/users/main.yml
Normal file
7
roles/web-app-suitecrm/users/main.yml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
users:
|
||||||
|
administrator:
|
||||||
|
username: "administrator"
|
||||||
|
contact:
|
||||||
|
username: "contact"
|
||||||
|
roles:
|
||||||
|
- mail-bot
|
||||||
24
roles/web-app-suitecrm/vars/main.yml
Normal file
24
roles/web-app-suitecrm/vars/main.yml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# General
|
||||||
|
application_id: "web-app-suitecrm"
|
||||||
|
entity_name: "{{ application_id | get_entity_name }}"
|
||||||
|
|
||||||
|
# Database
|
||||||
|
database_type: "mariadb"
|
||||||
|
|
||||||
|
# Webserver
|
||||||
|
client_max_body_size: "100m"
|
||||||
|
vhost_flavour: "generic"
|
||||||
|
|
||||||
|
# SuiteCRM container settings
|
||||||
|
SUITECRM_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.' ~ entity_name ~ '.version') }}"
|
||||||
|
SUITECRM_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.' ~ entity_name ~ '.image') }}"
|
||||||
|
SUITECRM_CUSTOM_IMAGE: "custom_suitecrm"
|
||||||
|
SUITECRM_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.' ~ entity_name ~ '.name') }}"
|
||||||
|
SUITECRM_SERVICE: "{{ entity_name }}"
|
||||||
|
|
||||||
|
# Volumes
|
||||||
|
SUITECRM_DATA_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.data') }}"
|
||||||
|
|
||||||
|
# URLs & features
|
||||||
|
SUITECRM_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
|
||||||
|
SUITECRM_OIDC_ENABLED: "{{ applications | get_app_conf(application_id, 'features.oidc') }}"
|
||||||
Reference in New Issue
Block a user