Developing a Local addon - 01

Getting to know the thing.

What is Local by Flywheel and why am I tampering with it?

The objective of Local by Flywheel is to make “local WordPress development” simple. It is the evolution of Pressmatic and as such it provides an easy way to set up a local, Docker based, way to set up a local WordPress installation that can sport different versions of PHP, 5.2 to 7.1, either Apache or Nginx as the server and Mailhog to capture and analyze emails generated by the site. It occupies about the same “market space” as [MAMP][7743-0003] but it’s completely free right now. Having transitioned through many tools during my short experience, MAMP being the first and fondly loved one, I’ve given Local a try to see, in particular, how difficult would it be to use it to manage plugins and themes tested with Codeception and wp-browser. Turns out configuring the two tools above to use Local is not as intuitive as I’d like it to be; most people get stuck while trying to setup Codeception and wp-browser so I’m trying to take a tour of all the most used local development tools to see if there is something I can do about it. While Local technology stack is not as easy to grasp as a MySQL and PHP server running on the “bare metal” it turns out that extending it to do “things” is possible.

Would be nice…

The first issue I came across is how XDebug configuration is managed. Local comes with an add-on (a plugin) that makes it a breeze to configure PHPStorm to work with it; the approach has, but, some limits. XDebug will be activated when specifying the XDEBUG_SESSION_START parameter in a GET or POST request; there is a handy Chrome extension to do just that but setting that parameter becomes quite a pain in more complex testing scenarios or when debugging secondary processes that do not inherit the primary process context and global vars. Plus I like to configure XDebug to autostart on remote requests and that requires specifying the remote_host parameter. Long story short: I’m developing a Local add-on to control Xdebug. Called “XDebug Control”. Because I’m a hell of a marketer.

The stack

I started my journey reading the article the good folks at Delicious Brains put together but I had any real progress only after getting a grasp of the stack of technologies underlying Local and how they work together. I work on a Mac so things might differ on Windows but, still: it’s a good hint. Local UI is an Electron application, React and all that stuff. The Local application is an interface around a virtual machine managed by Virtual Box. That virtual machine is a boot2docker Linux machine that runs, manages, serves and routes the requests to the correct Docker containers; that machine is set up to share the /Users folder on Mac and probably something similar in windows. So when the UI sends a command that command is sent to the virtual machine that will, in turn, send it to the correct container. Understanding the stack is important as it then makes developing the addon much easier; precisely what really speed things up is being able to connect to that virtual machine to see what is happening in there.

Logging into the virtual machine

The local machine Local uses is assigned an IP address when started, that IP address is the one that can be seen in the UI “Database” tab:

To connect with ssh to the machine I need to know the user name and the password. The details are nowhere to be found in the UI and that is not a bad thing: Local provides a UI and not a “please-hack-this-stuff” approach to things but the app has to use those details to connect to the machine and this means those are, probably, stored in clear someplace. That place is, on a Mac, the ~/.docker/machine/machines/local-by-flywheel folder; the folder contains a config.json file that provides the information I’m looking for in its first lines:

{
    "ConfigVersion": 3,
    "Driver": {
        "IPAddress": "192.168.94.100",
        "MachineName": "local-by-flywheel",
        "SSHUser": "docker",
        "SSHPort": 56737,
        "SSHKeyPath": "/Users/luca/.docker/machine/machines/local-by-flywheel/id_rsa",

The IPAddress entry confirms what I could see in the UI and it seems like I will be able to connect using the docker user and the /Users/luca/.docker/machine/machines/local-by-flywheel/id_rsa key. It turns out logging into the Local virtual machine is as easy:

The command is, on a Mac:

ssh -i ~/.docker/machine/machines/local-by-flywheel/id_rsa docker@192.168.94.100

Once I’m inside I can take a look around and see, as an example, what Docker containers are running:

I have a site with a custom configuration currently running so what I see makes sense: the first container is the Nginx reverse proxy in charge of routing requests for http://mysite.dev to the correct Docker container, the second container is the one that is currently serving my site.

Issuing some commands

My custom site is running PHP 5.2.17 and using Apache as the web server:

Before I attempt any UI operation I will try to activate and deactivate XDebug on it. Hitting the information button on the site I can see XDebug is currently active:

I log into the docker container:

docker exec -it fa6541c8e5c1 bash

After some trial and error I find out that:

  • the PHP 5.2.17 bin is located at /opt/php/5.2.17/bin/php-cgi
  • that the configuration file used by the PHP 5.2.17 bin is /conf/php/5.2.17/php.ini

Disabling XDebug is as easy as commenting the zend_extansion line and restarting the Apache service:

sed -i '/^zend_extension.*xdebug.so/ s/zend_ex/;zend_ex/g' /conf/php/5.2.17/php.ini
service apache2 restart

On the same line I can reactivate XDebug:

sed -i '/^;zend_extension.*xdebug.so/ s/;zend_ex/zend_ex/g' /conf/php/5.2.17/php.ini
service apache2 restart

Next

So… I started with a tool that wants to make local WordPress development easy and ended issuing Unix commands while logged into a Docker container running into a virtual machine. But that’s on purpose: now that I know how to try and debug my commands I can translate those into UI elements that will allow me, on a per-site basis,to activate and deactivate XDebug with one click. Next time I will delve into React development. Of which I know nothing.