A Love Letter to DDEV
I have a general love/hate relationship with development environments. There are times when it gets so complex that you spend more time fixing the environment than actually developing. I’ve tried many solutions over the years, depending on the type of project, programming language and general requirements. Some were good, some were bad - some were genuinely frustrating.
It seems to be that the dev community is constantly looking for the perfect solution - but with the sheer amount of programming languages, frameworks and tools out there, it’s impossible to have a one-size-fits-all solution.
WampServer#
I remember setting up WampServer for PHP projects back in the day. It was all you needed - install it on Windows and you had Apache, MySQL and PHP ready to roll. But with new PHP development moving at a rapid pace, it started to feel outdated. WampServer is very much tied to specific versions, so upgrading didn’t give me the amount of flexibility I needed.
Laragon#
Then came Laragon. I don’t post a lot on this blog, but one of the posts that has the most views is one where I explain how to change the PHP version in Laragon. I’m not sure what happened with their website but from what I recall, their forum shut down, and they moved to GitHub discussions and as the forum posts were mainly where most of the tutorials were, it pretty much wiped a load of things, and it was full of dead links. It’s still a great tool - you can easily switch PHP versions, it comes with Mailpit ready to go, it’s lightweight, but it’s Windows-only, already the user interface feels a bit dated and I can’t put my finger on it, but it just feels a bit hacked-together.
This isn’t a bash at Laragon - I imagine it’s a great tool, but I just don’t feel it’s the right fit. I looked into the state of it when writing this post, and it seems a lot of the documentation has been restored on their GitHub repo and they’ve added a few new features but still, I can’t help but feel it just had that “clunky” vibe to it.
Enter DDEV#
Then I discovered DDEV. At first, I was a bit sceptical. I don’t like Docker much - mostly because it just seems like an unnecessary layer of complexity. I’m very aware that I’m in the minority here but the whole concept took such a long time to get my head around, by the time I did, I’d got that much of a bad taste in my mouth that I didn’t want to bother. I should say that I’m referring to “Docker” as in the vanilla Docker experience, not the ecosystem around it.
DDEV is a tool that’s built on top of Docker, but it abstracts away a lot of the faff. Its sole purpose is to make local development easier, and it does just that - and more. It’s mainly targeted at PHP developers and has some built-in support for most popular CMSes like Drupal and WordPress, but it can be used for any PHP project.
You define your environment in a very simple config file that - if you stick to the defaults - generally looks like this:
name: project-name
type: php
docroot: ''
php_version: '8.3'
webserver_type: nginx-fpm
xdebug_enabled: false
additional_hostnames: []
additional_fqdns: []
database:
type: postgres
version: '17'
use_dns_when_possible: true
composer_version: '2'
web_environment: []
corepack_enable: false
From there, you just run ddev start in your project folder, and it does all the hard work for you - containers are built, services are started, databases are spun up, and you get presented with an mkcert-signed HTTPS URL to access your project at https://project-name.ddev.site.
Very, very simple. You don’t have to worry about Docker (other than getting it installed), you can set your “public” folder which is where Apache/Nginx will serve from, you can set just about any PHP version (within reason), and you can even add additional background processes if you need them.
Isn’t that just Laragon but with Docker?#
Not quite. Laragon is Windows-only. DDEV is cross-platform and runs on pretty much any platform that Docker supports. For Windows it works best with WSL2 - which is another tool that I love, thanks to DDEV.
The USP of DDEV for me isn’t the fact that I can pretty much start the project from any workstation and have it pretty much exactly the same without having to worry about Docker itself. It’s the fact that good people out there have spent their time porting common services to DDEV.
Mailpit? Built-in.
Redis? One line and it’s in.
Meilisearch? Bit niche but also one line.
DDEV has a whole ecosystem of add-ons that you literally just run ddev add-on get <addon> and it’s ready to go. No faffing, just restart your project with ddev restart and the service is there.
ddev describe#
All of these services are running in their own containers, but all it takes is one simple command and you’ve got a table in the terminal that shows you every service that’s running under the hood, their internal ports, their external ports, and how to connect to them.

This is beautiful. No more trying to remember which port MySQL is running on, or what the root password is. It’s all there, in one place.
Non-PHP Projects#
So I’d used DDEV for a while for PHP projects, and I was very happy with it. But then I started to do what every PHP developer does at some point - I got lured in by the beautiful world of Javascript - and Node.js. Things got complicated. Yes, I’ve got Node installed and I’m using WSL thanks to DDEV so I can easily set up Postgres and Redis, but I miss the pretty URLs. I miss the one-liner setup. I miss the simplicity.
Turns out, I’d completely missed the memo that DDEV can be used for non-PHP projects too. Those containers that DDEV spins up? You can use them for Node too. See, one of the things that DDEV also does was staring me in the face the whole time. Remember those background processes I mentioned earlier? You can make one of those a Node.js process.
DDEV has built-in support for Node and Yarn.
web_extra_daemons:
- name: 'my-app'
command: 'yarn dev'
directory: /var/www/html
Boom. That’s it. I’d recommend setting your Node app up and ensure it’s running first with ddev exec (the command that lets you run commands inside the web container) and then add it as a background process once you’re happy.
I also recently found out that thanks to DDEV’s amazing community, there’s even a DDEV add-on for Bun - which is particularly useful as my two current projects are using Bun as their runtime. (Cheeky plug! LoveInvoice and FormKid - coming soon! 😉)
Other Features#
This is already becoming an essay so I’ll try and keep this brief. Here are some other features that I love about DDEV:
- Extra Exposed Ports: If you need to expose additional ports for your services, you can easily do that in the config file.
- Apache/Nginx Configuration: You can add custom configuration files for Apache or Nginx if you need to tweak something or proxy requests to your Node app without exposing the ports.
- Additional Hostnames: FormKid runs the same application for both the API and its submission endpoint, but on different subdomains. Piece of cake.
- Database Management: Add-ons for Adminer and phpMyAdmin. All you need really. Oh, and the databases are created for you automatically with every project - just choose between MySQL, MariaDB or Postgres and set all the options except the port (yes, including hostname) to “db”.
- Built-In Composer: Just run
ddev composerand it works. No need manually add Composer on your host machine or inside the container. - Add-ons: There are so many already.
- Need to check logs?: Cool.
ddev logs -f
Conclusion#
Overall, I am in love. This tool has made my life so much easier. If you have a spare few minutes and want to try something that is going to make your development life easier, give DDEV a go. You won’t regret it.
