Table of content
  1. Configuration
    1. Poudriere
    2. Build
    3. Apache
  2. Tuning
    1. CPU usage
    2. Network usage
    3. Open files
  3. Profiles
    1. Jail
    2. Packages
  4. Commands
  5. Using

Poudriere allows to build packages from the ports tree in a clean and reproducible environment. It’s able to leverage the ccache of the ports infrastructure to decrease build time. Once packages build, they can be deployed on multiple hosts.

Build information

Ensure the following options:

sysutils/smartmontools
1
# No selectable options
  • Poudriere is not yet able to leverage distcc to increase build speed by distributing compilation unit to multiple servers. So it’s better to install poudriere on a computer with plenty of CPU/cores as well as memory.
  • Only a single port tree called default will be used in these documentation, which will result in some description/configuration shortcuts.
  • Updating from SVN is deprecated (SVN repository has been closed in April 2021).

Configuration

Poudriere

poudriere.conf
1
2
# FreeBSD data fetching (using local mirror)
FREEBSD_HOST=ftp://ftp.fr.freebsd.org
poudriere.conf
1
2
3
4
5
6
# Filesystems and paths
ZPOOL=data
ZROOTFS=/freebsd/poudriere
BASEFS=/var/poudriere
CCACHE_DIR=/var/cache/ccache
DISTFILES_CACHE=/usr/ports/distfiles

Jail is configured to use the same DNS server as the one defined for the server: /etc/resolv.conf.

poudriere.conf
1
2
# Jails
RESOLV_CONF=/etc/resolv.conf
poudriere.conf
1
2
3
# Ports
CHECK_CHANGED_OPTIONS=verbose
CHECK_CHANGED_DEPS=yes
poudriere.conf
1
2
3
4
# Packages
WRKDIR_ARCHIVE_FORMAT=txz
KEEP_OLD_PACKAGES_COUNT=3
PKG_REPO_SIGNING_KEY=/usr/local/etc/cert/=/ALL.sdalu.com.key

To help having a reproducible build use an hardcoded hostname (not depend of the building host) and preserve timestamp:

poudriere.conf
1
2
3
# Reproductible build
BUILDER_HOSTNAME=freebsd-build.example.com
PRESERVE_TIMESTAMP=yes
poudriere.conf
1
2
3
# Building
USE_PORTLINT=no
USE_TMPFS="yes" # Change to "data" if memory constrained
poudriere.conf
1
2
3
4
# Publishing of building process
URL_BASE=https://freebsd-build.example.com/poudriere
HTML_TYPE="hosted"
HTML_TRACK_REMAINING=yes

Build

As were are building the packages for ourselves, accept all the licenses.

poudriere.d/make.conf
1
2
# Acknowled all licenses
DISABLE_LICENSES=yes

Apache

Apache will be used to distribute the build packages (of course, it is possible to use other webserver such a nginx to create the same kind of configuration).

apache.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    # Distribute packages
    ######################################################################

    # Map poudiere package directories to clean URL
    Alias /freebsd/packages/amd64/12.2/gaming/                           \
          /var/poudriere/data/packages/amd64:12_2:workstation-default-gaming/
    Alias /freebsd/packages/amd64/13.0/server/                           \
          /var/poudriere/data/packages/amd64:13_0:server-default-server/

    # Fallback for all packages
    Alias /freebsd/packages/ /var/poudriere/data/packages/

    <Directory /var/poudriere/data/>
        Options Indexes FollowSymLinks
        Require all granted
    </Directory>

If you want to monitor poudriere build progress, the following configuration must be added as well:

apache.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    # Give access to poudriere build informations
    ######################################################################

    Alias /freebsd/data/     /var/poudriere/data/logs/bulk/
    Alias /freebsd/          /usr/local/share/poudriere/html/

    <Directory /var/poudriere/data/logs/bulk/>
        Options Indexes FollowSymLinks
    	Require all granted
    </Directory>

    <Directory /usr/local/share/poudriere/html/>
        Options Indexes FollowSymLinks
        Require all granted
    </Directory>

Tuning

CPU usage

By default poudriere only allows 1 job (ie: make -j 1) per port build, this allows limiting CPU load as it will build many ports in parallel (by default 1 port per cpu/core/thread, ie: sysctl hw.ncpu).

It could be tempting to increase the number of jobs, using ALLOW_MAKE_JOBS_PACKAGES for some compilation intensive ports (like: chromium, gcc, llvm, firefox, …), but the number of jobs for theses ports must be carefully chosen:

poudriere.d/make.conf
1
2
3
# Carefully chose the value according to: sysctl -n kern.smp.cpus
# and don't forget that poudriere also build multiple port in parallel
MAKE_JOBS_NUMBER_LIMIT=3
poudriere.conf
1
2
# Number of ports to build in parallel
PARALLEL_JOBS=4

Now only remains to list the ports for which we want to remove the limit of 1 job per port (but still limited by MAKE_JOBS_NUMBER_LIMIT):

poudriere.conf
1
2
# List of ports (glob pattern possible) for which we allow more than one job
ALLOW_MAKE_JOBS_PACKAGES="pkg ccache gcc* llvm*"

