Migrate Unifi Controller to Docker

Thu, Nov 26, 2015

Updated on June 7th, 2016 Having a bit more experience with Docker and running Unifi as a container I thought it was time to update this page a bit.

I have been a fan of the Ubiquiti Unifi APs and have been running one at home now since mid-2011. The Unifi APs do have a controller service that should be run on a computer on the network that is used for AP configuration, captive portal, event logging, and metrics collection. Ubiquiti provides packages for Windows, OSX, as well as Ubuntu/Debian to set this up. I’ve been running the controller on my home server, which runs Ubuntu, for the past several years. I never bothered to put this in a Virtual Machine of it’s own because I didn’t want the overhead of dedicating resources to a Virtual Machine. Back in 2011 Docker wasn’t an option. What follows is how I migrated my existing controller to run in a Docker container.

There are several ways to treat networking and volumes (persistent data) with Docker. What follows is just one option.

First thing to do is get Docker installed on your server. You can check the requirements to run Docker but any fairly recent Linux distribution should do.

You have a choice on how to install Docker.

  1. You can simply install it using your distro’s package manager.
  2. Follow the instructions from https://docs.docker.com/installation/ for your distro.

Docker development is moving at a rapid pace so the version found in a distro’s repo will likely be older than the one available directly from the Docker project.

Next you need to log into your existing Unifi Controller with an admin account and backup your settings. To do this login and goto Settings => Maintenance => Download Backup Settings . Selected how much historical data you wish to export, I chose “All Time”.

Since I’m creating my container on the same host that is currently running my Unifi Controller I had to stop the existing unifi service before moving on to the next step.

Docker has a Hub which has Docker images that have been built and shared by the community. Jacob Alberty has create a nice unifi docker image . To create a container using this image run the following command, which will download the latest tag from Jacob’s image on the Docker Hub and create a container using it.

docker run --name=unifi-data --entrypoint=/bin/true -d jacobalberty/unifi:latest
docker run --name=unifi --net=host --volumes-from unifi-data -d jacobalberty/unifi:latest

Let’s take a closer look at what we’re doing here.
docker run is the command to create a new container so here we are creating 2 containers. The first one named unifi-data is just a container to hold a reference on the data volumes. There are other ways to manage the persistent data but this is the approach I’ve settled on for now. This approach is commonly referred to as a storage or data volume container.

--name=unifi names this container “unifi”
--net=host sets the network mode for this container to host. This skips placing the containers networking inside the container and binds any services to the native networking stack of the host. This allows the software to run as if it were running natively on the host from a networking point of view. This may not be desirable in all situations.
--volumes-from unifi-data This maps the volumes from our data volume container to the new container. -d detach. This runs the container in the background. jacobalberty/unifi:latest this is the image to use to create the container.

Now to restore our configuration that we backed up earlier we need to connect to our new Unifi Controller. Since we used the --net=host option we simply point a browser to

:8433/>. When you connect it will start the setup wizard which has an option to restore configuration from a backup. Select this and then upload the file that was saved previously.

At the end of this it will say restarting however due to the way containers work this container will exit. To re-start it run the following command.

docker start unifi

You should now be able to login to your new Unifi Controller container using the same credentials as you previously used.

Once you’re happy with your new Unifi Controller container we should clean up the old installation.

In my case I had to do the following.

The next step is to setup this container to automatically start on boot. There’s a few ways to do this.

I still prefer integration into the native init system for this use case. Especially since we’re using --net=host . See https://docs.docker.com/articles/host_integration/ for more information on this.

Upstart
Here’s an example to start the unifi container using upstart.
Create /etc/init/unifi.conf with the following contents

description "Unifi Controller"
author "<Your Name>"
start on filesystem and started docker
stop on runlevel [!2345]
respawn
script
  /usr/bin/docker start -a unifi
end script

Stop the existing container and restart it under upstart by running the following.

sudo docker stop unifi
sudo service unifi start

You should now have successfully migrated your Unifi Controller over to running inside a container.

Systemd
This is the approach I currently use. Create /lib/systemd/system/unifi.service with the following contents

[Unit]
Description=Unifi container
Requires=docker.service
After=docker.service

[Service]
Restart=always
ExecStart=/usr/bin/docker start -a unifi
ExecStop=/usr/bin/docker stop -t 2 unifi

[Install]
WantedBy=local.target

Stop the existing container and restart it under upstart by running the following.

sudo docker stop unifi
sudo systemctl enable unifi
sudo systemctl start unifi

You should now have successfully migrated your Unifi Controller over to running inside a container.

Docker
You can also have docker auto start the container. To do this we need to remove and recreate the unifi container with an additional option.

docker stop unifi
docker rm unifi
docker run --restart=always --name=unifi --net=host --volumes-from unifi-data -d jacobalberty/unifi:latest
comments powered by Disqus