For a customer we should do a bunch of sites build with Drupal. Multisite is not possible because of different hosting solutions.

Would creating a custom distribution work out for that case? Is it possible to make a "private" distribution not listed on Drupal.org?

  • Sounds more like a Composer-based multi-site. I guess private distros are not possible on drupal.org.
    – leymannx
    Feb 11, 2019 at 11:20
  • How it will work with composer-multisites when each site will be deployed individually? And how with updating them?
    – Max
    Feb 11, 2019 at 11:35
  • Ah OK, I overread that, different hosting solutions. Still, I'd go for Composer and a version-managed custom profile. Why do you want a distribution?
    – leymannx
    Feb 11, 2019 at 11:46
  • My hope was a easier update and change management.
    – Max
    Feb 11, 2019 at 11:49

3 Answers 3


On drupal.org, a distribution is a single download containing Drupal core, contributed modules, themes, and pre-defined configuration. You could create a distribution locally, using the same tools used on drupal.org to create a distribution, but that would involve creating a drupal-org.make file using drush make, which is a command removed from Drush.

Instead, as Drush itself suggests, you should use Composer. Create a composer.json file, locally, and add all the dependencies (including modules) you need with composer require. If then you need, for example, to create specific content types, roles, taxonomy terms, or other entities, you could create an installation profile, as described in How to Write a Drupal 8 Installation Profile. Using an installation profile doesn't work for already created sites, but for sites you still have to create, a custom installation profile helps in building a site.

As example of what an installation profile can do, see the content of the core/profiles/standard directory, in particular the config directory, which contains the configuration files necessary to create the default entities you normally use on the default Drupal installation. The install/node.type.page.yml file is a configuration file that defines a node content type. (The filename is important for Drupal to understand it's a node content type.)

langcode: en
status: true
dependencies: {  }
name: 'Basic page'
type: page
description: 'Use <em>basic pages</em> for your static content, such as an ''About us'' page.'
help: ''
new_revision: true
preview_mode: 1
display_submitted: false

An installation profile can have dependencies and a list of core modules that needs to be installed but that aren't dependencies of the profile (see the standard.info.yml file), implement hook_install() (see the standard.install file) and other hooks a module can implements, including the one to alter the site configuration form shown during the installation of Drupal (see the standard.profile file).

function standard_install() {
  // Set front page to "node".
  \Drupal::configFactory()->getEditable('system.site')->set('page.front', '/node')->save(TRUE);

  // Allow visitor account creation with administrative approval.
  $user_settings = \Drupal::configFactory()->getEditable('user.settings');
  $user_settings->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save(TRUE);

  // Enable default permissions for system roles.
  user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, ['access comments']);
  user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, ['access comments', 'post comments', 'skip comment approval']);

  // Assign user 1 the "administrator" role.
  $user = User::load(1);
  $user->roles[] = 'administrator';

  // We install some menu links, so we have to rebuild the router, to ensure the
  // menu links are valid.

  // Enable the Contact link in the footer menu.
  /** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */
  $menu_link_manager = \Drupal::service('plugin.manager.menu.link');
  $menu_link_manager->updateDefinition('contact.site_page', ['enabled' => TRUE]);

  user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, ['access site-wide contact form']);
  user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, ['access site-wide contact form']);

  // Allow authenticated users to use shortcuts.
  user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, ['access shortcuts']);

  // Populate the default shortcut set.
  $shortcut = Shortcut::create([
    'shortcut_set' => 'default',
    'title' => t('Add content'),
    'weight' => -20,
    'link' => ['uri' => 'internal:/node/add'],

  $shortcut = Shortcut::create([
    'shortcut_set' => 'default',
    'title' => t('All content'),
    'weight' => -19,
    'link' => ['uri' => 'internal:/admin/content'],

  // Allow all users to use search.
  user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, ['search content']);
  user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, ['search content']);

  // Enable the admin theme.
  \Drupal::configFactory()->getEditable('node.settings')->set('use_admin_theme', TRUE)->save(TRUE);

Installation profiles cannot be changed once Drupal is installed. If you need to use a different installation profile, you need to re-install Drupal. If you aren't creating sites ex-novo, instead of an installation profile, you can create a custom module that you install on existing Drupal sites. A module can still create new entities or entity bundles via configuration files, have code executed when it's installed (via hook_install()), and define its dependencies. See, for example, what the Forum module does, for example with its config/optional/node.type.forum.yml file.

langcode: en
status: true
      - forum
name: 'Forum topic'
type: forum
description: 'A <em>forum topic</em> starts a new discussion thread within a forum.'
help: ''
new_revision: false
preview_mode: 1
display_submitted: true

There are some light differences between a configuration file used from an installation profile and a configuration file. Those differences allow a module to be uninstalled and re-installed, and have its entities (or entity bundles) re-created when the module is re-installed. (Doing differently, re-installing the module would shown an error complaining about the entity existing already.)


As you are deploying the same Drupal sites for different hosting providers, and you may want to install the same modules again and again with same kind of settings. Distribution is the way to manage initial default module dependencies and settings, And you can create your custom distribution and place it in /profiles folder.

  • The /profiles directory is for installation profiles, which are quite different from distributions.
    – apaderno
    Feb 11, 2019 at 15:46

You can add your own git repositories as sources for composer. This way, you can allow composer to look for code updates in areas other than the standard (public) repositories.

In composer.json, look for the "extra" array, and add a "repositories" item, and then add your own repositories like this:

    "extra": {
        "repositories": [
                "type": "vcs",
                "url": "..."

More info on adding repositories to composer.

You can also configure composer to use private repositories.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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