How To Build Your Unifi Software In A Docker Container Now Even Smaller
By no means is this the end-all, be-all of what Docker can do and the below are just baseline examples and a good place to start.
Here, we will include two scenarios:
Scenario A. Create a Dockerfile, build a container and run an IMAGE. By default, this container will only retain data at the time of creation or after a commit.
Scenario B. Create a Dockerfile, build a container and run two images. Writing persistent data from your IMAGE into your host (physical) computer.
** Bonus: we will also include a script to commit and push this “image” to your hub.docker.com account automatically via cron if you choose to do so.
Let’s Get Started
Scenario A:
Our Goal: To build a Debian based CONTAINER and run a Ubiquiti Unifi IMAGE in it for managing wireless access points.
1. Optional but recommended: create an account at hub.docker.com
2. In your host computer, install Docker for Linux/Mac or install Boot2Docker for Windows.
3. Create a directory to house your Dockerfiles.
Example:
sudo mkdir /Dockerfiles/unifi/image
4. Create your Dockerfile and add your OS of choice and other variables.
Example:
cd /Dockerfiles/unifi/image
vi Dockerfile
Then add the following into Dockerfile:
FROM debian:squeeze
MAINTAINER GoodwinTek <[email protected]>
RUN echo deb https://www.ubnt.com/downloads/unifi/distros/deb/debian debian ubiquiti >> /etc/apt/sources.list
RUN echo deb https://downloads-distro.mongodb.org/repo/debian-sysvinit dist 10gen >> /etc/apt/sources.list
RUN apt-key adv --recv-keys --keyserver keyserver.ubuntu.com C0A52C50
RUN apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 7F0CEB10
RUN apt-get -y update && apt-get -y install unifi sudo
RUN useradd -m unifi
RUN touch /etc/sudoers.d/unifi && chmod 440 /etc/sudoers.d/unifi
RUN echo "unifi ALL = NOPASSWD:/usr/lib/unifi/bin/unifi.init" > /etc/sudoers.d/unifi
RUN echo "sudo /usr/lib/unifi/bin/unifi.init start" >> /home/unifi/.bashrc
USER unifi
CMD /bin/bash
Write and quit (save) the Dockerfile.
5. Build the Docker CONTAINER (make sure you are in the directory where your Dockerfile resides).
Example:
sudo docker build -t author/unifi .
This builds the Dockerfile in the current working directory. Author/unifi can be something like: Goodwintek/unifi for example. Goodwintek being our author name when we setup our hub.docker.com account and unifi being our repository name.
6. Run the Docker IMAGE with switches ” -d ” to run in the background, ” -it ” for interactive and ” -p ” for port forwarding from host to the image. We know Unifi needs ports 8081, 8080, 8443, 8880, 8843, 27117 and 3478 to function, so we will forward those:
sudo docker run -dit -p 8081:8081 -p 8080:8080 -p 8443:8443 -p 8880:8880 -p 8843:8843 -p 27117:27117 -p 3478:3478 author/unifi
You will see a IMAGE# will get printed to the screen.
Note: You can make a convenience script for this if you want.
You can also find a condensed set of these instructions and our repository at: https://registry.hub.docker.com/u/goodwintek/unifi/
7. Optional: You can connect to your running IMAGE# by using the Docker attach command. This is so you can poke around in that file-system and make any changes that you need. (but remember they won’t save without a commit or you have to keep the container running)
Example:
sudo docker attach IMAGE#
*To find your IMAGE#, you can use:
sudo docker ps
Note: When you are attached, you might have to press the enter key to see a command prompt.
*To detach from the IMAGE and leave it running:
hold CTRL-q then CTRL-p then CTRL-q
*You can also type exit to detach and kill the IMAGE.
*To stop an IMAGE:
sudo docker stop IMAGE#
Scenario B:
Our Goal: Use docker to run the Unifi software, writing persistent data from our IMAGE into our host (physical) computer.
1. Optional but recommended: create an account at hub.docker.com
2. In your host computer, install Docker for Linux/Mac or install Boot2Docker for Windows.
3. We are going to make a host mounted data only container, essentially one or more directories from an IMAGE will be copied into our host in real-time.
4. Create a directory to house your Dockerfile to build the unifi-installer CONTAINER.
Example:
sudo mkdir /Dockerfiles/Unifi/unifi-installer
5. Create your Dockerfile and add Debian and other variables.
Example:
cd /Dockerfiles/Unifi/unifi-installer
vi Dockerfile
Then add the following into the Dockerfile:
FROM debian:squeeze
MAINTAINER GoodwinTek <[email protected]>
#Add Sources.List and Keys For Unifi and MongoDB#
RUN echo deb https://www.ubnt.com/downloads/unifi/distros/deb/debian debian ubiquiti >> /etc/apt/sources.list
RUN echo deb https://downloads-distro.mongodb.org/repo/debian-sysvinit dist 10gen >> /etc/apt/sources.list
RUN apt-key adv --recv-keys --keyserver keyserver.ubuntu.com C0A52C50
RUN apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 7F0CEB10
#Update Package Lists and Install Sudo#
RUN apt-get -y update && apt-get -y install sudo
#Create Unifi User and Give Limited Sudo Priveledges#
RUN useradd -m unifi
RUN touch /etc/sudoers.d/unifi && chmod 440 /etc/sudoers.d/unifi
RUN echo "unifi ALL = NOPASSWD:/usr/bin/apt-get -y install unifi" > /etc/sudoers.d/unifi
#Autostart Unifi Installation Upon Containter Start#
RUN echo "sudo /usr/bin/apt-get -y install unifi" > /home/unifi/.bashrc
USER unifi
CMD /bin/bash
6. Build the Docker image (make sure you are in the directory where your Dockerfile resides).
Example:
sudo docker build -t author/unifi-installer .
This builds the Dockerfile in the current working directory. Author/unifi can be something like: Goodwintek/unifi for example. Goodwintek being our author name when we setup our hub.docker.com account and Unifi being our repository name.
7. Run the unifi-installer IMAGE
Example:
docker run -dit -v /dockerhdd:/var/lib/unifi -p 8081:8081 -p 8080:8080 -p 8443:8443 -p 8880:8880 -p 8843:8843 -p 27117:27117 -p 3478:3478 author/unifi-installer
8. You can now attatch to the IMAGE# and watch the Unifi install process if you choose:
Example:
sudo docker ps (to get the IMAGE#)
sudo docker attach IMAGE#
9. After Unifi is done installing and you can access it by http, detach from the IMAGE# with:
hold CTRL-q then CTRL-p then CTRL-q
10. Stop and remove the running unifi-installer IMAGE (but leaving the data on the host intact):
sudo docker ps (to get IMAGE#)
sudo docker stop IMAGE#
sudo docker images (get IMAGE ID)
sudo docker rmi IMAGE ID
11. Create a Dockerfile, build and run it like in Scenario A:
You can also find a condensed set of these instructions and our repository at: https://registry.hub.docker.com/u/goodwintek/unifi-installer/
**Bonus: To commit (save) and push (upload) to your Docker account follow these steps and use this script.
Caution: This script is not meant to be applied to production machines without testing to make sure the outcome is desired.
Caution: This script is meant for only 1 running IMAGE# at any given time.
Caution: DO NOT run this script if no IMAGES are running as it deletes the non-running CONTAINERS and IMAGES.
Note: You will need to login manually first using sudo docker login to create the .dockercfg file in your users home directory for future use.
Important: add line using visudo as ROOT (this is to make no password needed for the Docker user):
Dockeruser ALL=(ALL) NOPASSWD: /usr/bin/docker
Create commitandpush.sh in your Docker user’s home directory, name it and make it executable.
sudo touch /home/Dockeruser/commitandpush.sh
sudo chmod 700 commitandpush.sh
sudo vi /home/Dockeruser/commitandpush.sh
Add to this into commitandpush.sh:
#!/usr/bin/env bash
##Variable creation for the last running IMAGE#, assigns it the $CID tag##
CID=$(sudo docker ps -l -q)
echo $CID
##Commits $CID (last running IMAGE#) locally##
docker commit $CID author/repo
##Searches for IMAGES not running, deletes them and silences errors##
sudo docker ps -a | awk '{print $1}' | grep -v CONTAINER | xargs sudo docker rm 2>/dev/null
##Searches for Containers not currently running and deletes those, silencing errors##
sudo docker images | grep "<none>" | awk '{print $3}' | xargs sudo docker rmi 2>/dev/null
##Login to Hub.docker.com(After you have logged in by hand!)##
echo && echo && echo | docker login
##Pushes a repository of your choosing to Hub.docker.com##
sudo docker push author/repo
Write and quit or save your changes and exit.
Note: you can also split these commands up and make numerous scripts each with a different purpose.
To automate this task, you can now use:
sudo crontab -e