Saturday, July 21, 2018 - 08:19
Written by

Few months back I joined the civiCRM developers community as a Google Summer of Code intern with the objective of improving in my coding skills by making a significant contribution to open source software. It's gone quite well so far. With the help of my mentor and other CiviCRM community members I have successfully completed phase 1 and 2 of the program.

This blog post is a summary of what I have been able to achieve from the time coding began till July 09, 2018.

Docker, like many other cloud / container architectures, expects applications to work in a certain way. The Twelve Factor App does a good job of outlining what these are. CiviCRM violates a few of these principles (a simple example is that we hardcode the full URL across the app) and although it doesn't prevent us from getting it up and running, it does mean that in certain places we are not being particularly docker like or cloud friendly, and are preventing ourselves from making the most of the platform. On the one hand, we shouldn't get too religious about the one true Docker way. On the other hand, fixing these will help us leverage the power of Docker, and will help improve the architecture of CiviCRM more generally.

Here's a quick run down of how I approached and fixed some the issues documented on GitLab for the Cloud Native project :

A. Determine CiviCRM host and port in Docker-friendly way - via an environment variable (Reference Issues: #12 and #6).

The base URL in civiCRM is hardcoded in the civicrm.settings.php which is not the recommended approach for developing web applications according to The Twelve Factor App. In a sense, getting rid of th hard coded URL across the app - 'how should we define the host and port' was the starting point for addressing the issue. First tried a couple of approaches as solutions for this:

  1. Making CIVICRM_UF_BASEURL becomes dynamic to the hosting computer's current IP or domain. Therefore no need to change the site url and links from http://localhost:8080 to the new server/router IP http://192.168.x.xx:8080 inorder for images and css to load correctly or change the ip address in the site if the computer changes. This also ensured that the database and any theme/extension files are free from absolute urls generate by civicrm. Causing civicrm to use root-relative urls for everything. Makes site migrations to other domains far easier. However this approach wha rolled out by my mentor.

  2. Defining canonical URL - CIVICRM_UF_BASEURL by an environment variable. In this sense all we really needed for Docker is a way to define the host and port via an environment variable. To achieve this we have updated civicrm.settings.php.template with a getenv() for the canonical URL. Tailoring this recommendation in light of some of the conversations on the issue thread on GitLab, in the civicrm.settings.php.template, the calculation for CIVICRM_UF_BASEURL used a fallback process:

    • Use a concrete value from the settings file. (This value is seeded during installation -- ie %%baseURL%%.)
    • If an environment variable specifies CIVICRM_UF_BASEURL, use that
B. Move the cache for CRM_Extension_Browser out of the filesystem and use a SqlGroup instead(Reference Issue: #2 and #17).

The current code in CRM_Extension_Browser is coded specifically for an adhoc, file-based caching logic. The recommendation standard is basically to change the backing/storage from a JSON file to the civicrm_cachetable (at least, for the typical usage). In an attempt to address this issue, we added an extension_browser group, then created a default instance that returns CRM_Extension_Browser. And reworked this to store cache in civicrm_cache.

C. Soften messages for read-only extensionsDir(Reference Issue: #2 and #18).

Improve messaging when someone has a different policy for managing extensionsDir.This is continuation of this PR. Most of the messaging update has already been done. There is only one message ("Read-Only Extensions"). It still encourages web-writable policy, but it lowers the severity and presents it a choice ("if you want X, do Y"). Probably, changing the warning into a notice was the only thing to update:- a warning implies something is wrong, while a notice says it's merely out of the ordinary.

I will be updating this writeup in the coming weeks with the steps for testing and reviewing the changes.

Filed under