This is a base profile for Drupal 8/9/10 projects to be used within the EUF. This template is built upon the drupal-composer/drupal-project and docker4drupal - refer to the respective documentations whenever necessary.
In order to test this profile with Docker, you need docker
, docker-compose
and make
installed on your system. If your system meets the requirements, follow these steps:
git clone [email protected]:EuropeanUniversityFoundation/euf-base.git
cd euf-base
cp .env.example .env # The .env file is ignored by version control
nano .env # Edit the environment variables if necessary
make up # Create and start the Docker containers
make shell # Access a shell in the PHP container
composer install # Install the necessary packages
bash scripts/env-install.sh # Quick command line installation
This project includes docker4drupal with some particular changes to provide an easy and consistent way to launch projects across different development environments. This approach is not without its downsides but it works consistently and is recommended for development.
docker4drupal is built around a set of variables that are specific to each development environment, so this project includes a .env.example
file that should be copied to .env
and adapted according to specific needs. The .env
file is ignored in version control to guarantee that the project is not "polluted" with environment specific code.
cp .env.example .env # The .env file is ignored by version control
nano .env # Edit the environment variables if necessary
These environment variables are injected into the docker-compose.yml
file to define all the Docker containers and their particular configuration. This is accomplished with the Makefile
present at the root of the project, containing the necessary aliases to create / start, interact with, stop and delete Docker containers.
make up # Create and start the Docker containers
make start # Start existing Docker containers
make stop # Stop all running Docker containers
make down # Same as make stop
make prune # Delete the Docker containers
make shell # Access a shell in the PHP container (default)
Out of the box, this modified version of docker4drupal includes the following containers:
- Traefik as a reverse proxy / load balancer;
- NginX as a web server;
- PHP and crond as the runtime environment (with
composer
anddrush
) - MariaDB as the database engine;
- Mailhog to handle emails.
The docker4drupal stack can include many more components, but it is recommended that any additional components be included via a docker-composer.override.yml
file, which will be ignored by version control, to keep the base project simple and fast. Some examples are included:
Use this to modify the PHP container and add a Github authentication token to Composer. Some dependencies are pulled directly from Github repositories. During development, every composer
operation will hit the Github API, which can lead to too many anonymous calls and getting locked out. To avoid this, generate a Personal Access Token and include it in the .env
file; the token will then be loaded by the Composer configuration inside the PHP container.
Also, the overrides include mounting your personal git configuration and SSH key, allowing to commit and push from within the PHP container shell - no more commits by wodby
!
Use this to add a container with NodeJS for custom theme development.
Use this to add a container with phpMyAdmin for easier access to the database.
Inside the .env
file there are many variables that impact the Docker setup, and most are set to sensible defaults. Others require some attention:
PROJECT_NAME
is used to prefix the container names;PROJECT_BASE_URL
is used to define the URLs for all containers;HTTP_PORT
can be leveraged to start multiple Docker setups (see below);DB_
variables are used for the database container and whatever connects to it;COMPOSER_AUTH
can be used with the Github override described above.
By default the Traefik container will bind to port 8000; in order to use multiple setups at the same time, change the port number on your local environment to another number. Warning: port 8025 is used by Mailhog.
When using a regular LAMP stack (Linux + Apache + MySQL + PHP), be sure to have Composer on your system to be able to install dependencies. Optionally, install Drush launcher to facilitate using the local Drush which comes installed with this project, otherwise any drush <command>
must be executed as vendor/bin/drush <command>
(assuming it is run from the project root).
For the Apache web server, there are some additional rules that must be included in the Virtualhost definition:
<VirtualHost *:80>
ServerName DOMAIN
DocumentRoot "/var/www/vhosts/DOMAIN/PROJECTROOT/web"
<Directory "/var/www/vhosts/DOMAIN/PROJECTROOT/web">
Options Includes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
Some variables inside the .env
file will have no impact, while others do, since this setup is different from the Docker setup:
PROJECT_NAME
is not currently used in a LAMP setup;PROJECT_BASE_URL
may be used in Drupal settings, so it should be reviewed;HTTP_PORT
is not currently used in a LAMP setup;DB_
variables are used for the stack database so they should be reviewed;COMPOSER_AUTH
is not currently used in a LAMP setup;
Adding a Github authentication token to Composer should be done manually, and it only needs to be done once per system.
Installing Drupal for the first time can be done via the web GUI using your browser, or it can be done via the command line with the help of Drush. This project includes shell scripts to leverage the variables set in the .env
file and perform the installation quickly via the command line. Installing via the web GUI is also possible, although it requires more attention to details, especially in a Docker setup.
To perform a first time installation, make sure you get the latest version of the required packages by running these commands:
rm composer.lock # contains exact versions, might be outdated
composer install # installs packages as defined in composer.json
Use the bundled shell script to perform a quick install from the .env
variables:
chmod u+x scripts/env_install.sh # ensure the script is executable
bash scripts/env_install.sh # run the script using bash (safest)
Environment specific settings are usually placed in a settings.local.php
file which can be created from the example.settings.local.php
file from Drupal core, but it is recommended to use the provided version instead:
cp web/sites/default/custom.settings.local.php web/sites/default/settings.local.php
After a first time installation, change the settings.php
file to use settings.local.php
instead:
chmod u+w web/sites/default/settings.php
nano web/sites/default/settings.php
Comment out the database settings block and add the following lines to the end of the file:
if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) {
include $app_root . '/' . $site_path . '/settings.local.php';
}
This allows settings.local.php
to use the variables defined in the .env
file. Finally, clear the cache:
vendor/bin/drush cr # or use `drush cr` if your setup allows
If you want to reinstall your project using the exported configuration in the config/sync
directory, install the exact packages versions and configuration by running these commands:
composer install
chmod u+x scripts/config_install.sh
bash scripts/config_install.sh
If necessary, perform the same changes to settings.php
as described above and clear the cache.
It is possible to run PHPUnit tests within this project, given some preliminary setup:
mkdir web/sites/simpletest
chmod a+w web/sites/simpletest/ -R
To run PHPUnit tests for your custom modules, execute the following commands:
docker-compose exec --user www-data php sh
vendor/bin/phpunit -c phpunit.xml.dist web/modules/custom/
In a regular LAMP stack, configuration must be changed. Individual PHPUnit configuration is ignored and Functional tests in particular must be run with a different system user:
cp phpunit.xml.dist phpunit.xml
sudo -u www-data -E vendor/bin/phpunit -c phpunit.xml web/modules/custom/
Some common issues and quick solutions...
Composer require or update may fail because the scaffold plugin cannot replace files in web/sites/default
; fix with chmod u+w web/sites/default
.
When installing the given composer.json
some tasks are taken care of:
- Drupal will be installed in the
web
-directory. - Autoloader is implemented to use the generated composer autoloader in
vendor/autoload.php
, instead of the one provided by Drupal (web/vendor/autoload.php
). - Modules (packages of type
drupal-module
) will be placed inweb/modules/contrib/
- Theme (packages of type
drupal-theme
) will be placed inweb/themes/contrib/
- Profiles (packages of type
drupal-profile
) will be placed inweb/profiles/contrib/
- Creates default writable versions of
settings.php
andservices.yml
. - Creates
web/sites/default/files
-directory. - Latest version of drush is installed locally for use at
vendor/bin/drush
. - Latest version of DrupalConsole is installed locally for use at
vendor/bin/drupal
. - Creates environment variables based on your .env file. See .env.example.
This project will attempt to keep all of your Drupal Core files up-to-date; the project drupal/core-composer-scaffold is used to ensure that your scaffold files are updated every time drupal/core is updated. If you customize any of the "scaffolding" files (commonly .htaccess), you may need to merge conflicts if any of your modified files are updated in a new release of Drupal core.
Follow the steps below to update your core files.
- Run
composer update drupal/core drupal/core-dev --with-dependencies
to update Drupal Core and its dependencies. - Run
git diff
to determine if any of the scaffolding files have changed. Review the files for any changes and restore any customizations to.htaccess
orrobots.txt
. - Commit everything all together in a single commit, so
web
will remain in sync with thecore
when checking out branches or runninggit bisect
. - In the event that there are non-trivial conflicts in step 2, you may wish
to perform these steps on a branch, and use
git merge
to combine the updated core files with your customized files. This facilitates the use of a three-way merge tool such as kdiff3. This setup is not necessary if your changes are simple; keeping all of your modifications at the beginning or end of the file is a good strategy to keep merges easy.
With using the "Composer Generate" drush extension
you can now generate a basic composer.json
file from an existing project. Note
that the generated composer.json
might differ from this project's file.
Composer recommends no. They provide argumentation against but also workrounds if a project decides to do it anyway.
The Drupal Composer Scaffold plugin can download the scaffold files (like
index.php, update.php, โฆ) to the web/ directory of your project. If you have not customized those files you could choose
to not check them into your version control system (e.g. git). If that is the case for your project it might be
convenient to automatically run the drupal-scaffold plugin after every install or update of your project. You can
achieve that by registering @composer drupal:scaffold
as post-install and post-update command in your composer.json:
"scripts": {
"post-install-cmd": [
"@composer drupal:scaffold",
"..."
],
"post-update-cmd": [
"@composer drupal:scaffold",
"..."
]
},
If you need to apply patches (depending on the project being modified, a pull request is often a better solution), you can do so with the composer-patches plugin.
To add a patch to drupal module foobar insert the patches section in the extra section of composer.json:
"extra": {
"patches": {
"drupal/foobar": {
"Patch description": "URL or local path to patch"
}
}
}
Follow the instructions in the documentation on drupal.org.
This project supports PHP 7.0 as minimum version (see Drupal 8 PHP requirements), however it's possible that a composer update
will upgrade some package that will then require PHP 7+.
To prevent this you can add this code to specify the PHP version you want to use in the config
section of composer.json
:
"config": {
"sort-packages": true,
"platform": {
"php": "7.0.33"
}
},