FreeBSD package builder with Poudriere

I’m using FreeBSD 10.0-RELEASE on my file server, which will double as my package builder. I’d prefer to run Poudriere inside a jail  so that all its binaries and configs are confined there, but this is not a supported configuration, and Poudriere requires so many permissions the security benefits would be minimal, and it still encounters trouble.

This shouldn’t be a problem though, as Poudriere won’t expose any services, and the packages will be published by a jail utilizing read-only nullfs mounts.

# Create ZFS datasets used by Poudriere
zfs create -o compress=lz4 mountpoint=/usr/local/poudriere storage/poudriere
zfs create storage/poudriere/data
zfs create -o compress=off storage/poudriere/ccache

# Base has "svnlite", which will be good enough for Poudriere,
# but Poudriere expects it to exist under the name "svn"
ln -s /usr/bin/svnlite /usr/local/bin/svn

Set up keys to sign your packages. This step is optional, but recommended. (source:

mkdir -p /usr/local/etc/ssl/keys /usr/local/etc/ssl/certs
chmod 600 /usr/local/etc/ssl/keys
openssl genrsa -out /usr/local/etc/ssl/keys/pkg.key 4096
openssl rsa -in /usr/local/etc/ssl/keys/pkg.key -pubout > /usr/local/etc/ssl/certs/pkg.cert

Install poudriere and ccache (optional), then copy /usr/local/etc/poudriere.conf.sample to /usr/local/etc/poudriere.conf and modify it to your needs. This is a diff of my changes:

< #ZPOOL=tank
> ZPOOL=storage
< # ZROOTFS=/poudriere
> ZROOTFS=/poudriere
< USE_TMPFS=yes --- > USE_TMPFS="wrkdir data"
< DISTFILES_CACHE=/usr/ports/distfiles
> DISTFILES_CACHE=/var/ports/distfiles
< #PKG_REPO_SIGNING_KEY=/etc/ssl/keys/repo.key
> PKG_REPO_SIGNING_KEY=/usr/local/etc/ssl/keys/pkg.key
< #CCACHE_DIR=/var/cache/ccache
> CCACHE_DIR=/usr/local/poudriere/ccache
< # NOLINUX=yes

It’s time to configure the default ports tree and default jail. I’ll be using SVN for the ports tree, ftp for the jail, and the jail will be FreeBSD 10.0-RELEASE AMD64.

# Set up the default ports tree using SVN. This may take a while.
poudriere ports -cp default -m svn+https
# Set up a 10.0-RELEASE amd64 build jail
poudriere jail -c -j 10_0x64 -v "10.0-RELEASE" -a amd64 -p default
# Create directory for storing lists of ports to build
mkdir /usr/local/etc/poudriere.d/pkglists

I’ll be defining package lists for each type of host. I’m starting with definitions for two:

echo "www/nginx" >>/usr/local/etc/poudriere.d/pkglists/pkg
echo "www/nginx-devel" >>/usr/local/etc/poudriere.d/pkglists/rproxy

Then I’ll create options for them:

poudriere options -f /usr/local/etc/poudriere.d/pkglists/rproxy -j 10_0x64 -z rproxy
poudriere options -f /usr/local/etc/poudriere.d/pkglists/pkg -j 10_0x64 -z pkg

And then it’s all ready to do a test build:

poudriere bulk -f /usr/local/etc/poudriere.d/pkglists/rproxy -j 10_0x64 -z rproxy
poudriere bulk -f /usr/local/etc/poudriere.d/pkglists/pkg -j 10_0x64 -z pkg

I’ll be running poudriere in daemon mode to process queued items. To do so, I modified /etc/rc.local:

# file: /etc/rc.local
# Poudriere
poudriere daemon -p /var/run/

In order to make it easier to automate build tasks for various targets, I’ve created a ‘poudriere bulk build enqueuer script’ (download), which expects the files to be named[.ignored string]. Therefore, I had to rename my package lists:

cd /usr/local/etc/poudriere.d/pkglist
mv rproxy 10_0x64.rproxy
mv pkg 10_0x64.pkg

And finally, I’ve set up crontab to keep things up to date and to schedule builds once every hour:

# crontab #
# Poudriere stuff #
# Update jails
@daily /usr/local/bin/poudriere jail -u -j 10_0x64 >/dev/null
# Update ports tree 10 minutes before whole hour
50 * * * * /usr/local/bin/poudriere ports -u -p default >/dev/null
# Enqueue tasks at full hour
0 * * * * /usr/local/poudriere/ "/usr/local/etc/poudriere.d/pkglists/" >/dev/null

Using the new package repository

To configure pkgng to use the new package repository, you have to create the directory it looks for alternate repositories in, and place your configuration there.

mkdir -p /usr/local/etc/pkg/repos
# file: /usr/local/etc/pkg/repos/poudriere.conf
# system: Clients using the package repositories

poudriere: {
 url: "http://your.url/here",
 mirror_type: "http",
 signature_type: "pubkey",
 pubkey: "/usr/local/etc/ssl/certs/pkg.cert",
 enabled: yes

Once that’s done, you have to tell pkgng to update its repositories.

# system: Clients using the package repositories
pkg update

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s