DDEV and Magento 2
Local development and GitHub actions
I would like to speak here about a tool that I discovered a few months ago: DDEV.
To summarize, DDEV makes it easier to set up a Docker stack for your PHP developments. I was surprised by how quickly it could be picked up, and I use it, among other things, for my Magento 2 developments.
I won't go into detail about everything that can be done with DDEV. There are a large number of resources (especially awesome-ddev) and its documentation seems clear enough to facilitate its installation and customization.
I simply prefer to share my experience here by evoking two types of tasks for which DDEV has simplified my life:
- install Magento 2 and develop modules locally
- set up GitHub actions to test several versions of Magento 2 and PHP in an automated way.
The first step is to install everything you need:
The best way to install DDEV is to follow the official documentation. On a Linux distribution, you could run this type of command:
sudo apt install linuxbrew-wrapper brew tap drud/ddev && brew install ddev
The final structure of the project will look like below.:
m2-sources │ │ (Magento 2 sources installed with composer) │ └───.ddev │ │ │ │ (DDEV configuration files) │ └───my-own-modules (only if you want to test some of your module(s)) │ │ └───yourVendorName-yourModuleName │ │ (Module sources)
To populate the above
.ddev folder, I will use here specific DDEV configurations.
It's, in fact, configurations that DDEV automatically generates when you tell it that you want to
work on a Magento 2 project, to which I added some DDEV files and commands. For example, I have
docker-compose.yaml files when I wanted to work with other Docker containers,
Varnish, PHPSTAN or Nginx configuration files for some very specific uses and I created commands
to simulate crons or run custom scripts.
For now, you could use my sources without trying to understand in detail, but the idea is that everyone should do according to their needs by adding their own DDEV files and commands. I will give below some more specific examples of custom commands.
So if you want to see what it looks like on your host:
- Create an empty
- In this folder, create an empty hidden
.ddevfolder and clone my GitHub repository:
mkdir m2-sources/.ddev && cd m2-sources/.ddev && git clone email@example.com:julienloizelet/ddev-m2.git ./
- In this example, we will install Magento 2.4.3 with PHP 7.4. To do this, copy a small configuration file:
cp .ddev/config_overrides/config.m243.yaml .ddev/config.m243.yaml
- Finally, launch DDEV
cd .ddev && ddev start
This should take some times on the first launch as this will download all necessary docker images. Later, it will be much faster.
If you are curious, you could then run a
ddev describe which will give you some information on the different Docker services.
To install Magento 2 you will need your private and public Magento 2 keys. You will be asked for them during the installation with
DDEV has some basic commands that allow you to launch usual commands in the right docker container. For example,
ddev composer runs
composer in the
web container where the sources are located.
So, to install Magento 2.4.3, you can do:
ddev composer create --repository=https://repo.magento.com/ magento/project-community-edition:2.4.3
ddev magento launches the CLI executable
bin/magento. So, to complete the installation, run:
ddev magento setup:install \ --base-url=https://m243.ddev.site \ --db-host=db \ --db-name=db \ --db-user=db \ --db-password=db \ --backend-frontname=admin \ --admin-firstname=admin \ --admin-lastname=admin \ --firstname.lastname@example.org \ --admin-user=admin \ --admin-password=admin123 \ --language=en_US \ --currency=USD \ --timezone=America/Chicago \ --use-rewrites=1 \ --elasticsearch-host=elasticsearch
Magento 2 is now installed and operational.
For convenience purpose, I sometimes add commands like:
ddev magento config:set admin/security/password_is_forced 0 ddev magento config:set admin/security/password_lifetime 0 ddev magento module:disable Magento_TwoFactorAuth ddev magento indexer:reindex ddev magento c:c
Or, to add test data:
ddev magento setup:performance:generate-fixtures setup/performance-toolkit/profiles/ce/small.xml
The installations are complete. In the second step, I describe how I develop my modules locally:
There are several ways to develop a module locally. Perhaps the easiest is to place your sources in
As far as I'm concerned, I prefer to modify the
composer.json of the project to add a
repository of type
which point to the module sources:
mkdir -p m2-sources/my-own-modules/yourVendorName-yourModuleName cd m2-sources/my-own-modules/yourVendorName-yourModuleName git clone email@example.com:yourGitHubName/yourGitHubModule.git ./ ddev composer config repositories.yourVendorName-yourModuleName path my-own-modules/yourVendorName-yourModuleName/ ddev composer require yourComposerModuleName:@dev ddev magento module:enable yourVendorName_yourModuleName ddev magento setup:upgrade ddev magento cache:flush
For the rest of this presentation, I will take as an example one of my modules called
Okaeli_CategoryCode. This one adds a
code attribute to the categories, but whatever. If you want to see what it looks like:
mkdir m2-sources/my-own-modules mkdir m2-sources/my-own-modules/okaeli-category-code cd m2-sources/my-own-modules/okaeli-category-code git clone firstname.lastname@example.org:julienloizelet/magento2-category-code.git ./ ddev composer config repositories.okaeli-category-code path my-own-modules/okaeli-category-code/ ddev composer require okaeli/magento2-category-code:@dev ddev magento module:enable Okaeli_CategoryCode ddev magento setup:upgrade ddev magento cache:flush
As mentioned above, one of the strengths of DDEV is that it allows you to add your own commands. I was thus able to define the phpcs, phpmd and phpstan commands which launch the tools of the same name:
- PHP Code Sniffer:
ddev phpcs my-own-modules/yourVendorName-yourModuleName
- PHP Mess Detector:
ddev phpmd my-own-modules/yourVendorName-yourModuleName
- PHP Stan:
ddev phpstan my-own-modules/yourVendorName-yourModuleName
If you have cloned the example module
I also added a command to launch PHPUNIT:
ddev phpunit my-own-modules/yourVendorName-yourModuleName/Test/Unit
Sorry, the example module does not have unit tests :).
If you want to see how I used DDEV to test crons and Varnish, you can watch here.
We have just seen how to test a module locally. The implementation of GitHub actions results directly from this way of doing:
I started using GitHub actions at the same time as DDEV. It was while creating the DDEV commands that I realized that it would be "easy" to launch them in a GitHub action. And I found that it also saves time: the commands that I create locally are directly applicable in my GitHub actions.
This is why the GitHub action I use to run the static tests (PHPCS, PHPMD and PHPSTAN) follows precisely the steps that I have just described above:
- we install DDEV
- we install Magento with DDEV
- we install a module with DDEV
- we launch tests with DDEV
The main difference is that we can play on the
strategy.matrix entry of the
yaml action file to test several
versions of Magento and PHP at the same time.
Here is what it looks like for the example module:
Small bonus if you have held up until then: these static and Varnish tests are close to those performed for the
technical review during a module submission to the marketplace (see here and here).
If you have a module to submit, it might save you from a
failed on this step.
This presentation is a use case and only covers a small part of DDEV's possibilities. I hope you find it useful if you ever want to give this tool a chance.