the need

The Other Day i needed a network controler for an old set of unifi ACs which i am reusing now to setup strong wlan in a our newly aquired retreat center.

As i reside 1 hour away from our beautiful retreat center, i want to be able to login into the controller over the internet to support the residents from home if needed.

flashing the raspi

i decided to go with the cheapest solution and buy a raspi 4b with 2gb ram which is enough for an headless ubuntu focal server running the unifi gui.

so i bought the raspi with a nice case including a fan a powercord and a 64GB SD Card.

Flashing with Ubuntu was really simple with raspberry pi imager:.

The imager lets you choose the os, downloads and copys the files correctly on the card. All you need is to put the card into the Pi, power it on and connect it with the wired network.
i choosed ubuntu focal 64.
I looked into my router and searched for the new device named ubuntu and its dhcp ip and ssh'd into the machine

first login

ssh -l ubuntu

password for first login is ubuntu and after login you got to change this.

setting up no-ip

i have a paid no-ip account like forever, so i go with this but there are also other dyndns players around, as long as they have a arm linux clent your good to go.

i'll go with the good old domain for this article

download the noi-ip client source

install the build-essential meta package

sudo apt install build-essential

and follow those instructions:

in brief:

become superuser, make and install the app

cd /usr/local/src/
tar xf noip-duc-linux.tar.gz
make install

configure the client:

/usr/local/bin/noip2 -C

you have to enter your credentials and choose the domains you will update an its all set

to run this as a service i found this handy systemd service files which works perfectly

# Simple Dynamic DNS Updater
# By Nathan Giesbrecht (
# 1) Install binary as described in's source file (assuming results in /usr/local/bin)
# 2) Run sudo /usr/local/bin/noip2 -C to generate configuration file
# 3) Copy this file noip2.service to /etc/systemd/system/
# 4) Execute `sudo systemctl daemon-reload`
# 5) Execute `sudo systemctl enable noip2`
# 6) Execute `sudo systemctl start noip2`
# systemd supports lots of fancy features, look here (and linked docs) for a full list:

[Unit] dynamic IP address updater


# Start main service

depending on your network setup you have to forward port 80 and 443 to your controller in your Router

install unifi

to install the controller you can add the official apt repos to your sources.list, but there is this script from this dutch guy and i choose this
i looked through the script before using it and it seemed trustworthy to run it

grab the script here and choose your desired version of the controller

i just ran the script without option choosed the defaults except i skipped the letsencrypt part because i want to use caddy as reverse proxy and reach the controller with the normal https port 443. and the unifi gui is listening to 8443 and i dont wont a extra acme software on my pi if i can have it all done by caddy.

after you ran the script all should be runnning and you should be able to reach your controller with https://ipofyourpi:8443
Your browser will greet you with a certificate warning, because the default one of unifi is of course self-signed, if you ignore that for now the setup page will greet you then.
we leave it for now as it is and go to our final step: setup caddy


I learned to love caddy1 as really simple and fast webserver in a K8s surrounding, as a go app, all its need is already compiles in the binary, no dependencies needed, easy to configure because it has already thoughtful and useful defaults, the config file called Caddyfile is really light and clear.
Caddy2 made alao more easier and the best thing is the auto tls feature which i was eager to try out ( in the K8s Cluster i maintain TLS Termination is already done by our haproxy)

So lets download the Binary from and choose ARM64 as platform. we dont need any further plugin so were good to go.

we also want to run caddy2 as systemd service so i just followed the steps described here:

move the binary into your $PATH
i choose /usr/local/bin

sudo mv caddy /usr/local/bin/


Configure Caddy with this simple Caddyfile,
reverse proxy all traffic and the websocket to the unifi port and accept the selsigned cert from unifi
encode gzip

log {
     output file   /var/lib/caddy/caddy.log

reverse_proxy  {
   to  https://localhost:8443
   transport http {

@websockets {
    header Connection *Upgrade*
    header Upgrade websocket
reverse_proxy @websockets {
  to https://localhost:8443
  transport http {

thats it !