Creation
Creating a Jail requires a CTID, name, ZFS pool, root filesystem source, network choice, and Jail type. The CLI accepts either core flags or a complete JSON request file.
Choose a root filesystem source
Section titled “Choose a root filesystem source”Exactly one source is required:
- A bootstrap managed under the selected ZFS pool.
- A completed base-rootfs download, referenced by its UUID.
Do not supply both --base and --bootstrap.
Inspect FreeBSD bootstraps
Section titled “Inspect FreeBSD bootstraps”List the bootstraps supported for a pool:
doas sylve jails bootstrap list --pool zrootInside the interactive console, the pool is positional:
jails bootstrap list zrootReal output from the test node includes:
Name Version Type Status15-0-Base 15.0 base not installed15-0-Minimal 15.0 minimal not installed15-1-Base 15.1 base not installed15-1-Minimal 15.1 minimal not installedInstall a bootstrap asynchronously:
doas sylve jails bootstrap create \ --pool zroot \ --version 15.1 \ --type minimalAdd --wait to keep the command open until installation completes or fails:
jails bootstrap create zroot 15.1 minimal --waitThe version must use major.minor form, and the type must be base or minimal. Run the list command again to follow the reported status and phase.
Use a downloaded base
Section titled “Use a downloaded base”List completed downloads and find one whose uType is base-rootfs:
doas sylve downloads list --jsonPass the download’s uuid to --base. Do not use its numeric list ID.
Create from core flags
Section titled “Create from core flags”The core creation flags are:
| Flag | Required | Purpose |
|---|---|---|
--ctid <id> |
Yes | Unique Jail ID from 1 through 9999. |
--name <name> |
Yes | Jail name. It cannot be empty. |
--pool <pool> |
Yes | ZFS pool that will contain the Jail dataset. |
--base <uuid> |
One source required | UUID of a completed base-rootfs download. |
--bootstrap <name> |
One source required | Name of an installed FreeBSD bootstrap in the selected pool. |
--switch <name> |
Yes | Switch name, none, or inherit. |
--type <type> |
Yes | Jail type: freebsd or linux. |
Supply exactly one of --base and --bootstrap. These flags are also available as explicit overrides when --file is used. The separate --json flag changes command output and is not part of the creation request.
The following FreeBSD example uses a previously installed bootstrap and does not attach a network:
doas sylve jails create \ --ctid 101 \ --name web01 \ --pool zroot \ --bootstrap 15-1-Minimal \ --switch none \ --type freebsdThe console accepts the same named creation options:
jails create --ctid 101 --name web01 --pool zroot --bootstrap 15-1-Minimal --switch none --type freebsdCTIDs must be unique integers from 1 through 9999. The type must be freebsd or linux. For --switch, supply a switch name, none, or inherit.
Configure DHCP and SLAAC on the selected switch
Section titled “Configure DHCP and SLAAC on the selected switch”The core --switch flag selects the switch, but the core flags do not expose address configuration. Use a JSON request to enable DHCP, SLAAC, static addresses, a MAC address, or VLAN tagging on the initial attachment.
This example creates a FreeBSD Jail attached to TTT, obtains IPv4 configuration through DHCP, and obtains IPv6 configuration through SLAAC:
{ "name": "auto-net", "ctId": 103, "hostname": "auto-net.example.test", "pool": "zroot", "bootstrapName": "15-1-Minimal", "switchName": "TTT", "dhcp": true, "slaac": true, "type": "freebsd", "allowedOptions": ["allow.mount.devfs"]}Save it as auto-net.json, then create the Jail:
doas sylve jails create --file ./auto-net.jsonSylve automatically generates a MAC object when neither mac nor macRaw is supplied. DHCP and SLAAC leave the corresponding static address and gateway fields unset.
allow.mount.devfs is required for DHCP because FreeBSD’s DHCP client needs access to a BPF device inside the Jail. Sylve applies its managed devfs ruleset, which exposes BPF while retaining the standard Jail device restrictions. Without this option, the Jail can start but dhclient cannot obtain a lease.
For a static IPv4 configuration, replace the automatic fields with raw address values:
{ "name": "static-net", "ctId": 104, "hostname": "static-net.example.test", "pool": "zroot", "bootstrapName": "15-1-Minimal", "switchName": "TTT", "dhcp": false, "ipv4Raw": "10.20.0.10/24", "ipv4GwRaw": "10.20.0.1", "type": "freebsd"}You can use ipv4 and ipv4Gw object IDs instead of raw values. IPv6 follows the same pattern with ipv6, ipv6Gw, ipv6Raw, and ipv6GwRaw. Add vlan or macRaw to the same request when the attachment requires them.
Use a downloaded root filesystem by replacing the bootstrap option:
doas sylve jails create \ --ctid 102 \ --name service01 \ --pool zroot \ --base 42f7f8df-dcbc-5ff1-ad93-c45209d733f4 \ --switch WAN \ --type freebsdThe UUID shown above is real output from the test node and is only an example. Always obtain the current UUID from your own node.
Create from a JSON request
Section titled “Create from a JSON request”Core flags intentionally expose only the common fields. Use a strict JSON request when you need hostname, address objects, resource limits, startup behavior, allowed options, hooks, or metadata.
{ "name": "web01", "ctId": 101, "hostname": "web01.example.test", "description": "Documentation example", "pool": "zroot", "base": "", "bootstrapName": "15-1-Minimal", "switchName": "none", "type": "freebsd", "allowedOptions": [], "hooks": { "prestart": { "enabled": false, "script": "" }, "start": { "enabled": false, "script": "" }, "poststart": { "enabled": false, "script": "" }, "prestop": { "enabled": false, "script": "" }, "stop": { "enabled": false, "script": "" }, "poststop": { "enabled": false, "script": "" } }}Create the Jail from that file:
doas sylve jails create --file ./web01.jsonExplicit core flags override matching fields loaded from the file. Unknown JSON fields are rejected, which helps catch misspelled configuration keys.
Complete JSON field reference
Section titled “Complete JSON field reference”The JSON document supports the complete CreateJailRequest implemented by Sylve. Fields marked as core are required after file values and command-line overrides are combined.
Identity and storage
Section titled “Identity and storage”| JSON field | Value | Purpose |
|---|---|---|
name |
String | Core. Non-empty Jail name. |
ctId |
Integer | Core. Unique CTID from 1 through 9999. |
hostname |
String | Hostname configured for the Jail. |
description |
String | Optional descriptive text. |
pool |
String | Core. ZFS pool used for Jail storage. |
base |
String | UUID of a completed base-rootfs download. Mutually exclusive with bootstrapName. |
bootstrapName |
String | Installed bootstrap name. Mutually exclusive with base. |
fstab |
String | Jail filesystem mount configuration. |
resolvConf |
String | Contents used for the Jail’s resolver configuration. |
Exactly one of base and bootstrapName must be non-empty.
Network configuration
Section titled “Network configuration”| JSON field | Value | Purpose |
|---|---|---|
switchName |
String | Core. Switch name, none, or inherit. |
inheritIPv4 |
Boolean | Inherit the host’s IPv4 networking. |
inheritIPv6 |
Boolean | Inherit the host’s IPv6 networking. |
dhcp |
Boolean | Request IPv4 configuration through DHCP. |
slaac |
Boolean | Request IPv6 configuration through SLAAC. |
ipv4 |
Integer | IPv4 host-object ID. |
ipv4Gw |
Integer | IPv4 gateway host-object ID. |
ipv4Raw |
String | Manual IPv4 address value. |
ipv4GwRaw |
String | Manual IPv4 gateway value. |
ipv6 |
Integer | IPv6 host-object ID. |
ipv6Gw |
Integer | IPv6 gateway host-object ID. |
ipv6Raw |
String | Manual IPv6 address value. |
ipv6GwRaw |
String | Manual IPv6 gateway value. |
mac |
Integer | MAC-object ID. |
macRaw |
String | Manual MAC address. |
vlan |
Integer | VLAN identifier for the initial attachment. |
Object ID fields and their corresponding raw fields provide two ways to express the same kind of value. Prefer reusable objects when an address will be shared across configurations or managed centrally.
Resources and startup
Section titled “Resources and startup”| JSON field | Value | Purpose |
|---|---|---|
resourceLimits |
Boolean | Enable Jail CPU and memory limits. |
cores |
Integer | Number of CPU cores assigned when limits are enabled. |
memory |
Integer | Memory allocation used by the Jail service. |
startAtBoot |
Boolean | Start the Jail during Sylve startup. |
startOrder |
Integer | Relative startup ordering value. |
devfsRuleset |
String | Additional FreeBSD devfs rule content appended to the managed Jail ruleset. |
Jail behavior
Section titled “Jail behavior”| JSON field | Value | Purpose |
|---|---|---|
type |
String | Core. freebsd or linux. |
allowedOptions |
String array | Jail options explicitly allowed by the configuration. |
cleanEnvironment |
Boolean | Start with a clean Jail environment. |
additionalOptions |
String | Additional Jail configuration options. |
Hooks and metadata
Section titled “Hooks and metadata”| JSON field | Value | Purpose |
|---|---|---|
hooks.prestart |
Hook phase | Runs before the Jail starts. |
hooks.start |
Hook phase | Runs during the start phase. |
hooks.poststart |
Hook phase | Runs after the Jail starts. |
hooks.prestop |
Hook phase | Runs before the Jail stops. |
hooks.stop |
Hook phase | Runs during the stop phase. |
hooks.poststop |
Hook phase | Runs after the Jail stops. |
metadataMeta |
String | Additional metadata stored with the Jail. |
metadataEnv |
String | Environment metadata stored with the Jail. |
Each hook phase is an object containing an enabled boolean and a script string:
{ "enabled": true, "script": "/usr/local/libexec/sylve/hooks/web01-prestart.sh"}Boolean and numeric fields represented as pointers in the Go request can be omitted when no explicit value is needed. This differs from sending false or 0, which explicitly selects that value.
Use --json when a script needs the created CTID and name as structured output.