I've been using Vagrant + VirtualBox for a few years now and have become quite accustomed to spinning up a local development environment in 10 to 15 minutes. I can configure that toolset to do what I want, but altering /etc/hosts, apache/sites-available, and running commands like "sudo service reload" gets repetitive and cumbersome when I don't need the separation of concerns between my OS and the virtual machine. Our project manager suggested trying out DDEV, so this past week I took some time to give DRUD'S new tool a trial run. 

What is DDEV?

DDEV is, "An open source tool that makes it easy to spin up a PHP development environment." It's advertised to be flexible, extendable, and easy to work with on teams by eliminating the complexities of cross-host configuration.

I had my doubts that it would be as smooth as advertised, but so far my experience has been positive overall. The docs were very straightforward and I'll be referencing them throughout the piece. I would recommend bookmarking them and skimming through at least once to pick up its capabilities.

With that said, here's how easy it was to get it working.

First things first: Installation

Note: I'm coming from a Mac environment.

Starting Docker

  • DDEV won't work without running the daemon. Confirm that it's running by clicking it on the utility bar.

Docker is running

  • On Linux/Ubuntu, you'll probably need to run sudo service docker start or similar.

Now that Docker is installed and running, clone the site's repo into the directory you'll be working in and CD into it.

ddev start/config

  • Import your site's database: ddev import-db --src ~/Downloads/mydb.sql

import-db

  • It creates an setting.local.php: you'll need to copy this into settings.php.

You can then ddev ssh if needed and you're into the Ubuntu container. Tools like Compass are not installed by default on these images. You could install whatever you'd like but we decided it would be best to install and run compass watch on the host machine to listen for changes.

That's it. You're done - visit one of the URL's provided when ddev start completed.

The difference between Docker(Containers) and Vagrant(Virtualization)

Vagrant is a virtual machine manager. It helps you create, provision, and share a virtual machine. This is an operating system running on top of your native operating system. 

Virtualization is different in that each virtual machine (VM) runs its own entire operating system inside a simulated hardware environment.

Pros: The separation between the virtual machine(s) and the host enables you to have Linux virtual machines on a Windows host or vice versa.

Cons: You have to dedicate a set amount of resources to the VM's, and the hypervisor will eat up a lot of resources.

Docker creates virtual containers using a system called (surprise) containerization. Containerization allows multiple applications to run in isolated partitions of a single Linux kernel running directly on the physical hardware. 

Pros: Performance is higher than virtualization since there is no hypervisor overhead, and you are closer to the hardware.

Cons: Containers use the host machine’s kernel (shared).

There are a number of comparisons of Docker vs. Vagrant out there, but in essence: Virtual machines offer greater isolation at the expense of overhead, as each VM runs its own full kernel and os instance. Virtual containers offer less isolation, but lower overhead through shared resources of the host kernel and the operating system.

The two are not mutually exclusive - you can use Docker inside of Vagrant! The key takeaway here is that containers are generally more lightweight than virtual machines. Starting and stopping containers is extremely fast... which is very useful in my Drupal development workflow!

There are plenty of configuration options in DDEV, from extending DDEV commands using hooks, capturing outgoing mail using mailhog, and a no-configuration setup for XDebug in VSCode, which i'll get into now.

Setting up X-Debug in VSCode

Setting up X-Debug for DDEV was pretty simple.

  • Install the php-debug extension by clicking the extensions left-sidebar-menu button in vscode.
  • add this snippet to your launch.json's configurations array, which can be found by clicking on the Debug left-sidebar-menu button in vscode, and clicking the "gear" icon:

Gear icon

  • Here's an example of my newly modified launch.json
{

  "version": "0.2.0",

  "configurations": [

    {

      "type": "php",

      "request": "launch",

      "name": "Launch Program",

      "program": "${file}",

    },

    {

      "name": "Listen for XDebug",

      "type": "php",

      "request": "launch",

      "port": 9000,

      "pathMappings": {

        "/var/www/html": "${workspaceRoot}"

      }

    },

  ],

}
  • Then set a breakpoint and run the 'Listen for XDebug' job. You can also press F5 in the file you've set the breakpoint in.
  • You may also need to edit your .ddev/config.yaml file and set xdebug_enabled to true.

Wrap-up

Though I have not had to set up a multi-site install or done any complex configuration, DDEV seems to function as advertised. In fact, I've made the switch this week to a DDEV-only workflow. I'm sure there are ways to customize a container on initialization (having Compass installed by default etc.) However, I'll leave that for a later article. Until then I would recommend having a look at DDEV for local PHP environments - it could save you and your team quite a bit of time if it fits into your workflow.

Troubleshooting

Q: "ddev start" fails with:

Failed to start $SITE: db service health check timed out: labels map timed out without becoming healthy, status=exited

A: It's likely that you closed out Docker prior to shutting down your ddev instances. This causes the database connection to be cut off without closing correctly, therefore corrupting the database and not letting you start up your container with ddev start.

Running ddev remove --remove-data, will remove the corrupted database, allowing you to run ddev start, and ddev import-db --src. See: https://github.com/drud/ddev/issues/805

Q: "ddev start" fails with: 

Failed to start mysite: Failed to migrate db from bind-mounted db: failed to run migrate_file_to_volume.sh, err=failed to create/start docker container... container already exists

A: You may need to clean up your docker containers. What worked for me was running docker container prune. See: https://stackoverflow.com/questions/52075900/ddev-update-migrating-bind-mounted-database-in-ddev-to-docker-volume-mount

Q: How do I get the database information? (For MySQL workbench etc):

A: ddev describe will output your containers database information. Protip! phpMyAdmin is built into your container instance - just visit mysite.ddev.local:8036 (8036 by default).

Q: How do I switch php versions?

A: Simply edit your .ddev/config.yaml file:

php_version: "x.x"

The current default is php 7.1.