1

I want to have multiple instances of Craft, ideally running inside the same cPanel account root.

I note from the doc on Directory structure that there are separate config path variables that can be set for:

  • CRAFT_CONFIG_PATH
  • CRAFT_STORAGE_PATH
  • CRAFT_TEMPLATES_PATH
  • CRAFT_VENDOR_PATH

If these system assets for a given Craft instance are in a per instance child folder above web root, what are the implications for the location and variants of:

  • modules
  • .env
  • composer.json
  • composer.lock
  • craft

Should these all be duplicated per instance into the same child folder as well?

3

There are various ways to go about this. Here’s a few:

Option 1: Keep each site completely contained

If you are able to keep each installation in its own directory, each with its own web root, that would be ideal, since you could develop and deploy each site individually:

site-a/
  .env
  composer.json
  composer.lock
  craft
  config/...
  modules/...
  templates/...
  vendor/...
  web/...
site-b/
  .env
  composer.json
  composer.lock
  craft
  config/...
  modules/...
  templates/...
  vendor/...
  web/...

Option 2: Share the web root

If the sites must share the same web root, but you still want to generally think of them as separate installations, then you can at least keep each of the project’s non-web files together:

site-a/
  .env
  composer.json
  composer.lock
  craft
  config/...
  modules/...
  templates/...
  vendor/...
site-b/
  .env
  composer.json
  composer.lock
  craft
  config/...
  modules/...
  templates/...
  vendor/...
web/
  index.php <-- for site-a
  ...
  b/
    index.php <-- for site-b
    ...

Then the only constant you’ll need to worry about is CRAFT_BASE_PATH. For example with the above structure, here’s what those would look like:

web/index.php:

define('CRAFT_BASE_PATH', dirname(__DIR__) . '/site-a');

web/b/index.php:

define('CRAFT_BASE_PATH', dirname(__DIR__, 2) . '/site-b');

Option 3: Share the Composer and module files, too

If it makes sense to just have one shared set of Composer files (composer.json, composer.lock, and vendor/) and modules/ folder (they are inseparable since the module files get autoloaded by composer.json), you can use this structure:

composer.json
composer.lock
modules/
vendor/
site-a/
  .env
  craft
  config/...
  templates/...
site-b/
  .env
  craft
  config/...
  templates/...
web/
  index.php <-- for site-a
  ...
  b/
    index.php <-- for site-b
    ...

You’ll need to make the same changes to CRAFT_BASE_PATH as in option 2, as well as CRAFT_VENDOR_PATH (since vendor/ no longer lives alongside the site-specific files).

web/index.php:

define('CRAFT_BASE_PATH', dirname(__DIR__) . '/site-a');
define('CRAFT_VENDOR_PATH', dirname(__DIR__) . '/vendor');

web/b/index.php:

define('CRAFT_BASE_PATH', dirname(__DIR__, 2) . '/site-b');
define('CRAFT_VENDOR_PATH', dirname(__DIR__, 2) . '/vendor');

You’ll also need to update CRAFT_VENDOR_PATH within both of your craft executables, in this case (not CRAFT_BASE_PATH, though).

site-a/craft & site-b/craft:

define('CRAFT_VENDOR_PATH', dirname(__DIR__) . '/vendor');
1
  • Thanks Brandon. Very helpful. It’s helped me understand that Option 1, which I was already doing, is probably the best way to keep going. Mar 1 at 9:03
1

You could have multiple independent Craft CMS installs in separate directories, or have a single Craft instance but use mulit-site to have different domains pointed to a single Craft install.

https://craftcms.com/docs/3.x/sites.html

1
  • Thanks James. The multi-site option is not appropriate for my context. I’m going to get my head round Brandon’s reply. Mar 1 at 9:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.