<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=GrumpyMeow</id>
	<title>Alpine Linux - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=GrumpyMeow"/>
	<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/wiki/Special:Contributions/GrumpyMeow"/>
	<updated>2026-05-01T17:51:19Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Setting_up_dovecot_with_imap_and_tls&amp;diff=26313</id>
		<title>Setting up dovecot with imap and tls</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Setting_up_dovecot_with_imap_and_tls&amp;diff=26313"/>
		<updated>2024-01-21T09:39:42Z</updated>

		<summary type="html">&lt;p&gt;GrumpyMeow: provided alternative&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== General ==&lt;br /&gt;
Dovecot should be configured to let users fetch their mail through SSL. The aim is also to be able to fetch mail with your favorite email-client or mobile devices eg. mobile phones.&lt;br /&gt;
&lt;br /&gt;
Have a look at [[Hosting_services_on_Alpine#Mail]] for various alternatives and instructions.&lt;br /&gt;
&lt;br /&gt;
== Initial Setup ==&lt;br /&gt;
This document is referring to [[Setting_up_postfix_with_virtual_domains]]. You would benefit if you start by reading/following those instructions before you continue with these instructions.&lt;br /&gt;
&lt;br /&gt;
== Dovecot ==&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add dovecot}}&lt;br /&gt;
&lt;br /&gt;
=== Prepare ===&lt;br /&gt;
The upcoming configuration is going to need some certificates.&lt;br /&gt;
&lt;br /&gt;
==== Certificates ====&lt;br /&gt;
During the installation of Dovecot some default certificates were generated, which we will replace.&lt;br /&gt;
We want to keep things clean, so we create a dovecot folder for it&#039;s certs/keys&lt;br /&gt;
&lt;br /&gt;
{{Cmd|mkdir /etc/ssl/dovecot}}&lt;br /&gt;
&lt;br /&gt;
Now we start creating the certs&lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd /etc/ssl/dovecot&lt;br /&gt;
openssl genrsa 1024 &amp;gt; server.pem   # Choose 512 or 1024 as key length&lt;br /&gt;
openssl req -new -key server.pem -out request.pem  # You will get prompted for various information that is added the the file&lt;br /&gt;
openssl genrsa 2048 &amp;gt; server.key&lt;br /&gt;
openssl req -new -x509 -nodes -sha1 -days 3650 -key server.key &amp;gt; server.pem}}&lt;br /&gt;
&lt;br /&gt;
=== Configuration ===&lt;br /&gt;
For now I just dump whatever I have.&lt;br /&gt;
&lt;br /&gt;
I will clean up these notes soon.&lt;br /&gt;
&lt;br /&gt;
==== /etc/dovecot/dovecot.conf ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## These settings varies from the default configuration ##&lt;br /&gt;
base_dir = /var/run/dovecot/&lt;br /&gt;
protocols = imap imaps&lt;br /&gt;
listen = *&lt;br /&gt;
disable_plaintext_auth = no&lt;br /&gt;
ssl_disable = no&lt;br /&gt;
ssl_cert_file = /etc/ssl/dovecot/server.pem&lt;br /&gt;
ssl_key_file = /etc/ssl/dovecot/server.key&lt;br /&gt;
ssl_parameters_regenerate = 168&lt;br /&gt;
verbose_ssl = yes&lt;br /&gt;
login_chroot = yes&lt;br /&gt;
login_greeting = Dovecot ready.&lt;br /&gt;
mail_location = maildir:/var/spool/mail/vhosts/%d/%n&lt;br /&gt;
mail_privileged_group = mail&lt;br /&gt;
mail_debug = no&lt;br /&gt;
verbose_proctitle = no&lt;br /&gt;
valid_chroot_dirs = /var/spool/mail&lt;br /&gt;
protocols lda {     # This line is not changed - it&#039;s here to help you know where to make edits&lt;br /&gt;
  postmaster_address = postmaster@example.net&lt;br /&gt;
}     # This line is not changed - it&#039;s here to help you know where to make edits&lt;br /&gt;
auth_verbose = yes&lt;br /&gt;
auth_debug = yes&lt;br /&gt;
auth_worker_max_count = 30&lt;br /&gt;
auth default {     # This line is not changed - it&#039;s here to help you know where to make edits&lt;br /&gt;
  mechanism = plain login digest-md5&lt;br /&gt;
  passdb passwd-file {&lt;br /&gt;
    args = /etc/dovecot/dovecot-passwd&lt;br /&gt;
  }&lt;br /&gt;
  userdb passwd-file {&lt;br /&gt;
    args = /etc/dovecot/dovecot-users&lt;br /&gt;
  }&lt;br /&gt;
  socket listen {&lt;br /&gt;
    path = /var/spool/postfix/private/auth&lt;br /&gt;
    user = postfix&lt;br /&gt;
    group = postfix&lt;br /&gt;
    mode = 0660&lt;br /&gt;
  }&lt;br /&gt;
}     # This line is not changed - it&#039;s here to help you know where to make edits&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== /etc/dovecot/dovecot-users ====&lt;br /&gt;
The uid/gid number below &#039;1000&#039; should match your &#039;vmail&#039; account (the account that owns &#039;/var/spool/mail/vhosts&#039;)&lt;br /&gt;
&lt;br /&gt;
 user1@example.net::1000:1000::/var/spool/vhosts/example.net/:/bin/false::&lt;br /&gt;
 user2@example.net::1000:1000::/var/spool/vhosts/example.net/:/bin/false::&lt;br /&gt;
