Let’s say you’re using Docker for your local development in order to keep your development system nice and clean. Not having to install all needed dependencies on your local machine (like for instance PostgreSQL) and have everything packaged and documented for all developers is one of the advantages containers bring us.
But when developing in Rails, you still need to install your gems locally in order to have a correct Gemfile.lock. Installing gems locally also gives you the advantage of autocompletion when using an IDE like RubyMine or IntelliJ. From time to time, it might be that some gems need native extensions being compiled. The pg gem is one of them.
The easiest way to get this gem to install, is just install the full database server. But lets face it, why install the full database server, when you only need a client interface?
I ran into this “issue” again after doing a clean install of my MacBook Pro. So I started Googling around to see how other developers solved this issue.
PostgreSQL and libpq
As it turns out, libpq is the C application programmer’s interface to PostgreSQL. libpq is a set of library functions that allow client programs to pass queries to the backend server and to receive the results of these queries.
Since I’m using Homebrew to mange packages on MacOS, installing libpq was a breeze:
$ brew install libpq
Rubygems & bundler
Now that you have installed libpq, you still need to install the pg gem. Specify the –with-opt-dir build option using the gem binary through the command line:
$ gem install pg -- --with-opt-dir="/usr/local/opt/libpq"
If you are using Install using bundler and it is most likely you are, you can save the build option in the bundler build config. This will create a hidden bundle directory in you projects tree structure holding your bundler configuration as a key / value pair, where the key is the build option and the value the location of the custom extension.
$ bundle config --local build.pg --with-opt-dir="/usr/local/opt/libpq" $ bundle install
And that is all you need to do. Now all gems are installed locally and ready to be used.