Add Unifi migration to network-services

- compose-files/network-services/unifi: Full stack (MongoDB + Unifi app)
- compose-files/databases/mongodb: Deprecated, kept for reference
- playbooks/deploy-unifi-local.yml: Local deployment with resource limits
- playbooks/migrate-unifi.yml: Original migration playbook (deprecated)

Stack runs locally on network-services (.121) with:
- unifi-db: MongoDB 4.4.29 (512M/1CPU)
- unifi: Network Application (1G/1CPU)
- Proper labels for autoheal and watchtower
This commit is contained in:
Maddox 2026-01-24 21:28:38 +00:00
parent 383e803c5d
commit 8b46587b01
5 changed files with 433 additions and 3 deletions

View file

@ -0,0 +1,28 @@
services:
unifi-db:
image: docker.io/mongo:4.4.29
container_name: unifi-db
restart: unless-stopped
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=rootpassword
- MONGO_INITDB_DATABASE=unifi
volumes:
- /mnt/nas/docker/unifi/init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro
- /mnt/nas/docker/unifi/db:/data/db
ports:
- "27017:27017"
networks:
- database
labels:
- "autoheal=true"
- "com.centurylinklabs.watchtower.enable=true"
deploy:
resources:
limits:
memory: 512M
cpus: '1.0'
networks:
database:
external: true

View file

@ -7,9 +7,9 @@ name: immich
services:
immich-server:
container_name: immich_server
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
image: ghcr.io/immich-app/immich-server:\${IMMICH_VERSION:-release}
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
- \${UPLOAD_LOCATION}:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
env_file:
- .env
@ -30,10 +30,15 @@ services:
- "com.centurylinklabs.watchtower.enable=true"
networks:
- immich
deploy:
resources:
limits:
memory: 2G
cpus: '2.0'
immich-machine-learning:
container_name: immich_machine_learning
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
image: ghcr.io/immich-app/immich-machine-learning:\${IMMICH_VERSION:-release}
volumes:
- model-cache:/cache
env_file:
@ -50,6 +55,11 @@ services:
- "com.centurylinklabs.watchtower.enable=true"
networks:
- immich
deploy:
resources:
limits:
memory: 4G
cpus: '2.0'
redis:
container_name: immich_redis
@ -65,6 +75,11 @@ services:
- "com.centurylinklabs.watchtower.enable=true"
networks:
- immich
deploy:
resources:
limits:
memory: 256M
cpus: '0.5'
volumes:
model-cache:

View file

@ -0,0 +1,65 @@
services:
unifi-db:
image: docker.io/mongo:4.4.29
container_name: unifi-db
restart: unless-stopped
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=rootpassword
- MONGO_INITDB_DATABASE=unifi
volumes:
- /mnt/nas/docker/unifi/init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro
- /mnt/nas/docker/unifi/db:/data/db
networks:
- unifi-network
labels:
- "autoheal=true"
- "com.centurylinklabs.watchtower.enable=true"
deploy:
resources:
limits:
memory: 512M
cpus: '1.0'
unifi:
image: lscr.io/linuxserver/unifi-network-application:latest
container_name: unifi
restart: unless-stopped
environment:
- PUID=1000
- PGID=1000
- TZ=America/New_York
- MONGO_USER=unifi
- MONGO_PASS=unifipwd
- MONGO_HOST=unifi-db
- MONGO_PORT=27017
- MONGO_DBNAME=unifi
- MONGO_AUTHSOURCE=admin
- MEM_LIMIT=1024
- MEM_STARTUP=1024
volumes:
- /mnt/nas/docker/unifi/config:/config
ports:
- "8080:8080"
- "8443:8443"
- "3478:3478/udp"
- "10001:10001/udp"
- "8880:8880"
- "6790:6789"
- "5514:5514/udp"
depends_on:
- unifi-db
networks:
- unifi-network
labels:
- "autoheal=true"
- "com.centurylinklabs.watchtower.enable=true"
deploy:
resources:
limits:
memory: 1G
cpus: '1.0'
networks:
unifi-network:
driver: bridge

View file

