26 May 2024

Dockerize MythTV

To prepare for my new server, I needed to migrate the rest of MythTV including its MySQL database to Docker containers.


Migrate MythTV Backend and MySQL to Docker

  • Edit docker-compose-webserver.service to remove references to mysql.service
    • This step is only necessary if you followed my other guide that dockerized mythweb
    • sudo systemctl daemon-reload
  • Stop and Disable MythTV Backend
    • sudo systemctl stop mythtv-backend
    • sudo systemctl disable mythtv-backend
  • Create directories and set permissions
    • sudo mkdir -p /storage/containers/mythtv/mysql/lib
    • sudo chown -R mysql /storage/containers/mythtv/mysql
    • sudo chgrp -R mysql /storage/containers/mythtv/mysql
  • Dump the current mythconverg database to a file and update the hostname
    • sudo su
    • mysqldump -p<existing root password> mythconverg > mythconverg.mysqldump
    • sed "s/'<old hostname>'/'mythtv-backend'/g" mythconverg.mysqldump > mythconverg.mysqldump.host
    • exit
  • Stop and disable current MySQL instance
    • sudo systemctl stop mysql
    • sudo systemctl disable mysql
  • Identify the needed UIDs and GIDs
    • id mysql && id mythtv
  • Create the docker-compose.yml with just a MySQL section
# Begin docker-compose.yml
version: '3.5'
services:
    mythtv-mysql:
        container_name: 'mythtv-mysql'
        hostname: 'mythtv-mysql'
        user: '<mysql uid>:<mysql gid>'
        image: mysql:latest
        restart: always
        ports:
            - '3306:3306'
        environment:
            - MYSQL_ROOT_PASSWORD=RootSuperSecretPassword
            - MYSQL_USER=mythtv
            - MYSQL_PASSWORD=YourSuperSecretPassword
        volumes:
            - ./mysql/lib:/var/lib/mysql
# End docker-compose.yml
  • Restore the database:
    • sudo docker-compose up --build
    • sudo mysql -p -h 127.0.0.1 -P 3306
      • create database mythconverg ;
      • connect mythconverg ;
      • source mythconverg.mysqldump.host ;
      • grant all privileges on mythconverg to 'mythtv'@'%' ;
      • grant all privileges on mythconverg.* to 'mythtv'@'%' ;
      • quit ;
    • Use Ctrl-C to stop the container
  • Add the backend to docker-compose.yml
# Begin docker-compose.yml
version: '3.5'
services:
    mythtv-mysql:
        container_name: 'mythtv-mysql'
        hostname: 'mythtv-mysql'
        user: '<mysql uid>:<mysql gid>'
        image: mysql:latest
        restart: always
        ports:
            - '3306:3306'
        environment:
            - MYSQL_ROOT_PASSWORD=RootSuperSecretPassword
            - MYSQL_USER=mythtv
            - MYSQL_PASSWORD=YourSuperSecretPassword
        volumes:
            - ./mysql/lib:/var/lib/mysql
    mythtv-backend:
        container_name: 'mythtv-backend'
        hostname: 'mythtv-backend'
        user: '<mythtv uid>:<mythtv gid>'
        image: dheaps/mythbackend:latest
        restart: always
        depends_on:
            - mythtv-mysql
        network_mode: host
        # entrypoint: 'echo backend disabled'
        environment:
            - USER_ID=<mythtv uid>
            - GROUP_ID=<mythtv gid>
            - DATABASE_HOST=host.docker.internal
            - DATABASE_PORT=3306
            - DATABASE_NAME=mythconverg
            - DATABASE_USER=mythtv
            - DATABASE_PWD=YourSuperSecretPassword
            - TZ=America/New_York
        volumes:
            - /storage/mythtv:/var/lib/mythtv
        extra_hosts:
            - host.docker.internal:host-gateway
# End docker-compose.yml
  • Test it out
    • docker-compose up --build
    • Ctrl-C to stop it once you confirm it works
  • Add it to systemd: /etc/systemd/system/docker-mythtv.service
# Begin docker-mythtv.service
[Unit]
Description=Docker Compose MythTV Service
Requires=docker.service
After=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/storage/containers/mythtv
ExecStart=/usr/bin/docker-compose up --build -d
ExecStop=/usr/bin/docker-compose down
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target
# End docker-mythtv.service

  • Enable and start the service
    • sudo systemctl enable docker-mythtv
    • sudo systemctl start docker-mythtv
  • I also had to update docker-compose.yml for mythweb to use DATABASE_HOST=host.docker.internal and add the extra_hosts


Appendix

Errors

  • MythCoreContext::CheckSubnet(): Repeat denied connection from ip address
    • Connect to the MySQL database
      • sudo mysql -p -h 127.0.0.1 -P 3306
    • Run one of the following:
      • update settings set data = 1 where value = 'AllowConnFromAll' ;
      • OR
      • insert into settings(value, data, hostname)
      • values('AllowConnFromAll', '1', 'mythtv-backend')
      • ;
  • only one instance of "host" network is allowed
    • ensure that you are using either external host network or network_mode

Sources