There are several things in play at different levels with regard to the CiviCRM extensions directory location. The concepts to be aware of are:
- CiviCRM shipping codebase
- Drupal multisite
- Drupal's files directory
CiviCRM bundled extensions
As @Demerit's answer states, sites/<sitename>/modules/civicrm/ext
contains the extensions which ship with CiviCRM core. Don't put custom / additional extensions here; they may get deleted or overwritten on upgrade of the CiviCRM codebase.
(Would be good to add a link here to which extensions are bundled with core? This list will vary over time but presumably there's a core-extensions.json
or something like that in the build process. IDK.)
Drupal multisite directory
sites/default
sites/all
sites/example.org
This level of the structure relates to Drupal's multisite mapping. Drupal will read modules, themes, etc from two of these: whichever best matches the current site, and sites/all
. CiviCRM has a (non-Drupal) concept of multisite, but doesn't care about this level of the structure AFAIK. Your Drupal site developers likely do so if you have sites/all/civicrm
and sites/example.org/civicrm
you might infer that the latter is applied only to the example.org sites, but you'd need to check CiviCRM configuration to be certain.
Above and below, the active multisite directory and the shared directory (default
, example.org
etc and all
also) will be referred to as <sitename>
.
Drupal files directory
Drupal's sites/<sitename>/files
directory is configured to be writable to the PHP application (and it's recommended to configure the webserver to prevent direct execution of PHP code in that folder). See Drupal public file directory documentation for more.
Many developers resist having a web application's files writable to the webserver - preventing a web application modifying its own code is a defense against attacks which persist over time by introducing malicious code to files which will be executed by the application later. This is what KarinG's answer is referring to. Others will prefer the convenience of allowing applications to self-manage and therefore self-update.
CiviCRM's default placement of extensions in sites/<sitename>/files/civicrm/extensions
reflects the latter position, as CiviCRM can then download and run extensions from within that directory.
Developers who prefer to manage their codebase through tools such as Git may prefer to use the former model and relocate the extensions directory to sites/<sitename>/civicrm/extensions
, sites/<sitename>/civicrm-ext
etc. Since this isn't a Drupal practice there's no established standard for the structure.
CiviCRM ain't Drupal
It's worth noting that CiviCRM doesn't require you to keep extensions in the webroot at all, unless an extension requires direct access (probably not a good sign?). So you could merrily set the extensions directory to /tmp/whatever
and CiviCRM would function quite fine. Only convention, if you subscribe to it, dictates that the extensions might live alongside Drupal modules, themes etc.
~/extensions
? Can you give an example using a site's docroot? & when you say "common practice" - how did you come by that understanding?/var/www/joe-demo/htdocs/sites/all/civicrm-custom/extensions
. By common practice - I know of at least two Civi partner shops that seem to follow the practice. So OK maybe it's not 'common'. Updating.~/ext
do you mean the ext dir that's in the tarball download that includes extensions shipped directly with core like IATS? If you put new ones in there they're likely to get wiped during upgrade, so it's common to put them somewhere outside the civi folder./ext
directory. So the answer is "[new extensions] are likely to get wiped during [an] upgrade, so it's common to put them somewhere outside the civi folder." Cool. Want to add that as an Answer and I'll accept it? And is that anywhere in the docs and I have just not found it?