FreeBSD Poudriere Cheat Sheet

Sat 21 June 2014 by feld

On FreeBSD poudriere is now the best way to maintain your software from the ports tree. It provides a cleanroom build environment and your packages will always be built properly. Manual installation and portmaster are certainly still viable, but they should be handled with care by advanced users. For those who cannot use the public FreeBSD pkg repository, here's a quick rundown on maintaining your own.

Install poudriere. At this time I recommend poudriere from packages or your own ports tree.

# cd /usr/ports/ports-mgmt/poudriere
# make install clean

Edit poudriere.conf to your own liking.

# vi /usr/local/etc/poudriere.conf

Create a build jail. If you want to target FreeBSD 10.1 amd64:

# poudriere jail -c -j 101amd64 -v 10.1-RELEASE -a amd64

Create the poudriere ports tree. I recommend following svn.

# poudriere ports -c -m svn+http

Generate a list of packages you'd like to build and put them in a text file. I prefer to call mine origins.txt.

audio/beets
audio/murmur
comms/minicom
comms/picocom
... etc

Set the build options for your build environment and ports. Edit /usr/local/etc/poudriere.d/make.conf

DEFAULT_VERSIONS= mysql=5.5 pgsql=9.3 php=5

# custom options
accessibility_redshift_SET= GNOME GUI
audio_beets_SET= BEATPORT CHROMA DISCOGS FFMPEG
audio_murmur_UNSET= ICE
... etc

Setup the web interface for poudriere. I use nginx, so here's my vhost config:

server {
        listen       1.2.3.4:80;
        server_name  pkg.feld.me;
        root         /usr/local/share/poudriere/html;

        # Allow caching static resources
        location ~* ^.+\.(jpg|jpeg|gif|png|ico|svg|woff|css|js|html)$ {
                add_header Cache-Control "public";
                expires 2d;
        }

        location /data {
                alias /usr/local/poudriere/data/logs/bulk;

                # Allow caching dynamic files but ensure they get rechecked
                location ~* ^.+\.(log|txz|tbz|bz2|gz)$ {
                        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
                }

                # Don't log json requests as they come in frequently and ensure
                # caching works as expected
                location ~* ^.+\.(json)$ {
                        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
                        access_log off;
                        log_not_found off;
                }

                # Allow indexing only in log dirs
                location ~ /data/?.*/(logs|latest-per-pkg)/ {
                        autoindex on;
                }

                break;
        }

        location /repo {
                alias /usr/local/poudriere/data/packages;
        }
}

The clients will be fetching from http://pkg.feld.me/repo/${ABI}/. ${ABI} will expand to FreeBSD:10:amd64. You cannot use FreeBSD:10:amd64 as a build jail name because of the colons, so make a symlink so this just works automagically.

# cd /usr/local/poudriere/data/packages
# ln -s 101amd64-default FreeBSD:10:amd64

Setup a build script to update ports, clean poudriere package repo for unused packages, and build your list of packages:

#!/bin/sh

poudiere ports -u
poudriere pkgclean -y -j 101amd64 -f /path/to/origins.txt
poudriere bulk -j 101amd64 -f /path/to/origins.txt

Do your first build run!

# poudriere bulk -j 101amd64 -f /path/to/origins.txt

Now, your jails or servers can use your package repository. Until the release of pkg 1.3.0 I recommend you do not attempt to mix package repositories as it will not work as expected. On the clients/servers/jails you can use these two config files to activate your repo and disable the official FreeBSD repo:

/usr/local/etc/pkg/repos/feld.me.conf

feld: {
url: "http://pkg.feld.me/repo/${ABI}/",
mirror_type: "a",
enabled: yes
}

/usr/local/etc/pkg/repos/freebsd.conf

FreeBSD: {
enabled: no
}

Now on your clients you can install packages with pkg. If you have additional needs such as signing your repository or different repositories with their own specific global options (sets) check the poudriere man page -- it's all there!

04/09/2015: Updated to reflect some more recent changes