Migrating from Craft Nitro to DDEV
With Nitro being discontinued, we recommend DDEV as a great local development environment:
- It’s Docker-based, freely available, and it works on macOS, Windows, and Linux.
- It’s well documented and has an active community.
- It’s perfect for PHP-based projects like Craft.
- It’s a convenient layer on top of Docker, and you can bring as little or as much Docker as you want.
For each site you migrate, you’ll need to grab a database export (from Nitro or your production environment), create and configure a new DDEV site, and import the database.
Most sites should only take a few minutes to migrate.
1. Export existing databases #
Pick either method for exporting each site’s database:
- From your production environment, you can visit the Craft control panel (with sufficient permissions) and navigate to Utilities → Database Backup, make sure Download backup is checked, and press Backup. This will create and download a compressed database dump.
- From your local machine with Nitro installed, you can run
nitro db backup
and choose each engine and database. (Take note of the directories these are saved to, or collect the backups someplace more convenient for step 5.)
While you can use tools like pg_dump
and mysqldump
, we recommend using Craft or Nitro’s export options because they’re configured to keep things consistent and encourage a smooth experience.
2. Stop Nitro #
Running Nitro and DDEV simultaneously may invite port conflicts, so we’ll stop Nitro to ensure that DDEV will be the only local environment running.
You can stop all Nitro’s containers using the stop command:
nitro stop
3. Install DDEV #
Follow DDEV’s documentation get it installed and running on your OS.
4. Create DDEV sites #
In the same way you’ve used nitro add
to create a site with Nitro, you’ll use ddev config
to create a site with DDEV.
- Navigate to your project directory, run
ddev config
, and follow the prompts. The auto-detected docroot (web
) and project type (craftcms
) should work for most projects, but you can pass them explicitly if you're using a non-standard setup:ddev config --project-type=craftcms --webroot=app/public
. - Open the newly-created
.ddev/config.yaml
to adjust settings.- Set
php_version
to whichever you need. (More inconfig.yaml
’s comments.) - The database type can be
mariadb
,mysql
, orpostgres
with a corresponding version. - Use
additional_hostnames
for other*.ddev.site
domain names you’d like to use, oradditional_fqdns
for other custom domain names.
- Set
- Run
ddev start
to prepare and run the containers needed for the site. - Run
ddev describe
to get details about the site, and update Craft’s settings with new path and database connection details:CRAFT_DB_SERVER=my-site-db
(DDEVInDocker
hostname)CRAFT_DB_DATABASE=db
CRAFT_DB_USER=db
CRAFT_DB_PASSWORD=db
DEFAULT_SITE_URL=my-site.ddev.site
(DDEVweb
URL)
This will write a .ddev/
directory at the root of the project. You can either add that directory to your .gitignore
file or check it into your project to share with other developers and/or machines.
DDEV’s default container path is /var/www/html
, so you may need to update any references to Nitro’s /app
directory. If your web root is /app/web
, for example, it will become /var/www/html/web
.
Any time you’ve saved edits to .ddev/config.yaml
, you can use ddev start
to apply them and restart the container(s).
5. Import databases #
From each project directory, import the database export you prepared in step 1:
ddev import-db --src=dump.sql
That’s it! You should be able to run ddev launch
to open your freshly-migrated site in a browser.
6. Uninstall Nitro #
To remove Nitro from your system, run nitro destroy
and follow the OS-specific instructions for removing the system components that are left.
Getting Oriented #
At a high level, Nitro and DDEV are not wildly different. DDEV offers a lot of additional functionality and some key architectural differences:
- Each project has its own YAML and supporting configuration files, and generates intermediate Docker Compose YAML you can customize (or never look at!) depending on your needs.
- Each project is more tightly coupled to its database, which runs in its own separate database container.
- Projects can be independently started and stopped.
- You can add first- and third-party services like you could with Nitro, but you can customize further with config file conventions, hooks, Docker Compose, and whatever custom images you’d like to introduce.
Connecting to the Database #
DDEV is similar to Nitro in that you’ll need to be mindful about connecting to the database container externally or within another Docker container.
Use ddev describe
to see project details that include a db
section. The InDocker
details are what you’d provide Craft, while the Host
details are what you’d use externally for something like a GUI client. (Notice the Host port, which will change with each project.)
Credentials will always be db
for the username, password, and database.
macOS users with TablePlus installed can use ddev tableplus
to open the current project’s database without entering any connection details. DDEV has commands for other database GUIs, as well!
Starting and Stopping Projects #
Each project can be started with ddev start
, which will apply any configuration changes. ddev pause
will pause a project’s containers, and ddev stop
will remove the containers while preserving data. (You can use ddev stop --remove-data
to remove all project data.)
To have DDEV remove and forget everything about a project including its configuration, use ddev delete --omit-snapshot --yes
.
Xdebug #
Nitro’s xon
and xoff
commands become ddev xdebug on
and ddev xdebug off
, and you’ll need to remap PhpStorm and VS Code to the container’s new folder structure. (/app
→ /var/www/html
.)
Learn more in the DDEV docs. There’s also a video tutorial on configuring PhpStorm and DDEV.
Redis #
Redis isn’t included with a new site, but the first-party service is quick to add:
ddev get drud/ddev-redis
ddev restart
You’ll need to provide Craft with your the new Redis container’s hostname, which you can find running ddev describe
.
If you’ve configured your Craft site like the examples in the documentation, you can specify the hostname in your .env
file:
REDIS_HOSTNAME=ddev-my-project-redis
Custom Ports #
DDEV automatically notifies you about any port conflicts so that you can stop conflicting services. You can also configure DDEV to use non-conflicting ports from .ddev/config.yaml
.
Learn more in the DDEV docs.
MailHog #
MailHog is included by default with each new DDEV site.
Run ddev describe
to get that project’s MailHog URL, or run ddev launch -m
.
Node.js & npm #
Each web container comes preinstalled with node
, npm
, nvm
, and yarn
. You can configure the default versions and override that with the ddev nvm
command.
If you run any additional web servers inside the web container—Vite or webpack, for example—you’ll need to use a custom Docker Compose file to open the ports you’d like to use. One Darnley Road’s starter project has a great example for using Vite with port 3000.
Cheat Sheet #
Most Nitro commands have a DDEV equivalent.
Nitro Command | DDEV Command |
---|---|
nitro add | ddev config |
nitro apply | ddev start |
nitro bridge | No DDEV equivalent. |
nitro clean | ddev clean |
nitro completion | See Adding Shell Completion (bash, zsh, etc.). |
nitro composer | ddev composer |
nitro context | ddev describe |
nitro craft | ddev php craft |
nitro db add | ddev import-db --target --src (see docs) |
nitro db backup | ddev export-db |
nitro db destroy | No 1:1, but ddev delete removes project information including the database. |
nitro db import | ddev import-db |
nitro db new | Each engine is created when adding a database. |
nitro destroy | See Uninstalling DDEV. |
nitro disable | ddev service disable |
nitro edit | No DDEV equivalent. |
nitro enable | ddev service enable |
nitro extensions | No 1:1. See Providing custom PHP configuration (php.ini). |
nitro help | ddev help |
nitro hosts | ddev hostname |
nitro iniset | Static files. See Extending and Customizing Environments. |
nitro init | Resources initialized on demand. |
nitro logs | ddev logs -f |
nitro ls | ddev list |
nitro npm | ddev exec npm |
nitro php | ddev php |
nitro portcheck | Port conflicts are automatically called out. |
nitro queue | ddev php craft queue/listen --verbose |
nitro remove | ddev delete |
nitro restart | ddev restart |
nitro self-update | Depends on install method. See Installation. |
nitro share | ddev share |
nitro ssh | ddev ssh |
nitro start | ddev start |
nitro stop | ddev poweroff |
nitro trust | n/a |
nitro update | ddev config + ddev start for each project. |
nitro validate | Project YAML validated on the fly. (i.e. for ddev start ) |
nitro version | ddev version |
nitro xoff | ddev xdebug off |
nitro xon | ddev xdebug / ddev xdebug on |
Shell Aliases #
If a common command like ddev php craft
or ddev xdebug on
is a bit too much keyboarding, you can create your own shell aliases:
alias ddev-craft="ddev exec php craft"
alias ddev-xon="ddev xdebug on"
alias ddev-xon="ddev xdebug off"
Troubleshooting #
If you run into issues with your migrated sites, check out Troubleshooting a Failed Craft Installation and Troubleshooting Database Connection Issues.
If you’ve got an internal server error that’s not generating application-level logs, you may be able to use ddev logs -f
to take a look at relevant container logs as they’re written.
If all else fails, consider troubleshooting in the #devops channel in the Craft CMS Discord server or popping by DDEV’s own Discord server.
Further Reading #
- CraftQuest DDEV and Craft CMS Quick Start Guide
- CraftQuest’s Starter Code for Craft CMS article includes some opinionated Craft CMS scaffold projects, DDEV and beyond.