Hi,
What I do is to combine three tools: poudriere, darkhttpd and AppJail.
* poudriere: To manage my custom repository.
* darkhttpd: To distribute packages over my network. Not necessary when you don't need to distribute your packages to others.
* AppJail: To manage my jails, specifically for this context, to create a jail only with the package I have built.
	
	
	
		Code:
	
	
		# poudriere ports -l
PORTSTREE METHOD  TIMESTAMP           PATH
default   git+ssh 2023-11-02 13:59:53 /usr/local/poudriere/ports/default
# poudriere jail -l
JAILNAME VERSION         ARCH  METHOD TIMESTAMP           PATH
132amd64 13.2-RELEASE-p4 amd64 http   2023-10-13 06:28:21 /usr/local/poudriere/jails/132amd64
	 
 
As you can see, I have installed and configured poudriere and it already contains packages in that repository. What I need to do is install darkhttpd and mount a volume.
 appjail makejail -j darkhttpd -f gh+AppJail-makejails/darkhttpd -o virtualnet=":<random> default" -o nat -o fstab="/usr/local/poudriere/data/packages/132amd64-default /usr/local/www/darkhttpd" -o expose=80
After running this command, I can see my packages from another computer:
	
	
	
		Code:
	
	
		$ fetch -qo - http://192.168.1.105
fetch -qo - http://192.168.1.105
<html>
<head>
<title>/</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>/</h1>
<tt><pre>
<a href="../">..</a>/
<a href=".buildname">.buildname</a>              21
<a href=".jailversion">.jailversion</a>            16
<a href=".latest/">.latest</a>/
<a href=".pkg-cache/">.pkg-cache</a>/
<a href=".real_1698965306/">.real_1698965306</a>/
<a href="All/">All</a>/
<a href="Latest/">Latest</a>/
<a href="meta.conf">meta.conf</a>              163
<a href="meta.pkg">meta.pkg</a>               236
<a href="meta.txz">meta.txz</a>               236
<a href="packagesite.pkg">packagesite.pkg</a>      44008
<a href="packagesite.txz">packagesite.txz</a>      44008
</pre></tt>
<hr>
Generated by darkhttpd/1.14 on Thu, 02 Nov 2023 22:57:46 GMT
</body>
</html>
	 
 
After the above command succeeds, I can create a jail, commonly with the name of the port I want to test, but with configuration files for 
pkg(8) to use my custom repository and the latest branch. For this example, I will test 
sysutils/initool.
 appjail quick initool virtualnet=":<random> default" nat copydir=files file=/usr/local/etc/pkg/repos/FreeBSD.conf file=/usr/local/etc/pkg/repos/Custom.conf overwrite=force start
I have created a custom directory from where AppJail will copy the files:
	
	
	
		Code:
	
	
		# tree -pug files/
[drwxr-xr-x root     wheel   ]  files/
└── [drwxr-xr-x root     wheel   ]  usr
    └── [drwxr-xr-x root     wheel   ]  local
        └── [drwxr-xr-x root     wheel   ]  etc
            └── [drwxr-xr-x root     wheel   ]  pkg
                └── [drwxr-xr-x root     wheel   ]  repos
                    ├── [-rw-r--r-- root     wheel   ]  Custom.conf
                    └── [-rw-r--r-- root     wheel   ]  FreeBSD.conf
 
6 directories, 2 files
# cat files/usr/local/etc/pkg/repos/Custom.conf
custom {
        url: http://192.168.1.105
        priority: 1
}
# cat files/usr/local/etc/pkg/repos/FreeBSD.conf
FreeBSD: {
  url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest",
  mirror_type: "srv",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}
	 
 
The last step is simply to install the port and test it.
	
	
	
		Code:
	
	
		# appjail pkg jail initool install -y initool
Updating FreeBSD repository catalogue...
[initool.appjail] Fetching meta.conf: 100%    163 B   0.2kB/s    00:01
[initool.appjail] Fetching packagesite.pkg: 100%    7 MiB 629.4kB/s    00:11
Processing entries: 100%
FreeBSD repository update completed. 34178 packages processed.
Updating custom repository catalogue...
[initool.appjail] Fetching meta.conf: 100%    163 B   0.2kB/s    00:01
[initool.appjail] Fetching packagesite.pkg: 100%   43 KiB  44.0kB/s    00:01
Processing entries: 100%
custom repository update completed. 148 packages processed.
All repositories are up to date.
The following 3 package(s) will be affected (of 0 checked):
 
New packages to be INSTALLED:
        gmp: 6.3.0 [custom]
        indexinfo: 0.3.1 [custom]
        initool: 0.14.0 [custom]
 
Number of packages to be installed: 3
 
The process will require 3 MiB more space.
553 KiB to be downloaded.
[initool.appjail] [1/3] Fetching indexinfo-0.3.1.pkg: 100%    6 KiB   5.7kB/s    00:01
[initool.appjail] [2/3] Fetching initool-0.14.0.pkg: 100%   70 KiB  72.1kB/s    00:01
[initool.appjail] [3/3] Fetching gmp-6.3.0.pkg: 100%  477 KiB 488.4kB/s    00:01
Checking integrity... done (0 conflicting)
[initool.appjail] [1/3] Installing indexinfo-0.3.1...
[initool.appjail] [1/3] Extracting indexinfo-0.3.1: 100%
[initool.appjail] [2/3] Installing gmp-6.3.0...
[initool.appjail] [2/3] Extracting gmp-6.3.0: 100%
[initool.appjail] [3/3] Installing initool-0.14.0...
[initool.appjail] [3/3] Extracting initool-0.14.0: 100%
# appjail cmd jexec initool initool v
0.14.0
	 
 
Some time ago I wrote a howto in the AppJail wiki, maybe it will help you:
* 
Using a custom repository in a jail with poudriere.
There is a lot of information about poudriere and custom repositories, start with their wiki:
* 
Creating pkg(8) repositories.
---
You can use a GUI application (although it requires some additional configuration), but for simplicity I used a command line tool. I prefer to use jails instead of combining the ports and the official repository because it can mess up my host and I don't want such a thing.