My homebrew installation of Postgres is always there when I need it. 😍 I can be
confident that even just after login, my database is only a psql
away.
Homebrew 🍺 (everyone’s favorite missing package manager for MacOS) not only
manages installation and cleanup of
the stuff we need that Apple doesn’t provide,
but provides an abstraction over managing background processes with the native
daemon manager launchctl
.
What’s launchctl and why should I care?
Launchctl is Apple’s replacement for cron. Cron was deprecated in OSX Tiger, version 10.4. (That’s 2005 for those of you keeping score).
cron wasn’t the only tool replaced but alsoxinetd
, mach_init
and init
. Launchctl was created to serve as a single
performant native API to replace those UNIX tools.
Launchctl can handle running programs at certain times, like cron
, but also in
response to other triggers like login or file changes, and can relaunch
programs if they crash.
What does homebrew give me that using launchctl directly doesn’t?
Starting a process on login without brew services
means writing (or copying, or
symlinking) a plist file to
~/Library/LaunchAgents
for a single user and /Library/LaunchDaemons
for all
users.
The plist, which stands for “property list”, acts as instructions to launchctl about how, when, and what to do with the application.
Here is a snippet of a plist from my homebrew managed Postgres installation:
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/opt/postgresql@14/bin/postgres</string>
<string>-D</string>
<string>/opt/homebrew/var/postgresql@14</string>
</array>
<key>RunAtLoad</key>
<true/>
If the app was updated or uninstalled, choosing to manage the file means remembering to update or delete the plist ourselves.
brew services
handles all that for us.
When we run brew services start postgresql@14
we’re telling homebrew to copy
the necessary plist to the correct folder and manage it. If we remove postgres
(😱), homebrew removes the plist.
Something changed in MacOS Ventura?
Apple made a change in MacOS 13 that provides a new scheme for these launchctl plist files.
“Rather than apps installing their own helpers and property lists, MacOS 13 (Ventura) introduces a new scheme where those are provided within the app” – The Eclectic Light Company
It should make this process more seamless for users, but not every program will
or has taken advantage of this yet, so brew services
isn’t going away.
Something also changed in homebrew?
That’s right! Previously we would need to “tap” (install) the services package
before using it with brew tap homebrew/services
, but it will now install
itself the first time we run the command.
Because services is the preferred way to manage launch items installed via
homebrew, messaging after installing applications no longer directs us to
symlink plist files to */Library
, but instead to use brew services
.
What do I need to know?
There are only a few commands commonly needed to manage loading processes with homebrew.
brew services start xyz
and brew services stop xyz
will start and stop an
application, but will also remove or add the plist file instructing launchctl
to run the program at login.
If a running application needs to be turned off and on again (as we all do
sometimes), brew services restart xyz
will do that for us.
That’s usually the extent of it, but also handy are these—
brew services run xyz
and brew services kill xyz
will start and stop an
application without changing anything with regards to launchctl
.
Should we want to see what processes are running via launchctl
, some of which
might not be managed by homebrew, we can run brew services list
. This is what
mine currently looks like–
postgresql@14 started aji ~/Library/LaunchAgents/homebrew.mxcl.postgresql@14.plist
redis started aji ~/Library/LaunchAgents/homebrew.mxcl.redis.plist
Can I silence that warning that pops up every time I change something with brew services?
Sadly, no.
Apple wants us to know what is happening in the background of our computer, and rightly so! Security is always in tension with convenience, and in this tradeoff, our notification centers will have to pay the price.