The Problem

Within an article on their website, LinuxServer.io have announced that they will be deprecating the current linuxserver/unifi-controller public image as of 2024/01/01. Happy New Year! The README on the current tooling that I imagine most are using mentions a direct upgrade if you were using the mongoless tag which, due to what’s colloquially known as “Sod’s Law”, I am not.

On the new repo as well as the DockerHub page, the docs currently have a brief mentioning of requiring an external MongoDB instance but the code snippits don’t actuall have one… This seemed a little problematic, and after migrating my setup last night, figured I’d include a quick walkthrough.

The Solution

Unfortunately, there’s no one and done migration to just switch images and bring the container back up, but it’s not exactly a difficult process.

I’ve included the docker-compose.yml in the section below, just copy pasta, change the passwords (anywhere you see SUPERSTRONGPASSWORD), and you’re good (also create a init-mongo.js using the below file too as this will automatically create the correct user, db, and permissions).

DO NOT copy across the current Unifi config folder, restoring from the backup will create this in a safer way.

The newest supported MongoDB version currently is 4.4 so that’s what I’m using in my stack, if that changes I’ll likely see about migrating to newer, and will update this post if I do.

  1. Manual backup of current configuration

    • Settings > System > Backups > Download (in the new UI, anyway)
    • I’d set the export time to ‘No Limit’ to keep stats, etc, but you do you
  2. Stop the current container

    • Just do a docker compose down on the current stack
    • Unless you’re migrating to another box you need to stop the current stack because the new one is going to need the same ports :upside_down_face:
  3. Start the new container

    • I said it above, but just in case, copy the compose file into the new location (I’d just make a different folder for this new controller)
    • You guessed it, docker compose up -d
    • I’d recommend watching the logs with docker compose logs -f because you’ll see a final log line from the MongoDB container related to Authentication, and as long as that’s not an error that’s when you’ll know that the container is up and ready
  4. Restore from the backup

    • Go to https://container-host-name-or-ip:8443
    • Start the process, until you see a link allowing you to resore from a backup
    • Click that link
    • Select the backup you just downloaded from the old controller
    • Wait a couple of minues, you’ll see the MongoDB logs going crazy and then the controller will reboot
    • Reload, log in, and check all your APs still report in
    • Breathe a sigh of relief
    • You can now remove the volume binding for the init-mongo.js file and restart the stack for purity’s sake if you like
  5. Don’t touch it for another 6 months :wink:

And the best bit is that if it breaks in some way and you need to roll back, just start the old stack and you’re back in business :partying_face:.

Docker-Compose File

NB: You can also use a proper Docker volume instead of a local folder in the unifi-db container

version: "2.1"
services:
  unifi-db:
    image: mongo:4.4
    restart: always
    volumes:
      - ./db:/data/db
      - ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro
  unifi-network-application:
    image: lscr.io/linuxserver/unifi-network-application:latest
    container_name: unifi-network-application
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
      - MONGO_USER=unifi
      - MONGO_PASS=SUPERSTRONGPASSWORD
      - MONGO_HOST=unifi-db
      - MONGO_PORT=27017
      - MONGO_DBNAME=unifi
      - MEM_LIMIT=1024 #optional
      - MEM_STARTUP=1024 #optional
    volumes:
      - ./config:/config
    ports:
      - 8443:8443
      - 3478:3478/udp
      - 10001:10001/udp
      - 8080:8080
      - 8843:8843 #optional
      - 8880:8880 #optional
      - 6789:6789 #optional
      - 5514:5514/udp #optional
    restart: always
    depends_on:
      - unifi-db

init-mongo.js File

db.getSiblingDB("unifi").createUser({
  user: "unifi",
  pwd: "SUPERSTRONGPASSWORD",
  roles: [{ role: "readWrite", db: "unifi" }],
});
db.getSiblingDB("unifi_stat").createUser({
  user: "unifi",
  pwd: "SUPERSTRONGPASSWORD",
  roles: [{ role: "readWrite", db: "unifi_stat" }],
});