MediaCMS: A Self-Hosted Video and Media CMS on Django and React
MediaCMS is a modern, fully featured open source video and media CMS, written in Python/Django and React, featuring a REST API.
At a glance
- What is it?
- MediaCMS is an AGPL-3.0 video and media platform built on Django, Celery and React, aimed at universities, organisations with sensitive content and community portals. It is a full application, not a library, and the decision to adopt it turns on whether you want to own the transcoding pipeline and the storage bill.
- Who is it for?
- Adopt MediaCMS if you need a self-hosted portal with public, private and unlisted publishing, HLS playback, subtitles, playlists and an LMS hook, and you are willing to run PostgreSQL, Redis, Celery, Nginx, FFMPEG and Bento4 yourself. Do not adopt it if you only need to embed a handful of clips, or if AGPL-3.0 and the threefold disk multiplier are unacceptable.
- 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 received new commits within the last day.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem MediaCMS addresses: owning the media pipeline
Uploading a video to a third party service is easy until the content is not yours to hand over. The README names this case directly under example cases: organisation sensitive content, where material cannot be uploaded to external sites. The same section lists universities and schools, where administrators and editors decide what gets published and students are not shown advertisements, and personal portals where the owner organises and categorises their own library.
The README frames the project around three goals: deliver the functionality expected of a modern system, make installation and maintenance easy, and make customisation and feature addition easy. That third goal is what separates MediaCMS from a hosted video platform. URLs, logos, fonts and aesthetics are configurable, and the frontend is a React application sitting on a Django REST API, so a team can change the interface without forking a closed product. The intended operator is a small organisation with a server, not an individual who wants to paste an embed code into a blog post.
Architecture: Django, Celery, FFMPEG and a video.js player
The technology list in the README is the clearest description of the data flow: Python, Django, Django Rest Framework, Celery, PostgreSQL, Redis, Nginx, Gunicorn, React, Fine Uploader, video.js, FFMPEG and Bento4. Read as a pipeline, uploads arrive through the React frontend using chunked file uploads, which the README says support pausable and resumable transfer. Django and DRF own the media records and the API, documented through Swagger. Celery workers, queued through Redis, run the transcoding jobs against FFMPEG, with Bento4 in the stack for packaging. Nginx and Gunicorn serve the application, and video.js plays the result.
Transcoding is where the storage and CPU cost lives. The README lists defaults for 144p, 240p, 360p, 480p, 720p and 1080p, across h264, h265 and vp9 profiles, and states that adaptive streaming is possible through HLS. Transcoding is scalable through priorities, which implies a queue ordering mechanism rather than parallel unconstrained encoding. Automatic transcription runs through Whisper locally, and the README warns that supporting it means considering more CPUs. That is a design choice worth naming: transcription is not an external API call, so the compute sits on your hardware and in your queue alongside encoding jobs.
Publishing controls, permissions and the LMS integration
MediaCMS supports public, private, unlisted and custom publishing workflows, and layers role-based access control on top. The README describes RBAC categories connected to user groups with view and edit access on their media, and a separate media permissions document is linked from the docs list. User management can be self registration, invite only or closed, and individual actions such as download, comments, likes, dislikes and media reporting are configurable, which matters for an institution that wants playback without a social layer.
For education deployments, the README states LTI 1.3 support plus a Moodle plugin for embedding media in an LMS, with a dedicated docs/moodle_plugin.md page. SAML support is also listed, with mappings to system roles and groups. These are the features that make the project plausible for a university rather than a generic upload site, because identity and course integration are usually the blockers in that setting. The rest of the feature list is conventional but complete: categories, tags, playlists with reordering, multilingual subtitles, a video trimmer that can replace, save as new or create segments, light and dark themes, and translations for much of the interface.
Getting it running: Docker Compose or the automation script
The README gives two installation routes and points to docs/admins_docs.md for both. The first is Docker Compose, referenced as section 3 of the administrators documentation, with a linked blog post titled How to self-host and share your videos in 2021. The second is an automation script that installs and configures all needed services on a server. A Docker Hub image exists under the mediacms/mediacms repository, and the README also notes a one-click deployment on Elestio.
What the README does not give is a literal command sequence. It names the services rather than the compose file, so the actual invocation has to be read from docs/admins_docs.md rather than copied from this page. Configuration is likewise pointed at section 5 of the same document, covering logos, fonts, styling and additional pages. If you are evaluating the project, the honest first step is opening docs/admins_docs.md and checking whether the compose topology matches your host, because PostgreSQL, Redis, Celery workers, Nginx and Gunicorn all need to be accounted for before anything plays.
Hardware sizing and the threefold storage rule
The README is unusually direct about sizing, which is rare and useful. For a small to medium installation with a few hours of video uploaded daily and a few hundred active daily users, it suggests 4GB RAM and 2 to 4 CPUs as a minimum. For larger installations with many hours uploaded daily, it says to add more CPUs and RAM. Automatic transcription through Whisper is called out separately as a reason to add CPUs.
Disk is the number to plan around. The README states a general rule of multiplying expected uploaded video size by three, because the system keeps original versions, encoded versions and HLS. Its worked example: 1GB per day across a year implies roughly a 1TB disk. That multiplier is a direct consequence of the transcode-everything design, and it is the single figure most likely to be underestimated in a pilot. A team that tests with a handful of short clips will not see the problem; a team that imports an existing archive will.
Where MediaCMS is the wrong tool
The project is a full CMS with its own frontend, database and worker fleet. If the requirement is to host a few clips and embed them elsewhere, that stack is overhead with no matching benefit, and a simpler static hosting plus a player would do the job with less to patch. The README's own framing supports this: the example cases are portals, archives and community sites, not embed-only use.
The licence is the second boundary. MediaCMS is AGPL-3.0, and the README points to a services page offering custom installations, extra functionality, migration from existing systems, legacy integrations, training and support. AGPL-3.0 carries network-use obligations that differ from permissive licences, and how those apply to a modified deployment is a question for your own legal review, not something to settle from a README. The third boundary is operational: transcoding queues, Whisper transcription, Celery workers and Redis are components you now own. The README's goal of easy maintenance is a stated intention, and the linked administrators documentation is the place to test it. A team with no one willing to run PostgreSQL, Redis and FFMPEG should treat that as a disqualifier rather than a detail.
Alternatives and the difference in approach
The README names Elestio as a commercial hosting option with one-click deployment and a revenue share arrangement. That is not a different product so much as a different operating model: Elestio runs MediaCMS for you, which removes the server and upgrade work but keeps the same application, the same licence and the same storage multiplier. It is the reasonable path for a team that wants the feature set without the on-call rotation, and the wrong path for an organisation whose content cannot leave its own infrastructure, which is precisely the case the README lists as sensitive content.
PeerTube is the other obvious comparison, and the difference is architectural rather than cosmetic. PeerTube is built around federation between independent instances, so content can be discovered and mirrored across a network of hosts. MediaCMS is a single portal: users, groups, RBAC categories and LMS mappings live inside one installation, and the README's example cases describe one institution or community running one site. If your goal is to join a federated network of video hosts, MediaCMS is not designed for that. If your goal is a controlled portal with private and unlisted workflows, LTI 1.3 and a Moodle plugin, federation is not what you need.
Maintenance, releases and licence implications
The release history shows a steady cadence: v8.4.0 and v8.3.5 both dated 2026-08-25, and v8.3.4 on 2026-07-15, with the last push to the default branch on 2026-09-10. Two releases on the same day suggests a patch following a feature release, which is normal for an actively developed application. The repository is not archived. Upgrading means applying Django migrations, rebuilding the React frontend and restarting Celery workers, so the cost is not just pulling a new image; it is a maintenance window on a live portal.
Because the licence is AGPL-3.0, any modified version you expose over a network carries source-availability obligations. The README offers paid custom development and migration services, which is one route to changes you would rather not maintain yourself. That is a commercial arrangement, not a licence exemption, and the terms of AGPL-3.0 should be read against your own deployment. For a public university portal running unmodified code, the practical burden is publishing the source you already have; for a company modifying the frontend and serving it to customers, the analysis is different and belongs with counsel.
Editorial conclusion
Adopt MediaCMS if you need a self-hosted portal with public, private and unlisted publishing, HLS playback, subtitles, playlists and an LMS hook, and you are willing to run PostgreSQL, Redis, Celery, Nginx, FFMPEG and Bento4 yourself. Do not adopt it if you only need to embed a handful of clips, or if AGPL-3.0 and the threefold disk multiplier are unacceptable. Before committing, verify the Docker Compose guide in docs/admins_docs.md against your host, confirm that the transcoding profiles in docs/transcoding.md match your CPU budget, and decide whether Whisper transcription is worth the extra CPUs the README asks for.
Community notes