WhyPoudriere 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:
# No selectable options
- Poudriere is not yet able to leverage
distccto increase build speed by distributing compilation unit to multiple servers. So it’s better to installpoudriereon a computer with plenty of CPU/cores as well as memory. - Only a single port tree called
defaultwill 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
# FreeBSD data fetching (using local mirror)
FREEBSD_HOST=Select a local mirror
# Filesystems and paths ZPOOL=ZFS pool ZROOTFS=Poudrirere dedicated dataset hierarchy BASEFS=Emplacement of poudriere data CCACHE_DIR=Directory holding ccache data DISTFILES_CACHE=/usr/ports/distfiles
Jail is configured to use the same DNS server as the one defined
for the server: /etc/resolv.conf.
# Jails RESOLV_CONF=/etc/resolv.conf
# Ports CHECK_CHANGED_OPTIONS=verbose CHECK_CHANGED_DEPS=yes
# Packages
WRKDIR_ARCHIVE_FORMAT=txz
KEEP_OLD_PACKAGES_COUNT=3
PKG_REPO_SIGNING_KEY=Signing key
To help having a reproducible build use an hardcoded hostname (not depend of the building host) and preserve timestamp:
# Reproductible build
BUILDER_HOSTNAME=Hardcoded builder hostname
PRESERVE_TIMESTAMP=yes
# Building USE_PORTLINT=no USE_TMPFS="yes" # Change to "data" if memory constrained
# 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.
# 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).
# 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:
# 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:
- to not overload the processors if all these ports are build together
- to avoid starving poudriere if it is waiting for a cpu intensive dependency being built with only one job.
# 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=Maximum number of jobs for a port build
# Number of ports to build in parallel
PARALLEL_JOBS=Maximum number of parallel port building
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):
# List of ports (glob pattern possible) for which we allow more than one job
ALLOW_MAKE_JOBS_PACKAGES=List of packages
Network usage
# List of ports (glob pattern possible) for which we allow network access
ALLOW_NETWORKING_PACKAGES=List of packages
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:
# 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:
- amd64 server with no need for graphical interface
- amd64 workstation
- aarch64 raspberry pi for embedded development
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:
/usr/local/etc/poudriere.d/src | src-env.conf /usr/local/etc/poudriere.d/setname-src | src-env.conf /usr/local/etc/poudriere.d/jailname-src | src-env.conf
Follows an example building a jail for FreeBSD 13.0 target at server where NIS has been removed as well as wireless networking:
WITHOUT_NIS=yes WITHOUT_WIRELESS=yes WITHOUT_BLUETOOTH=yes
poudriere jail -c -j Jail name -z Compilation profile \ -b -m git+https -v Git branch
Packages
- make.conf (5)
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:
/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:
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
poudriere options -z Set name Port origin
/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
poudriere jail -c -j Jail name -z Compilation profile \ -b -m git+https -v Git branch -J Number of core to use
poudriere jail -u -j Jail name -z Compilation profile
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
poudriere bulk -j Jail name -z Set name -f File with ports origin
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:
poudriere: {
url: Link to the package repository
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
}
}