On this page
- Composer (includes also cURL)
- Guide to follow
- Then
- Test
- Output (example)
- Useful suggestions
- More resources on Composer
- Apache2 and PHP
- Guide to follow
- Test
- Output
- Then
- Test Apache
- Test PHP
- Useful suggestions
- Other useful resources
- MySQL
- Guide to follow
- Test
- Output (example)
- Set Up Apache Virtual Hosts
- Guide to follow
- An example test index.html file
- An example Virtual Host File
- One time
- Then for each site
- Then
- Test
- Output
- Add a single domain to resolve to localhost
- Use dnsmasq to resolve ALL .localhost-domains to localhost
- Guide to follow
- Test
- Output
- Enable clean URLs
- Set the permissions of /var/www/html right
- Guide to follow
- Then
- When on a remote server for the live site
- An extended example Virtual Host File, including port 443 for HTTPS
- SSL renewal
Set up a local development environment
This documentation is deprecated.
Most of the steps needed are command-line commands. Press Ctrl-Alt-T to open the terminal and use them. The advantage is that you can use the same commands also to set up a remote server when connecting through SSH.
Composer (includes also cURL)
Pulls in required dependencies defined in a composer.json file in the root of a project. This is the common way to install Drupal projects as it excludes most of the code that is not under your version control from your repository, getting external packages only when necessary. In the steps below Composer is used to install Drupal 8, Drush, and Code Sniffer.
Guide to follow
How To Install and Use Composer on Ubuntu 22.04 | DigitalOcean. Steps 1 and 2. Read the other steps later as good info.
NOTE:
It might be needed to move the installer file:
mv composer-setup.php /tmp/composer-setup.phpAlternatively: Composer | getcomposer.org
Then
Change the owner to the current user to avoid using sudo:
sudo chown -R $USER .composer/Test
composer --version
Output (example)
Composer version 2.0.11 2021-02-24 14:57:23
Useful suggestions
- Troubleshooting - Composer, especially note the use of
composer diagthat provides a bunch of useful system version info - Get a list of all globally installed packages:
composer global show - Update all globally installed packages:
composer global update - Update Composer itself:
sudo composer self-updateor re-install Composer if running into issues. - php - How to downgrade or install a specific version of Composer? - Stack Overflow
- Create a new project:
composer create-project drupal/recommended-project my-project - Add development dependencies like PHPUnit (on your local machine):
composer require --dev drupal/core-dev - Install all except development dependencies (on your server):
composer install --no-dev # Skip installing packages listed in require-dev - Parallel package downloads (more information):
composer global require hirak/prestissimo - When in a feature branch on a project, you use the below a lot (look them up in the docs above):
composer validate # To run before you commit your composer.json file. composer install # Always safe to run from the project root. composer update --lock # Only updates the lock file hash to suppress warning about the lock file being out of date.Remember not to run
composer installwhen inside a module folder that contains a composer.json. That does not harm but it would create an unnecessary vendor folder there. Be aware thatcomposer validatechecks apart from a project's composer.json also your global Composer configuration at ~/.composer/config.json. - Do NOT use
composer updatewithout any options or without specifying a specific project. It will upgrade core, all contributed modules, and vendor libraries in one go, which is a terrible idea for big projects. Instead, you want to update each independently so you can test and make sure things don't break. Read more. - Example to install a dev branch module over a stable release:
composer require drupal/entityqueue:1.x-dev#3ace5b7 # Adding the commit hash avoids upgrading the dev version to possibly unstable future versions. -
Instead of using git clone when developing on a dependency package itself (for module developers), you might want to use Composer to make sure the module gets also added to the composer.json file. Example with the Git Info Report module:
composer require drupal/gitinfo:1.x-dev --prefer-source cd web/modules/contrib/gitinfo git checkout 8.x-1.x # Change from the default branch (latest stable) to the development branch git remote set-url origin git@git.drupal.org:project/gitinfo.git # Use SSH to connect to the remote git pull # Verify the connection -
Remove a package/module:
drush pmu gitinfo # Uninstall the module first composer remove drupal/gitinfo - How to find the exact version of a package? - Stack Overflow
-
composer show package/name -
How to resolve a "Can only install one of:" conflict? - Stack Overflow
To see where the problematic package is referenced from in your project, run:composer why package/name -t -
While the above command shows the current chain of requirements that is requesting a package,
composer why-not package/name:[next.version.number] -tIt shows if the next version of a package is allowed. The version should be the next version you intend to install, not the currently installed version. If the output is identical to the command above (composer why), it should be fine to upgrade.
--tree (-t): Prints the results as a nested tree and recursively resolves up to the root package, showing also the dependencies of the dependencies, up to the project root composer.json (the one you usually act on).
The command composer why is also known as composer depends, while composer why-not is the same as composer prohibits.
See Command-line interface / Commands - Composer. -
Start clean (upgrade, downgrade, or remove unused packages):
rm -rf vendor composer install - It is recommended to add a composer.json file to your modules.
- Last but not least, Composer is also the recommended way to apply patches to your codebase, both for the core as contrib projects:
Apply Drupal 8 Patch by Composer without update Drupal Core | Drupal Groups
It depends on:
cweagans/composer-patches: Simple patches plugin for Composer
Additionally:
How do I apply patch in vendor directory using composer? - Drupal Answers
Note: To make the patch valid, it seems that the a/ and b/ prefixes have to be removed.
For example:diff --git docroot/.htaccess docroot/.htaccess index 27e19a0..03eacf5 100644 --- docroot/.htaccess +++ docroot/.htaccess @@ -149,6 +149,8 @@ ....
More resources on Composer
- In the terminal use
composer listto see all available commands orcomposer help [command]to get detailed info. - Basic usage - Composer
- Drupal 8 Composer Best Practices | Lullabot
- Versions and constraints - Composer (for example what is the difference between a tilde (~) and a caret (^) version range indicator)
- What's the difference between require and require-dev? - Stack Overflow
- Drupal and Composer: Part 1 — Understanding Composer | Morpht
- Tips for Managing Drupal 8 projects with Composer | Jeff Geerling
- The Composer Lock File Demystified
- Updating core to a specific version with Composer - Drupal Answers
- Composer Best Practices for Updating Drupal 8 Core and Modules | Grazitti Interactive
- Most of this Acquia BLT documentation page (Build and Launch Tool) about Dependency Management is also useful for other kinds of installations as well.
- 24 Tips for Using Composer Efficiently — Martin Hujer blog
- Going from 1.7 to 1.9: Re-install Composer | gaus.vip
- Migrating from webflo/drupal-core-require-dev to drupal/core-dev
- Composer for Drupal Developers | Morpht
- Rollback to version 1 of composer - Stack Overflow
Apache2 and PHP
Apache is an open-source HTTP server. It is the most commonly used web server for Drupal. Drupal will work on Apache 2.x hosted on UNIX/Linux, OS X, or Windows. PHP 7.4 is the default PHP version in Ubuntu 20.04. Please check Web server requirements | System requirements | Drupal Wiki guide on Drupal.org and PHP requirements | System requirements | Drupal Wiki guide on Drupal.org to see the recommended versions for the Drupal core you intend to use.
PHP is a server-side scripting language designed primarily for web development. PHP 7.3 or higher is recommended for current release versions of Drupal 8 and 9.
Guide to follow
How To Install Linux, Apache, MySQL, PHP (LAMP) stack on Ubuntu 20.04 | DigitalOcean
Test
Output
Then
In /etc/php/7.2/apache2/php.ini set:
short_open_tag = On
Test Apache
To just check the Apache 2 version, independent from the service running or not:
apache2ctl -vThe expected output looks like this:
Server version: Apache/2.4.29 (Ubuntu)
Server built: 2020-08-12T21:33:25Test PHP
How To Install Linux, Apache, MySQL, PHP (LAMP) stack on Ubuntu 16.04 - Step 4 Test PHP | DigitalOcean (still valid for 20.04, open for discussion)
Then visit http://localhost/info.php.
Useful suggestions
How to switch between PHP 7 and PHP 5.6 on Ubuntu 16.04? - Ask Ubuntu (seems still valid for 18.04, open for discussion).
Related to that How to add PHP extensions (e.g. CURL) for a multi-version PHP setup.
Quickly check your current PHP version:
php -vQuickly check your current PHP extensions:
php -mIf you miss extensions after switching PHP version, just install them relative to the new version, for example, if missing a PostgreSQL driver:
sudo apt-get install php7.4-pgsql
sudo systemctl restart apache2For Drupal >= 8.5 PHP 7.2 is recommended, however, drupal/core 8.5.x requires gd so do:
sudo apt-get install php-gdWe might as well install other common PHP extensions that might be missing:
sudo apt-get install -y php-xml php-mbstring php-curl php-bz2 php-zipIt might be needed to enable some of those:
sudo phpenmod dom xmlCheck if the MySQL Improved Extension is enabled:
php -m | grep mysqliBe aware that if you run PHP from the command line, it uses cli/php.ini and apache2/php.ini when running it through Apache (used by the browser). Modifying the last one requires restarting Apache to get changes applied:
systemctl restart apache2TIP: Safeguard against breaking php.ini changes.
Other useful resources
MySQL
An open-source relational database management system.
Note that Drupal can also run on MariaDB, Percona Server, PostgreSQL, SQLite, and others. Please check Database server | Drupal 8 guide on Drupal.org to see the recommended versions for the Drupal core you intend to use.
Guide to follow
How To Install MySQL on Ubuntu 20.04 | DigitalOcean
Test
mysql --version
Output (example)
mysql Ver 8.0.23-0ubuntu0.20.04.1 for Linux on x86_64 ((Ubuntu)
Set Up Apache Virtual Hosts
A method for hosting multiple domain names on a server.
Guide to follow
How To Set Up Apache Virtual Hosts on Ubuntu 16.04 | DigitalOcean (seems still valid for 18.04, open for discussion) with a slight variation using the location /var/www/html as the location for our sites instead of /var/www. The reasons behind it are best described in Where to place my local website starting with the 2.4.7 version of apache2? - Ask Ubuntu. Furthermore, we do not use the public_html folder therefore for this example the index.html file should be at /var/www/html/example.localhost/index.html.
An example test index.html file
/var/www/html/example.localhost/index.html
<html>
<head>
<title>Welcome to Example.localhost!</title>
</head>
<body>
<h1>Success! The virtual host is working!</h1>
</body>
</html>An example Virtual Host File
/etc/apache2/sites-available/example.localhost.conf
<VirtualHost *:80>
ServerName example.localhost
ServerAlias www.example.localhost
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html/example.localhost
ErrorLog /var/www/html/logs/example.localhost/error.log
CustomLog /var/www/html/logs/access.log combined
</VirtualHost>To copy the above file under another name to create another site:
cd /etc/apache2/sites-available
sudo cp example.localhost.conf new.localhost.conf
sudo nano new.localhost.conf
# In the newly created file replace all instances of 'example' with 'new'.
^\
example
new
^x
One time
sudo mkdir /var/www/html/logs
# Create an empty access log.
sudo touch /var/www/html/logs/access.log
Then for each site
sudo mkdir /var/www/html/logs/example.localhost
# Create an empty error log.
sudo touch /var/www/html/logs/example.localhost/error.log
# Enable the new site.
sudo a2ensite example.localhost.confThen
sudo systemctl restart apache2If you get any errors on Apache restart, you can debug with:
systemctl status apache2.serviceTest
Go to http://localhost/example.localhost/. If that does not result in the below output check the existence of /etc/apache2/sites-enabled/example.localhost.conf. If it exists delete it, check the content of /etc/apache2/sites-available/example.localhost.conf, modify any mistakes, and repeat sudo a2ensite example.localhost.confand sudo systemctl restart apache2.
Output
Add a single domain to resolve to localhost
In the case of a Drupal multisite setup, you would have a folder name identical to the domain. Add the single domain to the /etc/hosts file:
127.0.0.1 localhost example.com some.other.example.comThe drawback is that you need another machine to check the "live" site with the same domain name. The use of the TLD extension .localhost as described below, is preferred.
Use dnsmasq to resolve ALL .localhost-domains to localhost
DNS forwarding.
Note that this is a one-time action that does not need to be executed again once done successfully.
sudo apt-get install dnsmasq
Guide to follow
From the yum command onwards (only for CentOS, we used the above command instead), follow Make all *.dev domains resolve to localhost - hutter.io but instead of .dev use .localhost.
Note that using the .local extension results in problems. Do not use it. From the list of Reserved TLDs .localhost is the most appropriate to use.
Test
Go to http://www.example.localhost/. If that does not result in the below output then dnsmasq is still not configured right.
Output
Enable clean URLs
sudo nano /etc/apache2/apache2.confOpen /etc/apache2/apache2.conf in your editor and in the section <Directory /var/www/>set AllowOverride All.
sudo a2enmod rewrite
sudo systemctl restart apache2More detailed info: Enable clean URLs | Drupal.org
Set the permissions of /var/www/html right
Setting the permissions on the Apache website hosting directory.
Guide to follow
Permissions problems with /var/www/html and my own home directory for a website document root - Ask Ubuntu until step 4.
Then
In Nautilus (Ubuntu) go to /var/www/html and add the location as a bookmark to have a shortcut.
When on a remote server for the live site
To set up a remote server the same instructions as above can mainly be followed but with a few distinctions. You connect to your remote first, using:
ssh root@[your-ip-address]An extended example Virtual Host File, including port 443 for HTTPS
NameVirtualHost *:80
<VirtualHost *:80>
ServerName example.com
Redirect / https://example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
ServerAlias example.com
ServerAdmin admin@example.com
DocumentRoot /var/www/html/example.com/web
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/example.com.crt
SSLCertificateKeyFile /etc/apache2/ssl/example.com.key
SSLCertificateChainFile /etc/apache2/ssl/example.com.ca-bundle
ErrorLog /var/log/apache2/example.com/error.log
CustomLog /var/log/apache2/example.com/access.log combined
</VirtualHost>Notice that the differences compared with our local setup are due to using HTTPS instead of HTTP. The three certificate files will be generated when you create that (out of the scope of this manual).
SSL renewal
- Reissue the certificate.
- Validate all SAN URLs, preferably by uploading a validation file on each domain under [domain]/.well-known/pki-validation/[token-file-name].txt. The file can be downloaded once you submit an activation request and the status switches to “pending”. When uploading the file, do not change the name or its content. The status will change to “activated” after validation is successful.
- After that, the new certificate can be downloaded. Only the CRT file needs to be uploaded under the same name as the previous one, see the configuration files in the /etc/apache2/sites-enabled folder.
- Restart Apache. It might be necessary to restart your browser as well if you are still seeing the site in unsafe mode (HTTP).
Alternatively, to have both automatic renewal and a free SSL certificate, use Certbot.
Next: Set up Drupal 8 >>
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion

