Page MenuHomePhabricator

macOS host environment management
Open, LowPublic

Description

I've helped guide two teammates through homebrew based local environment setup (after bad experiences with trying to get started with MediaWiki-Docker) on macOS, and am thinking that it could be useful to have this managed by mwcli, so it's more easily repeated.

The main reference is the Homebrew section of this document https://www.mediawiki.org/w/index.php?title=Manual:Running_MediaWiki_on_macOS#Homebrew_Setup

I'm unsure of how this would fit into the existing command structure, especially as dev is aliased to mwdd, but maybe somethjing like mw dev-environment init --homebrew or something like that. The command would do the following:

  1. check if homebrew is installed, if not, execute the install script from https://brew.sh or error out and ask the user to install via https://brew.sh/
  2. once homebrew is installed
    1. check if php is installed, if not guide the user to install it.
    2. if php is installed, verify that which php comes from a homebrew managed directory, if not guide the user how to install and export the php binary to PATH
      1. prompt the user to install xdebug and other plugins as needed with pecl
    3. guide the user through downloading and installing composer globally
    4. check if httpd is installed, if not guide the userto install it.
    5. ask the user where mediawiki/core is cloned, if not prompt to clone it
    6. modify the httpd conf to include the path to the user's mediawiki core directory and support apache short URLs
    7. modify httpd conf to ensure php7 is linked
    8. restart httpd and php-fpm
    9. ask the user if they want to run mysql through mariadb (homebrew) or via a docker image (in single container setup or replicated setup)
      1. print out relevant docker run command, or guide user through homebrew managed mariadb install
    10. ask the user if they want to run elasticsearch (through docker only)
      1. print out relevant docker run command
  3. guide the user through cloning additional extensions/skins (I think there's already a mwcli task for this)
  4. guide the user through the install.php script

Event Timeline

kostajh updated the task description. (Show Details)

@Addshore @jeena if you can give me some ideas for what the command name(s) should be, I could try to implement at least some of this.

Is the main reason for this homebrew approach over using mwcli dev as it currently is because the images are not ready for the architecture?

I'm unsure of how this would fit into the existing command structure, especially as dev is aliased to mwdd

We can rewrite some code to have it configurable which of many dev environments dev aliases to.

Is the main reason for this homebrew approach over using mwcli dev as it currently is because the images are not ready for the architecture?

It's because performance on Docker for Mac is incredibly poor (T273305) and that situation is unlikely to change any time soon, so I personally would rather work with homebrew managed PHP/Apache and get <0.5 second page load times instead of Docker for Mac where pages can take seconds or tens of seconds (once resource loader calls are done) to finish loading.

@CCicalese_WMF speed wise how do you find the environment on your mac?

It isn't exactly speedy, but I've gotten used to it. It can often take many seconds to load a wiki page, especially while debugging. But, the productivity improvement of being able to test/debug locally with different software versions and databases is huge. I just discovered how easy it is to switch to postgres and use adminer, which was necessary when debugging erroneous behavior progressively upgrading from postgres database backups as old as MW 1.31. So, at a macro level, the speed of being able to get up and running and switch software versions, repeatedly rebuilding the wiki from backup was more than adequate. Yes, I would love an improvement in the page loading time, though.

It isn't exactly speedy, but I've gotten used to it. It can often take many seconds to load a wiki page, especially while debugging. But, the productivity improvement of being able to test/debug locally with different software versions and databases is huge. I just discovered how easy it is to switch to postgres and use adminer, which was necessary when debugging erroneous behavior progressively upgrading from postgres database backups as old as MW 1.31. So, at a macro level, the speed of being able to get up and running and switch software versions, repeatedly rebuilding the wiki from backup was more than adequate. Yes, I would love an improvement in the page loading time, though.

Could you please share what hardware you are using, and how many skins/extensions are present in your environment? (And also if you tend to run composer update / npm install in the extension/skin directories?)

MacBook Pro
13-inch, 2019
2.8 GHz Quad-Core Intel Core i7
16 GB 2133 MHz LPDDR3 RAM

Right now, I'm running with a single skin and no extensions. I'm replacing my previous environment, which was using mediawiki-docker-dev, with mwcli. I expect to be using up to a dozen extensions and a couple of skins once I'm actively using the environment for testing. Yes, I do tend to run composer update / npm install in extension/skin directories.

MacBook Pro
13-inch, 2019
2.8 GHz Quad-Core Intel Core i7
16 GB 2133 MHz LPDDR3 RAM

Right now, I'm running with a single skin and no extensions. I'm replacing my previous environment, which was using mediawiki-docker-dev, with mwcli. I expect to be using up to a dozen extensions and a couple of skins once I'm actively using the environment for testing. Yes, I do tend to run composer update / npm install in extension/skin directories.

OK, similar (or maybe same) as my work computer, mine's from 2018.

One issue is that while performance is tolerable with a single skin, once extensions are added it goes downhill fast.

It can often take many seconds to load a wiki page

Using homebrew managed php/apaceh, my page load times are in the 200-400 millisecond time, including time needed for resource loader requests to resolve. It's so hard to go from that to 3-4 seconds per page load 😭

I think the environment manager proposed here would also support switching databases (either using docker containers or homebrew managed services), as well as switching between homebrew-managed PHP 7 versions. The main thing is to get PHP/Apache out of Docker managed volume mounts as that's by far the biggest performance block.

It isn't exactly speedy, but I've gotten used to it. It can often take many seconds to load a wiki page

That is not ideal, lets work on this, shame I don't have a mac! :D

The main thing is to get PHP/Apache out of Docker managed volume mounts as that's by far the biggest performance block.

Right, and I guess that is where T273307: Investigate using Mutagen to boost performance comes in?

It isn't exactly speedy, but I've gotten used to it. It can often take many seconds to load a wiki page

That is not ideal, lets work on this, shame I don't have a mac! :D

The main thing is to get PHP/Apache out of Docker managed volume mounts as that's by far the biggest performance block.

Right, and I guess that is where T273307: Investigate using Mutagen to boost performance comes in?

Yes, although, the idea with Mutagen is that you would use Docker for PHP/Apache, it's just that everything is copied into the container and then only files that are touched are the host are synced to the container as needed (AIUI). I'm not exactly convinced this is a better solution, for me anyway, but I guess it would depend on the performance and resource usage -- even something like 1 second for a GET request is too long IMO; my happiness and productivity as a developer is tied closely to the page load speed. :)

