LibreTime on Ubuntu 24.04 on Azure User Guide
Overview
This guide covers the deployment and configuration of LibreTime on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. LibreTime is an open source, self hosted platform for running an internet or community radio station. It gives you a browser based studio where you upload and organise an audio library, build playlists and smart blocks, and lay shows out on a scheduling calendar, then it plays your programming out automatically and streams it live to listeners through a built in Icecast server. It is the community maintained successor to Airtime.
The cloudimg image ships the free and open source, AGPL-3.0 licensed LibreTime, run the officially supported way as the upstream container stack pinned to version 4.5.0: PostgreSQL, RabbitMQ, the Icecast streaming server, the Liquidsoap playout engine and the LibreTime analyzer, worker, playout, API and legacy web services, fronted by nginx on port 80. All images are captured into the VM, so your instance starts without pulling anything. Because the upstream project seeds a single default admin / admin account and default service passwords, nothing here ships with a known credential: every service password, the Django secret key and the internal API key are generated per VM on first boot, and the default administrator login is rotated to a random per instance password before the web interface is ever started. Backed by 24/7 cloudimg support.
LibreTime is a trademark of its respective owners. This image is produced by cloudimg and is not affiliated with, endorsed by, or sponsored by the LibreTime project. It ships the free and open source AGPL-3.0 licensed self hosted software, unmodified.

What is included:
- LibreTime 4.5.0 (the AGPL-3.0 licensed radio broadcast automation platform), run as the official upstream containers
- PostgreSQL 15, RabbitMQ 3.13 and the LibreTime API, worker, analyzer, playout and legacy web services
- A built in Icecast 2.4.4 streaming server on port
8000and a Liquidsoap playout engine with live input harbours on ports8001and8002 - Docker Engine with every service on a private network, fronted by nginx on port
80as the single web front door docker.service,libretime-firstboot.serviceandlibretime.serviceas systemd units, enabled and active on boot- Per VM PostgreSQL, RabbitMQ and Icecast passwords, a per VM Django secret key and internal API key, all generated on first boot and never baked into the image
- The vendor default
admin/adminlogin rotated to a random per instance password before the web interface is reachable, written to a root only file - A fresh, empty database and media library created on first boot
- Ubuntu 24.04 LTS base with latest security patches applied at build time
- Azure Linux Agent for seamless cloud integration and SSH key injection
- 24/7 cloudimg support with guaranteed 24 hour response SLA
Prerequisites
- Active Azure subscription, SSH public key, VNet + subnet in target region
- Subscription to the LibreTime listing on Azure Marketplace
Recommended virtual machine size: Standard_B2ms (2 vCPU, 8 GB RAM) is the recommended starting point, because the full stack runs ten services. For a busy station with a large library and many listeners use Standard_D2s_v5 or larger. NSG inbound: allow 22/tcp from your management network, 80/tcp for the web interface, 8000/tcp for the public Icecast stream, and optionally 8001/tcp and 8002/tcp if you will connect a live source such as a DJ client.
Step 1: Deploy from the Azure Portal
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for LibreTime by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size (Standard_B2ms or larger); under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTP (80), and add 8000 for the stream. Then Review + create and Create.
Step 2: Deploy from the Azure CLI
RG="libretime-prod"; LOCATION="eastus"; VM_NAME="libretime-01"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/libretime-ubuntu-24-04/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az network vnet create -g "$RG" --name lt-vnet --address-prefix 10.100.0.0/16 --subnet-name lt-subnet --subnet-prefix 10.100.1.0/24
az network nsg create -g "$RG" --name lt-nsg
az network nsg rule create -g "$RG" --nsg-name lt-nsg --name allow-ssh --priority 100 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp
az network nsg rule create -g "$RG" --nsg-name lt-nsg --name allow-web --priority 110 \
--destination-port-ranges 80 8000 --access Allow --protocol Tcp
az vm create -g "$RG" --name "$VM_NAME" --image "$GALLERY_IMAGE_ID" \
--size Standard_B2ms --storage-sku StandardSSD_LRS \
--admin-username azureuser --ssh-key-values "$SSH_KEY" \
--vnet-name lt-vnet --subnet lt-subnet --nsg lt-nsg --public-ip-sku Standard
Step 3: Connect to your VM
ssh azureuser@<vm-ip>
Step 4: Confirm the services are running
LibreTime runs as ten containers under one libretime.service, brought up after libretime-firstboot.service has prepared the per VM secrets and database. Confirm the systemd units are active:
sudo systemctl is-active docker libretime-firstboot libretime
All three report active. You can list the containers, each on the private libretime network with nginx on :80 as the single public front door:
sudo docker compose --env-file /etc/libretime/libretime.env -f /etc/libretime/compose.yaml ps
Step 5: Read the per instance credentials
Every service password, the Django secret key and the internal API key were generated for this VM on the first boot, and the default admin / admin login was rotated to a random per instance password before the web interface was started. They are written to a root only file:
sudo cat /root/libretime-credentials.txt
The file (mode 0600 root:root) holds ADMIN_USERNAME and ADMIN_PASSWORD (the account you sign in to the web interface with), the WEB_URL and ICECAST_STREAM_URL, and the per VM PostgreSQL, RabbitMQ, Icecast and API secrets. None of these ship in the image; every value is unique to this VM, so no two instances share a credential and there is no default login to change.

