Swing Music on Ubuntu 24.04 on Azure User Guide
Overview
Swing Music is a beautiful, self-hosted music streaming server and player for your own local audio files — like a private Spotify for a collection you actually own. Point it at a folder of music and it scans your tracks, reads their tags and cover art, groups everything into albums and artists, and streams it to a polished multi-user web player with playlists, favourites, listening statistics and a mobile-friendly interface. Your library and your listening habits stay on infrastructure you control.
The Swing Music server is a single self-contained binary that serves both the REST API and the bundled web client, using embedded SQLite databases — no external database or runtime interpreter is required. It runs behind nginx as a reverse proxy on port 80; the server itself listens on 127.0.0.1:1970 and binds to the loopback interface only.
On the first boot of every deployed VM, a one-shot service starts the server, creates the sole administrator account with a per-instance password (Swing Music ships with no baked-in default — the first account created becomes the admin), regenerates a fresh per-instance server key, and writes the login to /root/swing-music-credentials.txt with mode 0600. nginx is held back until that bootstrap has finished, so port 80 never answers before the administrator exists. Two VMs deployed from the same image never share credentials, and the upstream default admin / admin login never works.

What is included:
- Swing Music 3.0.0 server (single self-contained binary, bundles the web client, embedded SQLite) at
/opt/swingmusic/swingmusic - nginx reverse proxy on
:80(tuned for streaming) in front of the Swing Music server on loopback:1970 - ffmpeg for audio transcoding, and the configuration and SQLite databases under
/var/lib/swingmusic - Per-VM administrator password generated at first boot, in a root-only file — no default login ships in the image
swingmusic.service,nginx.serviceand a one-shotswing-music-firstboot.serviceas systemd units- The complete, unmodified upstream AGPL-3.0 source for the shipped version on disk under
/opt/swingmusic/SOURCE - A fully patched Ubuntu 24.04 LTS security baseline at capture time, with unattended security updates enabled
- 24/7 cloudimg support
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a good starting point — Swing Music is lightweight; scale up for very large libraries or many concurrent listeners. You will also want a data disk or generous OS disk for your music. NSG inbound: allow 22/tcp from your management network and 80/tcp (plus 443/tcp once you enable HTTPS) from the networks your listeners will reach Swing Music on.
Step 1 — Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Swing Music 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 → Create. First boot initialisation takes a few seconds after the VM starts.
Step 2 — Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name swing-music \
--image <marketplace-image-urn> \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name swing-music --port 80 --priority 1010
Step 3 — Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4 — Verify the Swing Music stack
Confirm the services are active and that the web app answers through nginx:
systemctl is-active swingmusic nginx
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/
Both service lines read active and the web app returns 200.
Confirm the Swing Music server binds to loopback only, with nginx the sole public listener:
sudo ss -tlnp | grep -E ':80 |:1970 '
Port 80 (nginx) listens on all interfaces; port 1970 (Swing Music) is bound to 127.0.0.1 only.

Step 5 — Retrieve your administrator login
The administrator login generated on the first boot of your VM is stored in a root-only file. It lists the Swing Music URL, the administrator username (admin) and the password:
sudo cat /root/swing-music-credentials.txt
Store the password in your password manager and treat the file as sensitive. You can change it at any time from the web app (top-right profile → account settings), or from the command line with Swing Music's own reset tool:
printf 'admin\n' | sudo -u swingmusic /opt/swingmusic/swingmusic --password-reset --config /var/lib/swingmusic

Step 6 — Verify authentication
The login API issues a JWT access token for the generated administrator password, and rejects the upstream default admin / admin. The first request returns a token; the second reports HTTP 401:
PASS=$(sudo grep '^swingmusic.admin.pass=' /root/swing-music-credentials.txt | cut -d= -f2-)
curl -s -X POST http://127.0.0.1/auth/login -H 'Content-Type: application/json' -d "{\"username\":\"admin\",\"password\":\"$PASS\"}" | jq -r '.accesstoken' | cut -c1-24
curl -s -o /dev/null -w '%{http_code}\n' -X POST http://127.0.0.1/auth/login -H 'Content-Type: application/json' -d '{"username":"admin","password":"admin"}'
The first line prints the start of a valid token; the second prints 401, proving the shipped image has no working default credential.