@ -0,0 +1,153 @@
---
# Deploy Unifi Stack Locally on network-services
# - Cleans up old MongoDB from databases VM
# - Deploys MongoDB + Unifi together on network-services
# - Uses local bridge network, proper resource limits, labels
- name: Cleanup old MongoDB from databases VM
hosts: databases
gather_facts: no
tags: [cleanup]
tasks:
- name: Stop and remove MongoDB containers
shell: |
docker stop unifi-db 2>/dev/null || true
docker rm unifi-db 2>/dev/null || true
changed_when: true
- name: Remove MongoDB image
shell: docker rmi mongo:4.4.29 2>/dev/null || true
changed_when: true
- name: Remove MongoDB compose directory
file:
path: /home/docker/appdata/mongodb
state: absent
- name: Prune unused images
shell: docker image prune -f
changed_when: true
- name: Verify cleanup
shell: |
echo "Containers:" && docker ps -a --filter name=unifi --format "{{'{{'}}.Names{{'}}'}}"
echo "Images:" && docker images | grep -i mongo || echo "No mongo images"
register: cleanup_verify
changed_when: false
- name: Show cleanup status
debug:
msg: "{{ cleanup_verify.stdout_lines }}"
- name: Stop existing Unifi on network-services
hosts: network-services
gather_facts: no
tags: [stop]
tasks:
- name: Stop existing containers
shell: |
docker stop unifi unifi-db 2>/dev/null || true
docker rm unifi unifi-db 2>/dev/null || true
changed_when: true
- name: Deploy Unifi stack on network-services
hosts: network-services
gather_facts: no
tags: [deploy]
tasks:
- name: Ensure appdata directory exists
file:
path: /root/docker/appdata/unifi
state: directory
mode: '0755'
- name: Verify NFS mount
stat:
path: /mnt/nas/docker/unifi
register: nfs_check
- name: Fail if NFS not mounted
fail:
msg: "NFS mount /mnt/nas/docker/unifi not accessible"
when: not nfs_check.stat.exists
- name: Deploy compose file
copy:
src: "../compose-files/network-services/unifi/docker-compose.yml"
dest: /root/docker/appdata/unifi/docker-compose.yml
mode: '0644'
- name: Pull images
shell: |
cd /root/docker/appdata/unifi
docker compose pull
register: pull_result
- name: Start stack
shell: |
cd /root/docker/appdata/unifi
docker compose up -d
register: start_result
- name: Wait for MongoDB to be ready
shell: |
for i in $(seq 1 30); do
if docker exec unifi-db mongo --eval "db.adminCommand('ping')" 2>/dev/null | grep -q "ok"; then
echo "MongoDB ready"
exit 0
fi
sleep 2
done
echo "MongoDB timeout"
exit 1
register: mongo_ready
changed_when: false
- name: Wait for Unifi startup
pause:
seconds: 90
prompt: "Waiting for Unifi to initialize (90s)..."
- name: Check container status
shell: |
docker ps --filter name=unifi --format "table {{'{{'}}.Names{{'}}'}}\t{{'{{'}}.Status{{'}}'}}\t{{'{{'}}.Ports{{'}}'}}" | head -5
register: container_status
changed_when: false
- name: Show status
debug:
msg: "{{ container_status.stdout_lines }}"
- name: Verify resource limits applied
shell: |
echo "=== Resource Limits ==="
docker inspect unifi-db --format '{{'{{'}}.Name{{'}}'}}: Memory={{'{{'}}.HostConfig.Memory}} CPUs={{'{{'}}.HostConfig.NanoCpus}}'
docker inspect unifi --format '{{'{{'}}.Name{{'}}'}}: Memory={{'{{'}}.HostConfig.Memory}} CPUs={{'{{'}}.HostConfig.NanoCpus}}'
register: limits_check
changed_when: false
- name: Show resource limits
debug:
msg: "{{ limits_check.stdout_lines }}"
- name: Summary
hosts: localhost
gather_facts: no
tags: [always]
tasks:
- name: Next steps
debug:
msg:
- "============================================"
- "UNIFI DEPLOYMENT COMPLETE"
- "============================================"
- "Stack: network-services (.121)"
- " - unifi-db (MongoDB 4.4.29) - 512M/1CPU"
- " - unifi (Network App) - 1G/1CPU"
- ""
- "Access: https://192.168.1.121:8443"
- ""
- "UPDATE APs:"
- " ssh admin@<AP-IP>"
- " set-inform http://192.168.1.121:8080/inform"
- "============================================"

169
playbooks/migrate-unifi.yml Normal file
View file

@ -0,0 +1,169 @@
---
# Unifi Migration Playbook
# MongoDB -> databases (.81), Unifi app -> network-services (.121)
#
# Usage:
# ansible-playbook playbooks/migrate-unifi.yml --tags=setup-nfs
# ansible-playbook playbooks/migrate-unifi.yml --tags=stop-old
# ansible-playbook playbooks/migrate-unifi.yml --tags=deploy
# ansible-playbook playbooks/migrate-unifi.yml # full migration
- name: Setup NFS mount on network-services
hosts: network-services
gather_facts: no
become: yes
tags: [setup-nfs, deploy]
tasks:
- name: Create mount directory
file:
path: /mnt/nas/docker
state: directory
mode: '0755'
- name: Check if NFS already in fstab
shell: grep -q "192.168.1.251:/volume1/docker" /etc/fstab
register: fstab_check
ignore_errors: yes
changed_when: false
- name: Add NFS mount to fstab
lineinfile:
path: /etc/fstab
line: "192.168.1.251:/volume1/docker /mnt/nas/docker nfs defaults 0 0"
state: present
when: fstab_check.rc != 0
- name: Mount NFS
shell: mount -a
changed_when: false
- name: Verify mount
stat:
path: /mnt/nas/docker/unifi
register: mount_check
- name: Fail if mount not working
fail:
msg: "NFS mount failed - /mnt/nas/docker/unifi not accessible"
when: not mount_check.stat.exists
- name: Stop Unifi on docker666
hosts: docker666
gather_facts: no
tags: [stop-old]
tasks:
- name: Stop old Unifi stack
shell: |
cd /volume1/docker/unifi
docker compose down
register: stop_result
ignore_errors: yes
- name: Show result
debug:
msg: "{{ stop_result.stdout_lines | default(['Stopped']) }}"
- name: Deploy MongoDB on databases
hosts: databases
gather_facts: no
tags: [deploy, deploy-mongo]
tasks:
- name: Ensure database network exists
shell: docker network inspect database >/dev/null 2>&1 || docker network create database
changed_when: false
- name: Create compose directory
file:
path: /home/docker/appdata/mongodb
state: directory
mode: '0755'
- name: Copy MongoDB compose
copy:
src: "../compose-files/databases/mongodb/docker-compose.yml"
dest: /home/docker/appdata/mongodb/docker-compose.yml
mode: '0644'
- name: Deploy MongoDB
shell: |
cd /home/docker/appdata/mongodb
docker compose pull
docker compose up -d
- name: Wait for MongoDB
shell: |
for i in $(seq 1 30); do
if docker exec unifi-db mongo --eval "db.adminCommand('ping')" 2>/dev/null | grep -q "ok"; then
echo "MongoDB ready"
exit 0
fi
sleep 2
done
exit 1
register: mongo_wait
changed_when: false
- name: Deploy Unifi on network-services
hosts: network-services
gather_facts: no
tags: [deploy, deploy-unifi]
tasks:
- name: Ensure proxy network exists
shell: docker network inspect proxy >/dev/null 2>&1 || docker network create proxy
changed_when: false
- name: Create compose directory
file:
path: /root/docker/appdata/unifi
state: directory
mode: '0755'
- name: Copy Unifi compose
copy:
src: "../compose-files/network-services/unifi/docker-compose.yml"
dest: /root/docker/appdata/unifi/docker-compose.yml
mode: '0644'
- name: Deploy Unifi
shell: |
cd /root/docker/appdata/unifi
docker compose pull
docker compose up -d
- name: Wait for Unifi startup
pause:
seconds: 60
prompt: "Waiting for Unifi to initialize..."
- name: Check Unifi status
shell: docker ps --filter name=unifi --format "table {{'{{'}}.Names{{'}}'}}\t{{'{{'}}.Status{{'}}'}}"
register: unifi_status
- name: Show status
debug:
msg: "{{ unifi_status.stdout_lines }}"
- name: Migration summary
hosts: localhost
gather_facts: no
tags: [always]
tasks:
- name: Next steps
debug:
msg:
- "============================================"
- "UNIFI MIGRATION SUMMARY"
- "============================================"
- "MongoDB: 192.168.1.81:27017"
- "Unifi: https://192.168.1.121:8443"
- ""
- "UPDATE YOUR 4 APs:"
- " ssh admin@<AP-IP>"
- " set-inform http://192.168.1.121:8080/inform"
- ""
- "Or from Unifi UI: Settings > System > Advanced"
- " Set 'Inform Host' to: 192.168.1.121"
- ""
- "CLEANUP (after APs reconnect):"
- " ssh docker666 'cd /volume1/docker/unifi && docker compose down'"
- "============================================"