Automatically convert a FreeBSD system to use pkgbase.
This project is sponsored by the FreeBSD Foundation.
Both the pkgbasify tool and pkgbase itself are experimental. Running pkgbasify may result in irreversible data loss and/or a system that fails to boot. It is highly recommended to make backups before running this tool.
That said, I am not aware of any bugs in pkgbasify and have done my best to make it as robust as possible. I currently believe pkgbasify to be as reliable as manual conversion if not better.
If you find a bug in pkgbasify please open an issue!
Ensure you have at least 5 GiB of free disk space. Conversion can likely succeed with less, but pkg is not yet able to detect and handle insufficient space gracefully. It can be difficult to recover if the system runs out of space during conversion.
Download the script, give it permission to execute, run it as root:
fetch https://github.com/FreeBSDFoundation/pkgbasify/raw/refs/heads/main/pkgbasify.luachmod +x ./pkgbasify.lua./pkgbasify.lua
If conversion succeeds:
- Verify that expected users and groups are present in
/etc/master.passwdand/etc/group, and that/etc/ssh/sshd_configis as expected. These should be handled automatically by pkg(8), but since the consequences are high it is recommended to double check. - Restart the system.
If there is an error during installation of the pkgbase packages, the system may be left in a partially-converted state.
In this case, the user should fix whatever issue caused the error and run ./pkgbasify.lua --force to try and complete the conversion.
See also Common Problems and Solutions.
pkgbasify performs the following steps:
- Select a repository based on the output of freebsd-version(1) and create
/usr/local/etc/pkg/repos/FreeBSD-base.conf. - Select package sets that correspond to the currently installed base system components.
- For example: if the lib32 component is not already installed,
pkgbasify will not install
FreeBSD-set-lib32. - pkgbasify never installs
FreeBSD-set-srcpackage even if/usr/srcis present and non-empty. This prevents unwanted overwriting of potentially modified source files and/or a VCS repository.
- For example: if the lib32 component is not already installed,
pkgbasify will not install
- Prompt the user to create a "pre-pkgbasify" boot environment using bectl(8) if possible.
- Download selected packages
- Register selected packages in the pkg database without installing any files (
pkg install --register-only). - Install selected packages, overwriting normal files and merging config files (
pkg install --force).- As per normal pkg(8) behavior,
.pkgnewfiles are created for config files for which merge fails.
- As per normal pkg(8) behavior,
- If sshd(8) is running, restart the service.
- Run pwd_mkdb(8) and cap_mkdb(1).
- Remove
/boot/kernel/linker.hints.
[1/66] Installing FreeBSD-runtime-15.snap20250604185611...
[1/66] Extracting FreeBSD-runtime-15.snap20250604185611: 33%
pkg: Fail to create hardlink: /.pkgtemp..profile.6vmf7kjyXtm8 <-> /root/.pkgtemp..profile.h5D7P2AMln3A:Cross-device link
[1/66] Extracting FreeBSD-runtime-15.snap20250604185611: 100%
Error: exit
This may be caused by a mountpoint over the top of a file or directory that pkg is trying to update.
pkg expects that the TMPDIR and the destination are on the same filesystem.
Unmount whatever is on top, and run ./pkgbasify.lua --force to finish conversion.
In this case, /root had been put on its own zfs dataset.
[1/66] Installing FreeBSD-runtime-15.snap20250604185611...
[1/66] Extracting FreeBSD-runtime-15.snap20250604185611: 100%
pkg: Fail to set time on /var/empty:Read-only file system
Error: exit
This may be caused by having a zfs filesystem zroot/var/empty with the property readonly=on.
Set readonly=off and run ./pkgbasify.lua --force to finish conversion.