Step 7 — First sign-in to the web app
Open a web browser and navigate to http://<vm-public-ip>/. Sign in with the username admin and the password from /root/swing-music-credentials.txt. The web app opens on the Home page, from which you can browse your library, folders, favourites, playlists and listening statistics.

Step 8 — Add your music folder
Swing Music streams music you already own. Upload or copy your audio files onto the VM (for example under /srv/music), make sure the swingmusic service user can read them, then register the folder so Swing Music scans it. In the web app open the profile menu → Settings → Folders, add the path, and Swing Music indexes it immediately — reading tags and cover art and grouping tracks into albums and artists.
You can also register a folder over the API with your admin token, then trigger a scan:
TOKEN=$(sudo grep '^swingmusic.admin.pass=' /root/swing-music-credentials.txt | cut -d= -f2- | { read P; curl -s -X POST http://127.0.0.1/auth/login -H 'Content-Type: application/json' -d "{\"username\":\"admin\",\"password\":\"$P\"}" | jq -r '.accesstoken'; })
curl -s -X POST http://127.0.0.1/notsettings/add-root-dirs -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -d '{"new_dirs":["/srv/music"],"removed":[]}' | jq -r '.root_dirs[]?'
curl -s "http://127.0.0.1/notsettings/trigger-scan" -H "Authorization: Bearer $TOKEN" | jq -r '.msg'
The first command lists your registered root directories; the scan responds Scan triggered!. Refresh the Albums view and your library appears.
Step 9 — Browse and play your music
Open Albums (or Artists, Folders or Playlists) to browse your collection. Swing Music extracts each album's cover art and themes the page around its colours. Select an album to see its track list, then press Play on any track — the player controls at the bottom of the window show the current track, artwork and a seek bar, and streaming begins immediately.


Step 10 — Add more users
Swing Music is multi-user: each account gets its own playlists, favourites and listening statistics. As the administrator, open the profile menu → Settings → Users to create additional accounts, or create a read-only guest account for shared listening. Every new user signs in at the same URL with their own credentials.
Security baseline
The image is captured with the Ubuntu 24.04 security baseline fully applied (including phased updates) and ships with unattended security upgrades enabled, so your VM keeps patching itself after deployment:
cat /etc/apt/apt.conf.d/20auto-upgrades
systemctl is-enabled unattended-upgrades || true
The Swing Music server binds to loopback only and nginx is the single public listener. The shipped image contains no database and no user account, and nginx is gated on the first-boot marker so port 80 never answers before the per-VM administrator has been created:
ls -la /opt/swingmusic/SOURCE/
grep ConditionPathExists /etc/systemd/system/nginx.service.d/*.conf

Enabling HTTPS
For production use, serve Swing Music over HTTPS so that logins and streaming are encrypted in transit. Point a DNS A record at the VM's public IP address, then install a certificate with Certbot (replace the domain):
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.com
After enabling HTTPS, open 443/tcp in the NSG and restrict or close inbound port 80.
Backup and maintenance
All Swing Music state lives under /var/lib/swingmusic/swingmusic — the SQLite databases (users, library index, playlists, favourites, settings) and the per-instance server key. The simplest logical backup is to copy that directory while the service is stopped, or snapshot the OS disk:
sudo systemctl stop swingmusic
sudo tar czf /var/backups/swingmusic-$(date +%F).tar.gz -C /var/lib/swingmusic swingmusic
sudo systemctl start swingmusic
Apply operating system security updates with sudo apt update && sudo apt upgrade; the services restart cleanly. Restart the server at any time with sudo systemctl restart swingmusic.
Licence and source
Swing Music is free software licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). In compliance with the licence, the complete, unmodified upstream source for the exact version shipped in this image is placed on disk at /opt/swingmusic/SOURCE/swingmusic-v3.0.0-source.tar.gz, with a NOTICE pointing to it and to the upstream repository. cloudimg makes no modifications to the Swing Music program itself.
Support
This image is backed by 24/7 cloudimg support. Contact us by email and chat for deployment help, library and folder configuration, TLS termination and multi-user setup.
All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.