Resource icon

Create an unofficial iocage plugin

This resource will walk you through the process of setting up an iocage plugin. The intent is to familiarize people with the basic layout of an iocage plugin, so that they start building plugins and contribute to them community. :)

Note that there’s way more to plugins that is mentioned in this document. For more information, please refer to the official documentation:

  • You have a GitHub account
  • You have access to a FreeNAS / TrueNAS CORE system
  • You can do basic navigation and file management using the command line
  • Please don’t do any of this as root, but set up a user in wheel with sudo permission
  • Use a proper SSH cllient
The below was produced and tested on a laptop using Firefox and running FreeNAS-11.2-MASTER-201809080900 in VirtualBox. [EDIT: Updated for TrueNAS CORE 12.0]

In this exercise, we will create a simple plugin to play Tetris.
We will create an iocage jail, install some packages and then configure and start the relevant service.

Step #1 Create artifact repository
We start by creating the artifact repository called iocage-plugin-tetris. The artifact repository is used to hold scripts, files and other resources that come into play after the jail is created and packages are installed.
Go to, logon if needed, chose New Repository, enter the following information and click Create

You could edit/add the various files directly in your browser, but I prefer to clone this repository to my local system and then push my changes back.
Get the URL of the repo you just created by clicking the Clone or download button and pick the Clone with HTTPS option.

Now Go to the FreeNAScommand line and clone the repo:
jurgen@freenas:~ % git clone
Cloning into 'iocage-plugin-tetris'...
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 7 (delta 0), reused 4 (delta 0), pack-reused 0
Unpacking objects: 100% (7/7), done.

jurgen@freenas:~ % ls

jurgen@freenas:~ % cd iocage-plugin-tetris/
jurgen@freenas:~/iocage-plugin-tetris % ls       ui.json

In this directory, create a new file with the following content:

# Create user 'tetris'
pw add user -n tetris -c Tetris -s /bin/csh -m

# Configure shellinabox
fetch -o /home/tetris/white-on-black.css
sysrc shellinaboxd_enable=YES
sysrc shellinaboxd_flags="--css /home/tetris/white-on-black.css -t -s /:tetris:tetris:HOME:bastet"

# Start the service
service shellinaboxd start

Make sure to make it executable by running chmod +x

The shellinaboxd service will run program bastet on http://<IP of jail>:4200/. To link this URL to the Management link in the UI, we create a file ui.json with the following content:
    "adminportal": "http://%%IP%%:4200/",
    "docurl": ""

That’s it! Before pushing the changes back to GitHub, set your user name and email address in git. (This is a one-time activity if you pass the --global option)
git config --global "<Your github user name>"
git config --global "<Your GitHub email address>"

Now commit your changes and push them back to GitHub. Enter your Github credentials when it prompts for them.
git add .
git commit -m "Initial commit"
git push origin master

The end result should look similar to this:

Step #2 Create manifest file
The manifest is a JSON file that contains all the information iocage needs to create the jail and the list of packages to be installed.
Create a new file tetris.json in any directory (don't put in iocage-plugin-tetris) with the following content:
  "name": "tetris",
  "release": "12.3-RELEASE",
  "artifact": "",
  "properties": {
      "nat_forwards": "tcp(4200:4200)"
  "pkgs": [
  "packagesite": "${ABI}/quarterly",
  "fingerprints": {
          "plugin-default": [
                  "function": "sha256",
                  "fingerprint": "b0170035af3acc5f3f3ae1859dc717101b4e6c1d0a794ad554928ca0cbb2f438"
    "official": false

The end result should look like this:

The content is almost self-explanatory:
  • name (required) This will be the name of the jail, note that iocage will automatically convert the name to lowercase. Avoid periods/dots and underscore characters in the name.
  • release (required) You shouldn't pick a release that is newer than the one of the FreeNAS host. Get a list by running iocage list --remote or iocage list -R
  • artifact [required] Link to GitHub artifact repository, as created above
  • properties [optional] Set various iocage attribute as specified, otherwise it will just use the default iocage attibutes /iocage/defaults.json. Note that any properties specified at the CLI will override the properties in the json file.
  • pkgs (required, but may be empty) List of packages that will be installed.
  • packagesite Package repository that will be used to install packages above, examples:${ABI}/latest (Vanilla FreeBSD pkg repo, latest)${ABI}/quarterly (Vanilla FreeBSD pkg repo, quarterly)
  • fingerprints (required) fingerprint and method for signing the pkg repo above.
    For the vanilla FreeBSD repo, use b0170035af3acc5f3f3ae1859dc717101b4e6c1d0a794ad554928ca0cbb2f438
  • Official Boolean to distinguish “official” versus “community” plugins
Step #3 Install the plugin locally
Finally, install the plugin. All you need is that JSON manifest file and some network information. Currently you need to install/create from the command line, but a feature request exists that will let you install a local plugin from the UI.

jurgen@freenas:~ % sudo iocage fetch -P tetris.json -n tetris-plugin-name
Plugin: tetris
  Official Plugin: False
  Using Branch: 13.0-RELEASE
  Post-install Artifact:
  These pkgs will be installed:
    - games/bastet
    - security/ca_root_nss
    - www/shellinabox

Testing Host DNS response to
Testing tetris-plugin-name's SRV response to
Testing tetris-plugin-name's DNSSEC response to

Installing plugin packages:
  - games/bastet... 
  - security/ca_root_nss... 
  - www/shellinabox... 

Fetching artifact... 
Cloning git repository

Branch 13.0-RELEASE does not exist at!
Using "master" branch for plugin, this may not work with your RELEASE

/home/tetris/white-on-black.css                        889  B 4273 kBps    00s
         889  B 4273 kBps    00s
shellinaboxd_enable:  -> YES
         889  B 4273 kBps    00s
shellinaboxd_flags:  -> --css /home/tetris/white-on-black.css -t -s /:tetris:tetris:HOME:bastet
         889  B 4273 kBps    00s
Starting shellinaboxd.
         889  B 4273 kBps    00s

Admin Portal:

Doc URL:

Your plugin will now show up under "Installed Plugins" and also "Jails", woohoo!

Submit to iXSystems
To have the plugin included in the official INDEX file, fork and submit a pull request with:
  • the new plugin.json file.
  • the plugin icon .png added to the icons/ directory.
  • an update to the INDEX file with an entry for the new plugin.
  • a link to the artifact repository populated with all required plugin files.
Jurgen Segaert
First release
Last update
4.50 star(s) 2 ratings

Latest reviews

Thanks for the guide! I went from not having a clue what to do; to creating a plugin within an hour.
A few tiny changes to language in some places would make this great for newbies.

Recommend adding a section at the top, regarding Git, which says "if you're new to Git, make an account and follow the 'hello-world' tutorial"

Thanks for hard work