Most of the time FreeBSD systems are used with wide open connection to the Internet along with fully working DNS that resolves anything the Root Servers resolve … but FreeBSD – besides being used as SONY PlayStation gaming systems or Netflix storage layer.

Its also used in high security environments without any external DNS access or direct Internet connection to the outside World … yet the security patches are fetched and applied and custom PKGBASE and/or Poudriere systems build base system/packages while fetching them from the Internet over some dedicated proxy.
Many people will not read entire article so I will point that in the beginning – that I am really grateful to Mariusz Zaborski (oshogbo) for his help with this one – without his help – it just would not happen.
By default FreeBSD does not work well in such environments … in this article we will configure FreeBSD to make everything work as needed.
The Table of Contents is as follows.
- FreeBSD and Poudriere in High Security Environments
- Example Proxy Configuration
- Physical (or Virtual) FreeBSD Host
- pkg(8)
- FreeBSD Ports Tree
- Proxy on the Fly
- Back to the PKGBASE
- Poudriere in Proxy World
- Basic Poudriere Setup
- Important Poudriere Config Part
Example Proxy Configuration
For completeness I will add Squid configuration used here – so that all information will be available.
proxy # grep '^[^#]' /usr/local/etc/squid/squid.conf http_port 127.0.0.1:3128 http_port 10.0.0.41:3128 acl SSL_ports port 443 acl Safe_ports port 80 # http acl Safe_ports port 21 # ftp acl Safe_ports port 443 # https acl Safe_ports port 70 # gopher acl Safe_ports port 210 # wais acl Safe_ports port 1025-65535 # unregistered ports acl Safe_ports port 280 # http-mgmt acl Safe_ports port 488 # gss-http acl Safe_ports port 591 # filemaker acl Safe_ports port 777 # multiling http acl CONNECT method CONNECT http_access deny !Safe_ports http_access deny CONNECT !SSL_ports http_access allow localhost manager http_access deny manager acl localnet src 127.0.0.1 acl localnet src 10.0.0.0/8 # RFC 1918 local private network (LAN) acl localnet src 172.16.0.0/12 # RFC 1918 local private network (LAN) acl localnet src 192.168.0.0/16 # RFC 1918 local private network (LAN) http_access allow localnet http_access allow localhost http_access deny all visible_hostname proxy.xyz acl custom-local dstdomain .custom.xyz cache_peer 10.0.0.42 parent 3128 0 no-query default name=weathertop cache_peer_domain 10.0.0.43 !.xyz never_direct deny custom-local never_direct allow all cache_dir ufs /var/local/squid/cache 50 16 256 coredump_dir /var/local/squid/cache access_log stdio:/var/local/log/squid/access.log cache_store_log stdio:/var/local/log/squid/store.log cache_log /var/local/log/squid/cache.log refresh_pattern ^ftp: 1440 20% 10080 refresh_pattern ^gopher: 1440 0% 1440 refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 refresh_pattern . 0 20% 4320 email_err_data off
Now we will configure a FreeBSD host to use it properly.
Physical (or Virtual) FreeBSD Host
For a start we will make pkg(8) work with our proxy system.
pkg(8)
I installed that FreeBSD 15.0-RELEASE system with PKGBASE way – Brave New PKGBASE World – described in details here. With offline install using PKGBASE packages from the install disc1.iso medium.
That means the pkg(8) is already bootstrapped … we will turn that ‘OFF’ for a moment.
test # pkg info FreeBSD-acct-15.0 System resource accounting FreeBSD-acpi-15.0 Advanced Configuration and Power Interface (ACPI) utilities FreeBSD-apm-15.0 Intel / Microsoft APM BIOS utility (...) FreeBSD-zlib-lib32-15.0 DEFLATE (gzip) data compression library (32-bit libraries) FreeBSD-zoneinfo-15.0 Timezone database pkg-2.4.2 Package manager test # mv /var/db/pkg /var/db/pkg.BCK test # mv /usr/local /usr/local.BCK
Now if you would like to bootstrap pkg(8) it will fail.
test # pkg The package management tool is not yet installed on your system. Do you want to fetch and install it now? [y/N]: y Bootstrapping pkg from pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly, please wait... pkg: Error fetching https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/Latest/pkg.pkg: Transient resolver failure A pre-built version of pkg could not be found for your system. Bootstrapping pkg from pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0, please wait... pkg: Error fetching https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/Latest/pkg.pkg: Transient resolver failure A pre-built version of pkg could not be found for your system.
Now we will export(1) needed proxy setting into environment.
test # export HTTP_PROXY="http://10.0.0.41:3128" test # export HTTPS_PROXY="http://10.0.0.41:3128" test # export FTP_PROXY="http://10.0.0.41:3128" test # env | grep -i proxy HTTP_PROXY=http://10.0.0.41:3128 HTTPS_PROXY=http://10.0.0.41:3128 FTP_PROXY=http://10.0.0.41:3128
If you want to make it permanent for the default sh(1) shell then do this.
test # cat < /etc/profile.d/proxy.sh export HTTP_PROXY=http://10.0.0.41:3128 export HTTPS_PROXY=http://10.0.0.41:3128 export FTP_PROXY=http://10.0.0.41:3128 EOF
Now with each new login these proxy settings will be available.
Lets try with pkg(8) again.
test # pkg info The package management tool is not yet installed on your system. Do you want to fetch and install it now? [y/N]: y Bootstrapping pkg from pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly, please wait... Verifying signature with trusted certificate pkg.freebsd.org.2013102301... done Installing pkg-2.4.2... Extracting pkg-2.4.2: 100% pkg-2.4.2 Package manager
The pkg(8) has now bootstrap completed and will work, right? Right?
test # pkg update
Updating FreeBSD-ports repository catalogue...
pkg: No SRV record found for the repo 'FreeBSD-ports'
Fetching meta.conf: 100% 179 B 0.2kB/s 00:01
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/data.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/data.tzst -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/packagesite.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/packagesite.tzst -- pkg+:// implies SRV mirror type
Unable to update repository FreeBSD-ports
Updating FreeBSD-ports-kmods repository catalogue...
pkg: No SRV record found for the repo 'FreeBSD-ports-kmods'
Fetching meta.conf: 100% 179 B 0.2kB/s 00:01
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/data.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/data.tzst -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/packagesite.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/packagesite.tzst -- pkg+:// implies SRV mirror type
Unable to update repository FreeBSD-ports-kmods
Error updating repositories!
Small modification is needed. One need to remove pkg+ prefix from all url: paths and to switch mirror_type: from srv to none. Then it will work.
Now … the reason why FreeBSD uses the pkg+ prefix is this:
- pkg+https:// tells pkg(8) to use libpkg internal HTTP/HTTPS fetcher.
- https:// tells pkg(8) to use external fetcher – usually with FreeBSD fetch(1) tool.
Now … the needed changes.
test # \
grep '^[^#]' /etc/pkg/FreeBSD.conf \
| sed -e 's.pkg+..g' \
-e 's."srv"."none".g' \
-e 's.enabled: no.enabled: yes.g' \
> /root/FreeBSD.conf
The diff(1) for that change is below.
root # diff -u /etc/pkg/FreeBSD.conf /root/FreeBSD.conf --- /etc/pkg/FreeBSD.conf 2025-11-28 00:00:00.000000000 +0000 +++ /root/FreeBSD.conf 2026-01-07 00:11:41.534051000 +0000 @@ -10,23 +10,23 @@ # FreeBSD-ports: { - url: "pkg+https://pkg.FreeBSD.org/${ABI}/quarterly", - mirror_type: "srv", + url: "https://pkg.FreeBSD.org/${ABI}/quarterly", + mirror_type: "none", signature_type: "fingerprints", fingerprints: "/usr/share/keys/pkg", enabled: yes } FreeBSD-ports-kmods: { - url: "pkg+https://pkg.FreeBSD.org/${ABI}/kmods_quarterly_${VERSION_MINOR}", - mirror_type: "srv", + url: "https://pkg.FreeBSD.org/${ABI}/kmods_quarterly_${VERSION_MINOR}", + mirror_type: "none", signature_type: "fingerprints", fingerprints: "/usr/share/keys/pkg", enabled: yes } FreeBSD-base: { - url: "pkg+https://pkg.FreeBSD.org/${ABI}/base_release_${VERSION_MINOR}", - mirror_type: "srv", + url: "https://pkg.FreeBSD.org/${ABI}/base_release_${VERSION_MINOR}", + mirror_type: "none", signature_type: "fingerprints", fingerprints: "/usr/share/keys/pkgbase-${VERSION_MAJOR}", - enabled: no + enabled: yes }
Now – lets leave the original /etc/pkg/FreeBSD.conf unmodified and create /usr/local/etc/pkg/repos/FreeBSD.conf that will override the defaults.
test # mkdir -pv /usr/local/etc/pkg/repos /usr/local/etc/pkg /usr/local/etc/pkg/repos test # cp /root/FreeBSD.conf /usr/local/etc/pkg/repos/
Now that pkg(8) should work well over proxy.
test # pkg update
Updating FreeBSD-ports repository catalogue...
Fetching meta.conf: 100% 179 B 0.2kB/s 00:01
Fetching data.pkg: 100% 10 MiB 3.6MB/s 00:03
Processing entries: 100%
FreeBSD-ports repository update completed. 36390 packages processed.
Updating FreeBSD-ports-kmods repository catalogue...
Fetching meta.conf: 100% 179 B 0.2kB/s 00:01
Fetching data.pkg: 100% 31 KiB 31.3kB/s 00:01
Processing entries: 100%
FreeBSD-ports-kmods repository update completed. 204 packages processed.
Updating FreeBSD-base repository catalogue...
Fetching meta.conf: 100% 179 B 0.2kB/s 00:01
Fetching data.pkg: 100% 80 KiB 81.5kB/s 00:01
Processing entries: 100%
FreeBSD-base repository update completed. 496 packages processed.
Lets try to actually install any software.
test # pkg install lsblk beadm Updating FreeBSD-ports repository catalogue... FreeBSD-ports repository is up to date. Updating FreeBSD-ports-kmods repository catalogue... FreeBSD-ports-kmods repository is up to date. Updating FreeBSD-base repository catalogue... FreeBSD-base repository is up to date. All repositories are up to date. The following 2 package(s) will be affected (of 0 checked): New packages to be INSTALLED: beadm: 1.3.5_1 [FreeBSD-ports] lsblk: 4.0 [FreeBSD-ports] gitup: 1.0 [FreeBSD-ports] Number of packages to be installed: 3 18 KiB to be downloaded. Proceed with this action? [y/N]: y [1/3] Fetching lsblk-4.0~3110a4bb46.pkg: 100% 7 KiB 7.2kB/s 00:01 [2/3] Fetching beadm-1.3.5_1~53f06720d4.pkg: 100% 11 KiB 11.0kB/s 00:01 [3/3] Fetching gitup-1.0~2c88a1f1f1.pkg: 100% 36 KiB 37.0kB/s 00:01 Checking integrity... done (0 conflicting) [1/3] Installing beadm-1.3.5_1... [1/3] Extracting beadm-1.3.5_1: 100% [2/3] Installing lsblk-4.0... [2/3] Extracting lsblk-4.0: 100% [3/3] Installing gitup-1.0... [3/3] Extracting gitup-1.0: 100% test # lsblk -d DEVICE SIZE MODEL nda0 10G bhyve-NVMe - 10G TOTAL SYSTEM STORAGE
Works.
If for some reason the above method will not work – you may also configure proxy server within the pkg(8) config /usr/local/etc/pkg.conf file.
test # tail -5 /usr/local/etc/pkg.conf
PKG_ENV {
HTTP_PROXY: "http://10.0.0.41:3128"
HTTPS_PROXY: "https://10.0.0.41:3128"
FTP_PROXY: "http://10.0.0.41:3128"
}
These settings will also override any ‘system’ settings we set previously in the /etc/profile.d/proxy.sh file.
FreeBSD Ports Tree
We already installed gitup tool that will allow us to update the FreeBSD Ports tree easily.
Its default config is more then enought.
test # grep -m 1 -A 6 ports /usr/local/etc/gitup.conf
"ports" : {
"repository_path" : "/ports.git",
"branch" : "main",
"target_directory" : "/usr/ports",
"ignores" : [],
},
Lets try fetching the FreeBSD Ports tree now.
test # gitup ports
# Host: git.freebsd.org
# Port: 443
# Proxy Host: 10.0.0.41
# Proxy Port: 3128
# Repository Path: /ports.git
# Target Directory: /usr/ports
# Want: 284813ec0382a2bfe5b2e74a3081a67599d3155d
# Branch: main
# Action: clone
75 MB in 0m25s, 4614 kB/s now
+ /usr/ports/.arcconfig
+ /usr/ports/.gitignore
+ /usr/ports/.hooks/pre-commit
(...)
+ /usr/ports/x11/zutty/Makefile
+ /usr/ports/x11/zutty/distinfo
+ /usr/ports/x11/zutty/pkg-descr
#
# Please review the following file(s) for important changes.
# /usr/ports/UPDATING
# /usr/ports/mail/dspam/files/UPDATING
#
# Done.
Seems to work.
To now update the FreeBSD Ports tree run gitup(1) command again.
test # gitup ports
# Scanning local repository...
# Host: git.freebsd.org
# Port: 443
# Proxy Host: 10.0.0.41
# Proxy Port: 3128
# Repository Path: /ports.git
# Target Directory: /usr/ports
# Have: 284813ec0382a2bfe5b2e74a3081a67599d3155d
# Want: 7b2f3c4f484b1634066997a91836554608c72c48
# Branch: main
# Action: pull
* /usr/ports/lang/spidermonkey115/Makefile
* /usr/ports/lang/spidermonkey115/distinfo
* /usr/ports/lang/spidermonkey140/Makefile
* /usr/ports/lang/spidermonkey140/distinfo
# Done.
If for some reason You will find gitup(1) or git(1) does not work – you may always configure system wide proxy as follows.
test # git config --system http.proxy http://10.0.0.41:3128
That would help.
Proxy on the Fly
If for some reason You will need to force the proxy settings for a single command – then use something like that below.
test # \
env HTTP_PROXY="http://10.0.0.41:3128" \
HTTPS_PROXY="http://10.0.0.41:3128" \
FTP_PROXY="http://10.0.0.41:3128"
command ...
Back to the PKGBASE
Now – lets bring back our original pkg(8) config – we may ‘keep’ the current ‘test’ bootstrap if needed with .CUSTOM suffix.
test # mv /usr/local /usr/local.CUSTOM test # mv /var/db/pkg /var/db/pkg.CUSTOM test # mv /usr/local.BCK /usr/local test # mv /var/db/pkg.BCK /var/db/pkg
Now the ‘original’ pkg(8) config that keeps PKGBASE information works again.
test # pkg info | (head -3 ;echo '(...)'; tail -3)
FreeBSD-acct-15.0 System resource accounting
FreeBSD-acpi-15.0 Advanced Configuration and Power Interface (ACPI) utilities
FreeBSD-apm-15.0 Intel / Microsoft APM BIOS utility
(...)
FreeBSD-zlib-lib32-15.0 DEFLATE (gzip) data compression library (32-bit libraries)
FreeBSD-zoneinfo-15.0 Timezone database
pkg-2.4.2 Package manager
But when we will now try to update the pkg(8) repositories it will fail … why?
test # pkg update
Updating FreeBSD-ports repository catalogue...
pkg: No SRV record found for the repo 'FreeBSD-ports'
Fetching meta.conf: 100% 179 B 0.2kB/s 00:01
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/data.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/data.tzst -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/packagesite.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/quarterly/packagesite.tzst -- pkg+:// implies SRV mirror type
Unable to update repository FreeBSD-ports
Updating FreeBSD-ports-kmods repository catalogue...
pkg: No SRV record found for the repo 'FreeBSD-ports-kmods'
Fetching meta.conf: 100% 179 B 0.2kB/s 00:01
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/data.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/data.tzst -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/packagesite.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+https://pkg.FreeBSD.org/FreeBSD:15:amd64/kmods_quarterly_0/packagesite.tzst -- pkg+:// implies SRV mirror type
Unable to update repository FreeBSD-ports-kmods
Error updating repositories!
Its because our config override was placed in /usr/local path … and we just wiped that away.
Copy working proxy config again then.
test # mkdir -pv /usr/local/etc/pkg/repos /usr/local/etc/pkg /usr/local/etc/pkg/repos test # cp /root/FreeBSD.conf /usr/local/etc/pkg/repos/
Now update will work again.
test # pkg update
Updating FreeBSD-ports repository catalogue...
Fetching meta.conf: 100% 179 B 0.2kB/s 00:01
Fetching data.pkg: 100% 10 MiB 5.4MB/s 00:02
Processing entries: 100%
FreeBSD-ports repository update completed. 36390 packages processed.
Updating FreeBSD-ports-kmods repository catalogue...
Fetching meta.conf: 100% 179 B 0.2kB/s 00:01
Fetching data.pkg: 100% 31 KiB 31.3kB/s 00:01
Processing entries: 100%
FreeBSD-ports-kmods repository update completed. 204 packages processed.
Updating FreeBSD-base repository catalogue...
pkg: Repository FreeBSD-base has a wrong packagesite, need to re-create database
Fetching meta.conf: 100% 179 B 0.2kB/s 00:01
Fetching data.pkg: 100% 80 KiB 81.5kB/s 00:01
Processing entries: 100%
FreeBSD-base repository update completed. 496 packages processed.
All repositories are up to date.
You can even do PKGBASE upgrade if wanted.
test # pkg upgrade
Updating FreeBSD-ports repository catalogue...
FreeBSD-ports repository is up to date.
Updating FreeBSD-ports-kmods repository catalogue...
FreeBSD-ports-kmods repository is up to date.
Updating FreeBSD-base repository catalogue...
FreeBSD-base repository is up to date.
All repositories are up to date.
Checking for upgrades (4 candidates): 100%
Processing candidates (4 candidates): 100%
The following 4 package(s) will be affected (of 0 checked):
Installed packages to be UPGRADED:
FreeBSD-kernel-generic: 15.0 -> 15.0p1 [FreeBSD-base]
FreeBSD-rescue: 15.0 -> 15.0p1 [FreeBSD-base]
FreeBSD-runtime: 15.0 -> 15.0p1 [FreeBSD-base]
FreeBSD-utilities: 15.0 -> 15.0p1 [FreeBSD-base]
Number of packages to be upgraded: 4
62 MiB to be downloaded.
Proceed with this action? [y/N]:
Poudriere in Proxy World
Now to another deeper level – like in Inception (2010) movie – the Poudriere package building harvester.
If you want to check more on the Poudriere itself you can check these:
Now – first we need to install poudriere-devel package as it has the latest features.
test # pkg install poudriere-devel ccache4 git nginx Updating FreeBSD-ports repository catalogue... FreeBSD-ports repository is up to date. Updating FreeBSD-ports-kmods repository catalogue... FreeBSD-ports-kmods repository is up to date. Updating FreeBSD-base repository catalogue... FreeBSD-base repository is up to date. All repositories are up to date. The following 28 package(s) will be affected (of 0 checked): New packages to be INSTALLED: brotli: 1.1.0,1 [FreeBSD-ports] ccache4: 4.10.2_1 [FreeBSD-ports] curl: 8.16.0 [FreeBSD-ports] expat: 2.7.3 [FreeBSD-ports] gettext-runtime: 0.23.1 [FreeBSD-ports] git: 2.51.0 [FreeBSD-ports] indexinfo: 0.3.1_1 [FreeBSD-ports] libffi: 3.5.1 [FreeBSD-ports] libidn2: 2.3.8 [FreeBSD-ports] libnghttp2: 1.67.0 [FreeBSD-ports] libpsl: 0.21.5_2 [FreeBSD-ports] libssh2: 1.11.1,3 [FreeBSD-ports] libunistring: 1.4.1 [FreeBSD-ports] mpdecimal: 4.0.1 [FreeBSD-ports] nginx: 1.28.0_3,3 [FreeBSD-ports] p5-Authen-SASL: 2.1900 [FreeBSD-ports] p5-Crypt-URandom: 0.54 [FreeBSD-ports] p5-Digest-HMAC: 1.05 [FreeBSD-ports] p5-Error: 0.17030 [FreeBSD-ports] p5-IO-Socket-SSL: 2.095 [FreeBSD-ports] p5-MIME-Base32: 1.303 [FreeBSD-ports] p5-MIME-Base64: 3.16 [FreeBSD-ports] p5-Mozilla-CA: 20250602 [FreeBSD-ports] p5-Net-SSLeay: 1.94 [FreeBSD-ports] p5-URI: 5.32_1 [FreeBSD-ports] poudriere-devel: 3.4.99.20251213 [FreeBSD-ports] python311: 3.11.14 [FreeBSD-ports] readline: 8.2.13_2 [FreeBSD-ports] Number of packages to be installed: 28 The process will require 283 MiB more space. 41 MiB to be downloaded. Proceed with this action? [y/N]: y [1/25] Fetching mpdecimal-4.0.1~f774e949d8.pkg: 100% 157 KiB 160.5kB/s 00:01 (...) [28/28] Installing git-2.51.0... ===> Creating groups Creating group 'git_daemon' with gid '964' ===> Creating users Creating user 'git_daemon' with uid '964' [28/28] Extracting git-2.51.0: 100%
Basic Poudriere Setup
We will now setup some basic Poudriere setup.
test # export SSL=/usr/local/etc/ssl test # mkdir -p \ /usr/ports/distfiles \ ${SSL}/keys \ ${SSL}/certs test # chmod 0600 ${SSL}/keys test # openssl genrsa -out ${SSL}/keys/poudriere.key 4096 test # openssl rsa \ -in ${SSL}/keys/poudriere.key -pubout \ -out ${SSL}/certs/poudriere.cert test # mkdir /var/ccache test # cat < /usr/local/etc/poudriere.conf ZPOOL=zroot FREEBSD_HOST=ftp://ftp.freebsd.org BASEFS=/usr/local/poudriere POUDRIERE_DATA=/usr/local/poudriere/data DISTFILES_CACHE=/usr/ports/distfiles CCACHE_DIR=/var/ccache CHECK_CHANGED_OPTIONS=verbose CHECK_CHANGED_DEPS=yes PKG_REPO_SIGNING_KEY=/usr/local/etc/ssl/keys/poudriere.key URL_BASE=http://0.0.0.0/ USE_TMPFS=no TMPFS_LIMIT=12 MAX_MEMORY=12 PARALLEL_JOBS=4 PREPARE_PARALLEL_JOBS=4 MAX_FILES=4096 KEEP_OLD_PACKAGES=yes KEEP_OLD_PACKAGES_COUNT=3 CHECK_CHANGED_OPTIONS=verbose CHECK_CHANGED_DEPS=yes RESTRICT_NETWORKING=no PACKAGE_FETCH_URL="http://pkg.FreeBSD.org/\${ABI}" PACKAGE_FETCH_BRANCH="latest" export HTTP_PROXY="http://10.0.0.41:3128" export HTTPS_PROXY="http://10.0.0.41:3128" export FTP_PROXY="http://10.0.0.41:3128" EOF test # mkdir -p /usr/local/poudriere/data/logs/bulk test # ln -s \ /usr/local/etc/ssl/certs/poudriere.cert \ /usr/local/poudriere/data/logs/bulk/poudriere.cert test # cat < /usr/local/etc/poudriere.d/make.conf # general ALLOW_UNSUPPORTED_SYSTEM=yes DISABLE_LICENSES=yes # ccache(1) WITH_CCACHE_BUILD=yes # ports options FORCE_MAKE_JOBS=yes MAKE_JOBS_UNSAFE=yes MAKE_JOBS_NUMBER=8 EOF test # sed -i '' -E 's|text/plain[\t\ ]*txt|text/plain txt log|g' /usr/local/etc/nginx/mime.types test # cat < /usr/local/etc/nginx/nginx.conf events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; server { listen 80 default; server_name 0.0.0.0; root /usr/local/share/poudriere/html; location /data { alias /usr/local/poudriere/data/logs/bulk; autoindex on; } location /packages { root /usr/local/poudriere/data; autoindex on; } } } EOF test # mkdir /root/.cache test # ln -sf /var/ccache /root/.cache/ccache test # cat < /var/ccache/ccache.conf max_size = 0 cache_dir = /var/ccache base_dir = /var/ccache hash_dir = false EOF
Important Poudriere Config Part
The IMPORTANT settings here – to allow Poudriere function properly within proxy environment – are these five lines in the /usr/local/etc/poudriere.conf file.
export HTTP_PROXY="http://10.0.0.41:3128"
export HTTPS_PROXY="http://10.0.0.41:3128"
export FTP_PROXY="http://10.0.0.41:3128"
PACKAGE_FETCH_URL="http://pkg.FreeBSD.org/\${ABI}"
PACKAGE_FETCH_BRANCH="latest"
The first three are obvious – and YES – they need the export prefix to work.
The other two are less obvious … and I will show You why in a moment.
We need to create some FreeBSD jail – we will use 14.3-RELEASE as example. Use any version that you will be building packages for.
test # poudriere jail -c -j 14-3-R-amd64 -v 14.3-RELEASE [00:00:00] Creating 14-3-R-amd64 fs at /usr/local/poudriere/jails/14-3-R-amd64... done [00:00:00] Using pre-distributed MANIFEST for FreeBSD 14.3-RELEASE amd64 [00:00:00] Fetching base for FreeBSD 14.3-RELEASE amd64 base.txz 200 MB 5128 kBps 41s [00:00:41] Extracting base... done [00:00:49] Fetching src for FreeBSD 14.3-RELEASE amd64 src.txz 206 MB 4828 kBps 44s [00:01:34] Extracting src... done [00:01:46] Fetching lib32 for FreeBSD 14.3-RELEASE amd64 lib32.txz 60 MB 11 MBps 05s [00:01:52] Extracting lib32... done [00:01:54] Cleaning up... done [00:01:54] Recording filesystem state for clean... done [00:01:54] Upgrading using http Looking up update.FreeBSD.org mirrors... none found. Fetching public key from update.FreeBSD.org... done. Fetching metadata signature for 14.3-RELEASE from update.FreeBSD.org... done. Fetching metadata index... done. Fetching 2 metadata files... done. Inspecting system... done. Preparing to download files... done. Fetching 196 patches.....10....20....30....40....50....60....70....80....90....100....110....120....130....140....150....160....170....180....190... done. Applying patches... done. Fetching 40 files... ....10....20....30....40 done. The following files will be removed as part of updating to 14.3-RELEASE-p7: /usr/src/contrib/libarchive/libarchive/archive_getdate.c /usr/src/contrib/libarchive/libarchive/archive_getdate.h /usr/src/contrib/libarchive/libarchive/test/test_archive_getdate.c (...) /usr/src/usr.bin/tar/tests/Makefile /usr/src/usr.sbin/freebsd-update/freebsd-update.sh /usr/src/usr.sbin/rtsold/rtsol.c Installing updates... done. 14.3-RELEASE-p7 [00:03:25] Recording filesystem state for clean... done [00:03:25] Jail 14-3-R-amd64 14.3-RELEASE-p7 amd64 is ready to be used test # poudriere jail -l JAILNAME VERSION OSVERSION ARCH METHOD TIMESTAMP PATH 14-3-R-amd64 14.3-RELEASE-p7 1403000 amd64 http 2026-01-07 01:33:45 /usr/local/poudriere/jails/14-3-R-amd64
We also need FreeBSD Ports tree … just in a Poudriere way.
test # poudriere ports -c [00:00:00] Creating default fs at /usr/local/poudriere/ports/default... done [00:00:00] Cloning the ports tree... fatal: unable to access 'https://git.FreeBSD.org/ports.git/': Could not resolve host: git.FreeBSD.org [00:00:45] Error: /usr/local/share/poudriere/ports.sh:303: fail [00:00:45] Error while creating ports tree, cleaning up.
This is where the dedicated git(1) config is needed as its a bitch and ignores *_PROXY variables π
test # git config --system http.proxy http://10.0.0.41:3128 test # poudriere ports -c [00:00:00] Creating default fs at /usr/local/poudriere/ports/default... done [00:00:00] Cloning the ports tree... done test # poudriere ports -l PORTSTREE METHOD TIMESTAMP PATH default git+https 2026-01-07 01:49:46 /usr/local/poudriere/ports/default
Works.
Now – lets try to actually build something with Poudriere.
We will try two ports that one needs to be actually build (dosunix) and one that is in POSIX sh(1) and does not need building (lsblk).
I will intentionally run first building process with proxy variables disabled like this in the /usr/local/etc/poudriere.conf file:
# PACKAGE_FETCH_URL="http://pkg.FreeBSD.org/\${ABI}"
# PACKAGE_FETCH_BRANCH="latest"
# export HTTP_PROXY="http://10.0.0.41:3128"
# export HTTPS_PROXY="http://10.0.0.41:3128"
# export FTP_PROXY="http://10.0.0.41:3128"
Here.
test # poudriere bulk -c -C -j 14-3-R-amd64 -b latest -p default sysutils/lsblk converters/dosunix
Result is below … and as expected it failed.
test # poudriere bulk -c -C -j 14-3-R-amd64 -b latest -p default sysutils/lsblk converters/dosunix [00:00:00] Creating the reference jail... done [00:00:00] Mounting system devices for 14-3-R-amd64-default [00:00:00] Stashing existing package repository [00:00:00] Mounting ccache from: /var/ccache [00:00:00] Mounting ports from: /usr/local/poudriere/ports/default [00:00:00] Mounting packages from: /usr/local/poudriere/data/packages/14-3-R-amd64-default [00:00:00] Mounting distfiles from: /usr/ports/distfiles [00:00:00] Appending to make.conf: /usr/local/etc/poudriere.d/make.conf /etc/resolv.conf -> /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref/etc/resolv.conf [00:00:00] Starting jail 14-3-R-amd64-default Updating /var/run/os-release done. [00:00:00] Will build as root:wheel (0:0) [00:00:00] Ports supports: FLAVORS SUBPACKAGES SELECTED_OPTIONS [00:00:00] Inspecting /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref//usr/ports for modifications to git checkout... no [00:00:03] Ports top-level git hash: 284813ec0382a2bfe5b2e74a3081a67599d3155d [00:00:03] Acquiring build logs lock for 14-3-R-amd64-default... done [00:00:03] Logs: /usr/local/poudriere/data/logs/bulk/14-3-R-amd64-default/2026-01-07_01h58m23s [00:00:03] WWW: http://0.0.0.0//build.html?mastername=14-3-R-amd64-default&build=2026-01-07_01h58m23s [00:00:03] Loading MOVED for /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref/usr/ports [00:00:04] Gathering ports metadata [00:00:04] Calculating ports order and dependencies [00:00:04] Sanity checking the repository [00:00:04] -c specified, cleaning all packages... done [00:00:04] -C specified, cleaning listed packages [00:00:04] (-C) Flushing package deletions [00:00:04] Trimming IGNORED and blacklisted ports [00:00:04] Package fetch: Looking for missing packages to fetch from pkg+http://pkg.FreeBSD.org/${ABI}/latest [00:00:04] Package fetch: bootstrapping pkg Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest, please wait... pkg: Attempted to fetch pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/Latest/pkg.pkg pkg: Attempted to fetch pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/Latest/pkg.txz pkg: Error: Address family for host not supported Address resolution failed for http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest. [00:08:58] Package fetch: Not fetching as remote repository is unavailable. [00:08:58] pkg bootstrap missing: unable to inspect existing packages, cleaning all packages... done [00:08:58] Deleting stale symlinks... done [00:08:58] Deleting empty directories... done [00:08:58] Unqueueing existing packages [00:08:58] Unqueueing orphaned build dependencies [00:08:58] Sanity checking build queue [00:08:58] [14-3-R-amd64-default] [2026-01-07_01h58m23s] [pkgqueue_sanity_check] Time: 00:08:54 Queued: 4 Inspected: 0 Ignored: 0 Built: 0 Failed: 0 Skipped: 0 Fetched: 0 Remaining: 4 [00:08:58] Recording filesystem state for prepkg... done [00:08:58] Processing PRIORITY_BOOST [00:08:58] Building 4 packages using up to 4 builders [00:08:58] Hit CTRL+t at any time to see build progress and stats [00:08:58] [01] [00:00:00] Builder starting [00:08:58] [01] [00:00:00] Builder started [00:08:58] [01] [00:00:00] Building ports-mgmt/pkg | pkg-2.5.1 [00:11:56] [01] [00:02:58] Finished ports-mgmt/pkg | pkg-2.5.1: Failed: fetch [00:11:56] [01] [00:02:58] Skipping devel/ccache | ccache-3.7.12_8: Dependent port ports-mgmt/pkg | pkg-2.5.1 failed [00:11:56] [01] [00:02:58] Skipping converters/dosunix | dosunix-1.0.14: Dependent port ports-mgmt/pkg | pkg-2.5.1 failed [00:11:56] [01] [00:02:58] Skipping sysutils/lsblk | lsblk-4.0: Dependent port ports-mgmt/pkg | pkg-2.5.1 failed [00:11:57] Stopping up to 4 builders [00:11:57] Creating pkg repository [00:11:57] No packages present [00:11:57] Committing packages to repository: /usr/local/poudriere/data/packages/14-3-R-amd64-default/.real_1767751820 via .latest symlink [00:11:57] Removing old packages [00:11:57] Failed ports: ports-mgmt/pkg:fetch [00:11:57] Skipped ports: converters/dosunix devel/ccache sysutils/lsblk [00:11:57] [14-3-R-amd64-default] [2026-01-07_01h58m23s] [committing] Time: 00:11:53 Queued: 4 Inspected: 0 Ignored: 0 Built: 0 Failed: 1 Skipped: 3 Fetched: 0 Remaining: 0 [00:11:57] Logs: /usr/local/poudriere/data/logs/bulk/14-3-R-amd64-default/2026-01-07_01h58m23s [00:11:57] WWW: http://0.0.0.0//build.html?mastername=14-3-R-amd64-default&build=2026-01-07_01h58m23s [00:11:57] Cleaning up [00:11:57] Stopping up to 4 builders [00:11:57] Unmounting file systems test #
Now I will run it again but with proxy setting enabled in the /usr/local/etc/poudriere.conf file like that.
# PACKAGE_FETCH_URL="http://pkg.FreeBSD.org/\${ABI}"
# PACKAGE_FETCH_BRANCH="latest"
export HTTP_PROXY="http://10.0.0.41:3128"
export HTTPS_PROXY="http://10.0.0.41:3128"
export FTP_PROXY="http://10.0.0.41:3128"
It should work with one small caveat.
test # poudriere bulk -c -C -j 14-3-R-amd64 -b latest -p default sysutils/lsblk converters/dosunix [00:00:00] Creating the reference jail... done [00:00:00] Mounting system devices for 14-3-R-amd64-default [00:00:00] Stashing existing package repository [00:00:00] Mounting ccache from: /var/ccache [00:00:00] Mounting ports from: /usr/local/poudriere/ports/default [00:00:00] Mounting packages from: /usr/local/poudriere/data/packages/14-3-R-amd64-default [00:00:00] Mounting distfiles from: /usr/ports/distfiles [00:00:00] Appending to make.conf: /usr/local/etc/poudriere.d/make.conf /etc/resolv.conf -> /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref/etc/resolv.conf [00:00:00] Starting jail 14-3-R-amd64-default Updating /var/run/os-release done. [00:00:00] Will build as root:wheel (0:0) [00:00:01] Ports supports: FLAVORS SUBPACKAGES SELECTED_OPTIONS [00:00:01] Inspecting /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref//usr/ports for modifications to git checkout... no [00:00:04] Ports top-level git hash: 284813ec0382a2bfe5b2e74a3081a67599d3155d [00:00:04] Acquiring build logs lock for 14-3-R-amd64-default... done [00:00:04] Logs: /usr/local/poudriere/data/logs/bulk/14-3-R-amd64-default/2026-01-07_02h13m56s [00:00:04] WWW: http://0.0.0.0//build.html?mastername=14-3-R-amd64-default&build=2026-01-07_02h13m56s [00:00:04] Loading MOVED for /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref/usr/ports [00:00:04] Gathering ports metadata [00:00:04] Calculating ports order and dependencies [00:00:04] Sanity checking the repository [00:00:04] -c specified, cleaning all packages... done [00:00:04] -C specified, cleaning listed packages [00:00:04] (-C) Flushing package deletions [00:00:04] Trimming IGNORED and blacklisted ports [00:00:04] Package fetch: Looking for missing packages to fetch from pkg+http://pkg.FreeBSD.org/${ABI}/latest [00:00:04] Package fetch: bootstrapping pkg Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest, please wait... [14-3-R-amd64-default] Installing pkg-2.5.1... [14-3-R-amd64-default] Extracting pkg-2.5.1: 100% Updating Poudriere repository catalogue... pkg: No SRV record found for the repo 'Poudriere' [14-3-R-amd64-default] Fetching meta.conf: 100% 179 B 0.2 k/s 00:01 pkg: packagesite URL error for pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/data.pkg -- pkg+:// implies SRV mirror type pkg: packagesite URL error for pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/data.tzst -- pkg+:// implies SRV mirror type pkg: packagesite URL error for pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/packagesite.pkg -- pkg+:// implies SRV mirror type pkg: packagesite URL error for pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/packagesite.tzst -- pkg+:// implies SRV mirror type Unable to update repository Poudriere Error updating repositories! [00:00:29] Package fetch: Not fetching as remote repository is unavailable. [00:00:29] pkg bootstrap missing: unable to inspect existing packages, cleaning all packages... done [00:00:29] Deleting stale symlinks... done [00:00:29] Deleting empty directories... done [00:00:29] Unqueueing existing packages [00:00:29] Unqueueing orphaned build dependencies [00:00:29] Sanity checking build queue [00:00:29] [14-3-R-amd64-default] [2026-01-07_02h13m56s] [pkgqueue_sanity_check] Time: 00:00:26 Queued: 4 Inspected: 0 Ignored: 0 Built: 0 Failed: 0 Skipped: 0 Fetched: 0 Remaining: 4 [00:00:29] Recording filesystem state for prepkg... done [00:00:29] Processing PRIORITY_BOOST [00:00:30] Building 4 packages using up to 4 builders [00:00:30] Hit CTRL+t at any time to see build progress and stats [00:00:30] [01] [00:00:00] Builder starting [00:00:30] [01] [00:00:00] Builder started [00:00:30] [01] [00:00:00] Building ports-mgmt/pkg | pkg-2.5.1 [00:02:34] [01] [00:02:04] Finished ports-mgmt/pkg | pkg-2.5.1: Success [00:02:34] [02] [00:00:00] Builder starting [00:02:34] [01] [00:00:00] Building devel/ccache | ccache-3.7.12_8 [00:02:35] [02] [00:00:01] Builder started [00:02:35] [02] [00:00:00] Building sysutils/lsblk | lsblk-4.0 [00:02:36] [02] [00:00:01] Finished sysutils/lsblk | lsblk-4.0: Success [00:02:39] [01] [00:00:05] Finished devel/ccache | ccache-3.7.12_8: Success [00:02:39] [01] [00:00:00] Building converters/dosunix | dosunix-1.0.14 [00:02:42] [01] [00:00:03] Finished converters/dosunix | dosunix-1.0.14: Success [00:02:42] Stopping up to 4 builders [00:02:42] Creating pkg repository [00:02:42] Signing repository with key: /usr/local/etc/ssl/keys/poudriere.key Creating repository in /tmp/packages: 100% Packing files for repository: 100% [00:02:43] Signing pkg bootstrap with method: pubkey [00:02:43] Committing packages to repository: /usr/local/poudriere/data/packages/14-3-R-amd64-default/.real_1767752199 via .latest symlink [00:02:43] Removing old packages [00:02:43] Built ports: ports-mgmt/pkg sysutils/lsblk devel/ccache converters/dosunix [00:02:43] [14-3-R-amd64-default] [2026-01-07_02h13m56s] [committing] Time: 00:02:39 Queued: 4 Inspected: 0 Ignored: 0 Built: 4 Failed: 0 Skipped: 0 Fetched: 0 Remaining: 0 [00:02:43] Logs: /usr/local/poudriere/data/logs/bulk/14-3-R-amd64-default/2026-01-07_02h13m56s [00:02:43] WWW: http://0.0.0.0//build.html?mastername=14-3-R-amd64-default&build=2026-01-07_02h13m56s [00:02:43] Cleaning up [00:02:43] Stopping up to 4 builders [00:02:43] Unmounting file systems
Also in nice graphical colored form.

