migrating from proxmox to freebsd (part 11): jail
so a lot of tinkering and getting past quite a few learning curves i have successfully created a jail that i’m using as a “shell box” which is running freebsd 14.2-p3 RELEASE (latest RELEASE thus far although 14.3 is due out soon). as i said earlier i settled on using bastille which is really just a means to make jail management a little easier. i’m going to skip the whole how to set it up thing. the only thing that i can tell you is to edit the /usr/local/etc/bastille/bastille.conf file first!
# /usr/local/etc/bastille/bastille.conf
#####################
## [ BastilleBSD ] ##
#####################
## default paths
bastille_prefix="/usr/local/bastille" ## default: "/usr/local/bastille"
bastille_backupsdir="${bastille_prefix}/backups" ## default: "${bastille_prefix}/backups"
bastille_cachedir="${bastille_prefix}/cache" ## default: "${bastille_prefix}/cache"
bastille_jailsdir="${bastille_prefix}/jails" ## default: "${bastille_prefix}/jails"
bastille_releasesdir="${bastille_prefix}/releases" ## default: "${bastille_prefix}/releases"
bastille_templatesdir="${bastille_prefix}/templates" ## default: "${bastille_prefix}/templates"
bastille_logsdir="/var/log/bastille" ## default: "/var/log/bastille"
## pf configuration path
bastille_pf_conf="/etc/pf.conf" ## default: "/etc/pf.conf"
## bastille scripts directory (assumed by bastille pkg)
bastille_sharedir="/usr/local/share/bastille" ## default: "/usr/local/share/bastille"
## bootstrap archives, which components of the OS to install.
## base - The base OS, kernel + userland
## lib32 - Libraries for compatibility with 32 bit binaries
## ports - The FreeBSD ports (3rd party applications) tree
## src - The source code to the kernel + userland
## test - The FreeBSD test suite
## this is a whitespace separated list:
## bastille_bootstrap_archives="base lib32 ports src test"
bastille_bootstrap_archives="base" ## default: "base"
## default timezone
bastille_tzdata="" ## default: empty to use host's time zone
## default jail resolv.conf
bastille_resolv_conf="/etc/resolv.conf" ## default: "/etc/resolv.conf"
## bootstrap urls
bastille_url_freebsd="http://ftp.freebsd.org/pub/FreeBSD/releases/" ## default: "http://ftp.freebsd.org/pub/FreeBSD/releases/"
bastille_url_hardenedbsd="https://installers.hardenedbsd.org/pub/" ## default: "https://installer.hardenedbsd.org/pub/HardenedBSD/releases/"
bastille_url_midnightbsd="https://www.midnightbsd.org/ftp/MidnightBSD/releases/" ## default: "https://www.midnightbsd.org/pub/MidnightBSD/releases/"
## ZFS options
bastille_zfs_enable="YES" ## default: "NO"
bastille_zfs_zpool="platters" ## default: ""
bastille_zfs_prefix="bastille" ## default: "bastille"
bastille_zfs_options="-o compress=lz4 -o atime=off" ## default: "-o compress=lz4 -o atime=off"
## Export/Import options
bastille_compress_xz_options="-0 -v" ## default "-0 -v"
bastille_decompress_xz_options="-c -d -v" ## default "-c -d -v"
bastille_compress_gz_options="-1 -v" ## default "-1 -v"
bastille_decompress_gz_options="-k -d -c -v" ## default "-k -d -c -v"
bastille_export_options="--gz" ## default "" predefined export options, e.g. "--safe --gz"
## Networking
bastille_network_loopback="bastille0" ## default: "bastille0"
bastille_network_pf_ext_if="ext_if" ## default: "ext_if"
bastille_network_pf_table="jails" ## default: "jails"
bastille_network_shared="" ## default: ""
bastille_network_gateway="192.168.1.1" ## default: ""
bastille_network_gateway6="" ## default: ""
## Default Templates
bastille_template_base="default/base" ## default: "default/base"
bastille_template_empty="" ## default: "default/empty"
bastille_template_thick="default/thick" ## default: "default/thick"
bastille_template_clone="default/clone" ## default: "default/clone"
bastille_template_thin="default/thin" ## default: "default/thin"
bastille_template_vnet="default/vnet" ## default: "default/vnet"
bastille_template_vlan="default/vlan" ## default: "default/vlan"
i kept the defaults for most of it. but a few things you might want to look at is which zpool you want to use, and where you want to put it. the setup will set most of the things up for you and edit loader.conf or rc.conf if necessary. i’d say make sure you also set up a bridge0 first too. take a look at the gateway in the .conf as well. that messed me up for a minute. it will show yellow (maybe) but then pick up the gateway/router. at least take a look at the file first after you install bastille. then check out their documentation which can be found here so you can go off the horse’s mouth.
there are different templates you can use but i’m just going to work on making a plex server from scratch using a native jail. i tried tinkering with linux jails just to have the option but the debootstrap failed on usr-is-merged. not sure what’s going on there but i’m sure it has something to do with debian.
# bastille bootstrap 14.2-RELEASE update
this will grab freebsd and stage it for creating jails. the update should take it up to the latest minor release. you can update it by hand as well by running the same command. this will get your base image up to date prior to creating the jails.
now that this is in place making a jail is pretty easy.
# bastille create -BM hopeplex 14.2-RELEASE 192.168.1.51/24 bridge0
Valid: (192.168.1.51/24).
Valid: (bridge0).
Creating a thinjail...
boot: -> on
priority: -> 99
[hopeplex]:
epair1a
e1a_hopeplex
e1b_hopeplex
hopeplex: created
[hopeplex]:
Applying template: default/vnet...
No value provided for arg: GATEWAY6
[hopeplex]:
ifconfig_e1b_hopeplex_name: -> vnet0
[hopeplex]:
ifconfig_vnet0: -> inet 192.168.1.51/24
[hopeplex]:
defaultrouter: NO -> 192.168.1.1
[hopeplex]:
Template applied: default/vnet
[hopeplex]:
Applying template: default/thin...
[hopeplex]:
Applying template: default/base...
[hopeplex]:
[hopeplex]:
[hopeplex]:
daily_status_world_kernel: -> NO
[hopeplex]:
syslogd_flags: -s -> -ss
[hopeplex]:
sendmail_enable: NONE -> NO
[hopeplex]:
sendmail_submit_enable: YES -> NO
[hopeplex]:
sendmail_outbound_enable: YES -> NO
[hopeplex]:
sendmail_msp_queue_enable: YES -> NO
[hopeplex]:
cron_flags: -> -J 60
[hopeplex]:
/etc/resolv.conf -> /usr/local/bastille/jails/hopeplex/root/etc/resolv.conf
Template applied: default/base
Template applied: default/thin
[hopeplex]:
hopeplex: removed
[hopeplex]:
epair1a
e1a_hopeplex
e1b_hopeplex
hopeplex: created
i did this before as well. i tend to want to use thick jails because they are a bit more independent of the host image. so let me destroy it and remake it. no harm no foul.
# bastille stop hopeplex
[hopeplex]:
hopeplex: removed
# bastille destroy hopeplex
Deleting Jail: hopeplex.
Note: jail console logs archived.
/var/log/bastille/hopeplex_console.log-2025-05-25
# bastille create -T -BM hopeplex 14.2-RELEASE 192.168.1.51/24 bridge0
Valid: (192.168.1.51/24).
Valid: (bridge0).
Creating a thickjail. This may take a while...
boot: -> on
priority: -> 99
[hopeplex]:
epair1a
e1a_hopeplex
e1b_hopeplex
hopeplex: created
[hopeplex]:
Applying template: default/vnet...
No value provided for arg: GATEWAY6
[hopeplex]:
ifconfig_e1b_hopeplex_name: -> vnet0
[hopeplex]:
ifconfig_vnet0: -> inet 192.168.1.51/24
[hopeplex]:
defaultrouter: NO -> 192.168.1.1
[hopeplex]:
Template applied: default/vnet
[hopeplex]:
Applying template: default/thick...
[hopeplex]:
Applying template: default/base...
[hopeplex]:
[hopeplex]:
[hopeplex]:
daily_status_world_kernel: -> NO
[hopeplex]:
syslogd_flags: -s -> -ss
[hopeplex]:
sendmail_enable: NONE -> NO
[hopeplex]:
sendmail_submit_enable: YES -> NO
[hopeplex]:
sendmail_outbound_enable: YES -> NO
[hopeplex]:
sendmail_msp_queue_enable: YES -> NO
[hopeplex]:
cron_flags: -> -J 60
[hopeplex]:
/etc/resolv.conf -> /usr/local/bastille/jails/hopeplex/root/etc/resolv.conf
Template applied: default/base
Template applied: default/thick
[hopeplex]:
hopeplex: removed
[hopeplex]:
epair1a
e1a_hopeplex
e1b_hopeplex
hopeplex: created
done. it created it. added an interface to bridge0. and started it up.
# ping 192.168.1.51
PING 192.168.1.51 (192.168.1.51): 56 data bytes
64 bytes from 192.168.1.51: icmp_seq=0 ttl=64 time=0.069 ms
# bastille list
JID IP Address Hostname Path
18 hopeplex /usr/local/bastille/jails/hopeplex/root
# bastille console hopeplex
[hopeplex]:
root@hopeplex:~ #
# freebsd-version
14.2-RELEASE-p3
at this point you can just pretend it is a typical freebsd machine and work on doing what you want with it. so i’ll consider jails a success. there were other things i did like getting rclone to mount smb into the jails which was a dealbreaker for me. in the future i’m going to see about migrating apache2 servers off of proxmox to freebsd jails. i also have to take a look at something to manage bhyve in case i need to run virtual machines. i tend to go with containers or jails whenever possible. for now i’ll consider jails a successful replacement for lxc/containers from proxmox. i don’t get the cool clicky pointy interface that proxmox has but imo freebsd is a lot more “leave it alone” stable.
a side note. i did try tinkering with cbsd and clonos for a little while. cbsd was interesting but a little more complicated than bastille. it also had a lot of xen and virtualbox nonsense i didn’t need. clonos is severely underdeveloped. i douubt there is anything with parity to proxmox for freebsd for now.