From 331ff20272a899e32ff7b7c8630448c8e38a4b70 Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Fri, 25 Apr 2025 19:05:17 +0200 Subject: [PATCH] Finished EspoCRM implementation --- roles/docker-espocrm/Administration.md | 32 --------------- roles/docker-espocrm/Installation.md | 25 ----------- roles/docker-espocrm/README.md | 41 +++++++++++++++---- roles/docker-espocrm/Todo.md | 2 - roles/docker-espocrm/meta/main.yml | 2 +- roles/docker-espocrm/tasks/main.yml | 14 +++++++ .../templates/docker-compose.yml.j2 | 3 +- roles/docker-espocrm/templates/env.j2 | 13 ++++-- templates/vars/applications.yml.j2 | 6 +-- 9 files changed, 61 insertions(+), 77 deletions(-) delete mode 100644 roles/docker-espocrm/Administration.md delete mode 100644 roles/docker-espocrm/Installation.md delete mode 100644 roles/docker-espocrm/Todo.md diff --git a/roles/docker-espocrm/Administration.md b/roles/docker-espocrm/Administration.md deleted file mode 100644 index 2c3b92ca..00000000 --- a/roles/docker-espocrm/Administration.md +++ /dev/null @@ -1,32 +0,0 @@ -# Administration - -## 🗑️ Cleanup (Remove instance & volumes) -```bash -cd {{path_docker_compose_instances}}espocrm/ -docker compose down -# EspoCRM keeps all uploaded files in the *data* volume -docker volume rm espocrm_data espocrm_database -cd {{path_docker_compose_instances}} && rm -vR {{path_docker_compose_instances}}espocrm -``` - -## 🔍 Access EspoCRM container shell -```bash -docker compose exec -it web /bin/bash -``` - -## 🛠️ Database migrations (after image upgrade) -EspoCRM applies migrations automatically on start‑up. To run them manually: -```bash -docker compose exec -it web php command.php upgrade -``` - -## 🗄️ Backup database -```bash -# Dump the MySQL/MariaDB database -docker exec espocrm_database /usr/bin/mysqldump -u root -p$MYSQL_ROOT_PASSWORD espocrm > backup_$(date +%F).sql -``` - -## 🧹 Clear cache -```bash -docker compose exec web php command.php clear cache -``` \ No newline at end of file diff --git a/roles/docker-espocrm/Installation.md b/roles/docker-espocrm/Installation.md deleted file mode 100644 index bc8de8e3..00000000 --- a/roles/docker-espocrm/Installation.md +++ /dev/null @@ -1,25 +0,0 @@ -# ⚙️ Configuration & Setup - -## 🔧 Create credentials & pull image -```bash -# Pull the latest EspoCRM image -docker pull espocrm/espocrm:latest - -# If you need to pre‑create a config file, copy the default -# (the container will generate one automatically on first start) -``` - -## 🏗️ Initial deployment with Docker Compose -```bash -# Change into the instance directory created by the role -cd {{path_docker_compose_instances}}espocrm/ - -# Launch the stack -docker compose up -d -``` -The first start can take a minute while EspoCRM initialises the database schema. - -## 🔐 LDAP & OIDC authentication -Both mechanisms are supported out of the box: -- **LDAP:** Configure under *Administration → Authentication → LDAP* after the first login. -- **OIDC:** Configure under *Administration → Authentication → OpenID Connect* and paste the Issuer URL, Client ID and Client Secret from your IdP (Keycloak, Authentik, Entra ID, …). \ No newline at end of file diff --git a/roles/docker-espocrm/README.md b/roles/docker-espocrm/README.md index e29179bf..1d9a001d 100644 --- a/roles/docker-espocrm/README.md +++ b/roles/docker-espocrm/README.md @@ -2,15 +2,38 @@ ## Description -EspoCRM is a lightweight, open‑source Customer Relationship Management platform that helps you manage leads, accounts, opportunities and post‑sale support in a single, web‑based interface. -This Ansible role deploys EspoCRM with Docker, mirroring the structure of the Mastodon role for a consistent operations workflow. +Enhance your sales and service processes with EspoCRM, an open-source CRM featuring workflow automation, LDAP/OIDC single sign-on, and a sleek, lightweight UI! 🚀💼 ## Overview -- **Sales Pipeline & Activities Stream** – track every interaction and schedule follow‑ups. -- **Workflow & BPM** – automate routine tasks and notifications. -- **Extensible Authentication** – native LDAP and OpenID Connect (OIDC) login support. -- **Containerised Architecture** – separate services for the web application, cron jobs and an upstream MySQL/MariaDB database. -For detailed instructions see: -- [Installation.md](./Installation.md) -- [Administration.md](./Administration.md) +This Ansible role deploys EspoCRM using Docker. It handles: + +- MariaDB database provisioning via the `docker-central-database` role +- Nginx domain setup with WebSocket and reverse-proxy configuration +- Environment variable management through Jinja2 templates +- Docker Compose orchestration for **web**, **daemon**, and **websocket** services +- Automatic OIDC scope configuration within the EspoCRM container + +With this role, you'll have a production-ready CRM environment that's secure, scalable, and real-time. + +## Features + +- **Workflow Automation:** Create and manage automated CRM processes with ease 🛠️ +- **LDAP/OIDC SSO:** Integrate with corporate identity providers for seamless login 🔐 +- **WebSocket Notifications:** Real-time updates via ZeroMQ and WebSockets 🌐 +- **Config via Templates:** Fully customizable `.env` and `docker-compose.yml` with Jinja2 ⚙️ +- **Health Checks & Logging:** Monitor service health and logs with built-in checks and journald 📈 +- **Modular Role Composition:** Leverages central roles for database and Nginx, ensuring consistency across deployments 🔄 + +## Additional Resources + +- [EspoCRM Official Website](https://www.espocrm.com/) 🌍 +- [EspoCRM Documentation](https://docs.espocrm.com/) 📖 +- [CyMaIS Project Repository](https://github.com/kevinveenbirkenbach/cymais) 🔗 + +## Credits + +Developed and maintained by **Kevin Veen-Birkenbach**. +Consulting & Coaching Solutions: [veen.world](https://www.veen.world) 🌟 +Part of the [CyMaIS Project](https://github.com/kevinveenbirkenbach/cymais) 📂 +License: [CyMaIS NonCommercial License (CNCL)](https://s.veen.world/cncl) ⚖️ diff --git a/roles/docker-espocrm/Todo.md b/roles/docker-espocrm/Todo.md deleted file mode 100644 index 66736ae0..00000000 --- a/roles/docker-espocrm/Todo.md +++ /dev/null @@ -1,2 +0,0 @@ -# Todos -- Finish draft implementation \ No newline at end of file diff --git a/roles/docker-espocrm/meta/main.yml b/roles/docker-espocrm/meta/main.yml index 102e775e..9483f3a3 100644 --- a/roles/docker-espocrm/meta/main.yml +++ b/roles/docker-espocrm/meta/main.yml @@ -18,5 +18,5 @@ galaxy_info: issue_tracker_url: "https://s.veen.world/cymaisissues" documentation: "https://s.veen.world/cymais" logo: - class: "fa-solid fa-briefcase" + class: "fa-solid fa-phone" dependencies: [] \ No newline at end of file diff --git a/roles/docker-espocrm/tasks/main.yml b/roles/docker-espocrm/tasks/main.yml index 12932e50..ccc3e99f 100644 --- a/roles/docker-espocrm/tasks/main.yml +++ b/roles/docker-espocrm/tasks/main.yml @@ -16,3 +16,17 @@ - name: "copy docker-compose.yml and env file" include_tasks: copy-docker-compose-and-env.yml + +- name: Set OIDC scopes in EspoCRM config (inside web container) + ansible.builtin.shell: | + docker compose exec -T web php -r ' + require "/var/www/html/bootstrap.php"; + $writer = (new \Espo\Core\Application()) + ->getContainer() + ->get("injectableFactory") + ->create("\Espo\Core\Utils\Config\ConfigWriter"); + $writer->set("oidcScopes", ["openid", "profile", "email"]); + $writer->save(); + ' + args: + chdir: "{{ docker_compose.directories.instance }}" \ No newline at end of file diff --git a/roles/docker-espocrm/templates/docker-compose.yml.j2 b/roles/docker-espocrm/templates/docker-compose.yml.j2 index 2378aa81..c90c9a4b 100644 --- a/roles/docker-espocrm/templates/docker-compose.yml.j2 +++ b/roles/docker-espocrm/templates/docker-compose.yml.j2 @@ -5,7 +5,6 @@ services: web: image: espocrm/espocrm:{{ applications.espocrm.version }} {% include 'roles/docker-compose/templates/services/base.yml.j2' %} - command: "php-fpm" healthcheck: test: ["CMD", "curl", "-f", "http://localhost/"] ports: @@ -41,7 +40,7 @@ services: volumes: - data:/var/www/html ports: - - "{{ ports.localhost.websocket[application_id] | default('127.0.0.1:8081') }}:8080" + - "127.0.0.1:{{ ports.localhost.websocket[application_id] }}:8080" {% include 'templates/docker/compose/volumes.yml.j2' %} data: diff --git a/roles/docker-espocrm/templates/env.j2 b/roles/docker-espocrm/templates/env.j2 index 3827e584..70d8dd2a 100644 --- a/roles/docker-espocrm/templates/env.j2 +++ b/roles/docker-espocrm/templates/env.j2 @@ -35,8 +35,8 @@ ESPOCRM_CONFIG_TIME_ZONE={{ HOST_TIMEZONE }} # ESPOCRM_CONFIG_WEEK_START: 0 = Sunday, 1 = Monday ESPOCRM_CONFIG_WEEK_START=1 ESPOCRM_CONFIG_DEFAULT_CURRENCY={{ HOST_CURRENCY }} -ESPOCRM_CONFIG_THOUSAND_SEPARATOR={{ HOST_THOUSAND_SEPARATOR }} -ESPOCRM_CONFIG_DECIMAL_MARK={{HOST_DECIMAL_MARK}} +#ESPOCRM_CONFIG_THOUSAND_SEPARATOR={{ HOST_THOUSAND_SEPARATOR }} +#ESPOCRM_CONFIG_DECIMAL_MARK={{HOST_DECIMAL_MARK}} # ------------------------------------------------ # Logger @@ -82,6 +82,7 @@ ESPOCRM_CONFIG_LDAP_USER_LOGIN_FILTER=(sAMAccountName=%USERNAME%) # ------------------------------------------------ # OpenID Connect settings # ------------------------------------------------ +ESPOCRM_CONFIG_OIDC_ALLOW_ADMIN_USER=true ESPOCRM_CONFIG_AUTHENTICATION_METHOD=Oidc ESPOCRM_CONFIG_OIDC_FALLBACK=false # set true if you want LDAP as fallback @@ -94,5 +95,11 @@ ESPOCRM_CONFIG_OIDC_USER_INFO_ENDPOINT={{ oidc.client.user_info_url }} ESPOCRM_CONFIG_OIDC_JWKS_ENDPOINT={{ oidc.client.certs }} ESPOCRM_CONFIG_OIDC_AUTHORIZATION_REDIRECT_URI=https://{{ domains[application_id] }}/oidc/callback -ESPOCRM_CONFIG_OIDC_SCOPES=openid,profile,email +#ESPOCRM_CONFIG_OIDC_SCOPES=openid,profile,email # Defined in main.yml + +ESPOCRM_CONFIG_OIDC_CREATE_USER=true +ESPOCRM_CONFIG_OIDC_SYNC=true +ESPOCRM_CONFIG_OIDC_USERNAME_CLAIM={{oidc.attributes.username}} +# ESPOCRM_CONFIG_OIDC_SYNC_TEAMS=true # (optional) Gruppen-→-Team-Mapping +# ESPOCRM_CONFIG_OIDC_GROUP_CLAIM=group {% endif %} diff --git a/templates/vars/applications.yml.j2 b/templates/vars/applications.yml.j2 index 84974c5e..94b503a3 100644 --- a/templates/vars/applications.yml.j2 +++ b/templates/vars/applications.yml.j2 @@ -128,7 +128,7 @@ defaults_applications: ## EspoCRM espocrm: - version: "fpm-alpine" + version: "latest" users: administrator: username: "{{ users.administrator.username }}" @@ -142,9 +142,9 @@ defaults_applications: {% endraw %}{{ features.render_features({ 'matomo': true, - 'css': true, + 'css': false, 'iframe': false, - 'ldap': true, + 'ldap': false, 'oidc': true, 'database': true }) }}{% raw %}