Change record status: 
Project: 
Introduced in branch: 
8.6.x
Introduced in version: 
8.6.0
Description: 

Drupal 8 now supports installing from existing configuration. This is useful because it allows developers to potentially work on a site without sharing databases. It can also be used in continuous integration environments to support testing.

Installation from configuration is supported in core in two ways:

1. The sync directory is already set in settings.php

You can set $config_directories in settings.php before installation. If the configured directory contains valid configuration for a profile that supports configuration install, then on the install profile selection screen, you will be able to select an option to install from existing configuration.

Note: Sync directory syntax was updated in Drupal 8.8.x (The sync directory is defined in $settings and not $config_directories) from $config_directories['sync'] to $settings['config_sync_directory']. To prepare default.settings.php (the basis for settings.php) run this command before installation:

echo '$settings["config_sync_directory"] = "../config/sync";' >> web/sites/default/default.settings.php

2. The install profile has a config/sync directory

You can create your own install profile and export your configuration to a config/sync directory inside the install profile. If you do this, you will probably have to update the core.extension configuration to replace the existing install profile. You will need to replace it in the module list and the profile.

Caveat

If the profile implements hook_install() configuration install is not supported. This might be addressed in #2982052: Allow an install hook in profiles to install from configuration. Possible workarounds for now are to either change the install profile to minimal or follow option 2 and create a new profile that does not implement the hook.

Drush

Drush 9.4 enhanced its site:install command with a new --existing-config option in order to support this feature.

Impacts: 
Site builders, administrators, editors
Module developers

Comments

Marko B’s picture

More info on this here.
https://www.drupal.org/project/drupal/issues/2980670

for example that this only works with minimal profile and standard profile wont work.

aguerrerowk’s picture

Hello,
i'm facing the same trouble using a custom profile, that i've created
Drupal\Core\Config\UnmetDependenciesException: Configuration objects provided by oneworkplace have unmet dependencies: core.entity_form_display.event_entity.event_entity.default (smart_date)

Smartdate is already placed on composer.json and installed on modules/contrib

what i'm doing wrong?

camil.bancioiu’s picture

Your custom profile is missing the file core.entity_form_display.event_entity.event_entity.default.yml.

The error you're seeing happens often when you forget to export a YAML file from an existing site, then another YAML file depends on it.

fathibn’s picture

Hello, I have an existing drupal 7 site and would like to generate a site profile so I could start a new drupal 8 site with all the modules used in the old site.

emscha’s picture

Using a custom profile to import existing configuration, without the install hook, ran into an error and the solution to fix was:

https://www.drupal.org/forum/support/post-installation/2019-07-31/error-...

can that minor check be added to /core/lib/Drupal/Core/Config/ConfigImporter.php? thanks.

    case 'create':
        if ($target_exists) {
          // If the target already exists, use the entity storage to delete it
          // again, if is a simple config, delete it directly.
          if ($entity_type_id = $this->configManager->getEntityTypeIdByName($name)) {
            $entity_storage = $this->configManager->getEntityTypeManager()->getStorage($entity_type_id);
            $entity_type = $this->configManager->getEntityTypeManager()->getDefinition($entity_type_id);
            $entity = $entity_storage->load($entity_storage->getIDFromConfigName($name, $entity_type->getConfigPrefix()));
            if ($entity) {
              $entity->delete();
              $this->logError($this->t('Deleted and replaced configuration entity "@name"', ['@name' => $name]));
            }
                      }
          else {
            $this->storageComparer->getTargetStorage($collection)->delete($name);
            $this->logError($this->t('Deleted and replaced configuration "@name"', ['@name' => $name]));
          }
          return TRUE;
        }