Step 6: Verify the security model
The web interface presents a login page, but the vendor default admin / admin account does not exist: it was rotated to the random per instance password in Step 5 before nginx ever served a request. Confirm that the login page and API are live, that the per instance admin password authenticates through the real login form, and that the default credential is rejected. The image bundles this exact round trip as a single script, which the build and smoke tests run to prove the credential works end to end:
sudo /usr/local/sbin/libretime-roundtrip.sh
It reports OK: the web interface, the API and the Icecast server are live; the per instance admin logs in (an HTTP 302 redirect to the studio); the default admin / admin login is rejected; and the database confirms the default credential hash is gone.

Step 7: Open the web interface and sign in
Browse to http://<vm-ip>/ to reach LibreTime. Sign in with the ADMIN_USERNAME (admin) and the ADMIN_PASSWORD from Step 5.

Step 8: Explore the studio and library
After signing in you land on the Now Playing studio. The left panel is your audio library of tracks, playlists and smart blocks; the right panel is the schedule timeline. The top bar shows what is currently on air and lets you drive live sources. Upload audio with the Upload button (top left), then organise it into playlists and smart blocks.

Step 9: Work with the media library over the API
Every feature is backed by a REST API, authenticated with the per VM API key. Read the key from the credentials file and list your library and the Icecast server, all through the front door on the VM itself:
API_KEY=$(sudo grep '^API_KEY=' /root/libretime-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'API version : HTTP %{http_code}\n' http://127.0.0.1/api/v2/version
curl -s -o /dev/null -w 'library (key) : HTTP %{http_code}\n' -H "Authorization: Api-Key $API_KEY" http://127.0.0.1/api/v2/files
curl -s -o /dev/null -w 'library (nokey): HTTP %{http_code}\n' http://127.0.0.1/api/v2/files
curl -s -o /dev/null -w 'Icecast :8000 : HTTP %{http_code}\n' http://127.0.0.1:8000/
The version endpoint is public, the library requires the API key (an unauthenticated request is rejected), and the Icecast streaming server answers on 8000. A fresh VM starts with an empty library; upload your own audio through the Upload button in the studio.

Step 10: Schedule a show
Open Calendar and choose New Show to schedule programming. Give the show a name, genre and description, set when it starts and how long it runs, and optionally make it repeat. Once a show exists, drag tracks, playlists or smart blocks onto it in the studio and LibreTime plays it out automatically at the scheduled time.

Step 11: Configure streaming
LibreTime broadcasts through the built in Icecast server. Open Settings > Streams to review and adjust the output: the stream label, the Icecast host, port, mount, format and bitrate. The image ships one Icecast output enabled, streaming OGG at 256 kbps, and reports Connected to the streaming server once playout starts. Listeners tune in at http://<vm-ip>:8000/main.

Step 12: Server components
| Component | Version / Detail |
|---|---|
| Platform | LibreTime 4.5.0 (AGPL-3.0), official upstream containers |
| Web + API | LibreTime legacy (PHP) and API (Django) fronted by nginx on :80 |
| Database | PostgreSQL 15 (created fresh on first boot) |
| Message queue | RabbitMQ 3.13 |
| Playout | Liquidsoap playout engine, live input harbours on :8001 / :8002 |
| Streaming | Icecast 2.4.4 on :8000 (OGG 256 kbps output) |
| Orchestration | Docker Compose under libretime.service |
| Service secrets | per instance, generated first boot into /etc/libretime/libretime.env and config.yml |
| Admin account | vendor default rotated to a per instance random password in /root/libretime-credentials.txt |
| Operating system | Ubuntu 24.04 LTS (patched at build) |
| License | AGPL-3.0 (LibreTime) |
Step 13: Managing the service
Check the units and configuration at any time:
sudo systemctl is-active docker libretime
The stack configuration lives in /etc/libretime/config.yml and /etc/libretime/compose.yaml, and the per VM secrets in /etc/libretime/libretime.env (root only). To restart the whole stack after a configuration change, run sudo systemctl restart libretime. Because libretime.service runs docker compose up, individual containers are managed with docker compose against /etc/libretime/compose.yaml.
Step 14: Use your own domain and HTTPS (production)
The image serves the web interface over plain HTTP on port 80. For production you should terminate TLS in front of the VM so the admin password travels encrypted:
- Front the VM with Azure Application Gateway, a load balancer with a managed certificate, or a CDN, and forward to nginx on port
80. - Point a DNS name you control at the VM public IP. Because LibreTime resolves its public URL at first boot from the reachable public address, use a stable public IP or set the address before first boot when using a custom domain.
- The public radio stream is served by Icecast on port
8000; front it separately or expose it directly to your listeners.
Step 15: Security recommendations
- Restrict the NSG. Allow TCP 80 and 8000 only from the networks that need them, and 22 only from your management network. Open 8001 and 8002 only if you connect a live source.
- Terminate TLS in front of the app (Step 14) so the admin password is encrypted in transit.
- Rotate the seeded admin password. Sign in and change it under the username menu, and create individual accounts for your team under Settings > Users.
- Keep the services private. PostgreSQL, RabbitMQ and the application services run on a private container network; only nginx on
:80, Icecast on:8000and the harbours on:8001/:8002are published. Keep it that way. - Keep the OS patched. Unattended security upgrades remain enabled on the running VM.
Step 16: Support and Licensing
LibreTime is distributed under the GNU Affero General Public License v3 (AGPL-3.0). This cloudimg image bundles the unmodified official open source release; cloudimg provides the packaging, the single nginx front door, the per instance secret generation and default admin rotation, the paired deploy guide, and 24/7 support with a guaranteed 24 hour response SLA. LibreTime is an independent open source project and this image is not affiliated with or endorsed by it.
Deploy on Azure
Launch LibreTime on Ubuntu 24.04 LTS by cloudimg from the Azure Marketplace and follow this guide to a working radio automation station in minutes.