DDEV: A Worthwhile Investment?

With the Big Day out of the way, I've been enjoying cracking open the to-do list and churning through tasks that have been sat on the back burner for weeks, months, and – in some cases – even years 😬 Many of these tasks have been quite simple, they just required a calm brain space and a moment of time to focus on them, but a few are fairly monstrous, many-legged beasts that are not just unpleasant to consider, but are actively blocking the way from more enjoyable or interesting tasks. The king of these has been upgrading this site to Craft 4.

The latest major version of my much-loved content management system launched back in May 2022, so overdue is an understatement, but in my defence it wasn't only me preventing this from happening earlier. Hopefully for the last time, version four saw Craft switch up the way its plugin ecosystem interfaces with the main CMS, which meant that whilst most Craft 3 plugins were compatible with Craft 4, they each needed to be validated and have a flag set before they could be installed. Many were updated on launch day, but several that have become critical to my workflow were no longer being actively maintained, and took months to be upgraded[1]. The last of these finally obtained its green checkmark in my admin panel around March of this year[2], at which point wedding planning was ramping up in earnest and so CMS maintenance slid down the priority list – perfect timing 😉

Well, the timing is now much better, and one of my core themes for this month is "website maintenance", so as the weekend rolled around I began to take another look at what was actually needed. The simple answer was to "just upgrade the server install", but as is always the case when it comes to DevOps/back-end stuff, the simple answer is rarely the right one. No, I wanted to do this right, rather than fast, because I didn't want to completely bork my CMS and I definitely didn't want to risk losing any data. And doing it right meant a trial run, AKA a local development environment. Eurgh...

Overall, my experience with running Craft locally feels akin to watching people scrape nails along a chalkboard. Back when I first started using the service the only real option was a LAMP-stack local server environment, similar to just about every other web tool of that era. Being a Windows developer, though, meant this was often trickier than people expected; I've likely spent weeks, if not months, of my life battling WAMP, MAMP, and similar tools, lost in a befuddled haze of dot files, config folders, and firewall settings. Still, over the years I had at least built a form of resilience to these tools, and had largely managed to get them to do what I'd wanted, so when Craft announced that it was officially migrating to something completely different – called Nitro – I was a little concerned.

That turned out to be well-founded. I tried installing Craft's Nitro application several times over the couple of years they used it, but I never once managed to get it to work. I don't quite remember the sticking points now, but I think Windows optimisations weren't great, and it relied heavily on a much broader tech stack including arcane tools like Docker, which I've never been able to get to do anything remotely sensible by myself. As a result, I wasn't exactly disappointed to discover that, with Craft 4, the company had switched directions again, retired Nitro, and was now recommending a more broadly used tool called DDEV. Guess I need to try and install that, then 😅

Despite my misgivings – and the pit my stomach sank into when I opened up the Quick Install Guide and saw the word Docker splashed around the page – I'll say that the DDEV installation process was not, in the end, awful. It also wasn't easy, and it sure as hell isn't "simple", no matter what the various support articles, blog posts, and kind commenters on the Craft Discord kept stating. If you come from a back-end, well, background, you'll probably find the installation a breeze. If you're using Linux or macOS, a lot of the gotchas simply won't exist for you. But if you're an ignored front-end dev on a Windows machine – like muggins over here – then there are some things it's useful to know about if you're taking a similar journey. For starters, there's WSL, which simultaneously makes the process much easier and means that the otherwise quite detailed installation guide occasionally devolves into a muddled mess of acronyms and assumed knowledge.


