Matt Watson

You might not need Docker

Matt Watson

I came accross a very good article on how to use Docker with PHP by Tom Butler on SitePoint. Nonetheless, I took issue with some of his preliminary statements, namely:

If, like me, you’re old enough to have been developing websites in the 90s, you’ll remember how frustrating the experience was. Back then, if you were in the minority who didn’t just develop on the live web server (yes, we really did this, yes it was a terrible idea), you would manually install Apache, PHP and MySQL on your development machine.

Well, this manual installation is the way I currently develop, and I didn’t start in web development until 2016.

In a similar vein, Butler says:

If you hang around various PHP facebook groups, you’ll find that a significant portion of new developers still follow tutorials from this era and a large number of existing developers never moved on, so XAMPP is still used quite widely. If this describes you, it’s time to move on.

I haven’t used XAMPP much, but it is not much different than manually configuring your localhost server like I do. And I have used Mac’s paid equivalent, MAMP, with much success. I don’t think that if you use these and are happy, which I’m willing to bet is a lot of people, “it’s time to move on.” As with so many other “best practices” recommendations in web development, it all depends.

My job involves building custom WordPress sites on more or less traditional, shared hosting. Even the majority of my side projects are written on the LAMP stack and deployed on traditional, shared hosting. I have had a few outlier projects using non-traditional hosting, such as AWS, Vercel or a Digital Ocean VPS. It seems to me that the increasing recommendation to use Docker applies more to these non-traditional services for deployment than for traditional hosting. So right off the bat, the idea that Docker, whose main point is to let you spin up a containerized virtual server, is Best PracticesTM assumes I’m not using traditional hosting and can spin up containers on a server.

But the other benefit of Docker besides using it on a virtual server is that you can run exactly the same stack in your dev environment as on your live server. This is true up to a point. But it is not used this way 99% of the times I’ve personally seen it used. Whether we’re talking about Docker or the older, similar VM solution, Vagrant, I’ve seen them used primarily as a way to get a local dev environment going, but which hardly ever perfectly matched what was in production.

For example, I have used Lando, which is essentially an approachable command line program for people who don’t know Docker. I used it for several months after I had somehow deleted all of my MySQL users and locked myself out of my locally installed MySQL instance (MariaDB). The other day, I finally got around to updating my Linux desktop, resetting my MySQL users, and a few Stackoverflows later I was back up and running with a functioning MySQL instance on my local machine. But whether I’m using Lando or a manual localhost configuration, I rarely need to match exactly what’s on the server. As long as I’m on the same major version of PHP, I’m safe to deploy, at least to a staging server.

Lando/Docker did come in handy for me while my local LAMP installation was down, and once or twice I used it to test a different MySQL or PHP version that more closely matched my server. For those reasons, Docker is definitely worth having as a tool in one’s belt, but here are some advantages I’ve noticed about using a traditional localhost installation:

No long Docker container startups

I don’t have to wait for Lando to start up a Docker container, which takes a few minutes the first time it runs for a new project, and even after that it can take a while sometimes. My local, native Apache virtual host is already running for all my projects on desktop startup, which equals zero wait time when project switching, and it only takes a minute to set up the first time for a new project. A new project involves creating one new .conf file in my apache sites-available directory, updating the /etc/hosts file to include a testing domain (e.g., mynewproject.test), and running two terminal commands to enable the site and restart Apache. Not as easy as running “lando start” on the command line, but it’s easy enough once you’ve done it a few times and is way quicker.

Consistent localhost virtual domains

With a traditional dev environment using virtual hosts (like what I do on my Linux desktop, or what could be done using XAMPP or MAMP or Apple’s Homebrew), you get a consitent localhost domain for each project, e.g. myproject.test, mysecondproject.test, mythirdproject.test, etc.

Using Docker as described in the aforementioned SitePoint article, you would have to stop and restart Docker containers every time you switch projects/containers, so that the container in use can serve at localhost, port 80, i.e. “http://127.0.0.1” in your browser address bar.

I imagine you could run multiple containers simultaneously by using different ports for each container, as this is what Lando does somehow automatically, but this gets confusing and tiresome and doesn’t play well with a WordPress site that requires WP_SITEURL and WP_HOME constants in PHP. And maybe I’m doing something wrong, but whenever I spin up a new Lando project, it often breaks the last one I started in some way or another, usually changing ports at the least.

There is a workaround for inconsistant host names in WordPress in which you dynamically define WP_SITEURL and WP_HOME using the request Host header, but it is not ideal. The workaround doesn’t account for internal links in the blog post contents and the like. But on a dev environment running a native (L)AMP stack with traditional virtual hosts, I can both set those constants to “myproject.test” and run a DB search/replace to use http://myproject.test in place of https://myrealdomain.com if I need to … and then I am good to go for local development and never have to think about it again.

Running terminal commands locally

Installing PHP and MySQL locally and keeping them updated gives you the added benefit of running them from the command line without having to ssh into a Docker container. Lando makes this part of things a little easier by giving you various utilities such as the “lando wp” command for running wp-cli and “lando db-import” for importing a database. But if you try to use Composer or npm with Lando, it seems to error out a lot, at least for me. Not to mention, having all these dev tools installed on each container for every project starts feeling like a waste, even if there’s supposedly some Docker voodoo sharing all these resources. So, for all these reasons and more, you’ll eventually wind up installing all these things locally anyway. And by the time you do that, why not just install Apache and serve the site from your machine?

Final thoughts

My personal opinion is that there is no good way to set up a dev environment. It’s one of those unenjoyable things about life. Scouring blog posts on dev setups for the past four years, I’ve noticed that people turn to a new solution when they start having problems they don’t know how to fix on their old solution, which is perfectly justified. But I have spent enough hours in Vagrant hell, Docker hell, and manual configuration hell to know they are all created equal. There are pros and cons to each method, and it is up to the developer or the team to hedge their bets.

Some decisions can be more informed than others. If you’re turning to Docker just because of peer pressure or the constant assurance it’s the Right Way, you’re making an uninformed decision. If you are avoiding it purely out of fear, you’re making an uninformed decision.

But if you decide to use Docker, and you say, “I need it for spinning up VPSes,” or, “I need it for quick, streamlined project setup for a team of developers,” then that makes a little bit more sense. If you decide not to use Docker, and you say, “I don’t have enough time to learn it for the amount of payout I expect for my use case,” or, “My stack is traditional and stable and doesn’t require containers for dev setups,” then that just makes sense.

Maybe one day, I’ll be doing enough fancy pants projects to justify always using Docker, but for now I’ll stick to my boring technology.