Nitro 2: The Docker powered development environment for Craft CMS

Pixel and Tonic have recently released Nitro 2, a tailored development environment for Craft CMS. Previously version 1 was based off Multipass. Nitro 2 however is big shift being based on Docker. More importantly for me, thanks to Windows Subsystem for Linux 2 (WSL2), there is a smoother Windows environment option now available, albeit with some caveats. Let’s explore Nitro 2 and why you should consider using it with your Craft CMS projects!

Docker is cool. I must admit I’ve been late to the Docker party. I’ve previously used environments like Vagrant and Nanobox and only recently decided to explore what Docker can do and what the fuss is about. Primarily working in Windows environments and thanks to the more recent Docker and WSL2 integration, the virtualisation and performance issues that hinder most environments on Windows (aside from a native IIS server) are somewhat mitigated with the Docker and WSL2. I have found over the course of several years that Windows is often a pain in the arse for a lot of development environments, mainly due to the layers of abstraction with virtualisation and the NTFS file system = SLOOOOOOOW. As well as issues with tools like npm which are symlink happy which also doesn’t play nice with the Windows filesystem with virtualisation. Of course, the poking fun answer is use a real Unix system to avoid this, but for various reasons my day to day work is done on Windows or WSL itself.

With Nitro 2, you must use WSL2 and Docker for Windows support but there are good reasons for it, mainly performance. There are also a few worthy mentions of the best configurations when using Docker and WSL2. The good news is, WSL is available on any SKU on Windows, so no more Windows 10 Pro Hyper-V dependency, that means any Windows 10 version can use Nitro 2, providing you are using build 19042 or above, as this is when WSL2 was released outside of insider builds.

Nitro is designed to do all the heavy lifting for you. While it’s cool to learn about docker-compose and crafting your own docker-compose.yml or Dockerfile, sometimes you just want to write code right? As a developer I sometimes have a love-hate relationship with how much time you can sometimes spend messing around with development environments on your local machine to have things “work”. Fortunately with Nitro 2, this process is made straight forward with two simple commands nitro init and nitro add

The init command essentially creates the base Docker containers and pulls the required images needed. Here you get to configure one or more database backends i.e. MySQL, in addition to Redis and some other toys.

Fun fact, Nitro uses official Craft CMS docker images. I previously evaluated the Docker images themselves outside of Nitro first and found them to be nicely curated and configured, well suited to Craft CMS development.

The add command, is for configuring an actual Craft CMS site, setting a hostname, the PHP version etc. You run this in the root of a Craft CMS project.

Example:

$ cd /path/to/project
$ nitro add
Adding site…
Enter the hostname [mysite.test]:
✓ setting hostname to mysite.test
✓ adding site ~/dev/support/mysite.test
Enter the webroot for the site [web]:
✓ using webroot web
Choose a PHP version:
1. 8.0
2. 7.4
3. 7.3
4. 7.2
5. 7.1
6. 7.0
Enter your selection: 2
✓ setting PHP version 7.4
… saving file ✓
Site added 🌍
Apply changes now [Y/n]? y
Checking network…
✓ network ready
Checking proxy…
✓ proxy ready
Checking databases…
… checking mysql-8.0-3306.nitro ✓
… checking postgres-13-5432.nitro ✓
Checking mounts…
… checking ~/dev/craftcms/cms-3 ✓
Checking services…
… checking mailhog service ✓
Checking sites…
… checking mysite.test ✓
Checking proxy…
… updating proxy ✓
Modifying hosts file (you might be prompted for your password)
Adding sites to hosts file…
… modifying hosts file ✓
Nitro is up and running 😃

Currently Nitro 2 does not support a way to automatically provision an environment based off a yaml file in similar way to docker-compose.yml, but it’s a feature request and it’s coming soon! This is more useful for multi-dev environments or when you deploy a specific project across multiple operating systems/different machines. While Nitro makes it straight forward to provision sites, constantly being prompted the same specific answer values is slightly time consuming and hence a non-interactive method of provisioning is something I’m looking forward to!

Nitro 2 provides a lot of options for configuration and extendibility, these include:

I would recommend not using anything lower than PHP 7.3 due to the EOL status of anything below 7.3 at this time of writing.

The great thing with Nitro 2 is you can easily add or swap out various elements with simple commands. You can also run multiple database backends at the same time. Nitro does the heavy lifting behind the scenes and sorts out all the container configuration and requirements, leaving you to just get on and code, the dream!

This is one of the major plus points for Nitro 2. If you have used Docker standalone you will know about port forwarding, mapping ports and making a service available to localhost for accessing on the host machine. Because of the way Nitro 2 is designed it essentially uses a reverse proxy to automatically send requests to the right configured Docker site container that has been requested by looking at the hostname. This means all your Nitro 2 Craft CMS sites can be reached on the standard HTTP and HTTPS ports through the example-site.nitro hostname (other TLDs are available). You don’t have to worry about multiple sites and having to select a unique port like 8000, 8001, 8002 etc. Similarly for services like MySQL, Postgres, Redis etc, these are configured as shared instances which can then be used by any site. Although if you did need to run two different versions of MySQL as an example, one would have to be on different port, as the default port 3306 cannot be used twice, but this would be automatically configured for you on a different port i.e. 3307.

This is a major bonus as the networking stack of Docker is notoriously difficult to manage manually and you can quickly get lost in some of the bridge, NAT and if you dare, complex VLAN configuration.

Because Nitro 2 uses Caddy as a proxy. It can take advantage of automatic HTTPS. These days with HTTP/2 being heavily tied to SSL, having valid and properly configured SSL certificates even for development environments make sense for performance. By leveraging LetsEncrypt, this is all configured for you. The exception is WSL2, which requires running certutil on the host to install the Caddy root certificate so the Windows host will see any Nitro site as valid, this is however prompted when needed and guides you on how to do it. Nitro 2 does not force SSL on any site requests configured however. While you can enforce HTTPS yourself, you might not want to as in some cases you may use something like browsersync which cannot proxy HTTPS without valid certificates being configured, instead you could continue to proxy plain HTTP for this scenario without further configuration.

While Craft CMS 2 is very much under security updates only now these days, there are some of us that may still be maintaining or migrating large Craft CMS 2 projects. Fortunately, Nitro 2 supports Craft CMS 2 sites as well. It isn’t exactly designed for Craft CMS 2, but because Nitro 2 let’s you configure the appropriate webroot path, you can run any Craft CMS 2 under Nitro alongside Craft CMS 3 sites as well. Typically the webroot for Craft CMS 2 sites would be public compared to the web webroot that is default with Craft CMS 3. Nitro is able to set this accordingly during nitro add and in most cases will automatically detect it based on the project structure.

There are plenty more benefits and features I haven’t mentioned but hopefully this gives you a good case for evaluating Nitro 2 as your development environment of choice. If you are already using Docker, I’d highly recommend the switch to Nitro 2, if you are considering switching your development environment from something else, definitely give Nitro 2 a try!

Here’s some resources to start you off.

Some thoughts from other developers:

I'm a web developer, but also like writing about technical networking and security related topics, because I'm a massive nerd!