&lt;br /&gt;
==== /etc/dovecot/dovecot-passwd ====&lt;br /&gt;
To generate the passwords you can use the dovecotpw command. The output can be used to create a password for your &#039;dovecot-passwd&#039;&lt;br /&gt;
&lt;br /&gt;
{{Cmd|dovecotpw -s MD5-CRYPT}}&lt;br /&gt;
or &lt;br /&gt;
{{Cmd|doveadm pw -s MD5-CRYPT}}&lt;br /&gt;
&lt;br /&gt;
The /etc/dovecot/passwd file should look like this:&lt;br /&gt;
&lt;br /&gt;
 user1@example.net:$1$tz5sbjAD$Wq9.NkSyNo/oElzFgI68.0&lt;br /&gt;
 user2@example.net:$1$tz5sbjAD$Wq9.NkSyNo/oElzFgI68.0&lt;br /&gt;
&lt;br /&gt;
=== Start dovecot ===&lt;br /&gt;
It&#039;s time to start. Hopefully it works!&lt;br /&gt;
&lt;br /&gt;
{{Cmd|rc-service dovecot start}}&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
In case something goes wrong you should have a look in your syslog. Personally I use to tail the logfile while debugging&lt;br /&gt;
&lt;br /&gt;
{{Cmd|tail -f /var/log/dovecot}}&lt;br /&gt;
&lt;br /&gt;
=== Adding/Removing users ===&lt;br /&gt;
To add or remove users you need to edit the following files (they are described above):&lt;br /&gt;
* [[#.2Fetc.2Fdovecot.2Fdovecot-users|/etc/dovecot/dovecot-users]]&lt;br /&gt;
* [[#.2Fetc.2Fdovecot.2Fdovecot-passwd|/etc/dovecot/dovecot-passwd]]&lt;br /&gt;
Nothing else should be needed.&lt;br /&gt;
&lt;br /&gt;
[[Category:Mail]]&lt;/div&gt;</summary>
		<author><name>GrumpyMeow</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Setting_up_dovecot_with_imap_and_tls&amp;diff=26312</id>
		<title>Setting up dovecot with imap and tls</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Setting_up_dovecot_with_imap_and_tls&amp;diff=26312"/>
		<updated>2024-01-21T09:35:21Z</updated>

		<summary type="html">&lt;p&gt;GrumpyMeow: Minor fixes to make things more clear&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== General ==&lt;br /&gt;
Dovecot should be configured to let users fetch their mail through SSL. The aim is also to be able to fetch mail with your favorite email-client or mobile devices eg. mobile phones.&lt;br /&gt;
&lt;br /&gt;
Have a look at [[Hosting_services_on_Alpine#Mail]] for various alternatives and instructions.&lt;br /&gt;
&lt;br /&gt;
== Initial Setup ==&lt;br /&gt;
This document is referring to [[Setting_up_postfix_with_virtual_domains]]. You would benefit if you start by reading/following those instructions before you continue with these instructions.&lt;br /&gt;
&lt;br /&gt;
== Dovecot ==&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add dovecot}}&lt;br /&gt;
&lt;br /&gt;
=== Prepare ===&lt;br /&gt;
The upcoming configuration is going to need some certificates.&lt;br /&gt;
&lt;br /&gt;
==== Certificates ====&lt;br /&gt;
During the installation of Dovecot some default certificates were generated, which we will replace.&lt;br /&gt;
We want to keep things clean, so we create a dovecot folder for it&#039;s certs/keys&lt;br /&gt;
&lt;br /&gt;
{{Cmd|mkdir /etc/ssl/dovecot}}&lt;br /&gt;
&lt;br /&gt;
Now we start creating the certs&lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd /etc/ssl/dovecot&lt;br /&gt;
openssl genrsa 1024 &amp;gt; server.pem   # Choose 512 or 1024 as key length&lt;br /&gt;
openssl req -new -key server.pem -out request.pem  # You will get prompted for various information that is added the the file&lt;br /&gt;
openssl genrsa 2048 &amp;gt; server.key&lt;br /&gt;
openssl req -new -x509 -nodes -sha1 -days 3650 -key server.key &amp;gt; server.pem}}&lt;br /&gt;
&lt;br /&gt;
=== Configuration ===&lt;br /&gt;
For now I just dump whatever I have.&lt;br /&gt;
&lt;br /&gt;
I will clean up these notes soon.&lt;br /&gt;
&lt;br /&gt;
==== /etc/dovecot/dovecot.conf ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
## These settings varies from the default configuration ##&lt;br /&gt;
base_dir = /var/run/dovecot/&lt;br /&gt;
protocols = imap imaps&lt;br /&gt;
listen = *&lt;br /&gt;
disable_plaintext_auth = no&lt;br /&gt;
ssl_disable = no&lt;br /&gt;
ssl_cert_file = /etc/ssl/dovecot/server.pem&lt;br /&gt;
ssl_key_file = /etc/ssl/dovecot/server.key&lt;br /&gt;
ssl_parameters_regenerate = 168&lt;br /&gt;
verbose_ssl = yes&lt;br /&gt;
login_chroot = yes&lt;br /&gt;
login_greeting = Dovecot ready.&lt;br /&gt;
mail_location = maildir:/var/spool/mail/vhosts/%d/%n&lt;br /&gt;
mail_privileged_group = mail&lt;br /&gt;
mail_debug = no&lt;br /&gt;
verbose_proctitle = no&lt;br /&gt;
valid_chroot_dirs = /var/spool/mail&lt;br /&gt;
protocols lda {     # This line is not changed - it&#039;s here to help you know where to make edits&lt;br /&gt;
  postmaster_address = postmaster@example.net&lt;br /&gt;
}     # This line is not changed - it&#039;s here to help you know where to make edits&lt;br /&gt;
auth_verbose = yes&lt;br /&gt;
auth_debug = yes&lt;br /&gt;
auth_worker_max_count = 30&lt;br /&gt;
auth default {     # This line is not changed - it&#039;s here to help you know where to make edits&lt;br /&gt;
  mechanism = plain login digest-md5&lt;br /&gt;
  passdb passwd-file {&lt;br /&gt;
    args = /etc/dovecot/dovecot-passwd&lt;br /&gt;
  }&lt;br /&gt;
  userdb passwd-file {&lt;br /&gt;
    args = /etc/dovecot/dovecot-users&lt;br /&gt;
  }&lt;br /&gt;
  socket listen {&lt;br /&gt;
    path = /var/spool/postfix/private/auth&lt;br /&gt;
    user = postfix&lt;br /&gt;
    group = postfix&lt;br /&gt;
    mode = 0660&lt;br /&gt;
  }&lt;br /&gt;
}     # This line is not changed - it&#039;s here to help you know where to make edits&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== /etc/dovecot/dovecot-users ====&lt;br /&gt;
The uid/gid number below &#039;1000&#039; should match your &#039;vmail&#039; account (the account that owns &#039;/var/spool/mail/vhosts&#039;)&lt;br /&gt;
&lt;br /&gt;
 user1@example.net::1000:1000::/var/spool/vhosts/example.net/:/bin/false::&lt;br /&gt;
 user2@example.net::1000:1000::/var/spool/vhosts/example.net/:/bin/false::&lt;br /&gt;
&lt;br /&gt;
==== /etc/dovecot/dovecot-passwd ====&lt;br /&gt;
To generate the passwords you can use the dovecotpw command. The output can be used to create a password for your &#039;dovecot-passwd&#039;&lt;br /&gt;
&lt;br /&gt;
{{Cmd|dovecotpw -s MD5-CRYPT}}&lt;br /&gt;
&lt;br /&gt;
The /etc/dovecot/passwd file should look like this:&lt;br /&gt;
&lt;br /&gt;
 user1@example.net:$1$tz5sbjAD$Wq9.NkSyNo/oElzFgI68.0&lt;br /&gt;
 user2@example.net:$1$tz5sbjAD$Wq9.NkSyNo/oElzFgI68.0&lt;br /&gt;
&lt;br /&gt;
=== Start dovecot ===&lt;br /&gt;
It&#039;s time to start. Hopefully it works!&lt;br /&gt;
&lt;br /&gt;
{{Cmd|rc-service dovecot start}}&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
In case something goes wrong you should have a look in your syslog. Personally I use to tail the logfile while debugging&lt;br /&gt;
&lt;br /&gt;
{{Cmd|tail -f /var/log/dovecot}}&lt;br /&gt;
&lt;br /&gt;
=== Adding/Removing users ===&lt;br /&gt;
To add or remove users you need to edit the following files (they are described above):&lt;br /&gt;
* [[#.2Fetc.2Fdovecot.2Fdovecot-users|/etc/dovecot/dovecot-users]]&lt;br /&gt;
* [[#.2Fetc.2Fdovecot.2Fdovecot-passwd|/etc/dovecot/dovecot-passwd]]&lt;br /&gt;
Nothing else should be needed.&lt;br /&gt;
&lt;br /&gt;
[[Category:Mail]]&lt;/div&gt;</summary>
		<author><name>GrumpyMeow</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=NZBGet&amp;diff=24323</id>
		<title>NZBGet</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=NZBGet&amp;diff=24323"/>
		<updated>2023-08-15T12:35:49Z</updated>

		<summary type="html">&lt;p&gt;GrumpyMeow: Fixes some minor issue&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:NZBGet}}&lt;br /&gt;
{{TOC right}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
* This guide explains how to install the popular service [https://nzbget.net/ NZBGet] on Alpine Linux. Specifically, the environment used is 3.18 running in an LXC container. This guide should still work in a standard Alpine Linux install.&lt;br /&gt;
* This guide sets up NZBGet as a standard rc init service.&lt;br /&gt;
* The path {{path|/opt}} is used in this guide, however the choice of path is immaterial to the outcome, for example, {{path|/srv}} should work fine.&lt;br /&gt;
* This guide assumes all commands are run as root unless specified.&lt;br /&gt;
&lt;br /&gt;
== Download and install nzbget ==&lt;br /&gt;
&lt;br /&gt;
Fetch and install the latest NZBGet install script. (If you have security concerns, NZBGet code is available to inspect on [https://github.com/nzbget/nzbget GitHub]).&lt;br /&gt;
&lt;br /&gt;
{{Cmd|$ wget https://nzbget.net/download/nzbget-latest-bin-linux.run}}&lt;br /&gt;
&lt;br /&gt;
Run the install script.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|$ chmod +x nzbget-latest-bin-linux.run &amp;amp;&amp;amp; ./nzbget-latest-bin-linux.run}}&lt;br /&gt;
&lt;br /&gt;
Move the nzbget directory to {{path|/opt}}}&lt;br /&gt;
&lt;br /&gt;
{{Cmd|# mv nzbget /opt/}}&lt;br /&gt;
&lt;br /&gt;
== Create NZBGet Service ==&lt;br /&gt;
&lt;br /&gt;
Create the NZBGet init file:&lt;br /&gt;
&lt;br /&gt;
{{Cat|/etc/init.d/nzbget|#!/sbin/openrc-run&lt;br /&gt;
 &lt;br /&gt;
depend() {&lt;br /&gt;
	need net&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
start() {&lt;br /&gt;
	/opt/nzbget/nzbget -D&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
stop() {&lt;br /&gt;
	/opt/nzbget/nzbget -Q&lt;br /&gt;
}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Notice that the commands &amp;lt;code&amp;gt;/opt/nzbget/nzbget -D&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;/opt/nzbget/nzbget -Q&amp;lt;/code&amp;gt; are used to cleanly start and stop the service.&lt;br /&gt;
&lt;br /&gt;
Make the service file executable:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|# chmod +x /etc/init.d/nzbget}}&lt;br /&gt;
&lt;br /&gt;
Add the service to rc init:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|# rc-update add nzbget}}&lt;br /&gt;
&lt;br /&gt;
Start the service:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|# rc-service nzbget start}}&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* At this point, you should be able to reach nzbget at &#039;&#039;&#039;http://&amp;lt;YOURIP&amp;gt;:6789&#039;&#039;&#039;. You should be able to start and stop the nzbget service and the service should start after a system restart/reboot:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|# rc-service nzbget start}}&lt;br /&gt;
&lt;br /&gt;
{{Cmd|# rc-service nzbget stop}}&lt;br /&gt;
&lt;br /&gt;
* Any further configs can be set using the webgui or in {{path|/opt/nzbget/nzbget.conf}}.&lt;br /&gt;
* Of note is the line in {{path|/opt/nzbget/nzbget.conf}}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;DaemonUsername=root&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allows the service to start and run as a specific user, which is a common setup if NZBGet is used in conjunction with other media managers and shared storage. Note that any working directories specified in the settings will require their permissions updated to work correctly.&lt;br /&gt;
* NZBGet is quite descriptive in its logs. Check NZBGet&#039;s &#039;&#039;&#039;Messages&#039;&#039;&#039; section for errors, including permissions and paths.&lt;br /&gt;
&lt;br /&gt;
== Updating NZBGet ==&lt;br /&gt;
&lt;br /&gt;
As of version 21.2, the certificate that ships with NZBGet for updating from nzbget.net is expired and updates will consequently fail until it is updated. Fortunately, this can be rectified:&lt;br /&gt;
&lt;br /&gt;
Stop the nzbget service:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|# rc-service nzbget stop}}&lt;br /&gt;
&lt;br /&gt;
If you run the nzbget service under any other user than root, change this back to root temporarily for the update in {{path|/opt/nzbget/nzbget.conf}}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;DaemonUsername=root&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetch the new and valid certificate:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|$ curl --remote-name --time-cond cacert.pem https://nzbget.net/info/cacert.pem}}&lt;br /&gt;
&lt;br /&gt;
Move the new certificate to the correct path:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|# mv cacert.pem /opt/nzbget/cacert.pem}}&lt;br /&gt;
&lt;br /&gt;
Start the NZBGet service:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|# rc-service nzbget start}}&lt;br /&gt;
&lt;br /&gt;
Navigate to your instance of NZBGet, Settings, System, Update NZBGet:&lt;br /&gt;
&lt;br /&gt;
[[File:2023-07-04 01-07.png|thumb|right|100px|nzbget update screenshot]]&lt;br /&gt;
&lt;br /&gt;
If required, stop the nzbget service again and revert the &amp;lt;code&amp;gt;DaemonUsername&amp;lt;/code&amp;gt; to its normal value in {{path|/opt/nzbget/nzbget.conf}}.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[category:Networking]]&lt;/div&gt;</summary>
		<author><name>GrumpyMeow</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=UniFi_Controller&amp;diff=22342</id>
		<title>UniFi Controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=UniFi_Controller&amp;diff=22342"/>
		<updated>2022-10-01T12:46:58Z</updated>

		<summary type="html">&lt;p&gt;GrumpyMeow: Wrong path probably due to copy/paste&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOC right}}&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
This guide explains how to install the generic Unix UniFi Controller, as available from [http://www.ui.com/ Ubiquiti Networks]. At the time of writing this, a native Alpine Linux package is not available.&lt;br /&gt;
&lt;br /&gt;
Furthermore, this guide uses the incredibly reliable and efficient [http://www.skarnet.org/software/s6/ s6] supervision suite to start and control the UniFi Controller.&lt;br /&gt;
&lt;br /&gt;
A summarized schematic of what will be installed on the filesystem.&lt;br /&gt;
&lt;br /&gt;
The choice of {{path|/srv}} for the UniFi Controller&#039;s root directory is based on the fact that it contains both run-time and configuration data, so installing to {{path|/usr/local}}, {{path|/opt}} or {{path|/home}} didn&#039;t seem appropriate. Feel free to adjust the steps below, replacing {{path|/srv/unifi}} with wherever you would prefer to install the UniFi Controller software.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/&lt;br /&gt;
`--etc&lt;br /&gt;
   |-- unifi&lt;br /&gt;
   |   `-- log&lt;br /&gt;
   |-- srv&lt;br /&gt;
   |   `-- unifi&lt;br /&gt;
   |       |-- bin&lt;br /&gt;
   |       |-- conf&lt;br /&gt;
   |       |-- data&lt;br /&gt;
   |       |-- dl&lt;br /&gt;
   |       |-- lib&lt;br /&gt;
   |       |-- logs&lt;br /&gt;
   |       |-- run&lt;br /&gt;
   |       `-- webapps&lt;br /&gt;
   |-- run&lt;br /&gt;
   |   `-- openrc&lt;br /&gt;
   |          `-- s6-scan&lt;br /&gt;
   |              `-- unifi --&amp;gt; /etc/unifi&lt;br /&gt;
    `-- var&lt;br /&gt;
        `-- log&lt;br /&gt;
            `-- unifi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Prerequisite Packages =&lt;br /&gt;
&lt;br /&gt;
== OpenJDK 8 JRE ==&lt;br /&gt;
&lt;br /&gt;
Install &amp;lt;code&amp;gt;openjdk8-jre&amp;lt;/code&amp;gt; from the community repository.&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;/etc/apk/repositories&amp;lt;/code&amp;gt; and uncomment the appropriate community repository for your Alpine version:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://host.name/alpine_version/community&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Update the package cache.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;apk update&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Install the package.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;apk add openjdk8-jre&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MongoDB ==&lt;br /&gt;
&lt;br /&gt;
Install MongoDB&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;apk add mongodb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== s6 ==&lt;br /&gt;
&lt;br /&gt;
Install [http://www.skarnet.org/software/s6/ s6]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;apk add s6&amp;lt;/code&amp;gt; which is a service supervision suite, for reliably and efficiently starting, stopping and keeping services running.&lt;br /&gt;
&lt;br /&gt;
The below shows a schematic process tree of how the UniFi Controller will be started and supervised by s6. The controller is written in Java, hence the Java process and it in turn, launches a dedicated instance of MongoDB to store its configuration and run-time data.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
init&lt;br /&gt;
`-- s6-svscan&lt;br /&gt;
    `-- s6-supervise&lt;br /&gt;
        |-- s6-log&lt;br /&gt;
        `-- java&lt;br /&gt;
            `-- mongod&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Install UniFi Controller =&lt;br /&gt;
&lt;br /&gt;
Create the &amp;lt;code&amp;gt;unifi&amp;lt;/code&amp;gt; user and group.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;adduser -D -H -h /srv/unifi unifi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Change to the parent folder within which you wish to install the UniFi Controller.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /srv&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Download the generic unix archive of the &amp;lt;code&amp;gt;VERSION&amp;lt;/code&amp;gt; you wish to install.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;wget http://www.ubnt.com/downloads/unifi/VERSION/UniFi.unix.zip&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unpack the archive.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;unzip UniFi.unix.zip&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rename the unpacked directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mv UniFi unifi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Change ownership.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown -R unifi:unifi unifi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lock down permissions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod o-rwx unifi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Change into the UniFi bin directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /srv/unifi/bin&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remove the existing file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rm mongod&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a symlink to &amp;lt;code&amp;gt;/usr/bin/mongod&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ln -s /usr/bin/mongod&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Configure Service Management =&lt;br /&gt;
&lt;br /&gt;
== Create UniFi Service Directory and Files ==&lt;br /&gt;
&lt;br /&gt;
Create an s6 service directory for UniFi.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/unifi/log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the &amp;lt;code&amp;gt;run&amp;lt;/code&amp;gt; script, using your favourite editor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/unifi/run&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy and paste the following into it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/ash&lt;br /&gt;
&lt;br /&gt;
user=&#039;unifi&#039;&lt;br /&gt;
group=&#039;unifi&#039;&lt;br /&gt;
&lt;br /&gt;
exec 2&amp;gt;&amp;amp;1&lt;br /&gt;
&lt;br /&gt;
base=&#039;/srv/unifi&#039;&lt;br /&gt;
&lt;br /&gt;
if [ -d $base ]; then&lt;br /&gt;
    cd $base&lt;br /&gt;
    chown -R $user:$group .&lt;br /&gt;
    version=`head -1 webapps/ROOT/app-unifi/.version`&lt;br /&gt;
    echo &amp;quot;Starting UniFi Controller $version&amp;quot;&lt;br /&gt;
    exec s6-setuidgid $user java -jar lib/ace.jar start&lt;br /&gt;
else&lt;br /&gt;
    echo &amp;quot;Missing $base ... aborting&amp;quot;&lt;br /&gt;
    touch down&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the &amp;lt;code&amp;gt;run&amp;lt;/code&amp;gt; script is executable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 755 /etc/unifi/run&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the &amp;lt;code&amp;gt;log/run&amp;lt;/code&amp;gt; script, using your favourite editor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/unifi/log/run&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy and paste the following into it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/ash&lt;br /&gt;
&lt;br /&gt;
log_user=&#039;log&#039;&lt;br /&gt;
&lt;br /&gt;
exec s6-setuidgid $log_user s6-log -b n20 s1000000 t /var/log/unifi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the log/run script is executable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 755 /etc/unifi/log/run&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create log User and Directory ==&lt;br /&gt;
&lt;br /&gt;
Create the &amp;lt;code&amp;gt;log&amp;lt;/code&amp;gt; user and group.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;adduser -D -H -h /var/log log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the &amp;lt;code&amp;gt;/var/log/unifi&amp;lt;/code&amp;gt; directory&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /var/log/unifi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Update the directory ownership.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown log:log /var/log/unifi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lock down the permissions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 750 /var/log/unifi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create the OpenRC Service Script ==&lt;br /&gt;
&lt;br /&gt;
Open the script file using your favourite editor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/init.d/unifi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paste the following into it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/sbin/openrc-run&lt;br /&gt;
&lt;br /&gt;
name=&amp;quot;unifi&amp;quot;&lt;br /&gt;
supervisor=s6&lt;br /&gt;
s6_service_path=&amp;quot;${RC_SVCDIR}/s6-scan/${name}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
depend() {&lt;br /&gt;
	need net s6-svscan&lt;br /&gt;
	after firewall&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
start_pre() {&lt;br /&gt;
        if [ ! -L &amp;quot;${RC_SVCDIR}/s6-scan/${name}&amp;quot; ]; then&lt;br /&gt;
	        ln -s &amp;quot;/etc/${name}&amp;quot; &amp;quot;${RC_SVCDIR}/s6-scan/${name}&amp;quot;&lt;br /&gt;
	fi&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ensure that the script is executable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 755 /etc/init.d/unifi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Start the UniFi Controller Service ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rc-service unifi start&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configure the UniFi Controller Service to start on boot ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rc-update add unifi boot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Simple Backup Script =&lt;br /&gt;
&lt;br /&gt;
Create &amp;lt;code&amp;gt;/usr/local/bin/unifi-backup&amp;lt;/code&amp;gt; using your favourite editor.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; This script assumes the use of s6-svc to control unifi. I will modify it in time, to use rc-service instead.&lt;br /&gt;
&lt;br /&gt;
Paste the following into the file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/ash&lt;br /&gt;
&lt;br /&gt;
conf_dir=&#039;/etc/unifi&#039;&lt;br /&gt;
backup_dir=&#039;/srv/backup/unifi&#039;&lt;br /&gt;
service_dir=&#039;/run/openrc/s6-scan/unifi&#039;&lt;br /&gt;
&lt;br /&gt;
start_state=&#039;down&#039;&lt;br /&gt;
&lt;br /&gt;
if s6-svok $service_dir; then&lt;br /&gt;
    if s6-svstat -o up,ready $service_dir | grep -q true; then&lt;br /&gt;
        echo &#039;Stopping the UniFi Controller&#039;&lt;br /&gt;
        start_state=&#039;up&#039;&lt;br /&gt;
        s6-svc -d $service_dir&lt;br /&gt;
        sleep 3&lt;br /&gt;
    fi&lt;br /&gt;
else&lt;br /&gt;
    echo &#039;Warning: The UniFi Controller is not supervised&#039;&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if s6-svstat -o up $service_dir | grep -q false; then&lt;br /&gt;
    echo &#039;Success: The UniFi Controller was stopped&#039;&lt;br /&gt;
else&lt;br /&gt;
    echo &#039;Error: The UniFi Controller is still running&#039;&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
stamp=`date +%Y-%m-%d_%H%M%S`&lt;br /&gt;
&lt;br /&gt;
mkdir -p $backup_dir&lt;br /&gt;
cd $backup_dir&lt;br /&gt;
mkdir &amp;quot;data-$stamp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Backing up to /srv/backup/unifi/data-$stamp.tar.gz&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if rsync -az /srv/unifi/data/ &amp;quot;data-$stamp&amp;quot;; then&lt;br /&gt;
    echo &#039;* rsync succeeded&#039;&lt;br /&gt;
    if tar czf &amp;quot;data-$stamp.tar.gz&amp;quot; &amp;quot;data-$stamp&amp;quot;; then&lt;br /&gt;
        echo &#039;* tar succeeded&#039;&lt;br /&gt;
        rm -rf &amp;quot;data-$stamp&amp;quot;&lt;br /&gt;
        echo &#039;Backup succeeded&#039;&lt;br /&gt;
    else&lt;br /&gt;
        echo &#039;Backup failed: tar failed&#039;&lt;br /&gt;
	exit 1&lt;br /&gt;
    fi&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ &amp;quot;$start_state&amp;quot; == &#039;up&#039; ]; then&lt;br /&gt;
    echo &#039;Starting the UniFi Controller&#039;&lt;br /&gt;
    s6-svc -u $service_dir&lt;br /&gt;
    sleep 5&lt;br /&gt;
    s6-svstat $service_dir&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[category:Networking]]&lt;/div&gt;</summary>
		<author><name>GrumpyMeow</name></author>
	</entry>
</feed>