Can I mix ports and pkgs?

Short answer

Yes, but don't do it.

Long answer

-But I really need to do it!

-Ok, let's talk...

In some cases we need a handful of ports built with non-default options, in other cases we need to build ports that can't be packaged for licensing reasons or other. But before we do that, let's make sure we understand the potential consequences.


The pkg repositories

Sometimes it is very tempting to mix ports and pkgs, and many of us have done so without problems.

But before we go down that path, it's important to understand a few key concepts.

Pkgs are built from the ports tree, but there are actually two active ports trees:

  • Head - the constantly updated ports tree —
  • Quarterly - a branch that gets updated four times a year + the occasional security patch or version bump — (at the time of writing 2018Q1)

The official pkgs are built from both the trees into two separate pkg repositories — quarterly and latest. Quarterly is the default pkg repo, as can be seen in /etc/pkg/FreeBSD.conf:

FreeBSD: {
  url: "pkg+${ABI}/quarterly",
  mirror_type: "srv",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes

The file contains some vague instructions on how to correctly change these settings without modifying /etc/pkg/FreeBSD.conf itself, see the appendix at the bottom of this page for a quick howto.

The ports tree(s)

When fetching the ports tree, whether you do use portsnap or svn, the default method will give you the head. I am not aware of any way to use portsnap to get a quarterly branch, but with svn it's as simple as specifying the branch:

svnlite checkout /usr/ports

So how do I do it?

The trick to mixing ports and pkgs is to minimize the gap in the timeline between the two. There are two ways to do this:

1. Staying close to head

By using the latest pkg repo, the pkgs will have been built from head at maximum a couple days ago. This is usually close enough to avoid any fallout due to the head tree expecting different versions than are installed from the pkg repo, but this is not perfect and a lot can happen in a couple days if you have bad luck with the timing. If you choose to do this, you should take great care with what you mix, and try not to build large and complex software from ports. And in any case; do this on your own risk and be prepared for failure. You are in fact mixing two sources from two different moments in time.

Also, consider locking your custom-built ports with pkg lock if you have custom options to prevent them from being reinstalled with default options once the repo catches up.

2. Staying at quarterly

This is the safest of the two options. The quarterly branch moves a lot slower than head as only security-related updates are merged into quarterly.

It will however require you to use svn to keep your ports tree updated, and you will need to change to a new branch every quarter of the year.

To make this easier, Chris Wells has made a shell script to grab the newest quarterly repo, making use of the following command, based on info received from Mathieu Arnold:

svn ls|sed -ne '/^2.*Q./s|/$||p'|tail -1

Read more about it and download the script from Chris Wells's website or his GitHub repo "freebsd-scripts".

Also in this case you should consider locking your custom-built ports with pkg lock to prevent reinstallation with default options.

3. Using poudriere

Do NOT EVER mix ports and pkgs like I described in point 1 and 2 on a production machine.

This is where poudriere will give you the best of both worlds, especially when combined with tools like portshaker to combine different ports trees etc. However, this is beyond the scope of this article.


Now you hopefully know the pros and cons on mixing ports and pkgs, and how to minimize the risk if you choose to do so.

Still, keep in mind that mixing the two is unsupported and the risk is entirely yours.

Appendix 1 — how to change pkg repo

Editing /etc/pkg/FreeBSD.conf directly is typically discouraged, because any changes may be overwritten during an upgrade if you're not paying close attention.

Instead, create a new, local file which overrides the settings:

mkdir -p /usr/local/etc/pkg/repos
sed 's/quarterly/latest/' /etc/pkg/FreeBSD.conf > /usr/local/etc/pkg/repos/FreeBSD.conf