Synopsis #
Start a private repository with one small package before adding a production package list. This procedure builds misc/figlet, signs the catalogue with a local RSA key, and installs the result on another FreeBSD system. One builder and disk-backed working files limit memory use.
The examples use ZFS pool zroot, a 15.1 amd64 jail, and ports branch 2026Q4. Substitute the actual pool, architecture, and reviewed branch. Clients need a compatible ABI; matching major versions alone do not qualify kernel modules or every base-library dependency.
Prepare the builder and signing key #
# pkg install poudriere git-lite
# install -d -m 755 /usr/local/poudriere/distfiles
# install -d -m 700 /usr/local/etc/ssl/keys
# install -d -m 755 /usr/local/etc/ssl/certs
# openssl genrsa -out /usr/local/etc/ssl/keys/poudriere.key 3072
# chmod 0600 /usr/local/etc/ssl/keys/poudriere.key
# openssl rsa -in /usr/local/etc/ssl/keys/poudriere.key -pubout -out /usr/local/etc/ssl/certs/poudriere.pub
# chmod 0644 /usr/local/etc/ssl/certs/poudriere.pub
Keep the private key outside the web root. Clients receive only the public key. Do not regenerate an established repository’s key during ordinary setup or rebuilds.
Edit these settings in /usr/local/etc/poudriere.conf, preserving unrelated configuration:
ZPOOL=zroot
BASEFS=/usr/local/poudriere
FREEBSD_HOST=https://download.freebsd.org
DISTFILES_CACHE=/usr/local/poudriere/distfiles
USE_TMPFS=no
PARALLEL_JOBS=1
PKG_REPO_SIGNING_KEY=/usr/local/etc/ssl/keys/poudriere.key
The distfiles directory must exist before building. Disk-backed working files do not remove a compiler’s own memory requirement.
Create the inputs and build #
# poudriere ports -c -p quarterly -B 2026Q4 -m git+https
# poudriere jail -c -j 151amd64 -v 15.1-RELEASE -a amd64
# poudriere ports -l
# poudriere jail -l
$ git -C /usr/local/poudriere/ports/quarterly rev-parse HEAD
Jail creation applies available base updates. Check its reported version. Preserve the ports commit with the approved package list and options; a quarterly branch continues changing.
Create /usr/local/etc/poudriere.d/small-packages containing:
misc/figlet
Set MAKE_JOBS_NUMBER=2 in /usr/local/etc/poudriere.d/make.conf, or use a lower value on a smaller host. Compiler jobs within a port are separate from concurrent port builders.
Build:
# poudriere bulk -j 151amd64 -p quarterly -J 1 -f /usr/local/etc/poudriere.d/small-packages
The first run also builds the package-management bootstrap. Review final counts and individual logs. Continue only after the requested packages and dependencies built successfully, with no unexplained failures or skips.
Publish a complete generation #
For these jail and ports-tree names, .latest selects the completed generation:
# install -d -m 755 /usr/local/www/packages/generation-1
# cp -a /usr/local/poudriere/data/packages/151amd64-quarterly/.latest/. /usr/local/www/packages/generation-1/
# chmod -R a+rX /usr/local/www/packages/generation-1
# ln -s generation-1 /usr/local/www/packages/current
Preserve the whole hierarchy, including catalogue files. Use a new generation name for later publications; do not overwrite files while clients read them. The web service needs read access to the copy, without write access or access to signing keys.
Expose current/ through the existing web server. An nginx server block can contain:
location /packages/ {
alias /usr/local/www/packages/current/;
autoindex off;
}
Validate and reload that server’s configuration. Use HTTPS for normal deployment. HTTP is appropriate only where a deliberately trusted private transport is acceptable; signatures provide authenticity, not confidentiality.
Configure a client with explicit trust #
Transfer poudriere.pub through an already trusted administrative channel. Install it on the client as /usr/local/etc/pkg/keys/poudriere.pub, readable by the package manager. Do not accept a signing key solely from the repository it is meant to authenticate.
Create /usr/local/etc/pkg/repos/Local.conf, substituting the real URL:
Local: {
url: "https://packages.example.org/packages",
enabled: yes,
signature_type: "pubkey",
pubkey: "/usr/local/etc/pkg/keys/poudriere.pub",
priority: 100
}
Preserve other repository definitions. Explicit -r Local limits the following transaction to this repository; it does not establish a complete policy for mixing sources.
$ fetch -o /dev/null https://packages.example.org/packages/meta.conf
# pkg update -f -r Local
$ pkg rquery -r Local '%n-%v'
# pkg install -r Local figlet
$ pkg info -f figlet
$ figlet -f small hello
Read the complete update output. Stop on an invalid signature even if another line says the repository is up to date. A previous cached catalogue can remain usable after an unsuccessful refresh. Check the trusted key, URL, and published generation; do not disable signature checking.
Confirm that the installed package identifies the intended repository and that the program runs. Before broad enrollment, repeat application checks for the actual package list. See repository operations for generation retention, key rotation, and client policy.