MediaCMS logo

MediaCMS

Modern, fully featured open source video and media CMS

Alternative to: youtube, vimeo, wistia


MediaCMS is a modern, fully featured open source video and media CMS built with Django and React. It lets you build a small to medium video and media portal within minutes, with features including transcoding, playlists, subtitles, live search, and a full REST API.

MediaCMS Docker Compose example

Self-host MediaCMS on your own server, homelab, or VPS starting from this Docker Compose example. It runs MediaCMS in Docker containers using the official mediacms/mediacms:latest, mediacms/mediacms:latest, mediacms/mediacms:latest, mediacms/mediacms:latest, postgres:17-alpine, redis:alpine images, with persistent volumes and automatic restarts preconfigured. Review the environment variables and adjust them to your setup, save the file as compose.yml (or docker-compose.yml), and start the stack with docker compose up -d.

services:
  migrations:
    image: mediacms/mediacms:latest
    restart: on-failure
    environment:
      ENABLE_UWSGI: "no"
      ENABLE_NGINX: "no"
      ENABLE_CELERY_BEAT: "no"
      ENABLE_CELERY_SHORT: "no"
      ENABLE_CELERY_LONG: "no"
      # Django secret key used to sign sessions, cookies and tokens. Keep it identical across all services.
      SECRET_KEY: "changeme"
      # Public URL where users reach the site. Also used to build the allowed-hosts list.
      FRONTEND_HOST: "http://localhost"
      # Display name of the portal, shown throughout the UI.
      PORTAL_NAME: "MediaCMS"
      # Username of the administrator account created on first run.
      ADMIN_USER: "admin"
      # Email address of the administrator account created on first run.
      ADMIN_EMAIL: "admin@localhost"
      # Password of the administrator account created on first run.
      ADMIN_PASSWORD: "changeme"
    command: "./deploy/docker/prestart.sh"
    depends_on:
      redis:
        condition: service_healthy
      db:
        condition: service_healthy

  web:
    image: mediacms/mediacms:latest
    restart: unless-stopped
    volumes:
      - media_store:/home/mediacms.io/mediacms/media_files/
      - static_store:/home/mediacms.io/mediacms/static/
    environment:
      ENABLE_CELERY_BEAT: "no"
      ENABLE_CELERY_SHORT: "no"
      ENABLE_CELERY_LONG: "no"
      ENABLE_MIGRATIONS: "no"
      # Django secret key used to sign sessions, cookies and tokens. Keep it identical across all services.
      SECRET_KEY: "changeme"
      # Public URL where users reach the site. Also used to build the allowed-hosts list.
      FRONTEND_HOST: "http://localhost"
      # Display name of the portal, shown throughout the UI.
      PORTAL_NAME: "MediaCMS"
    depends_on:
      - migrations

  celery_beat:
    image: mediacms/mediacms:latest
    restart: unless-stopped
    environment:
      ENABLE_UWSGI: "no"
      ENABLE_NGINX: "no"
      ENABLE_CELERY_SHORT: "no"
      ENABLE_CELERY_LONG: "no"
      ENABLE_MIGRATIONS: "no"
      # Django secret key used to sign sessions, cookies and tokens. Keep it identical across all services.
      SECRET_KEY: "changeme"
      # Public URL where users reach the site. Also used to build the allowed-hosts list.
      FRONTEND_HOST: "http://localhost"
    depends_on:
      - redis

  celery_worker:
    image: mediacms/mediacms:latest
    restart: unless-stopped
    volumes:
      - media_store:/home/mediacms.io/mediacms/media_files/
      - static_store:/home/mediacms.io/mediacms/static/
    environment:
      ENABLE_UWSGI: "no"
      ENABLE_NGINX: "no"
      ENABLE_CELERY_BEAT: "no"
      ENABLE_MIGRATIONS: "no"
      # Django secret key used to sign sessions, cookies and tokens. Keep it identical across all services.
      SECRET_KEY: "changeme"
      # Public URL where users reach the site. Also used to build the allowed-hosts list.
      FRONTEND_HOST: "http://localhost"
    depends_on:
      - migrations

  db:
    image: postgres:17-alpine
    restart: unless-stopped
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      POSTGRES_USER: "mediacms"
      POSTGRES_PASSWORD: "mediacms"
      POSTGRES_DB: "mediacms"
      # Timezone for the database container.
      TZ: "UTC"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
      interval: 30s
      timeout: 10s
      retries: 5

  redis:
    image: redis:alpine
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 30s
      timeout: 10s
      retries: 3

volumes:
  postgres_data:
  media_store:
  static_store:

Values set to changeme are required — replace them with your own values before starting MediaCMS.

Prefer a managed setup? WinterFlow installs, configures, and updates MediaCMS for you using this same Docker Compose configuration.