Running Multiple CLI Commands in One Terminal for Laravel Development

While working on Let Them Eat Cake 🍰 , I noticed when I was end-to-end testing the app locally, I need a few different things running at once:

  • Laravel Queue Worker - running queued jobs

  • Expose - Proxy for allowing external webhooks needed for my app

  • Stripe CLI - Passing Stripe webhooks to my app without using a proxy

  • Laravel Mix - Bundling static assets

Running each of these commands separately isn't that big of a deal, but it can be a hassle to remember to start them all. This was very apparent yesterday as my computer decided it wanted to reboot every time it went to sleep! A short trip around town running errands with my wife and my computer restarted 3 times in a couple of hours; frustrating!

Today I decided to look into some potential solutions. I had a few basic requirements while I was looking around.

  1. It needs to be easy to start and modify for each new project - this also implies some flexibility. No sudo password required nonsense.

  2. I can stop all running processes with SIGINT (CTRL+C)

  3. All process output is still visible so I can see compile errors or bad requests.

  4. Process output is in one terminal window/tab (optional - but I wanted it!)

A little searching and some testing later and I think I've come to a nice solution that gives me plenty of control and flexibility.

One of the first tools I discovered was moreutils, a package you can install with brew that essentially adds a handful of helpful CLI utilities. The name is play on coreutils, a set of packages included in most Linux distros. Specifically, there is a package called parallels that seemed to be just what I was looking for. It has lots of extra features and can start lots of parallel processes and close them all at once. The reason I ultimately chose not to go this route, was in case I work on any of my projects with other developers. Given the simplicity of my use case compared to the feature set of the package, it was honestly overkill. This also means my project is that much more portable between machines and developers. I keep my own dotfiles, but if I can avoid complexity, I like to try that route first. :)

The Solution

Ultimately, I settled on a little shell script courtesy of this Ask Ubuntu thread. Here is my adaptation:

#!/bin/bash
sh ./startexpose &
P1=$!
php artisan queue:listen &
P2=$!
stripe listen --forward-to eat-cake.test/stripe/webhook &
P3=$!
wait $P1 $P2 $P3

A quick rundown. The first process is essentially another wrapper with some Expose configuration details. The output from this is a big tail-ing table of incoming requests. The second is my queue worker. I opt for queue:listen here so the worker will automatically restart itself when any code in my application changes. Output from this command is a line for every queued job that is processed. Third is the Stripe CLI, which needs to be configured beforehand, but is a once every 90 day thing. Seeing as it has access to my payment data, I'm okay with the hassle tradeoff.

I'm still debating on whether or not to include my Laravel Mix watch command in this, and I might add a runtime flag for it, but without trying it for any reasonable length of time yet, I'm guessing I'll need to start/stop the watcher to do production compiles more often than anything else. The other commands can run mostly unmonitored unless I need to check something, but I tend to get a lot more feedback when I inevitably screw up the closing brackets in a JS file. 😬

Hope this helps you out! Feel free to ask any questions here or send me a tweet @DaronSpence. ✌️

Posted in:

Laravel