Yes, although, the idea with Mutagen is that you would use Docker for PHP/Apache, it's just that everything is copied into the container and then only files that are touched are the host are synced to the container as needed (AIUI). I'm not exactly convinced this is a better solution, for me anyway, but I guess it would depend on the performance and resource usage -- even something like 1 second for a GET request is too long IMO; my happiness and productivity as a developer is tied closely to the page load speed. :)

I suspect what this would mean is that sometimes, you may have some lag between you're OS changes and what is seen by the webserver.
But this should make the containers go faster as they are not reading from the mounted OS volume, instead just their own virtual drive or whatever.

But in theory this is already what the :cached type of file mount does in essance.
https://gitlab.wikimedia.org/releng/cli/-/blob/main/internal/mwdd/files/embed/mediawiki.yml#L11
From https://brandnewbox.com/notes/2019/09/docker-volume-cached/
TL;DR Adding :cached to your Docker bind mounts can improve performance in Docker for Mac at the tradeoff of some latency for your file changes to appear in the container.

Looking around at resources, there are the typical observations that having xdebug running makes everything supremely slow https://medium.com/swlh/trying-to-improve-docker-performance-on-macos-using-mutagen-699716e44825
@CCicalese_WMF do you always run with it enabled? or only turn it on / have it running for specific requests?

From that medium post I also see FYI: Docker for Mac is also adopting Mutagen. They first added it in version 2.3.10.
So does that mean docker for mac is already using mutagen out of the box?

Per https://medium.com/@marickvantuil/speed-up-docker-for-mac-with-mutagen-14c2a2c9cba7 it looks like either mutgen or docker-sync (whatever that is) should give some good speed improvements.

Looking at how mutagen is implemented etc, it should be easy enough to have the dev environment optionally NOT mount the mediawiki code, and instead setup a mutagen sync.
Perhaps I could throw together a draft branch?
Its cross platform afaik and not mac specific, so I could likely get it working on my own device.

Looking around at resources, there are the typical observations that having xdebug running makes everything supremely slow https://medium.com/swlh/trying-to-improve-docker-performance-on-macos-using-mutagen-699716e44825
@CCicalese_WMF do you always run with it enabled? or only turn it on / have it running for specific requests?

xdebug definitely makes a difference. I generally always run with it enabled. If my IP address changes, my performance gets much better, since xdebug can no longer connect. That's generally how I notice that my IP address has changed because pages loads become comparatively peppy ;-)

For my use case, adding latency in the file sync would be a showstopper. I need to know that the code that is running in the container is the same as the code I'm developing locally. And, since I often will have to switch back and forth between different MediaWiki releases, that would be a lot of syncing.

For my use case, adding latency in the file sync would be a showstopper. I need to know that the code that is running in the container is the same as the code I'm developing locally. And, since I often will have to switch back and forth between different MediaWiki releases, that would be a lot of syncing.

Ack. But the delay in file sync is something like a few hundred ms, and your terminal tells you if something is still in progress, so in theory it should be OK.

Looking around at resources, there are the typical observations that having xdebug running makes everything supremely slow https://medium.com/swlh/trying-to-improve-docker-performance-on-macos-using-mutagen-699716e44825
@CCicalese_WMF do you always run with it enabled? or only turn it on / have it running for specific requests?

xdebug definitely makes a difference. I generally always run with it enabled. If my IP address changes, my performance gets much better, since xdebug can no longer connect. That's generally how I notice that my IP address has changed because pages loads become comparatively peppy ;-)

