Skip to Main Content
Ddev seo

Local Development with DDev

A discusssion on using DDev for local development as a replacement for Mamp Pro or Xampps.

Local development is key when working on client sites. Over the years I've tried a number of different approaches including cowboy coding live on the server (not recommended), Xampp, Ampps, and Mamp Pro for Windows.

I've also looked into Laravel Valet and Docker. Valet is most appealing to me but the Windows fork never worked, and then yesterday I tried the fork that required Windows Subsystem for Linux and also had issues with it so moved on.

I additionally spent time learning Docker via an excellent course on Udemy, but decided it was too complex and would take too long to figure everything out. I need something that is not difficult and just works and is flexible allowing for different versions of PHP and mysql per site.


Why move on from Mamp Pro? A couple of reasons, I'm in a situation where I cannot upgrade Mamp Pro to the latest version. This is due to needing php 5.4, 5.5, and 5.6 for older projects and the latest Mamp doesn't include that. Also whenI did upgrade I needed to roll back due to problems with the mysql 5.6 to 5.7 update.

Additionally the max version of PHP available on my version of Mamp Pro is 7.2.1. I tried manually added in php 7.3.14 but couldn't get all the extensions needed for Craft sites to work.

DDev to the rescue

Once again I was googling and found DDev which is like a simplified Docker for local development. There is no GUI available but I'm comfortable working on the command line so that's not a big deal.

Part way through getting set up I was stuck and googled once again looking for specific help with Craft and DDev and came across this excellent article by Matt Stein Mamp Pro to DDEV.

At this point I recommend following Matt's instructions and you'll be set up and running. However note that here:

Edit 12/9: Note that there’s no DB_PORT specified here. DDEV chooses a new MySQL port every time your project spins up, so we need to let it expose its own DB_PORT environment variable (as it does by default).

Matt Stein

This can be overridden in your in your config.yaml file, by adding this line host_db_port: "32800" allowing you to use the same port every time you start the site. Very helpful for saving your settings in Navicat to connect to the database.

Matt Saves The Day

Using Matt's article I had this working 99%. However the Craft site  that I was working on insisted that craft was not installed despite connecting to the database. on the Craft Discord Server I hit up Matt and he, graciously, spent a few minutes helping me troubleshoot.

My issue was that I had my environment variables in both the dotenv file and the new docker-compose.environment.yaml file.This resulted in some conflict and as soon as I commented out all the variables except for SECURITY_KEY the site worked.

Now my .env file only has this SECURITY_KEY="some-random-string-here" and all of my other dontenv variables are stored in a file located in the .ddev directory called docker-compose.environment.yaml. See example below.

      version: '3.6'

      - ENVIRONMENT=dev
      - SECURITY_KEY=random-string-here
      - DB_DRIVER=mysql
      - DB_SERVER=db
      - DB_USER=db
      - DB_PASSWORD=db
      - DB_DATABASE=db
      - DB_PORT=3306
      - DB_SCHEMA=public
      - DB_TABLE_PREFIX=craft_

      # uploads path
      - ASSET_BASE_PATH=/var/www/html/public/uploads

      #Environment Label
      - CRAFT_ENV_LABEL_PREFIX= Local Site

      # site path
      - SITE_PATH=/var/www/html/siteroot


One final change was to the alias path settings I have in general.php which dynamically sets the path for the uploads folder depending on the environment. Because DDev is using a docker container under the hood, the path is not my windows path but the container path. See the relevant bits of general.php below specifically basePath.

      // Dev environment settings
    'dev' => [
        // Dev Mode (see
        'devMode' => true,
        'allowAdminChanges' => true,
        // 'aliases' => array(
        //     'environment' => 'dev',
        //     'basePath' => 'D:\sites\memoirs',
        //     'baseUrl'  => 'http://memoirs.test',
        // ),
        'aliases' => array(
            'environment' => 'dev',
            'basePath' => '/var/www/html',
            'baseUrl'  => 'http://memoirs.test',

Final Thoughts

I'm going to start moving away from Mamp Pro with new builds and sites that I'm actively working on. I'll keep Mamp Pro installed for sites relying on PHP 5.4/5.5 since DDev only goes back to php 5.6. Once I no longer need to support these sites I'll be done with Mamp.


  • Works well for Craft and ExpressionEngine sites - likely for almost any PHP based cms
  • Can peek under the hood at how DDev uses docker, allowing you to pick up more about Docker and move to a pure docker setup in the future.
  • local domains automatically generated based on folder name so D:/sites/myblog results in my local url as - this is manually configurable as well.
  • Excellent documentation
  • only need to know a few commands for day to day work: ddev start, ddev stop, ddev restart, ddev import-db, ddev describe, and ddev poweroff.


  • Running multiple sites at the same time requires manually setting different ports - MAMP does this out of the box and is a clear winner


After getting several craft sites up and running with DDev for local development I discovered that I was unable to save entries. On saving the CP hung for a bit and finally returned with an error page.

I did test with an ExpressionEngine site and did not have the same issue - probably because ExpressionEngine isn't using Mutex.

A little googling later and I found the solution in a github issue.

From your Craft config/app.php file, you can use this to set the isWindows property of the FileMutex class to true.

Once I added this snippet and restarted ddev all was good.

      return [
    'components' => [
        'mutex' => function() {
            $config = craft\helpers\App::mutexConfig();
            $config['isWindows'] = true;
            return Craft::createObject($config);


I  have run into an issue when trying to use the the Craft CMS CLI which I hadn't seen before. first I did ddev ssh which ssh's you into your container and then run any of the craft cli commands for example ./craft help and then I got this error.

/usr/bin/env: 'php\r': No such file or directory

Some googling and I determined that windows was adding hidden characters to the files when I pulled them down. Not a problem before using Ddev but since Ddev is using linux containers it wouldn't recognize the commands. The solution is simple.

First open a terminal and run this command:

git config --global core.autocrlf tru

and then you have to re-clone your repository. Yeah that part is not fun. You need to delete your local repository and then clone it from the bitbucket or github. Once you do this everything works as expected.

Related Articles