WSL (or WSL2 as it's often written in the DDEV docs) stands for Windows Subsystem for Linux. I'd be lying if I said I truly understand what it does, but the top-level explanation is that lets you run a Linux environment from within either Windows 10 or Windows 11, using some sort of virtual machine black magic. Once installed and configured – a surprisingly easy process – you can launch a WSL terminal, in the same way you can natively launch a regular CLI or Powershell terminal. With that open, you are effectively remotely controlling a Linux machine, through which you can install, run, manipulate, and generally utilise any kind of Linux command line software[3].

This allows you to install DDEV – and subsequently Craft – within a Linux environment, which has some pretty large advantages. For starters, the chances are very high that the server you deploy Craft on is running some flavour of Linux, so this brings your development environment into greater parity with your production environment. Secondly, both pieces of software are more optimised for Linux, which means your dev environment is snappier and less prone to bugging out. Finally (and this is more conjecture on my part) it seems to help sidestep some of Windows' less developer-friendly quirks, because WSL terminals have their own permission system, rather than using the often hard-to-control Windows Admin modes.

You'll see DDEV's documentation mainly reference WSL2, which is the latest version of the tool; they also recommend installing Ubuntu via WSL, rather than any other Linux distro. Don't worry about either of these "requirements". I found WSL2 is automatically installed via the activation command (see below) and the setup defaults to Ubuntu, so as long as you say "yes" if prompted (you may not be), you'll end up with the correct configuration with no fiddling or finagling required.

Right, so overall, WSL is worth using, but how do you go about doing so? I mean, you can install DDEV on Windows natively via a typical .exe file, but this is heavily discouraged, it's seemingly slower and generally a worse experience, so I didn't even try it. Instead, here are the steps I took:

  1. Open up a new terminal (Win + R, type cmd, hit Enter);
  2. Enter wsl --install – yes, this will just work without downloading anything. It seems Windows comes with a trimmed-down WSL installer built into the native CLI;
  3. If prompted for elevated permissions, grant them;
  4. Once the installation is complete, reboot your PC;
  5. On restart, you should see a WSL terminal open automatically and continue the Ubuntu install:

    Terminal window with the title
  6. Input a new username and password when prompted (these are the Linux install's main account, nothing to do with DDEV etc.);
  7. You'll get a success message along the lines of "Installation successful!", a welcome message from Ubuntu, and should then be able to use the terminal.

You can test the install process was fully successful in a couple of ways:

  1. Close the current terminal window and launch a new Windows terminal (see above);
  2. Enter wsl to load a WSL2 environment. This should result in either a Ubuntu welcome message or just getting a WSL terminal interface (for me this looked like a green username plus a mounted, blue folderpath);
  3. Enter lsb_release -a and you should get a printout of your Ubuntu version.

And that's all you need to do – WSL is now installed! 🎉

The last (albeit optional) step is to add WSL to the list of software Windows will automatically keep updated. I'm honestly not sure if this is a good or a bad thing; typically I like full control over a development environment. But there is a clear security risk with having a virtual machine installed that can run on a hidden terminal and manipulate almost every aspect of your OS architecture, so in this case I was happy to have it receive security patches ASAP.

To do this, go to the Windows Settings panel (you can launch it from the Start menu), select "Update & Security", and then "Advanced Options". If you scroll down you'll find a toggle to "receive updates for other Microsoft products" which should be enabled. There isn't any more modular way of doing this – it's all or nothing – but oh well.

Configuring DDEV et al.

Now that we have the operating environment for our tools, the rest of the process is fairly "typical" for a development environment: install a bunch of tools in a certain order using a CLI. The only difference is which CLI you use, because some parts will need to be done directly in WSL and others want to be installed via Windows itself. I'd start by closing any existing terminals that you have open, just to make sure you don't input something into the wrong one (like I did 😉).

  1. Open a new Powershell terminal in Admin mode (right-clicking the Windows logo in your taskbar and selecting "Windows Powershell (Admin)" is the simplest route);
  2. Enter the following command[4]:

    Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
    iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/ddev/ddev/master/scripts/install_ddev_wsl2_docker_inside.ps1'))
  3. This will kick off a sequence of installations and configuration prompts, starting with installing Chocolatey (if not already installed);
  4. Next it will install mkcert and create a new certificate; you may get a security prompt (see below) popup, so select "yes":

    A censored security warning seeking confirmation that the user is okay with the installation of a root certificate that Windows cannot verify.
  5. Finally, you'll see a bunch of Ubuntu libraries and packages being installed – this can take quite a while, and may appear to hang once or twice, but give it time and you should eventually get a success message staying "download complete" alongside the installed packages. These should include DDEV, Docker, Mutagen, and a few others:

    Confirmation message showing a Docker download being completed and a table of installed packges, including DDEV version 1.22, Docker version 24, and various helper libraries such as docker-compose, ddev-ssh-agent, and others.

We now have DDEV, Docker, WSL, and all of the other helper tools installed on our system, but how do we use it? The simplest way is via a WSL terminal, which can be launched from the Start menu or via any other CLI by entering the wsl command (as above). If you do that now and enter ddev -v you should get the current version number back, for example.

But that's not the most efficient way of interfacing with these tools, nor does it let us actually edit code. For that, we need an IDE; I'd personally recommend Visual Studio Code. Once you have that installed (this is a normal program installation on every OS), or if you have it already installed, open up a WSL terminal and enter code . (note the full stop) to launch VSCode from within the WSL environment.

You may be asked to trust the authors of the files, so select "yes" to any security prompts. You'll likely also get prompted to move the workspace to the Linux file system, but ignore this message (for now). The third prompt will hopefully be to install the WSL integration for VSCode, which you should do. If that doesn't happen, you can open the extensions menu and search for WSL; install the one with the Microsoft verification sticker.

At this point you should have WSL integrated with VSCode. Open a terminal from within the IDE and test it out; it should automatically open as either WSL or Linux Bash (either is fine), but if a Powershell or regular Windows terminal loads use the wsl command to convert it. You can then test the integration using ddev -v or any other WSL-specific command and they should just work.

There are some additional potential issues with using Firefox (see the Further Reading) but I didn't actually run into them so I can't say how annoying or troublesome they are. For me, launching a DDEV project just immediately loads in Firefox, by YMMV.

The Importance of File Spaces

With all of the necessary tools installed, you can jump into the Craft documentation to actually install Craft and get your development environment up and running; they're honestly very well written and I had almost no notes coming out of the back of the process. The one note I did have – and it was, admittedly, a big one – was "watch out for file spaces". Whilst I'd managed to get Craft installed and running relatively easily, once it had loaded it was sloooow. Like, ten-seconds-to-load-a-page slow. I asked about this on the official Discord, expecting that I needed to configure some system resources to WSL or something, but it turns out I'd just used the wrong file space.

Y'see, WSL can and will interact directly with your local Windows files, folders, and programs; that's the genius of it. So you can launch a DDEV project from your local C: drive, or pull an image from an attached USB stick, or whatever you want. But this isn't a simple process. There's some kind of middleware called Mutagen that makes this work (if I'm understanding things correctly), translating Windows functions into Linux commands and overseeing the whole two-way flow of data automatically. And that translation takes a second or two, which is why everything was running so slowly for me.

The trick is to make sure any files or folders being used by DDEV are stored on the Linux file system. Which sounds simultaneously incredibly simple and horrifyingly tricky. After all, we only have a WSL terminal to work with here, right?

Wrong! In the same way that DDEV can launch Firefox or Chrome from within WSL – even though those programs are installed and operating in Windows – we can also manipulate the Linux system from within Windows programs themselves. So if you pop open Windows Explorer, you can navigate to the folders stored inside the Ubuntu/Linux install. And yes, you can just copy and paste into those folders from Windows (or vice versa).

So if you're like me and have all of your code projects in a "Code" folder somewhere on your Windows machine, and that's where you installed Craft out of habit, you only have to copy and paste it across into the Linux VM and go from there. Finding that VM is a little less obvious, but it shouldn't take too long. For starters, if you launch a new WSL terminal (preferably not within VSCode this time) and enter explorer.exe . (again, note the full stop) it should just open an Explorer window at the root of your Linux file space (i.e. there shouldn't be a folder path starting with mnt). You can also access it through the Network folder, or as a mounted drive, if you look in the left-hand sidebar of a new Explorer window (Win + E); the user folders should be under something like Ubuntu\home\<username>.

Once you've located it, you can copy and paste the whole folder, then launch VSCode, open that folder, and your IDE should automatically switch to WSL mode. From here, open a Terminal, launch your CMS via the DDEV commands (ddev launch normally, though you may need to start the server first) and you're off to the races 🐎

So long as you now stick to doing everything from within the same filespace, the application should run smoothly (and genuinely blazingly fast) and everything should "just work" 🤞

Overall, then, was all of that worth it? Yes. I hate how convoluted server environments need to be, but now it's all up and running I've been happily tinkering without so much more as the occasional ddev restart or ddev launch – everything else just happens in the background. Need to sync a database?

ddev import-db --src=<file-path>

Need to generate a migration?

ddev php craft migrate/create <migration-name>

Update a plugin (assuming you've edited the package.json first):

ddev composer update

Heck, need to create a new Craft install to play around with some new plugin or workflow theory? Even that is only a handful of commands, and when I'm done, I just wipe the folder from the drive.

I've been able to install a specific version of Craft, configure my local environment, and then walk through the steps of upgrading to latest step-by-step, testing the whole way. Get something wrong? Wipe it and start again; it takes minutes, tops.

In the end, that upgrade process turned out to be pretty painless, but that's only because I was able to make mistakes early and often using DDEV. Critically, I feel like the team behind Craft have finally delivered on the promise that Nitro made: a "simple" environment that lets you spin up Craft installs with ease. Which is to say, it isn't simple to get going with (so don't worry if you're struggling; I had a lot of help from the folks in the Discord) but once it is up and running, it removes a lot/all of the sysadmin work, which is fantastic 👏

Explore Other Articles


Styling on the Server

The increasing use of React Server Components is meaning the end of the CSS-in-JS era. But what options exist to fill that gap? I've been pleasantly surprised with what I've found.


Better Diacritics on Windows

Annoyed by Alt-codes and incomplete keyboard shortcuts? Yearn for the long-press functionality of every other OS? Just freakin' want easier en-dash access? Windows doesn't have to be this annoying; there are some options!

Further Reading & Sources


Want to take part?

Comments are powered by Webmentions; if you know what that means, do your thing 👍


  • <p>Various notes from my battle to get a local development environment working for Craft CMS.</p>
  • Murray Adcock.
Article permalink

Made By Me, But Made Possible By:


Build: Gatsby

Deployment: GitHub

Hosting: Netlify

Connect With Me:

Twitter Twitter

Instagram Instragram

500px 500px

GitHub GitHub

Keep Up To Date:

All Posts RSS feed.

Articles RSS feed.

Journal RSS feed.

Notes RSS feed.