Instalación y configuración de poudriere FreeBSD 14.2 ZFS
Referencias bibliográficas:
https://freebsdfoundation.org/wp-content/uploads/2023/11/reushling_poudrier.pdf
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-poudriere-build-system-to-create-packages-for-your-freebsd-servers
Intel core i5-8350U 1.7 GHz
Procesador 4 cores
Procesador 8 hilos
RAM 16 GB
SWAP 16 GB
NVMe Pcie 4.0
ZPOOL=zroot
ZROOTFS=/poudriere
BASEFS=/usr/local/poudriere
FreeBSD 14.2-RELEASE (amd64) instalado
El dataset raíz de poudriere estará en zroot/poudriere y se montará en /usr/local/poudriere
Paquetes mínimos
pkg install -y poudriere \
git-lite
vim
screen
curl
ca_root_nss
Crear datasets ZFS.
Ventajas: posibilidad de hacer snapshots, rollback y compression por separado
zfs create -o mountpoint=/usr/local/poudriere -o compression=lz4 zroot/poudriere
zfs create zroot/poudriere/jails
zfs create zroot/poudriere/ports
zfs create zroot/poudriere/data
zfs create zroot/poudriere/data/packages
zfs create zroot/poudriere/data/logs
Archivo /usr/local/etc/poudriere.conf
ZPOOL=zroot
ZROOTFS=/poudriere
FREEBSD_HOST=ftp://ftp.freebsd.org
RESOLV_CONF=/etc/resolv.conf
BASEFS=/usr/local/poudriere
POUDRIERE_DATA=${BASEFS}/data
USE_TMPFS=all # usa RAM + swap para las builds
DISTFILES_CACHE=/usr/ports/distfiles
CHECK_CHANGED_OPTIONS=verbose
CHECK_CHANGED_DEPS=yes
CCACHE_DIR=/var/cache/ccache
ALLOW_MAKE_JOBS_PACKAGES="pkg ccache py* rust llvm*"
PARALLEL_JOBS=8 # 8 hilos logicos
Descargar y crear la jail base (14.2-RELEASE)
poudriere jail -c -j 142amd64 -v 14.2-RELEASE -a amd64
Esto descarga sets.txz y crea un dataset zroot/poudriere/jails/142amd64
Git -
poudriere ports -c -p default -m git -U https://git.FreeBSD.org/ports.git
poudriere ports -l
PORTSTREE METHOD TIMESTAMP PATH
default git+https 2025-08-24 18:50:19 /usr/local/poudriere/ports/default
local null 2025-08-24 16:41:27 /usr/local/poudriere/ports/default
poudriere jails -l
JAILNAME VERSION ARCH METHOD TIMESTAMP PATH
142amd64 14.2-RELEASE-p5 amd64 http 2025-08-24 18:42:25 /usr/local/poudriere/jails/142amd64
Ajustes globales
Archivo /usr/local/etc/poudriere.d/make.conf
# general
DEFAULT_VERSIONS+=ssh=openssl
OPTIONS_UNSET+=DOCS NLS EXAMPLES X11 IPV6
WITH_PKGNG=yes
DISABLE_LICENSES=yes
Crear listas de paquetes
Archivo /usr/local/etc/poudriere.d/port-list.txt
security/sudo
Primer bulk build
poudriere bulk -j 142amd64 -p default -f /usr/local/etc/poudriere.d/port-list.txt
Servidor de paquetes local (nginx)
pkg install nginx
sysrc nginx_enable=YES
Archivo de configuración de nginx
$ sed -e '/^[ ]*#/d' -e '/^$/d' /usr/local/etc/nginx/nginx.conf
server {
listen 80 default;
server_name localhost;
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;
}
}
Configurar pkg en la máquina anfitriona
mkdir /usr/local/etc/pkg/repos
Archivo /usr/local/etc/pkg/repos/poudriere.conf
poudriere {
url: "http://127.0.0.1/packages/142amd64-default/",
enabled = yes,
mirror_type: "http",
signature_type: "pubkey",
pubkey: "/usr/local/etc/poudriere/poudriere.pub",
}
Generar clave (una sola vez)
Crear el directorio donde se guardarán las claves
mkdir -p /usr/local/etc/poudriere
Generar la clave privada (4096 bits)
openssl genrsa -out /usr/local/etc/poudriere/poudriere.key 4096
chmod 600 /usr/local/etc/poudriere/poudriere.key
Extraer la clave pública
openssl rsa -in /usr/local/etc/poudriere/poudriere.key -pubout -out \
/usr/local/etc/poudriere/poudriere.pub
chmod 644 /usr/local/etc/poudriere/poudriere.pub
Asegúrarse de que poudiere la use al firmar.
Añadir esta línea al archivo /usr/local/etc/poudriere.conf
PKG_REPO_SIGNING_KEY=/usr/local/etc/poudriere/poudriere.key
El archivo /usr/local/etc/poudriere.conf queda así:
ZPOOL=zroot
ZROOTFS=/poudriere
FREEBSD_HOST=ftp://ftp.freebsd.org
RESOLV_CONF=/etc/resolv.conf
BASEFS=/usr/local/poudriere
POUDRIERE_DATA=${BASEFS}/data
USE_TMPFS=all # usa RAM + swap para las builds
DISTFILES_CACHE=/usr/ports/distfiles
CHECK_CHANGED_OPTIONS=verbose
CHECK_CHANGED_DEPS=yes
ALLOW_MAKE_JOBS_PACKAGES="pkg ccache py* rust llvm*"
PARALLEL_JOBS=8 # 8 hilos logicos
PKG_REPO_SIGNING_KEY=/usr/local/etc/poudriere/poudriere.key
Firmar el repositorio con la clave nueva
poudriere bulk -j 142amd64 -p default -f /usr/local/etc/poudriere.d/port-list.txt
Monitorear durante la compilación
poudriere status
SET PORTS JAIL BUILD STATUS QUEUE BUILT FAIL SKIP IGNORE FETCH REMAIN TIME LOGS
- default 142amd64 2025-08-26_08h57m21s parallel_build 3 0 0 0 0 0 3 00:00:22 \
/usr/local/poudriere/data/logs/bulk/142amd64-default/2025-08-26_08h57m21s
poudriere jail -l
JAILNAME VERSION ARCH METHOD TIMESTAMP PATH
142amd64 14.2-RELEASE-p5 amd64 http 2025-08-25 23:10:54 /usr/local/poudriere/jails/142amd64
poudriere ports -l
PORTSTREE METHOD TIMESTAMP PATH
default git+https 2025-08-26 08:55:04 /usr/local/poudriere/ports/default
local null 2025-08-24 16:41:27 /usr/local/poudriere/ports/default
root@solaris:/usr/local/etc/pkg/repos# poudriere
FreeBSD.conf packagesite.yaml
poudriere.conf
Logs en tiempo real
poudriere log -f -j 142amd64 -p default
Configurar pkg en los clientes, (o en la misma máquina), para que use la clave pública
mkdir -p /usr/local/etc/pkg/repos/
$ cat /usr/local/etc/pkg/repos/poudriere.conf
poudriere {
url: "http://127.0.0.1/packages/142amd64-default/",
enabled = yes,
mirror_type: "http",
signature_type: "pubkey",
pubkey: "/usr/local/etc/poudriere/poudriere.pub",
}
Tras esto, pkg install validará las firmas sin errores.
Comandos útiles de rescate. Limpiar paquetes obsoletos
poudriere pkgclean -j 142amd64 -p default -f port-list.txt
Destruir jail y volver a crear (por ejemplo, tras nueva RELEASE)
poudriere jail -d -j 142amd64
poudriere jail -c -j 142amd64 -v 14.3-RELEASE -a amd64
Actualizar paquetes
pkg update -f
Updating FreeBSD repository catalogue...
Fetching meta.conf: 100% 179 B 0.2kB/s 00:01
Fetching data.pkg: 100% 10 MiB 10.4MB/s 00:01
Processing entries: 100%
FreeBSD repository update completed. 35669 packages processed.
Updating poudriere repository catalogue...
Fetching meta.conf: 100% 179 B 0.2kB/s 00:01
Fetching data.pkg: 100% 2 KiB 2.0kB/s 00:01
Processing entries: 100%
poudriere repository update completed. 3 packages processed.
All repositories are up to date.
pkg upgrade
curl -I http://127.0.0.1/
HTTP/1.1 200 OK
Server: nginx/1.28.0
Date: Tue, 26 Aug 2025 12:07:38 GMT
Content-Type: text/html
Content-Length: 13036
Last-Modified: Sat, 09 Aug 2025 09:58:45 GMT
Connection: keep-alive
ETag: "68971bd5-32ec"
Accept-Ranges: bytes
Actualizar el árbol existente (lo mantiene, solo descarga nuevos commits)
poudriere ports -u -p default
Listo para compilar y servir paquetes locales con poudriere en FreeBSD 14.2
Opciones
Poudriere no guarda automáticamente las elecciones que se hacen al ejecutar
poudriere options, pero le indicamos con la bandera -z myset que lo guarde.
Ejecutar una vez poudriere options para el port que quiera
Las opciones seleccionadas se guardan en /usr/local/etc/poudriere.d/myset-options
poudriere options -z myset -c security/sudo
el flag -c fuerza que aparezca el menú incluso si ya existen opciones guardadas.
Un directorio "myset-options" es generado automaticamente por make config
/usr/local/etc/poudriere.d/myset-options/
y dentro del directorio los directorios categoria_paquete
ls /usr/local/etc/poudriere.d/myset-options
converters_libiconv/ devel_autoconf/ devel_m4/ lang_tcl86/
databases_sqlite3/ devel_kyua/ lang_lua54/ security_sudo/
devel_atf/ devel_lutok/ lang_perl5.42/
y dentro de esos directorio un archivo llamado options contiene las opciones de configuración.
cat /usr/local/etc/poudriere.d/myset-options/security_sudo/options
# This file is auto-generated by 'make config'.
# Options for sudo-1.9.17p2
_OPTIONS_READ=sudo-1.9.17p2
_FILE_COMPLETE_OPTIONS_LIST=AUDIT DISABLE_AUTH DISABLE_ROOT_SUDO DOCS EXAMPLES \
INSULTS LDAP NLS NOARGS_SHELL OPIE PAM PYTHON SSL GSSAPI_BASE GSSAPI_HEIMDAL \
GSSAPI_MIT
OPTIONS_FILE_SET+=AUDIT
OPTIONS_FILE_UNSET+=DISABLE_AUTH
OPTIONS_FILE_UNSET+=DISABLE_ROOT_SUDO
OPTIONS_FILE_UNSET+=DOCS
OPTIONS_FILE_UNSET+=EXAMPLES
OPTIONS_FILE_SET+=INSULTS
OPTIONS_FILE_UNSET+=LDAP
OPTIONS_FILE_UNSET+=NLS
OPTIONS_FILE_UNSET+=NOARGS_SHELL
OPTIONS_FILE_UNSET+=OPIE
OPTIONS_FILE_SET+=PAM
OPTIONS_FILE_UNSET+=PYTHON
OPTIONS_FILE_SET+=SSL
OPTIONS_FILE_UNSET+=GSSAPI_BASE
OPTIONS_FILE_UNSET+=GSSAPI_HEIMDAL
OPTIONS_FILE_UNSET+=GSSAPI_MIT
...
Compilar paquetes
poudriere bulk -j 142amd64 -p default -z myset -f /usr/local/etc/poudriere.d/port-list.txt
Para que pkg use los paquetes que acaba de compilar poudriere necesitas:
- Que poudriere haya terminado de firmar y publicar los paquetes.
- Un repositorio local servido por nginx (u otro)
- Un fichero /usr/local/etc/pkg/repos/poudriere.conf correctamente escrito
fichero /usr/local/etc/pkg/repos/poudriere.conf
poudriere {
url: "http://127.0.0.1/packages/142amd64-default/",
# url = "file:///usr/local/poudriere/data/packages/142amd64-default",
enabled = yes,
mirror_type: "http",
signature_type: "pubkey",
pubkey: "/usr/local/etc/poudriere/poudriere.pub",
}
root@solaris:/usr/local/poudriere/data/packages/142amd64-default/All# pkg repo .
Creating repository in .: 100%
Packing files for repository: 100%
root@solaris:/usr/local/poudriere/data/packages/142amd64-default/All# ls
data.pkg meta.conf pkg-2.2.2.pkg
data.tzst packagesite.pkg pkgconf-2.4.3,1.pkg
meta packagesite.tzst sudo-1.9.17p2.pkg
Desactivar el repositorio oficial (opcional)
#
# To disable this repository, instead of modifying or removing this file,
# create a /usr/local/etc/pkg/repos/FreeBSD.conf file:
#
# mkdir -p /usr/local/etc/pkg/repos
# echo "FreeBSD: { enabled: no }" > /usr/local/etc/pkg/repos/FreeBSD.conf
#
FreeBSD: {
url: "pkg+https://pkg.FreeBSD.org/${ABI}/quarterly",
# url: "pkg+https://pkg.FreeBSD.org/${ABI}/latest",
mirror_type: "srv",
signature_type: "fingerprints",
fingerprints: "/usr/share/keys/pkg",
enabled: no
}
Otra opción. La prioridad define el orden en que se utilizan estos repositorios
Por defecto, se utiliza el repositorio upstream de FreeBSD.org. Pero como queremos que nuestros propios paquetes tengan precedencia, le daremos una prioridad más alta que cero para que use nuestro repositorio de paquetes primero.
Quedaría así:
#
# To disable this repository, instead of modifying or removing this file,
# create a /usr/local/etc/pkg/repos/FreeBSD.conf file:
#
# mkdir -p /usr/local/etc/pkg/repos
# echo "FreeBSD: { enabled: no }" > /usr/local/etc/pkg/repos/FreeBSD.conf
#
FreeBSD: {
url: "pkg+https://pkg.FreeBSD.org/${ABI}/quarterly",
# url: "pkg+https://pkg.FreeBSD.org/${ABI}/latest",
mirror_type: "srv",
signature_type: "fingerprints",
fingerprints: "/usr/share/keys/pkg",
enabled: yes
}
Archivo /usr/local/etc/pkg/repos/poudriere.conf
poudriere {
url: "http://127.0.0.1/packages/142amd64-default/",
# url = "file:///usr/local/poudriere/data/packages/142amd64-default",
enabled = yes,
priority: 23,
mirror_type: "http",
signature_type: "pubkey",
pubkey: "/usr/local/etc/poudriere/poudriere.pub",
}
Veamos en acción
pkg update
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
Updating poudriere repository catalogue...
Fetching meta.conf: 100% 179 B 0.2kB/s 00:01
Fetching data.pkg: 100% 2 KiB 2.0kB/s 00:01
Processing entries: 100%
poudriere repository update completed. 3 packages processed.
All repositories are up to date.
root@solaris:/usr/local/etc/pkg/repos# pkg upgrade
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
Updating poudriere repository catalogue...
poudriere repository is up to date.
All repositories are up to date.
Checking for upgrades (206 candidates): 100%
Processing candidates (206 candidates): 100%
The following 4 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:
p5-Crypt-URandom: 0.54 [FreeBSD]
Installed packages to be UPGRADED:
nss: 3.115 -> 3.115.1 [FreeBSD]
p5-Authen-SASL: 2.18 -> 2.1900 [FreeBSD]
perl5: 5.40.2_2 -> 5.40.3_2 [FreeBSD]
Number of packages to be installed: 1
Number of packages to be upgraded: 3
18 MiB to be downloaded.
Proceed with this action? [y/N]: y
[1/4] Fetching nss-3.115.1.pkg: 100% 2 MiB 2.3MB/s 00:01
[2/4] Fetching p5-Crypt-URandom-0.54.pkg: 100% 17 KiB 17.6kB/s 00:01
[3/4] Fetching perl5-5.40.3_2.pkg: 100% 16 MiB 16.4MB/s 00:01
[4/4] Fetching p5-Authen-SASL-2.1900.pkg: 100% 44 KiB 44.7kB/s 00:01
Checking integrity... done (0 conflicting)
[1/6] Deinstalling p5-Authen-SASL-2.18...
[1/6] Deleting files for p5-Authen-SASL-2.18: 100%
[2/6] Deinstalling perl5-5.40.2_2...
[2/6] Deleting files for perl5-5.40.2_2: 100%
[3/6] Upgrading nss from 3.115 to 3.115.1...
[3/6] Extracting nss-3.115.1: 100%
[4/6] Installing perl5-5.40.3_2...
[4/6] Extracting perl5-5.40.3_2: 100%
[5/6] Installing p5-Crypt-URandom-0.54...
[5/6] Extracting p5-Crypt-URandom-0.54: 100%
[6/6] Installing p5-Authen-SASL-2.1900...
[6/6] Extracting p5-Authen-SASL-2.1900: 100%
tree /usr/local/poudriere/data/packages/
/usr/local/poudriere/data/packages/
└── 142amd64-default
├── All -> .latest/All
├── Latest -> .latest/Latest
├── data
├── data.pkg -> .latest/data.pkg
├── data.tzst -> .latest/data.tzst
├── logs -> .latest/logs
├── meta -> .latest/meta
├── meta.conf -> .latest/meta.conf
├── packagesite.pkg -> .latest/packagesite.pkg
├── packagesite.tzst -> .latest/packagesite.tzst
└── packagesite.yaml
5 directories, 8 files
Instalar paquete desde repositorio local
pkg install sudo
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
Updating poudriere repository catalogue...
poudriere repository is up to date.
All repositories are up to date.
Checking integrity... done (0 conflicting)
The following 1 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:
sudo: 1.9.17p2 [poudriere]
Number of packages to be installed: 1
The process will require 2 MiB more space.
Proceed with this action? [y/N]: y
[1/1] Installing sudo-1.9.17p2...
[1/1] Extracting sudo-1.9.17p2: 100%
Comprobar security con INSULTS activado:
sudo vim /etc/rc.conf
Password:
Quizás si usaras más de dos dedos...
Password:
¡Este hombre no sabe cuándo está vencido! Tampoco sabe cuándo está ganando.
No tiene... una especie de... aparato sensorial...
Password:
FreeBSD es genial!.