How to write a Drupal installation profile

Last updated on
8 February 2024

This article was originally written based on the Spark distribution.

Installation profiles are like modules

Installation profiles in Drupal 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 modern Drupal (Drupal >= 8) site.

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

  1. profilename.install file
  2. profilename.profile
  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 profilename.info.yml file should look similar to this:

name: Profile Name
type: profile
description: 'Description of your profile.'
core_version_requirement: '^8.8 || ^9 || ^10'

# 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.
distribution:
  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.
  #
  # To set your theme as the theme for the distribution installation uncomment the following:
  #
  # install:
  #   theme: my_theme
  #   # To redirect to specific URL after profile installation set your finish_url: 
  #   finish_url: ?welcome=1
  langcode: de

# Modules to install to support the profile.
# Unlike dependencies, these can be uninstalled later.
install:
  - history
  - 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

# Required modules. These cannot be uninstalled.
# Note that any dependencies of the modules listed here will be installed automatically.
dependencies:
  - node
  - block
  - views

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

.install file

Note that if your profile implements hook_install(), installation from configuration (see the section below) is not supported. This might be addressed in #2982052: Allow an install hook in profiles installing from configuration. See Installing Drupal from configuration (only certain profiles) for details.

<?php
/**
 * @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';
  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.

<?php
/**
 * @file
 * Enables modules and site configuration for a standard site installation.
 */

// Add any custom code here like hook implementations.

Configuration

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.

If you are using the standard_install() method mentioned above, you should copy user.role.administrator.yml from the standard profile to your custom 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' {} \;
    

In case you are on Mac OSX, the '-e' flag won't work. It duplicates the files and appends '-e' to the file (i.e. file-name.yml-e).  The ",+1d" also will not work on Mac OSX. Here's the command for Mac OSX.

find /path/to/PROFILE_NAME/config/install/ -type f -exec sed -i '' '/^uuid: /d' {} \;
find /path/to/PROFILE_NAME/config/install/ -type f -exec sed -i '' '/_core:/{N;d;}' {} \;

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 Drupal.org, 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.

Translations (optional)

If you want to provide your own translations you must create a folder in the root of your profile named translations, and inside, you must have the translation file, like this:

myprofile/translations/es/drupal-8.x.es.po

In this example the file translation is Spanish.

Help improve this page

Page status: No known problems

You can: