Ma
Media & Entertainment Azure

Music Assistant on Ubuntu 24.04 LTS on Azure

| Product: Music Assistant on Ubuntu 24.04 LTS

Overview

Music Assistant is a free, open source media library manager. It connects your streaming services — Spotify, Tidal, Qobuz, YouTube Music, Deezer and more — together with your local music files into a single, unified library, and streams it to a wide range of connected speakers, all from a rich web interface built with automation and multi room audio in mind.

The cloudimg image runs Music Assistant 2.9.9 from its official container image, orchestrated with Docker Compose behind nginx on a hardened, fully patched Ubuntu 24.04 LTS base.

The image is deliberately shipped unprovisioned, with no users and no secrets. Music Assistant's first time setup is unauthenticated: when its user database is empty, the server runs in setup mode and the first person to reach it creates the administrator account. So on the first boot of every VM a one shot service brings Music Assistant up on the loopback interface, creates a single administrator account with a random password written to a root only file, and confirms a second setup attempt is refused. Until that finishes, nothing is published on port 80 — so no instance is ever reachable from the network in an unprovisioned state where a passer by could claim the admin account, and no secret is ever shared between customers. Backed by 24/7 cloudimg support.

What is included:

  • Music Assistant 2.9.9 served through nginx, orchestrated by Docker Compose and managed by systemd
  • The Music Assistant web interface on :80, requiring an administrator sign in
  • The container bound to 127.0.0.1 only, so nginx on port 80 is the sole network facing service
  • A per VM administrator account created on first boot and recorded in a root only file
  • Nothing bound to port 80 until first boot has provisioned and secured the instance
  • docker.service and music-assistant.service as enabled systemd units so the stack returns after a reboot
  • 24/7 cloudimg support

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) runs Music Assistant comfortably for a personal library; size up to a memory larger VM if you connect many providers, scan a large local library, or want optional features such as Smart Fades that ask for more RAM. NSG inbound: allow 22/tcp from your management network and 80/tcp (plus 443/tcp once you terminate TLS on the VM) so your browser can reach Music Assistant.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Music Assistant by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTP (80). Then Review + create and Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name music-assistant \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Then open port 80 so your browser can reach Music Assistant:

az vm open-port --resource-group <your-rg> --name music-assistant --port 80

Step 3 - Confirm the services are running

SSH in as azureuser. First boot pulls no images (the container image is already in the image) and completes in well under a minute; once it has, nginx binds port 80 and Music Assistant is ready.

systemctl is-active docker music-assistant
ss -tlnp 2>/dev/null | grep ':80 ' | head -1 | sed 's/  */ /g' | cut -d' ' -f1-4

Confirm the container is up and which version is running:

sudo docker compose -f /opt/music-assistant/docker-compose.yml ps --format 'table {{.Service}}\t{{.Image}}\t{{.Status}}'

The docker and music-assistant systemd units reporting active, nginx bound to port 80, and the Music Assistant container up with its pinned 2.9.9 image reporting the running server version

If port 80 is not bound, first boot has not completed. That is deliberate and fail closed: Music Assistant is never published before it has been provisioned and secured. Check with systemctl status music-assistant-firstboot.service and journalctl -u music-assistant-firstboot.service.

Step 4 - Retrieve this VM's administrator credentials

Every VM creates its own administrator on first boot and writes the username and password, with the sign in address, to a root only credentials file:

sudo cat /root/music-assistant-credentials.txt

Because a real administrator now exists, Music Assistant's unauthenticated first time setup is closed — a second setup attempt is refused, so no one who reaches the instance after first boot can create an admin:

curl -s -o /dev/null -w 'second POST /setup -> HTTP %{http_code}\n' -X POST -H 'Content-Type: application/json' -d '{"username":"intruder","password":"attacker-password-123"}' http://127.0.0.1/setup

An HTTP 400 (setup already completed) is exactly what you want to see.

The credentials file reported at mode 600 owned by root with the password masked, and a second setup attempt refused with HTTP 400, confirming no post boot admin takeover is possible

You can prove the generated password really authenticates, straight from the command line. Music Assistant accepts a JSON login, so the correct password is issued a token while a wrong one is rejected:

U=$(sudo grep '^musicassistant.admin.username=' /root/music-assistant-credentials.txt | cut -d= -f2-); P=$(sudo grep '^musicassistant.admin.pass=' /root/music-assistant-credentials.txt | cut -d= -f2-); curl -s -o /dev/null -w 'correct password -> HTTP %{http_code}\n' -H 'Content-Type: application/json' -X POST -d "{\"provider_id\":\"builtin\",\"credentials\":{\"username\":\"$U\",\"password\":\"$P\"}}" http://127.0.0.1/auth/login; curl -s -o /dev/null -w 'wrong password   -> HTTP %{http_code}\n' -H 'Content-Type: application/json' -X POST -d "{\"provider_id\":\"builtin\",\"credentials\":{\"username\":\"$U\",\"password\":\"WRONG-password\"}}" http://127.0.0.1/auth/login

A 200 for the correct password and a 401 for the wrong one is exactly what you want to see.

The correct per VM administrator password authenticating to the login endpoint with HTTP 200 and a token issued, and a wrong password rejected with HTTP 401

Step 5 - Sign in to Music Assistant