The build generally ended successfully – we have our packages available.
test # ls -l /usr/local/poudriere/data/packages/14-3-R-amd64-default/All/
total 6294
-rw-r--r-- 1 root wheel 126041 Jan 7 02:16 ccache-3.7.12_8.pkg
-rw-r--r-- 1 root wheel 5963 Jan 7 02:16 dosunix-1.0.14.pkg
-rw-r--r-- 1 root wheel 6544 Jan 7 02:16 lsblk-4.0.pkg
-rw-r--r-- 1 root wheel 6290261 Jan 7 02:16 pkg-2.5.1.pkg
The only errors were these below and they did not broken our build:
(...)
Updating Poudriere repository catalogue...
pkg: No SRV record found for the repo 'Poudriere'
[14-3-R-amd64-default] Fetching meta.conf: 100% 179 B 0.2 k/s 00:01
pkg: packagesite URL error for pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/data.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/data.tzst -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/packagesite.pkg -- pkg+:// implies SRV mirror type
pkg: packagesite URL error for pkg+http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest/packagesite.tzst -- pkg+:// implies SRV mirror type
Unable to update repository Poudriere
Error updating repositories!
[00:00:29] Package fetch: Not fetching as remote repository is unavailable.
(...)
To get the idea what is wrong here we need to level up our debugging skill and get our hands dirty with FreeBSD tools like ktrace(8) and kdump(8) to know what is missing.
test # ktrace -di poudriere bulk -c -C -j 14-3-R-amd64 -b latest -p default sysutils/lsblk converters/dosunix
(...)
[00:00:32] [01] [00:00:00] Builder starting
[00:00:33] [01] [00:00:01] Builder started
[00:00:33] [01] [00:00:00] Building ports-mgmt/pkg | pkg-2.5.1
When You reach this place – just hit [CTRL]+[C] to stop it – its not needed to wait for it.
Now check with kdump(8) the gathered data.
test # kdump | grep -m 5 -C 2 'pkg+' | tail -4
Poudriere: {
url: pkg+http://pkg.FreeBSD.org/${ABI}/latest,
mirror_type: srv
}
I wanted to show only the part that was important – Of course I did not guessed it like that … just find it with a help of a friend.
Poudriere – on the fly – defines additional repository … and if you did not override it – yes – it will use both pkg+ and srv things that hurt our proxy environment.
This is part of the Poudriere code that is responsible for its generation.
cat >> "${MASTERMNT:?}/etc/pkg/poudriere.conf" <<-EOF
FreeBSD: {
enabled: no,
priority: 100
}
FreeBSD-kmods: {
enabled: no,
priority: 100
}
FreeBSD-ports: {
enabled: no,
priority: 100
}
FreeBSD-ports-kmods: {
enabled: no,
priority: 100
}
FreeBSD-base: {
enabled: no,
priority: 100
}
Poudriere: {
url: ${packagesite},
mirror_type: $(if [ "${packagesite#pkg+}" = "${packagesite}" ]; then echo "none"; else echo "srv"; fi)
}
EOF
So it will generate the ‘broken for proxy’ config like that:
Poudriere: {
url: pkg+http://pkg.FreeBSD.org/${ABI}/latest,
mirror_type: srv
}
Looking at the code above you can see the if that checks how the packagesite is defined.
Lets see how Poudriere figures that one out in the code.
test # grep -m 1 packagesite= common.sh
packagesite="${PACKAGE_FETCH_URL:+${PACKAGE_FETCH_URL}/}${PACKAGE_FETCH_BRANCH}"
So the answer is that we need to set PACKAGE_FETCH_URL and PACKAGE_FETCH_BRANCH in the /usr/local/etc/poudriere.conf file … the ones I commented out to explain all that in details.
So now – with all needed settings enabled at /usr/local/etc/poudriere.conf file … fully working Poudriere build in proxy environment.
PACKAGE_FETCH_URL="http://pkg.FreeBSD.org/\${ABI}"
PACKAGE_FETCH_BRANCH="latest"
export HTTP_PROXY="http://10.0.0.41:3128"
export HTTPS_PROXY="http://10.0.0.41:3128"
export FTP_PROXY="http://10.0.0.41:3128"
Remember to have the \$ as backslashed as Poudriere is written in POSIX sh(1).
Now the fully working run.
test # poudriere bulk -c -C -j 14-3-R-amd64 -b latest -p default sysutils/lsblk converters/dosunix [00:00:00] Creating the reference jail... done [00:00:00] Mounting system devices for 14-3-R-amd64-default [00:00:00] Stashing existing package repository [00:00:00] Mounting ccache from: /var/ccache [00:00:00] Mounting ports from: /usr/local/poudriere/ports/default [00:00:00] Mounting packages from: /usr/local/poudriere/data/packages/14-3-R-amd64-default [00:00:00] Mounting distfiles from: /usr/ports/distfiles [00:00:00] Appending to make.conf: /usr/local/etc/poudriere.d/make.conf /etc/resolv.conf -> /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref/etc/resolv.conf [00:00:00] Starting jail 14-3-R-amd64-default Updating /var/run/os-release done. [00:00:00] Will build as root:wheel (0:0) [00:00:00] Ports supports: FLAVORS SUBPACKAGES SELECTED_OPTIONS [00:00:00] Inspecting /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref//usr/ports for modifications to git checkout... no [00:00:03] Ports top-level git hash: 284813ec0382a2bfe5b2e74a3081a67599d3155d [00:00:03] Acquiring build logs lock for 14-3-R-amd64-default... done [00:00:03] Logs: /usr/local/poudriere/data/logs/bulk/14-3-R-amd64-default/2026-01-07_03h52m21s [00:00:03] WWW: http://0.0.0.0//build.html?mastername=14-3-R-amd64-default&build=2026-01-07_03h52m21s [00:00:03] Loading MOVED for /usr/local/poudriere/data/.m/14-3-R-amd64-default/ref/usr/ports [00:00:04] Gathering ports metadata [00:00:04] Calculating ports order and dependencies [00:00:04] Sanity checking the repository [00:00:04] -c specified, cleaning all packages... done [00:00:04] -C specified, cleaning listed packages [00:00:04] (-C) Flushing package deletions [00:00:04] Trimming IGNORED and blacklisted ports [00:00:04] Package fetch: Looking for missing packages to fetch from http://pkg.FreeBSD.org/${ABI}/latest [00:00:04] Package fetch: bootstrapping pkg Bootstrapping pkg from http://pkg.FreeBSD.org/FreeBSD:14:amd64/latest, please wait... [14-3-R-amd64-default] Installing pkg-2.5.1... [14-3-R-amd64-default] Extracting pkg-2.5.1: 100% Updating Poudriere repository catalogue... [14-3-R-amd64-default] Fetching meta.conf: 100% 179 B 0.2 k/s 00:01 [14-3-R-amd64-default] Fetching data: 100% 11 MiB 3.7 M/s 00:03 Processing entries: 100% Poudriere repository update completed. 36661 packages processed. All repositories are up to date. [00:00:20] Package fetch: Will fetch 3 packages from remote or local pkg cache Updating database digests format: 100% The following packages will be fetched: New packages to be FETCHED: ccache: 3.7.12_8 (134 KiB: 91.17% of the 147 KiB to download) dosunix: 1.0.14 (6 KiB: 4.04% of the 147 KiB to download) lsblk: 4.0 (7 KiB: 4.79% of the 147 KiB to download) Number of packages to be fetched: 3 147 KiB to be downloaded. [14-3-R-amd64-default] Fetching ccache-3.7.12_8: 100% 134 KiB 137.3 k/s 00:01 [14-3-R-amd64-default] Fetching lsblk-4.0: 100% 7 KiB 7.2 k/s 00:01 [14-3-R-amd64-default] Fetching dosunix-1.0.14: 100% 6 KiB 6.1 k/s 00:01 [00:00:21] Package fetch: Using cached copy of ccache-3.7.12_8 [00:00:21] Package fetch: Using cached copy of dosunix-1.0.14 [00:00:21] Package fetch: Using cached copy of lsblk-4.0 [00:00:21] Checking packages for incremental rebuild needs [00:00:21] Deleting stale symlinks... done [00:00:21] Deleting empty directories... done [00:00:21] Package fetch: Generating logs for fetched packages [00:00:21] Unqueueing existing packages [00:00:21] Unqueueing orphaned build dependencies [00:00:21] Sanity checking build queue [00:00:21] [14-3-R-amd64-default] [2026-01-07_03h52m21s] [pkgqueue_sanity_check] Time: 00:00:18 Queued: 4 Inspected: 0 Ignored: 0 Built: 0 Failed: 0 Skipped: 0 Fetched: 3 Remaining: 1 [00:00:21] Recording filesystem state for prepkg... done [00:00:21] Processing PRIORITY_BOOST [00:00:21] Building 1 packages using up to 1 builders [00:00:21] Hit CTRL+t at any time to see build progress and stats [00:00:21] [01] [00:00:00] Builder starting [00:00:21] [01] [00:00:00] Builder started [00:00:21] [01] [00:00:00] Building ports-mgmt/pkg | pkg-2.5.1 [00:02:25] [01] [00:02:04] Finished ports-mgmt/pkg | pkg-2.5.1: Success [00:02:25] Stopping up to 1 builders [00:02:25] Creating pkg repository [00:02:25] Signing repository with key: /usr/local/etc/ssl/keys/poudriere.key Creating repository in /tmp/packages: 100% Packing files for repository: 100% [00:02:25] Signing pkg bootstrap with method: pubkey [00:02:25] Committing packages to repository: /usr/local/poudriere/data/packages/14-3-R-amd64-default/.real_1767758087 via .latest symlink [00:02:25] Removing old packages [00:02:25] Built ports: ports-mgmt/pkg [00:02:25] Fetched ports: sysutils/lsblk converters/dosunix devel/ccache [00:02:25] [14-3-R-amd64-default] [2026-01-07_03h52m21s] [committing] Time: 00:02:23 Queued: 4 Inspected: 0 Ignored: 0 Built: 1 Failed: 0 Skipped: 0 Fetched: 3 Remaining: 0 [00:02:25] Logs: /usr/local/poudriere/data/logs/bulk/14-3-R-amd64-default/2026-01-07_03h52m21s [00:02:25] WWW: http://0.0.0.0//build.html?mastername=14-3-R-amd64-default&build=2026-01-07_03h52m21s [00:02:25] Cleaning up [00:02:25] Stopping up to 4 builders [00:02:25] Unmounting file systems test #
… and in the TECHNICOLOR form π

The part that was broken earlier is now fine.
Updating Poudriere repository catalogue... [14-3-R-amd64-default] Fetching meta.conf: 100% 179 B 0.2 k/s 00:01 [14-3-R-amd64-default] Fetching data: 100% 11 MiB 3.7 M/s 00:03 Processing entries: 100%
I believe that concludes this article – let me know if I missed anything.
































Installation is pretty straightforward.

