Are you using PHPStorm, and do you also have the green phone icon on to listen to connections? With XDebug 3 at least, I think there should no longer be a big performance difference if PHPStorm isn't actively listening for connections.

Yes, although, the idea with Mutagen is that you would use Docker for PHP/Apache, it's just that everything is copied into the container and then only files that are touched are the host are synced to the container as needed (AIUI). I'm not exactly convinced this is a better solution, for me anyway, but I guess it would depend on the performance and resource usage -- even something like 1 second for a GET request is too long IMO; my happiness and productivity as a developer is tied closely to the page load speed. :)

I suspect what this would mean is that sometimes, you may have some lag between you're OS changes and what is seen by the webserver.
But this should make the containers go faster as they are not reading from the mounted OS volume, instead just their own virtual drive or whatever.

But in theory this is already what the :cached type of file mount does in essance.
https://gitlab.wikimedia.org/releng/cli/-/blob/main/internal/mwdd/files/embed/mediawiki.yml#L11
From https://brandnewbox.com/notes/2019/09/docker-volume-cached/
TL;DR Adding :cached to your Docker bind mounts can improve performance in Docker for Mac at the tradeoff of some latency for your file changes to appear in the container.

Looking around at resources, there are the typical observations that having xdebug running makes everything supremely slow https://medium.com/swlh/trying-to-improve-docker-performance-on-macos-using-mutagen-699716e44825
@CCicalese_WMF do you always run with it enabled? or only turn it on / have it running for specific requests?

From that medium post I also see FYI: Docker for Mac is also adopting Mutagen. They first added it in version 2.3.10.
So does that mean docker for mac is already using mutagen out of the box?

Per https://medium.com/@marickvantuil/speed-up-docker-for-mac-with-mutagen-14c2a2c9cba7 it looks like either mutgen or docker-sync (whatever that is) should give some good speed improvements.

Looking at how mutagen is implemented etc, it should be easy enough to have the dev environment optionally NOT mount the mediawiki code, and instead setup a mutagen sync.
Perhaps I could throw together a draft branch?
Its cross platform afaik and not mac specific, so I could likely get it working on my own device.

The parent task links to the upstream issue (https://github.com/docker/roadmap/issues/7) which is painful and long reading, but the tl;dr is:

  • :cached was deprecated from Docker for Mac in favor of Mutagen, and Mutagen support was added in Docker for Mac, *but*...
  • Docker for Mac then removed Mutagen support because of their experimentation with gRPC, but that didn't solve the problem

Anyway, the basic idea is that you remove all volume mounting from docker-compose.yml and define those instead in a Mutagen specific sync. Then you start a mutagen sync command and everything "just works"

For my use case, adding latency in the file sync would be a showstopper. I need to know that the code that is running in the container is the same as the code I'm developing locally. And, since I often will have to switch back and forth between different MediaWiki releases, that would be a lot of syncing.

We could certainly make any mutagen support optional.

Are you using PHPStorm, and do you also have the green phone icon on to listen to connections? With XDebug 3 at least, I think there should no longer be a big performance difference if PHPStorm isn't actively listening for connections.

+1 xdebug can always be running, that is fun and you should see no real performance hit.
But I recommend only actually listening for connection in your IDE when you are debugging something.

Anyway, the basic idea is that you remove all volume mounting from docker-compose.yml and define those instead in a Mutagen specific sync. Then you start a mutagen sync command and everything "just works"

Sounds easy enough

For my use case, adding latency in the file sync would be a showstopper. I need to know that the code that is running in the container is the same as the code I'm developing locally. And, since I often will have to switch back and forth between different MediaWiki releases, that would be a lot of syncing.

We could certainly make any mutagen support optional.

Are you using PHPStorm, and do you also have the green phone icon on to listen to connections? With XDebug 3 at least, I think there should no longer be a big performance difference if PHPStorm isn't actively listening for connections.

+1 xdebug can always be running, that is fun and you should see no real performance hit.
But I recommend only actually listening for connection in your IDE when you are debugging something.

Anyway, the basic idea is that you remove all volume mounting from docker-compose.yml and define those instead in a Mutagen specific sync. Then you start a mutagen sync command and everything "just works"

Sounds easy enough

Yeah I think so; let's talk about it in T273307: Investigate using Mutagen to boost performance :)

For this task, I think the goal is to provide a scripted command or commands that users on macOS can use to decide if their environment runs homebrew php or docker php, uses mutagen or not mutagen, if apache/mysql/elastic etc are run using homebrew or docker containers, etc. Arguably this could also be abstracted for Linux systems as well, but we could do that some point later if needed.

Ack. But the delay in file sync is something like a few hundred ms, and your terminal tells you if something is still in progress, so in theory it should be OK.

Cool. That should be OK.

Are you using PHPStorm, and do you also have the green phone icon on to listen to connections? With XDebug 3 at least, I think there should no longer be a big performance difference if PHPStorm isn't actively listening for connections.

Yes. I do that when I remember to :-) I'm going to try to remember to do so more often, since I am unnecessarily making things difficult for myself by not remembering.