How to Write a Drupal 8 Installation Profile

Last updated on
28 June 2017

This article was originally written based on the Spark distribution.

Installation profiles are like modules

Installation profiles in Drupal 8 have all the functionality of modules, including access to hooks and plugins and, critically, the ability to provide configuration for your site in the form of .yml files.

Picking a machine name

First, you need a machine name for your profile. This is a name consisting of lowercase letters and underscores only. From here on, all references to profilename imply the profile machine name.

E.g if your profile is for Acme starter kit valid profile machine names would be

  • acme_starter_kit
  • acme_starter
  • acme_starter_profile
  • acme_kit

the following would be invalid

  • acme-starter-kit
  • acme-kit

This is because profiles are just like modules, and hence can implement hooks, - but acme-kit_form_alter would not constitute a valid PHP function name.

Creating the file structure

Your installation profile will reside in its own profilename directory in the /profiles directory of a Drupal 8 site.

All installation profiles must have a file. They may also have:

  1. profilename.profile
  2. profilename.install file
  3. config folder
  4. translations folder

When packaged, your installation profile will also have modules, src, and themes directories as needed.

.info.yml file

The file should look similar to this:

name: Profile Name
type: profile
description: 'Description of your profile.'
core: 8.x

# Optional: Declare your installation profile as a distribution
# This will make the installer auto-select this installation profile.
# The distribution_name property is used in the installer and other places as
# a label for the software being installed.
  name: Distribution Name
  # If you want your distribution to pre-select a language you can specify
  # the language code, as well. This will prevent the user from selecting
  # a language code in the user interface. While not recommended for generic
  # community distributions, this can be very useful for distributions that
  # are tailored to a language-specific audience (for example government
  # institutions in a certain country) but also site-specific installation
  # profiles. Note that this language code will also be used when installing
  # the site via Drush.
  langcode: de

# Required modules
# Note that any dependencies of the modules listed here will be installed automatically.
  - node
  - history
  - block
  - block_content
  - breakpoint
  - color
  - config
  - comment
  - contextual
  - contact
  - quickedit
  - help
  - image
  - options
  - path
  - taxonomy
  - dblog
  - search
  - shortcut
  - toolbar
  - field_ui
  - file
  - rdf
  - views
  - views_ui
  - editor
  - ckeditor

# List any themes that should be installed as part of the installation
# profile installation.
# Note that this will not set any theme as the default theme.
  - bartik
  - seven

.install file

 * @file
 * Install, update and uninstall functions for the profilename install profile.

 * Implements hook_install().
 * Perform actions to set up the site for this profile.
 * @see system_install()
function profilename_install() {
  // First, do everything in standard profile.
  include_once DRUPAL_ROOT . '/core/profiles/standard/standard.install';
  // Can add code in here to make nodes, terms, etc.

.profile file

The profilename.profile file has access to almost everything a normal Drupal modulename.module file does because Drupal is fully bootstrapped before almost anything in the profile runs.

 * @file
 * Enables modules and site configuration for a standard site installation.

// Add any custom code here like hook implementations.


Configuration files

Drupal 8 installation profiles can contain configuration files. You can start by taking the configuration directory (config folder) of an installed, configured site and copying it into the config/install folder in your profile.

Once that's in place, there are some other required tasks:

  1. Copy all of the modules and themes listed within core.extension.yml into your profile's info file (using the new info file's format).
  2. Delete core.extension.yml (and possibly some other config files).
  3. Remove all of the UUIDs and default_config_hash from your config files so that they don't conflict with those of new sites. This can be done quite easily on the command line like so all on one line:
    find /path/to/PROFILE_NAME/config/install/ -type f -exec sed -i -e '/^uuid: /d' {} \;
    find /path/to/PROFILE_NAME/config/install/ -type f -exec sed -i -e '/_core/,+1d' {} \;

If you just want to grab an existing site's configuration, and don't need to end up with a formal installation profile (for sharing on, for example), you can use the Configuration Installer installation profile to install a new site from the configuration of another site.

Default content

You can also include default content by making default_content a dependency of your installation profile and using it to import JSON-formatted content.

The configuration that needs content to work is possible by putting content (and configuration as needed) in modules you make (which your profile can depend on) that themselves depend on default_content.