Migrating UniFi controller from one FreeNAS Jail to another

Part of my FreeNAS migration that I decided to ignore for a while was the need to move the controller for my UniFi AP from its old warden-based jail to a new iocage jail. Like many things on my old FreeNAS, the existing implementation was first-time, my first Jail, and first install of the UniFi controller (and, on an FreeBSD, an OS unsupported by Unibiquti).  In other words, I had little recollection of how did it before, which was probably a slightly fragile combination of numerous suggestions from across the internet.....!

Start by creating the basic jail:

In the FreeNAS UI, configure a new jail using VNET, a free IP address and setting the default gateway. Leave everything else as default, as shown below:

jail configuration

Start the jail:

Starting the FreeNAS jail

and access the shell:

Accessing the jail's shell

First, update the packages lists. Then, as there there are some config files to edit, I prefer to install Nano than using Vi. (ignore the 2nd line If you prefer Vi):

pkg update && pkg upgrade -y
pkg install -y nano

Now - the whole lot can be done from the shell inside FreeNAS, but it can be easier using an external shell from something like iTerm or PuTTY. To do this, we'll need to enable ssh access (which we'll disable again at the end):

passwd <set a root password>
echo "sshd_enable=\"YES\" " >/etc/rc.conf

Also for ssh access - using 'nano', edit /etc/sshd_config to allow root login via password (again, we'll disable this later)

PermitRootLogin yes
PasswordAuthentication yes

And (final step for ssh access) then start ssh:

$ service sshd start

Now, from a convenient ssh client (iTerm etc), ssh in to the jail's IP address as root

Whether in the FreeNAS jail shell, or via ssh, do the following to set up the jail:

At the current time (December 2018), the UniFi controller depends very specifically on Perl 5.26.3, whereas the FreeBSD jail for 11.2-RELEASE installs Perl 5.26.2.  The easiest way around seems to be to get ports to de-install the existing 5.26.2 and then replace with 5.26.3. (there is probably a better way, but after an hour or so I needed to move along).

$ portsnap fetch extract
$ pkg install bash llvm40 openjdk8

$ cd /usr/ports/lang/perl5.26 
$ make deinstall
$ make install

$ pkg install -y mongodb36 snappyjava

Now build/install the UniFi controller:

$ cd /usr/ports/net-mgmt/unifi5
$ make install clean BATCH=yes
$ service unifi start

From a browser, the controller should be accessible:

UniFi Controller login

Now to tidy up the ssh access we opened up earlier..

  • remove PermitRootLogin & PasswordAuthentication from /etc/sshd_config
  • remove sshd_enable from /etc/rc.config
  • stop ssh (which logs you out, also)

So... All this was straight-forward and I've now got a newly built, clean, UniFi Controller jail -- but, no configuration!

The next thing I needed to do was get the config from my old (FreeNAS 9.x) UniFi Controller jail.  But my NAS is now upgraded and I never thought to take a backup of my UniFi config. I have the dataset/filesystems from the old jail nicely mounted on FreeNAS 11 - the zPool imported but not being actively used.

Googling suggested just copying the data directory (/usr/local/share/java/unifi/data) from old to new, but after many attempts at this I finally found that mongo (which is started by the UniFi java app) was barffing and complaining about out-of-date mongo versions.  I could, try to install an old mongodb and upgrade the database, then import to new mongoldb and..... NO! That way would just be deeper down the rabbit hole!!  But how else could I get the config from the old jail...  could I create a new jail with the same-old FreeBSD?  

Then I remembered -- In FreeNAS 11.2, the old UI is still available and can still start the old warden jails. Off I went back to the old UI, updated the relevant jail config (I've re-used the IP address) and started it up... Good 'old' UniFi controller.... I managed to export the config (it's a secret-password-rar apparently) and then hopped back to the new UniFi and imported it -- if there's only default data in the 'data' directory, browsing to the app on port 8443 gets a setup screen with an option to upload config.

The UniFi controller reported it was updating and restarting... but after a few minutes of nothing happening I opened the shell and found it wasn't running any more, so started it up (service unifi start)....30 seconds later I could log in, old config was there. = Success!!

An additional learning along the way was to find that the Unifi controller logs to the logs directory (likely /usr/local/share/java/unifi/logs) with mongodb.log and server.log in there.

All upgraded!