Custom Domains

🔒 Use the app with a custom domain, with, or without HTTPS support

New (v0.5.0)

Only supported in m3u editor v0.5.0+

NOTE: Custom domains are are not officially supported on versions under v0.5.0. For lower versions it’s recommended to use machine IP address, as outlined on the Getting Started page.

Table of contents


🐳 Docker compose updates

Update your docker-compose.yaml environment variables, specifically:

  • APP_URL

Example:

services:
  m3u-editor:
    image: sparkison/m3u-editor:latest
    container_name: m3u-editor
    environment:
      - TZ=Etc/UTC
      - APP_URL=https://your-custom-tld.com
    volumes:
      # This will allow you to reuse the data across container recreates.
      # Format is: <host_directory_path>:<container_path>
      # More information: https://docs.docker.com/reference/compose-file/volumes/
      - ./data:/var/www/config
    restart: unless-stopped
    ports:
      - 36400:36400
networks: {}

Restart the container to see the changes reflected.


🏁 Example NGINX configuration

If you’re running NGINX on your host machine, the above settings will tell m3u editor to run in secure mode under the provided domain. Now it’s up to your host machine to handle the SSL.

NOTE - It’s important to ensure your REVERB_HOST is also set correctly, and that REVERB_SCHEME is set to https, as outlined above to prevent websocket errors.

Example configuration file for your your-custom-tld.com website:

server {
  listen 80;
  listen [::]:80;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;

  ssl_certificate_key ...
  ssl_certificate ...

  server_name your-custom-tld.com;
  
  root ...

  # Redirect non-https to https
  if ($scheme != "https") {
    rewrite ^ https://$host$uri permanent;
  }
  
  # m3u editor reverse proxy
  location @reverse_proxy {
    proxy_pass http://127.0.0.1:36400;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }

  location / {
    try_files $uri @reverse_proxy;
  }
}

🚦 Traefik Example

If your running Traefik on your server, use something like the below to get m3u editor running properly under a custom domain.

Example docker-compose.yaml with Traefik labels:

services:
  m3u-editor:
    image: sparkison/m3u-editor:latest
    container_name: m3u-editor-traefik
    environment:
      - TZ=Etc/UTC
      - APP_URL=https://your-custom-tld.com
    volumes:
      - ./m3u-editor-config:/var/www/config
    restart: unless-stopped
    labels:
      - "traefik.enable=true"

      # Route all other paths (/) to the app on port 36400
      - "traefik.http.routers.m3u-main.rule=Host(`your-custom-tld.com`)"
      - "traefik.http.routers.m3u-main.entrypoints=websecure"
      - "traefik.http.routers.m3u-main.tls.certresolver=myresolver"
      - "traefik.http.routers.m3u-main.service=m3u-main"
      - "traefik.http.services.m3u-main.loadbalancer.server.port=36400"
      - "traefik.http.services.m3u-main.loadbalancer.server.scheme=http"
    ports:
      - 36400:36400

Make sure your Trafik container has the resolver, myresolver, defined, or change the name to match your setup.

E.g., the myresolver referenced in the setup above would look something like this in your Traefik container:

services:
  traefik:
    image: traefik:v3
    container_name: traefik
    restart: unless-stopped
    ports:
      - 443:443
      - 80:80
    command:
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entryPoints.web.address=:80
      - --entryPoints.websecure.address=:443
      - --certificatesresolvers.myresolver.acme.email=${LETSENCRYPT_EMAIL}
      - --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
      - --certificatesresolvers.myresolver.acme.httpchallenge=true
      - --certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web

🔒 Caddy Example

Caddyfile example:

m3u-editor {
  reverse_proxy /* m3u-editor:36400
}