LibreTime: running your own small radio station as a set of containers
LibreTime: Radio Broadcast & Automation Platform
At a glance
- What is it?
- LibreTime is a community managed fork of Sourcefabric's AirTime that schedules and plays out radio programming, built as a Docker Compose stack of Postgres, RabbitMQ, a playout service, Liquidsoap and an analyzer. The PHP legacy application still sits at the centre, and the licence is AGPL-3.0.
- Who is it for?
- LibreTime fits a small station, a community radio project or a school workshop that needs a real playout clock rather than a media server playlist, and it fits teams willing to run Postgres, RabbitMQ and a Liquidsoap container. Skip it if you only need scheduled file playback, since a plain media player with a cron job does the same thing with none of this.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What a station actually needs beyond a media player
A media player can play a playlist. A radio station needs more than that: a schedule that a person edits days ahead, a playout process that reads the current time, picks the right item at the right moment, transitions between tracks, and keeps going when the person editing the schedule is asleep. LibreTime exists to be that layer. The README describes it as making it easy to run your own online or terrestrial radio station, and it is a community managed fork of the AirTime project, which was originally built by Sourcefabric. The copyright headers in the repository make the lineage explicit, with Sourcefabric z.ú. holding 2011 to 2017 and the LibreTime community holding 2017 to 2023, and a LEGACY.md file carrying the earlier history. The audience is station staff and hobbyist broadcasters, not developers building a media product: they want a scheduling calendar, a playlist, a stream output and a way to check what actually went out over the air.
Five services that talk through RabbitMQ
The docker-compose.yml file is the clearest view of the architecture, and it defines five services. Postgres 17 holds the schedule and the media records, with a healthcheck running pg_isready:
postgres:
image: postgres:17
environment:
POSTGRES_USER: ${POSTGRES_USER:-libretime}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-libretime} # Change me !
healthcheck:
test: pg_isready -U libretimeRabbitMQ 4.2 on Alpine handles messaging between components, and it carries the environment defaults for a vhost and credentials, with a healthcheck that checks port 5672 is open. The playout service is the process that reads the schedule and plays audio, and the liquidsoap service runs the same image but with the command overridden to /usr/local/bin/libretime-liquidsoap, exposing ports 8001 and 8002. The analyzer service uses its own image, ghcr.io/libretime/libretime-analyzer, and the README does not describe what it analyses, so it is best treated as a component to inspect rather than a feature to promise. Every service that talks to the database or the queue mounts the same configuration file, read only, and the playout and Liquidsoap services receive LIBRETIME_GENERAL_PUBLIC_URL pointing at http://nginx:8080.
The PHP application and the new Python services in one tree
The repository layout is the story of a gradual rewrite. The legacy/ directory holds the original PHP AirTime application, and the Makefile still has a target that builds it inside a container, so it is live code, not an archive. Alongside it sit api/ and api-client/, both Python packages that the Dockerfile turns into wheels, and analyzer/, playout/ and shared/ as separate components with their own build steps. The Dockerfile works in stages: a python-builder stage on python:3.11-slim-bookworm that wheels shared and api-client, a python-base stage with a dedicated unprivileged libretime user and UID 1000, and a system package list generated from shared/packages.ini through tools/packages.py. The configuration file path is fixed in the image through the environment variable LIBRETIME_CONFIG_FILEPATH=/etc/libretime/config.yml, and the compose file mounts your config.yml onto that path. The Python base image sets PYTHONDONTWRITEBYTECODE=1 and PYTHONUNBUFFERED=1, so container logs are unbuffered and readable as they happen:
FROM python:3.11-slim-bookworm AS python-base
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1Bringing up a development instance with generated certificates
The Makefile has a dev target that assumes Docker Compose and prepares two things first. The .env target copies .env.dev to .env, and the dev-certs target removes any stale dev/certs/fake.* files and generates a self signed certificate for localhost with openssl, writing a key, a certificate and a combined .pem. The commands then build the images with BuildKit, build the PHP legacy application inside a container, run the database migration through the api service with the libretime-api migrate command, and bring the stack up detached. The migration step is the one to pay attention to. It means a fresh install is a scripted sequence, not a manual database setup, and that any upgrade path depends on migrations running cleanly against your existing data. For production there is a tarball target that assembles the release tree, excluding vendored directories, and produces a sha256sums.txt file so the artefact can be checked.
Community governance and where support actually goes
The README is explicit about how the project is run. LibreTime is managed by a community of stations around the globe that use, document and improve it, and the project asks contributors to agree to a Contributor Code of Conduct before taking part. The details of the development process live in CONTRIBUTING.md, and financial contributors are funded through OpenCollective. The support model is worth reading before you rely on it. The README says the project is moving towards using the forum for community support and reserving the GitHub issue queue for confirmed bugs and well formed feature requests, and it points to a Discourse forum at discourse.libretime.org plus a Matrix room at #libretime:matrix.org. In practice that means a question about your configuration is a forum question, not an issue, and a bug report needs to be reproducible enough to be treated as confirmed. There is also a SECURITY.md in the repository root and a separate security process referenced by it.
Limits worth knowing: the legacy layer, the node model and AGPL terms
Three constraints are visible rather than hidden. The first is the PHP legacy layer. The scheduling interface that most station staff use still lives in legacy/, and the Python api/ and api-client/ packages are a newer path that is not yet the whole product. That mixture is normal for a fork of an old codebase, but it means an upgrade can touch the PHP application, the Python services and the compose file at once, and it means contributors have to work in two languages. The second is the deployment shape: the compose file defines one Postgres, one RabbitMQ and one set of playout services, with no clustering or failover described anywhere, so this is a single site install with backups you arrange yourself rather than a multi node broadcast platform. The third is licensing. LibreTime is free software under the GNU Affero General Public License version 3, and the README spells out the two rights: redistribute and modify. For a station that runs the software as a service over a network, the AGPL terms carry obligations around publishing modifications, so a legal reading of LICENSE is needed before you fork it for a commercial or community deployment.
Release cadence and what an upgrade touches
The project is being worked on. The last push was on 2026-10-16, and the visible releases are 4.5.0 on 2025-07-16, 4.4.0 on 2025-05-29 and 4.3.0 on 2025-03-12, which is a sequence of minor releases spread over months rather than weeks. Note the gap between the release tags and the recent commits: if you are evaluating the project today, the main branch contains work that is newer than the newest tag, and the compose file pins images with the variable LIBRETIME_VERSION defaulting to latest, so an unpinned deployment drifts. The repository also carries docker-bake.json for multi image builds, a Vagrantfile and cloud-init.yml for provisioning a host, an api-client/ package for talking to the API from your own scripts, and a docs/ tree linted with Vale through the docs-lint target. The CHANGELOG.md in the root and the docs site at libretime.org/docs are where the upgrade notes live.
Editorial conclusion
LibreTime fits a small station, a community radio project or a school workshop that needs a real playout clock rather than a media server playlist, and it fits teams willing to run Postgres, RabbitMQ and a Liquidsoap container. Skip it if you only need scheduled file playback, since a plain media player with a cron job does the same thing with none of this. Before adopting, read the AGPL-3.0 terms in LICENSE with your legal reviewer, check the legacy/ directory in the release you plan to install because the PHP application is still the scheduling core, and test the playout and Liquidsoap services together on the target network path since the compose file publishes them on ports 8001 and 8002.
Frequently asked questions
What is LibreTime and what is its relationship to AirTime?
LibreTime is a community managed fork of the AirTime project, which was originally built by Sourcefabric. The README describes it as making it easy to run your own online or terrestrial radio station, and the copyright headers record Sourcefabric z.ú. for 2011 to 2017 and the LibreTime community from 2017.
How do I run LibreTime locally for development?
The Makefile dev target copies .env.dev to .env, generates self signed certificates with the dev-certs target, builds the images with docker compose build, builds the legacy application, runs the database migration with the libretime-api migrate command and then brings the stack up with docker compose up -d.
Which services does the LibreTime Docker Compose stack run?
The compose file defines Postgres 17, RabbitMQ 4.2 on Alpine, a playout service, a liquidsoap service that runs the libretime-liquidsoap command on ports 8001 and 8002, and an analyzer service. Images come from ghcr.io/libretime and each service mounts a config file at /etc/libretime/config.yml.
What licence is LibreTime released under?
The GNU Affero General Public License version 3. The README states you can redistribute and modify LibreTime under those terms, and a legal review is advisable before modifying a network deployed installation.
Where should I ask LibreTime questions?
The README says the project is moving towards community support on the forum at discourse.libretime.org and reserving the GitHub issue queue for confirmed bugs and well formed feature requests. There is also a Matrix room at #libretime:matrix.org.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/libretime-libretime)Was this useful?