{"id":75,"date":"2020-08-07T00:37:37","date_gmt":"2020-08-06T16:37:37","guid":{"rendered":"https:\/\/www.soholab.tw\/?p=75"},"modified":"2020-08-07T00:37:37","modified_gmt":"2020-08-06T16:37:37","slug":"installing-unifi-controller-on-ubuntu-with-docker","status":"publish","type":"post","link":"https:\/\/soholab.tw\/?p=75","title":{"rendered":"Installing UniFi Controller on Ubuntu with Docker"},"content":{"rendered":"\n<p>\u539f\u6587\u7db2\u5740\uff1a<a href=\"https:\/\/www.reddit.com\/r\/Ubiquiti\/comments\/7po0jr\/installing_unifi_controller_on_ubuntu_with_docker\/\">https:\/\/www.reddit.com\/r\/Ubiquiti\/comments\/7po0jr\/installing_unifi_controller_on_ubuntu_with_docker\/<\/a><\/p>\n\n\n\n<p>Step 1. Figure out the UID &amp; GID you want to run the controller as.<\/p>\n\n\n\n<p>None of the cool kids run as root. Why? Does anyone like the idea of a software bug that could end up with a total system compromise since the software was needlessly running with full system privileges? Yeah, me neither.<\/p>\n\n\n\n<p>Maybe you want to run the container as your own uid\/gid, or maybe you want to create one just for this job. Whatever, that&#8217;s up to you. Let&#8217;s suppose you want to create one. Let&#8217;s call the user &amp; group&nbsp;<code>docks<\/code>. Let&#8217;s create that user:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo adduser docks<\/code><\/pre>\n\n\n\n<p>After you add them, figure out what the UID and GID for that user are. If it&#8217;s the first user you&#8217;ve created since you installed Ubuntu on the host, that&#8217;s likely&nbsp;<code>1001<\/code>&nbsp;for each. Check&nbsp;<code>\/etc\/passwd<\/code>&nbsp;and&nbsp;<code>\/etc\/group<\/code>&nbsp;for further info.Step 2. Install Docker.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ curl -fsSL get.docker.com -o get-docker.sh\n$ sh get-docker.sh<\/code><\/pre>\n\n\n\n<p>At the end of the installation, it will mention that if you&#8217;d like to be able to execute Docker commands as non-root, to add the appropriate users to the&nbsp;<code>docker<\/code>&nbsp;group. You can do this with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo usermod -aG docker someuser<\/code><\/pre>\n\n\n\n<p>Step 3. Setup the space where you&#8217;re going to maintain the container&#8217;s persistent storage.<\/p>\n\n\n\n<p>Containers are, given their ephemeral nature, essentially throw-aways. Obviously, you don&#8217;t want to heave your database &amp; config into the bit bucket. So, you create a directory on the host filesystem that you&#8217;ll map into the container. In this case, you&#8217;ll want the directory to be owned by the&nbsp;<code>docks<\/code>&nbsp;user (or whatever uid\/gid you decided on).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ sudo mkdir -p \/var\/docks\/unifi\n$ sudo chown docks:docks \/var\/docks\/unifi<\/code><\/pre>\n\n\n\n<p>Step 4. Pull and create your container.<\/p>\n\n\n\n<p>In this example, I&#8217;m using Jacob Alberty&#8217;s&nbsp;<a href=\"https:\/\/hub.docker.com\/r\/jacobalberty\/unifi\/\" rel=\"noreferrer noopener\" target=\"_blank\">excellent container<\/a>. He does a great job of tagging releases by version number, stable, sc (stable candidate), and oldstable. Chances are you want to be on the current stable release. Pull the container now. It will download and unpack. This takes a minute or 2.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker pull jacobalberty\/unifi:stable<\/code><\/pre>\n\n\n\n<p>Now create the container. Here&#8217;s where it all comes together. You need the UID, GID, and the directory you setup in Step 3.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run -d \\\n    --restart=unless-stopped \\\n    --net=host \\\n    --name=unifi \\\n    -e TZ='Asia\/Taipei' \\\n    -e RUNAS_UID0=false \\\n    -e UNIFI_UID=1001 \\\n    -e UNIFI_GID=1001 \\\n    -v \/var\/docks\/unifi:\/unifi \\\n    jacobalberty\/unifi:stable<\/code><\/pre>\n\n\n\n<p>You just created and launched a container that&#8217;s named&nbsp;<code>unifi<\/code>, will automatically restart if it crashes (unless you explicitly stopped it), lives in the GMT-5 timezone, doesn&#8217;t run as root (uid\/gid are both 1001), and has&nbsp;<code>\/var\/docks\/unifi<\/code>&nbsp;from the Ubuntu host mapped to&nbsp;<code>\/unifi<\/code>&nbsp;inside the container. What about the&nbsp;<code>--net=host<\/code>&nbsp;business? Well, that&#8217;s done to allow for L2 discovery. If you don&#8217;t care\/need L2 discovery, just map ports. Read&nbsp;<a href=\"https:\/\/hub.docker.com\/r\/jacobalberty\/unifi\/\" rel=\"noreferrer noopener\" target=\"_blank\">Jacob&#8217;s page<\/a>&nbsp;to find out what ports can be exposed. By going with&nbsp;<code>--net=host<\/code>, you&#8217;ve really got a shortcut of sorts.<\/p>\n\n\n\n<p>Your controller is up. Go forth and configure in the usual manner.How do I upgrade this thing?<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ docker pull jacobalberty\/unifi:stable\n$ docker stop unifi\n$ docker rename unifi unifi.save\n$ &lt;the same command you used to create the container in Step 4>\n<\/code><\/pre>\n\n\n\n<p>Happy with your upgrade?&nbsp;<code>docker rm unifi.save<\/code><\/p>\n\n\n\n<p>You&#8217;ll at some point want to clean up your leftover images.\u00a0<code>docker images<\/code>\u00a0will reveal which ones you have. You only really need to keep the unifi image that&#8217;s tagged &#8220;stable&#8221;, and can nuke the other container id&#8217;s for jacobalberty\/unifi.<\/p>\n\n\n\n<p>REMARK: docker ps \u67e5\u770b\u555f\u52d5\u9032\u5ea6\uff0c\u5b8c\u5168\u555f\u52d5\u5f8c8443\u624d\u6703\u901a<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u539f\u6587\u7db2\u5740\uff1ahttps:\/\/www.reddit.com\/r\/Ubiquiti\/comments\/7po0jr\/ [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-75","post","type-post","status-publish","format-standard","hentry","category-network"],"_links":{"self":[{"href":"https:\/\/soholab.tw\/index.php?rest_route=\/wp\/v2\/posts\/75","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/soholab.tw\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/soholab.tw\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/soholab.tw\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/soholab.tw\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=75"}],"version-history":[{"count":0,"href":"https:\/\/soholab.tw\/index.php?rest_route=\/wp\/v2\/posts\/75\/revisions"}],"wp:attachment":[{"href":"https:\/\/soholab.tw\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=75"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/soholab.tw\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=75"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/soholab.tw\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=75"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}