Browse to http://<vm-public-ip>/. Music Assistant opens on its sign in screen — there is no open setup wizard, because your administrator was already created on first boot. Enter the musicassistant.admin.username and musicassistant.admin.pass values from Step 4.

The Music Assistant sign in page, protected by the administrator account generated on this VM's first boot

Change the password from Settings after your first sign in, and add any further users deliberately rather than leaving open registration on.

Step 6 - Connect your music and get started

After signing in, Music Assistant welcomes you and points you at the two things that make it useful: connecting your music sources and your players. The full library navigation — Discover, Search, Browse, Artists, Albums, Tracks, Playlists, Podcasts and more — is on the left, ready to fill as you add sources.

The Music Assistant home with the getting started panel inviting you to connect music sources and players, the full library navigation on the left, and the built in web player in the footer

Open Settings → Music sources → Add a music source to connect a streaming service or your local files. Music Assistant ships integrations for Spotify, Tidal, Qobuz, YouTube Music, Deezer, a local filesystem provider and more; pick one and follow its sign in.

The Add a music source catalogue listing streaming providers including Spotify, Tidal and Qobuz alongside a local filesystem provider

Streaming providers that use an OAuth sign in redirect back to Music Assistant, so if you connect one of those, set your instance's reachable address (your public IP or, better, a DNS name behind HTTPS) in Settings → Core → Web server first, so the redirect returns to the right place. Local files and token based providers work without this.

Step 7 - Add and control your players

Music Assistant streams to a wide range of devices. Under Settings → Players it ships providers for AirPlay, Chromecast, DLNA, Sonos, a synchronised group player and locally attached audio out, plus its own built in web player so you can listen from the browser straight away. Providers that discover devices on your local network (Chromecast, DLNA) show a reconfigure prompt until you point them at a network they can reach.

The Music Assistant player providers page listing AirPlay, Chromecast, DLNA, a local audio output, a synchronised group player and more, each ready to configure

Step 8 - Check persistence and the image pin

The stack is enabled to return after a reboot, and the container image is pinned so your instance is reproducible. Unattended security upgrades keep the base operating system patched:

systemctl is-enabled docker nginx music-assistant-firstboot music-assistant
systemctl is-enabled unattended-upgrades
sudo docker image ls --format '{{.Repository}}:{{.Tag}}' | grep music-assistant

The docker, nginx, first boot and music-assistant units all enabled, unattended-upgrades enabled, and the pinned Music Assistant container image

Step 9 - Enable HTTPS with Let's Encrypt

Put Music Assistant behind HTTPS before exposing it to the internet, so your credentials are encrypted in transit. Point a DNS record at the VM, then install a certificate. The bundled nginx proxies to Music Assistant on the loopback interface, so certbot's nginx integration terminates TLS in front of it:

sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d music.example.com

After issuing the certificate, set your instance's public address in Settings → Core → Web server to the https:// host name, make sure 443/tcp is open in the NSG, and reconnect any OAuth based providers so their redirects use the new address.

Step 10 - Back up and maintain your VM

Everything Music Assistant stores — its user accounts, library, provider configuration and settings — lives under /opt/music-assistant/data, so archiving that directory is a complete backup:

sudo systemctl stop music-assistant
sudo tar czf music-assistant-data-backup.tar.gz -C /opt/music-assistant data
sudo systemctl start music-assistant

Store the backup somewhere safe. Unattended security upgrades keep the operating system patched, and Azure Backup or managed disk snapshots give you whole VM recovery.

Security notes

  • No shared secret ships in the image. The image contains no users and no secrets. The administrator account is generated on the first boot of your VM.
  • The first setup cannot claim your instance. Music Assistant's unauthenticated first time setup creates the administrator; because first boot creates a real administrator before the app is reachable, and a second setup attempt is then refused, no passer by can register the admin account.
  • Nothing is published before it is secured. In the shipped image nothing is bound to port 80. The public site is enabled only after first boot has provisioned and secured Music Assistant, so an unprovisioned instance is never exposed to the network.
  • Fail closed. If first boot cannot complete, port 80 is never bound at all.
  • Put Music Assistant behind HTTPS before real traffic, and restrict 22/tcp to your management network.
  • The application is not exposed directly. The Music Assistant container binds 127.0.0.1 only; nginx on port 80 is the sole network facing service.

Architecture summary

Component Detail
Application Music Assistant 2.9.9 (Apache-2.0), ghcr.io/music-assistant/server:2.9.9
Orchestration Docker Compose at /opt/music-assistant, managed by music-assistant.service
Web server nginx reverse proxy on :80 to the loopback bound Music Assistant container (WebSocket aware)
Data /opt/music-assistant/data (user DB, library, provider config), in-VM only
Credentials /root/music-assistant-credentials.txt, mode 0600, root only
First boot music-assistant-firstboot.service, sentinel /var/lib/cloudimg/music-assistant-firstboot.done
Ports 22/tcp SSH, 80/tcp Music Assistant interface, 443/tcp once TLS is configured
Base image Ubuntu 24.04 LTS, fully patched, unattended security upgrades enabled

Support

cloudimg images come with 24/7 support. Email support@cloudimg.co.uk with your Azure subscription ID and the VM name. For Music Assistant itself, see the Music Assistant project and its documentation.