May 23, 2018
Under coding

You Might Not Need Homebrew

Homebrew is amazing. I love the user experience - it is super easy to add new packages to macOS. However, I've just realized, that I barely use it anymore. What follows is how I work without Homebrew.

How I've used Homebrew previously?

Ever since I can remember, I've used Homebrew extensively:

  • wget on macOS? just run
    brew install wget
  • need Redis for a project? no worries, Homebrew had my back with
    brew install redis

LaunchRocket made things even better. In case you are not familiar with LaunchRocket, it adds a preferencePane for your System Settings, so you have a UI on top of Homebrew. It enables you to easily turn on or off different services:

Homebrew LaunchRocket

Back in those days, setting up Docker on macOS was painful - you had to:

  • install VirtualBox,
  • install boot2docker,
  • and set up the
    environment variable.

While it does not seem a lot, it is far from a great user experience.

Luckily for us, Docker fixed this. With the help of HyperKit (a hypervisor built on top of the Hypervisor.framework in macOS), now we can run Docker natively on macOS.

As I've started to use Docker more, I've also started to use Homebrew a lot less frequently.

Why Docker instead of Homebrew?

Most companies running backend services deploy their artifacts using some kind of containerization technology, most probably Docker. I found that the closer one's development machine is to the production environment, the better understanding they'll have of their production systems. That can go a long way if you think about setting up new production environments, being on call, or just troubleshooting production issues.

How did Docker change my workflow?

-like commands on your Mac

As with Homebrew, you can search for Docker images using the Docker CLI too. In this case, we'd like to grab an image that has


docker search wget Docker search using

docker search wget

Once you have the image you'd like to run, you can run


docker run wget Running wget inside docker using

docker run --rm mwendler/wget

How does this work? The

that produces the image we used previously can be found below. The most important part of our example is the
instruction. An
allows us to configure a container that will run as an executable.

FROM alpine
# install openssl and the complete wget
RUN apk --update add openssl wget \
# clean up cached artifacts
&& rm -rf /var/cache/apk/*
# the exposed application

You may have noticed that the

file was generated, but it only lived inside the Docker container. For some commands, this behavior may be okay, or just using the standard output is enough, but there are cases when you want to access the file on your host machine. In those cases, you can simply mount your current working directory as a volume to the Docker container:

docker run with volumes Mount the current directory using

docker run --rm -v "$(pwd)":/app mwendler/wget -o /app/index.html

Running databases in Docker

Most probably it is not

that's most crucial to your day-to-day job, but some sort of database for the application you are working on.

To run a database in Docker locally, you'll have to do the same thing as we did with

. Let's take a look at PostgreSQL, and how you can run it locally using Docker!

Docker with PostgreSQL

Running PostgreSQL with Docker using

docker run --rm postgres:10.4

To set the PostgreSQL password, you can pass in the

environment variable:

docker run --rm -e POSTGRES_PASSWORD=mypassword postgres:10.4

The last thing to do is to expose the PostgreSQL port to the host machine. So the final command looks like this:

docker run --rm -p 5432:5432 -e POSTGRES_PASSWORD=mypassword postgres:10.4

Mission Control for Docker

Just like Homebrew, Docker can be controlled from an application with UI too: meet Kitematic.

Once downloaded and installed you can search for Docker images you'd like to run. Let's take a look at the example of ElasticSearch!

Pulling the ElasticSearch Container From Docker Hub

Once you search for ElasticSearch in the application and click "Create", Kitematic will pull the image and start up the container:

ElasticSearch with Kitematic- Running

Using the Web Preview

After the container has started, you can access its exposed API by clicking the "Web preview" button. As you can see, you've just spun up an ElasticSearch instance in a matter of minutes, without installing any of its dependencies locally:

ElasticSearch with Kitematic - Web preview

Configuring the Container

Go to the "Settings" tab to configure the container instance - you can pass in environment variables, expose ports, modify networking or attach volume if you'd like a persist your data.

ElasticSearch with Kitematic - Settings


Docker is not a replacement for Homebrew.

If you'd like to add packages to your macOS like

, you should pick Homebrew, as that's easier to use. Most probably you don't want to mount a volume just to download a file, right?

However, for more complex problems, like running databases, I'd recommend giving Docker a chance. It makes installing and running them frictionless, as you don't have to deal with installing tens of dependencies to run (or build) them, nor you have to be worried about these dependencies' conflicting version needs.

Further reading

Did you like this article? Subscribe to get notified about new ones on engineering management, open-source and the web!
No spam. Ever.