Homelab Update: Nextcloud + Music Assistant with Tailscale
“Every new service adds value. Every new service adds a new place to forget a setting.”
Today’s session was a full-stack homelab sprint: Nextcloud for file sync, Music Assistant for media control, and a pile of Tailscale + SMB details that only surface once you actually ship. It started as “let’s add two services,” and ended with a surprisingly long list of tiny fixes that turned a shaky setup into something repeatable.
If you’ve ever clicked “Add service,” felt good for five minutes, then spent the next hour chasing port conflicts and permissions—you’ll relate.
Note: I’ve redacted Tailscale DNS names, IPs, and LAN IPs in this public post. Replace placeholders like <TAILSCALE_HOST> and <DOCKERVM_LAN_IP> with your own values.
✅ What I Shipped
Music Assistant
- Deployed on the Docker VM, host network for discovery and playback.
- Media library via SMB:
/mnt/media/media/Music(read-only). - LAN UI:
http://<DOCKERVM_LAN_IP>:8095. - Tailscale access moved to port
18095to avoid host-network conflicts.
The reason for host network: Music Assistant relies on discovery and multicast. It behaves better when it can see the LAN directly.
Nextcloud
- Deployed on the Docker VM with MariaDB + Redis.
- Data directory:
/mnt/media/NextCloud(CIFS mount). - LAN UI:
https://<DOCKERVM_LAN_IP>:8081(self-signed TLS). - Tailscale HTTPS:
https://<TAILSCALE_HOST>:8081.
I chose the LSIO image for clean PUID/PGID handling, which matters when the data directory lives on a CIFS mount.
Operational improvements
- Added a boot automation systemd unit so containers start cleanly after reboot.
- Updated Homepage with Music Assistant and Nextcloud.
- Updated Home Assistant to 2026.1.3 to resolve Music Assistant integration mismatch.
The theme here: the services were easy; the glue was the hard part.
🧨 Gotchas (And Fixes That Actually Worked)
1) Music Assistant integration version mismatch
Symptom: “The Music Assistant server is not the correct version” in Home Assistant.
Fix: HA was too old. Updated Home Assistant to 2026.1.3 (backup created first). That pulled a newer music-assistant-client that matches MA’s API schema.
This is one of those “silent mismatch” failures—you can hit the MA UI fine, but the HA integration refuses to bind.
2) MA ↔ HA link 404 during OAuth callback
Symptom: Browser redirected to http://<DOCKERVM_LAN_IP>:8095/auth/external/callback with 404.
Root cause: I entered the Music Assistant URL instead of the Home Assistant URL during linking.
Fix: Use HA URL in MA’s prompt (e.g. http://<HOME_ASSISTANT_LAN_IP>:8123).
3) Nextcloud “Access through untrusted domain”
Symptom: Nextcloud refused access via https://<TAILSCALE_HOST>:8081.
Fix: Add Tailscale domain and IP to trusted_domains in config.php, then restart Nextcloud.
In practice, I also add LAN IP + hostname variants to avoid future “why is this blocked” surprises.
4) Nextcloud data directory “readable by other people”
Symptom: Nextcloud install blocked due to permissive CIFS mount permissions.
Fix: Update /etc/fstab to include file_mode=0660,dir_mode=0770 and remount.
This is a CIFS quirk: chmod inside the mount won’t fix it. The mode comes from mount options.
Also required:
systemctl daemon-reloadafter fstab edits.- If remount complained “device busy,” unmount first:
umount -f /mnt/mediathenmount /mnt/media.
5) Tailscale Serve stole my Docker ports
Symptom: Containers started but ports were dead locally; Docker logs showed port binding errors.
Root cause: tailscale serve had already bound host ports like 3000, 8080, 8081, 5678.
Fix: Disable Serve on those ports before container start, then re-enable after Docker publishes ports. Also switched the startup script to use docker compose up -d --force-recreate so ports are always re‑published.
If Docker can’t bind a port at boot, the container may appear “up” but won’t actually be reachable. I now treat port conflicts as a first‑class boot concern.
6) Music Assistant + Tailscale Serve conflict
Symptom: MA uses host networking; Serve on 8095 conflicts with that port.
Fix: Proxy MA via Tailscale on 18095, which forwards to 127.0.0.1:8095.
That keeps MA’s host network intact while still giving me clean remote access.
🛠️ Commands That Saved Me
# Quick restart of the Nextcloud stack
docker compose --env-file /opt/nextcloud/.env -f /opt/nextcloud/docker-compose.yml up -d
# Disable/enable Tailscale Serve ports
tailscale serve --https=8081 off
tailscale serve --bg --https=8081 --yes https+insecure://127.0.0.1:8081
# Verify Nextcloud data perms
stat -c "%a %n" /mnt/media/NextCloud
I keep these in my runbook now because I hit the same pitfalls more than once.
✅ Current Access Points
- Music Assistant (LAN):
http://<DOCKERVM_LAN_IP>:8095 - Music Assistant (Tailscale):
https://<TAILSCALE_HOST>:18095 - Nextcloud (LAN):
https://<DOCKERVM_LAN_IP>:8081 - Nextcloud (Tailscale):
https://<TAILSCALE_HOST>:8081
🔜 Next Up
- Finish Nextcloud setup wizard and enable Redis file locking.
- Add MA + Nextcloud widgets to Homepage.
- Optional: move MA off host network and into a dedicated port map if needed.
✅ Pro Tip: Make Reboots Boring
After a VM reboot, services may start in the wrong order. The fix is a boot automation script that:
- waits for Docker
- ensures
/mnt/mediais mounted and responsive - disables Tailscale Serve temporarily (so Docker can bind ports)
- uses
docker compose up -d --force-recreateto restore port publishing - re‑enables Serve after everything is up
This single change turned “every reboot is a fire drill” into “everything just comes back.”
🔗 References
- Music Assistant documentation
- Home Assistant: Music Assistant integration
- LinuxServer Nextcloud image
- Nextcloud trusted domains
- Nextcloud reverse proxy guidance
- Tailscale Serve docs
- Docker Compose reference
- mount.cifs manual
🧠 Meta Description
Today’s homelab sprint added Nextcloud and Music Assistant on Docker with Tailscale access, plus a full list of real-world gotchas and fixes: version mismatches, untrusted domains, CIFS permissions, and port conflicts.