Network usage

poudriere.conf
1
2
# List of ports (glob pattern possible) for which we allow network access
ALLOW_NETWORKING_PACKAGES="thunderbird"

Open files

Some port requires to handle a very large number of open file to build correctly, this is the case but not limited to: RStudio, atom, vscode. It is possible to rise the default limit for some specific ports:

poudriere.conf
1
2
3
4
5
6
7
# Default file descriptor limit
MAX_FILES=1024

# Adjusting per port
MAX_FILES_RStudio=2048
MAX_FILES_atom_ide=4096
MAX_FILES_vscode=4096

Profiles

Poudriere allows the use of profiles to customize the build process so that packages can be build for a specific target with specific needs, some examples:

Jail

The jail on which you build the packages need to match somehow the one on which you will deploy the packages:

  • same architecture
  • compatible OS release
  • same dependencies (example: NIS, KERBEROS, …)

Building a poudriere jail can be customized the same way FreeBSD is customized, using src.conf and src-env.conf. This files are created by poudriere by merging:

1
2
3
/usr/local/etc/poudriere.d/file.conf
/usr/local/etc/poudriere.d/setname-file.conf
/usr/local/etc/poudriere.d/jailname-file.conf

Follows an example building a jail for FreeBSD 13.0 target at server where NIS has been removed as well as wireless networking:

amd64:server-src.conf
1
2
3
WITHOUT_NIS=yes
WITHOUT_WIRELESS=yes
WITHOUT_BLUETOOTH=yes
Create build environment
1
2
poudriere jail -c -j amd64:13_0:server -z amd64:server \
               -b -m git+https -v releng/13.0

Packages

It is possible to chose a different set of options for the packages being compiled as usually you don’t want the same set of options for a server or for a workstation.

This is done by using make.conf for defining a set of options, this file will be generated by poudriere by merging the following files in this given order:

1
2
3
4
5
6
7
8
9
/usr/local/etc/poudriere.d/make.conf
/usr/local/etc/poudriere.d/setname-make.conf
/usr/local/etc/poudriere.d/tree-make.conf
/usr/local/etc/poudriere.d/jailname-make.conf
/usr/local/etc/poudriere.d/tree-setname-make.conf
/usr/local/etc/poudriere.d/jailname-tree-make.conf
/usr/local/etc/poudriere.d/jailname-setname-make.conf
/usr/local/etc/poudriere.d/jailname-tree-setname-make.conf
/usr/local/etc/poudriere.d/hooks/plugins/plugin/make.conf

For example in case of building packages for a server these options can be set/unset as default:

server-make.conf
1
2
3
OPTIONS_SET   += DTRACE
OPTIONS_UNSET += X11
OPTIONS_UNSET += AVAHI BONJOUR MDNS

Next the following first-matching directory will be used to store specific selected options for ports and will be populated by running

Configuring ports
1
poudriere options -z server category/port
1
2
3
4
5
6
7
8
/usr/local/etc/poudriere.d/jailname-tree-setname-options
/usr/local/etc/poudriere.d/jailname-setname-options
/usr/local/etc/poudriere.d/jailname-tree-options
/usr/local/etc/poudriere.d/tree-setname-options
/usr/local/etc/poudriere.d/setname-options
/usr/local/etc/poudriere.d/tree-options
/usr/local/etc/poudriere.d/jailname-options
/usr/local/etc/poudriere.d/options

Commands

Create build environment from git source
1
2
poudriere jail -c -j amd64:13_0:server -z amd64:server \
               -b -m git+https -v releng/13.0 -J 4
Update build environment
1
poudriere jail -u -j amd64:13_0:server -z amd64:server
Create `default` ports tree
1
2
3
poudriere ports -c -p default -m portsnap            # Using portsnap
poudriere ports -c -p default -m git+https -B main   # Using git `main` branch
poudriere ports -c -p default -m null -M /usr/ports  # Using /usr/ports
Building packages
1
poudriere bulk  -j amd64:13_0:server -z server -f build.pkglist

Using

A file describing this poudriere repository must be created so that the pkg command is able to update from it.

To help retrieve the correct version of the package (processor architecture, operating system version, …), the following variable are expanded in the URL definition:

Variable Description
ABI ABI string defined by the operating system
OSNAME Full version of the name of the operating system
RELEASE Full version of the operating system
VERSION_MAJOR Major version of the operating system
VERSION_MINOR Minor version of the operating system
ARCH Architecture of the system

An example that match the apache configuration previously given can be:

/usr/local/etc/pkg/repos/poudriere.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
poudriere: {
    url: https://freebsd-build.example.com/packages/${ARCH}/${VERSION_MAJOR}.${VERSION_MINOR}/server
    signature_type: none
    enabled: yes
    priority: 10

    # If IPv6 is badly configured, it is possible to force IPv4
    ip_version: 4
    
    # If using self signed certificates for the website distributing
    # the package, it can be necessary to not verify the certificate
    ENV : {
         SSL_NO_VERIFY_PEER: 1
    }
}