Migrate very old libretime version to latest version on new hardware

Hello guys,

I have a very old version of the software running but this weekend i started to migrate everything to a new server (i tried Debian Bookworm but two services refused to start so i installed a fresh Debian Bullseye).
I downloaded the latest version and ran the installer. Copied the music files and the postgresql db. Did the migration, started the services (they started all nicely), ran certbot, configured nginx and went to the website. The website appeared with https which was a good thing but after logging in i got the “oops” message. I presume it must be some rights problem.

This is the legacy log:

2023-06-19T23:55:25+02:00 ERR (3): [CORSHelper.php:14 - enableCrossOriginRequests()] - request origin 'https://djs.ternatseradio.be' is not in the configured 'allowed_cors_origins' 'https://djs.ternatseradio.be:8080'
2023-06-19T23:55:25+02:00 NOTICE (5): Trying to get property 'id' of non-object
2023-06-19T23:55:25+02:00 ERR (3): [ErrorController.php:28 - errorAction()] - Forbidden
2023-06-19T23:55:25+02:00 ERR (3): [ErrorController.php:29 - errorAction()] - #0 /usr/share/libretime/legacy/application/controllers/LoginController.php(24): CORSHelper::enableCrossOriginRequests()
#1 /usr/share/libretime/legacy/vendor/zf1s/zend-controller/library/Zend/Controller/Action.php(516): LoginController->indexAction()
#2 /usr/share/libretime/legacy/vendor/zf1s/zend-controller/library/Zend/Controller/Dispatcher/Standard.php(308): Zend_Controller_Action->dispatch()
#3 /usr/share/libretime/legacy/vendor/zf1s/zend-controller/library/Zend/Controller/Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch()
#4 /usr/share/libretime/legacy/vendor/zf1s/zend-application/library/Zend/Application/Bootstrap/Bootstrap.php(105): Zend_Controller_Front->dispatch()
#5 /usr/share/libretime/legacy/vendor/zf1s/zend-application/library/Zend/Application.php(391): Zend_Application_Bootstrap_Bootstrap->run()
#6 /usr/share/libretime/legacy/application/airtime-boot.php(77): Zend_Application->run()
#7 /usr/share/libretime/legacy/public/index.php(56): require_once('/usr/share/libr...')
#8 {main}
2023-06-19T23:55:25+02:00 ERR (3): [ErrorController.php:62 - errorAction()] - An internal application error has occurred.: Zend_Controller_Action_Exception: Forbidden in /usr/share/libretime/legacy/application/common/CORSHelper.php:17
Stack trace:
#0 /usr/share/libretime/legacy/application/controllers/LoginController.php(24): CORSHelper::enableCrossOriginRequests()
#1 /usr/share/libretime/legacy/vendor/zf1s/zend-controller/library/Zend/Controller/Action.php(516): LoginController->indexAction()
#2 /usr/share/libretime/legacy/vendor/zf1s/zend-controller/library/Zend/Controller/Dispatcher/Standard.php(308): Zend_Controller_Action->dispatch()
#3 /usr/share/libretime/legacy/vendor/zf1s/zend-controller/library/Zend/Controller/Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch()
#4 /usr/share/libretime/legacy/vendor/zf1s/zend-application/library/Zend/Application/Bootstrap/Bootstrap.php(105): Zend_Controller_Front->dispatch()
#5 /usr/share/libretime/legacy/vendor/zf1s/zend-application/library/Zend/Application.php(391): Zend_Application_Bootstrap_Bootstrap->run()
#6 /usr/share/libretime/legacy/application/airtime-boot.php(77): Zend_Application->run()
#7 /usr/share/libretime/legacy/public/index.php(56): require_once('/usr/share/libr...')
#8 {main}

and this is my config.yml

# See https://libretime.org/docs/admin-manual/setup/configuration/

general:
  # The public url.
  # > this field is REQUIRED
  public_url: https://djs.ternatseradio.be:8080
  # The internal API authentication key.
  # > this field is REQUIRED
  api_key: Pyv0OTONvp6WdQtBwfJy5q5AJgexH45r
  # The Django API secret key. If not defined, the value of [general.api_key] will be
  # used as fallback.
  # > this field will be REQUIRED starting with LibreTime 4.0.0
  secret_key: W0bCnGrd20K0QYeIsjUYeq1OPu0NWG8V

  # List of origins allowed to access resources on the server, the public url
  # origin is automatically included.
  # > default is []
  allowed_cors_origins: []

  # The server timezone, should be a lookup key in the IANA time zone database,
  # for example Europe/Berlin.
  # > default is UTC
  timezone: Europe/Brussels

  # How many hours ahead Playout should cache scheduled media files.
  # > default is 1
  cache_ahead_hours: 1

  # Authentication adaptor to use for the legacy service, specify a class like
  # LibreTime_Auth_Adaptor_FreeIpa to replace the built-in adaptor.
  # > default is local
  auth: local

storage:
  # Path of the storage directory.
  # > default is /srv/libretime
  path: /srv/libretime

database:
  # The hostname of the PostgreSQL server.
  # > default is localhost
  host: localhost
  # The port of the PostgreSQL server.
  # > default is 5432
  port: 5432
  # The name of the PostgreSQL database.
  # > default is libretime
  name: libretime
  # The username of the PostgreSQL user.
  # > default is libretime
  user: libretime
  # The password of the PostgreSQL user.
  # > default is libretime
  password: TQ4rwgdzrLJWffG25bVi9mrHaQYOKPDQ

rabbitmq:
  # The hostname of the RabbitMQ server.
  # > default is localhost
  host: localhost
  # The port of the RabbitMQ server.
  # > default is 5672
  port: 5672
  # The virtual host of RabbitMQ server.
  # > default is /libretime
  vhost: /libretime
  # The username of the RabbitMQ user.
  # > default is libretime
  user: libretime
  # The password of the RabbitMQ user.
  # > default is libretime
  password: rLbraZftztWkfFIJ4p0VmPac8O7vK4QZ

playout:
  # Liquidsoap connection host.
  # > default is localhost
  liquidsoap_host: localhost
  # Liquidsoap connection port.
  # > default is 1234
  liquidsoap_port: 1234

  # The format for recordings.
  # > must be one of (ogg, mp3)
  # > default is ogg
  record_file_format: ogg
  # The bitrate for recordings.
  # > default is 256
  record_bitrate: 256
  # The samplerate for recordings.
  # > default is 44100
  record_samplerate: 44100
  # The number of channels for recordings.
  # > default is 2
  record_channels: 2
  # The sample size for recordings.
  # > default is 16
  record_sample_size: 16

liquidsoap:
  # Liquidsoap server listen address.
  # > default is 127.0.0.1
  server_listen_address: "127.0.0.1"
  # Liquidsoap server listen port.
  # > default is 1234
  server_listen_port: 1234

  # Input harbor listen address.
  # > default is ["0.0.0.0"]
  harbor_listen_address: ["0.0.0.0"]

  # Input harbor tls certificate path.
  harbor_ssl_certificate:
  # Input harbor tls certificate private key path.
  harbor_ssl_private_key:
  # Input harbor tls certificate password.
  harbor_ssl_password:

stream:
  # Inputs sources.
  inputs:
    # Main harbor input.
    main:
      # Harbor input public url. If not defined, the value will be generated from
      # the [general.public_url] hostname, the input port and mount.
      public_url:
      # Mount point for the main harbor input.
      # > default is main
      mount: main
      # Listen port for the main harbor input.
      # > default is 8001
      port: 8001
      # Whether the input harbor is secured with the tls certificate.
      # > default is false
      secure: false

    # Show harbor input.
    show:
      # Harbor input public url. If not defined, the value will be generated from
      # the [general.public_url] hostname, the input port and mount.
      public_url:
      # Mount point for the show harbor input.
      # > default is show
      mount: show
      # Listen port for the show harbor input.
      # > default is 8002
      port: 8002
      # Whether the input harbor is secured with the tls certificate.
      # > default is false
      secure: false

  # Output streams.
  outputs:
    # Default icecast output
    # This can be reused to define multiple outputs without duplicating data
    .default_icecast_output: &default_icecast_output
      host: localhost
      port: 8000
      source_password: jR7XwgFRDsIi3rV8TYSGu8PRQN6BUPWz
      admin_password: GnpZ7sdE0rKqHXgNEmqRM0BNLE5igbYG
      name: LibreTime!
      description: LibreTime Radio!
      website: https://libretime.org
      genre: various

    # Icecast output streams.
    # > max items is 3
    icecast:
      # The default Icecast output stream
      - <<: *default_icecast_output
        enabled: true
        public_url:
        mount: main
        audio:
          format: ogg
          bitrate: 256

      # You can define extra outputs by reusing the default output using a yaml anchor
      - <<: *default_icecast_output
        enabled: false
        mount: main-low
        audio:
          format: ogg
          bitrate: 128

      - # Whether the output is enabled.
        # > default is false
        enabled: false
        # Output public url, If not defined, the value will be generated from
        # the [general.public_url] hostname, the output port and mount.
        public_url:
        # Icecast server host.
        # > default is localhost
        host: localhost
        # Icecast server port.
        # > default is 8000
        port: 8000
        # Icecast server mount point.
        # > this field is REQUIRED
        mount: main
        # Icecast source user.
        # > default is source
        source_user: source
        # Icecast source password.
        # > this field is REQUIRED
        source_password: hackme
        # Icecast admin user.
        # > default is admin
        admin_user: admin
        # Icecast admin password. If not defined, statistics will not be collected.
        admin_password: hackme

        # Icecast output audio.
        audio:
          # Icecast output audio format.
          # > must be one of (aac, mp3, ogg, opus)
          # > this field is REQUIRED
          format: ogg
          # Icecast output audio bitrate.
          # > must be one of (32, 48, 64, 96, 128, 160, 192, 224, 256, 320)
          # > this field is REQUIRED
          bitrate: 256

          # format=ogg only field: Embed metadata (track title, artist, and show name)
          # in the output stream. Some bugged players will disconnect from the stream
          # after every songs when playing ogg streams that have metadata information
          # enabled.
          # > default is false
          enable_metadata: false

        # Icecast stream name.
        name: LibreTime!
        # Icecast stream description.
        description: LibreTime Radio!
        # Icecast stream website.
        website: https://libretime.org
        # Icecast stream genre.
        genre: various

    # Shoutcast output streams.
    # > max items is 1
    shoutcast:
      - # Whether the output is enabled.
        # > default is false
        enabled: false
        # Output public url. If not defined, the value will be generated from
        # the [general.public_url] hostname and the output port.
        public_url:
        # Shoutcast server host.
        # > default is localhost
        host: localhost
        # Shoutcast server port.
        # > default is 8000
        port: 8000
        # Shoutcast source user.
        # > default is source
        source_user: source
        # Shoutcast source password.
        # > this field is REQUIRED
        source_password: hackme
        # Shoutcast admin user.
        # > default is admin
        admin_user: admin
        # Shoutcast admin password. If not defined, statistics will not be collected.
        admin_password: hackme

        # Shoutcast output audio.
        audio:
          # Shoutcast output audio format.
          # > must be one of (aac, mp3)
          # > this field is REQUIRED
          format: mp3
          # Shoutcast output audio bitrate.
          # > must be one of (32, 48, 64, 96, 128, 160, 192, 224, 256, 320)
          # > this field is REQUIRED
          bitrate: 256

        # Shoutcast stream name.
        name: LibreTime!
        # Shoutcast stream website.
        website: https://libretime.org
        # Shoutcast stream genre.
        genre: various

    # System outputs.
    # > max items is 1
    system:
      - # Whether the output is enabled.
        # > default is false
        enabled: false
        # System output kind.
        # > must be one of (alsa, ao, oss, portaudio, pulseaudio)
        # > default is alsa
        kind: alsa

The daemons aka services:

libretime-analyzer.service                                                                               loaded    active   running   LibreTime Media Analyzer Service
libretime-api.service                                                                                    loaded    active   running   LibreTime API Service
libretime-liquidsoap.service                                                                             loaded    active   running   LibreTime Liquidsoap Service
libretime-playout.service                                                                                loaded    active   running   LibreTime Playout Service
libretime-worker.service                                                                                 loaded    active   running   LibreTime Worker Service
libretime-api.socket                                                                                     loaded    active   running   LibreTime API Socket
libretime.target                                                                                         loaded    active   active    LibreTime Services

In the config files i’ve posted here are not the actual passwords of course.
What can i check?

Any help would be kindly appreciated,

Serge.

The first line in the legacy logs shows an error with “cors”.
You could try to add

https://djs.ternatseradio.be

as allowed cors to the config file like:

allowed_cors_origins : [ "https://djs.ternatseradio.be"]

I also found an error in the config.yml file.
The storage path should be, in my case /srv/libretime/stor
but i don’t know if that can be related.

Thanks for the help but it will take some weeks before i can further test the installation because i am abroad at the moment.

Serge

OS: Debian Bullseye (11)
LT version: 3.1.0.
I was able to solve the problems but now i ran into the “Can not connect to the streaming server. Problem with liquidsoap” error.
This is wat the liquidsoap.log tells me:

2023-06-27 12:23:21,102 | ERROR    | libretime_api_client._client:_request:93 - HTTPSConnectionPool(host='djs.ternatseradio.be', port=8080): Max retries exceeded with url: /api/v2/info (Caused by SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1123)')))
2023-06-27 12:23:21,963 | WARNING  | urllib3.connectionpool:urlopen:871 - Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1123)'))': /api/v2/info
2023-06-27 12:23:25,974 | WARNING  | urllib3.connectionpool:urlopen:871 - Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1123)'))': /api/v2/info
2023-06-27 12:23:33,992 | WARNING  | urllib3.connectionpool:urlopen:871 - Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1123)'))': /api/v2/info
2023-06-27 12:23:50,021 | WARNING  | urllib3.connectionpool:urlopen:871 - Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1123)'))': /api/v2/info

I can see that it is an SSL problem but could someone please clarify this for me?
I don’t know how to resolve this (and I tried every solution i could find on this forum)
Serge

I assume you want to access the LibreTime server at the following address: https://djs.ternatseradio.be

If that is so, togir gave you the wrong workaround. You need to change your general.public_url to the adress above, WITHOUT the port number.

Once you changed this, restart libretime and see if that solved it.

Thank you for your answer. When I am back home I will change the general.public_url.

Everything is working as expected now after I made the proposed change and I changed this line:

allowed_cors_origins: [https://djs.ternatseradio.be, https://192.168.0.1, https://localhost]
where 192.168.0.1 is the address of my gateway.

Thank you for your advice.

UPDATE: SOLVED!

Seems that new Nginx install’s comes with an upload limit of 1Mb. Most songs are larger in size.
Knowing this all you have to do is edit the /etc/nginx/nginx.conf file and add ``client_max_body_size xxxM;`’ to the http section where, of course, xxx has to be replaced with the maximum upload limit. In my case i’ve chosen for a limit of 500M.

Original message:

And of course one day before the new server goes on air I ran into a new problem.
When i upload Music i get this error:

Update: Nginx error.log shows me this:
2023/07/14 11:21:38 [error] 48366#48366: *575996 client intended to send too large body: 6825815 bytes, client: 192.168.0.1, server: djs.ternatseradio.be, request: "POST /rest/media HTTP/1.1", host: "djs.ternatseradio.be", referrer: "https://djs.ternatseradio.be/plupload"

Is there anyone who can point me in the right direction to solve this PLEASE?

Thank you very much,
Serge

Hello, I can’t help you with nginx, but I have another solution for you and you can help me with my libretime project.

I advise you to leave libretime with its installation just as it leaves the factory, it would even leave the domain in the IP and nothing else: for example http://192.168.0.10

Then on another computer connected to the internet on your home line, I would put a website manager, for example ispconfig, I would create a real domain, like for example myradio.example.net with automatic ssl (ispconfig does it) and I would put a reverse proxy in the domain options, something like

 ProxyPass / http://192.168.0.10/
 ProxyPassReverse / http://192.168.0.10/

This will allow people to connect to your web station, but it will not be possible to connect to manage, which is not a defect, due to the weak security that libretime has at the moment

What I would need from you is information about your installation to be able to replicate it locally as well as possible

what version of debian have you used?
What version of librtetime have you used exactly?

What I want to do is create disk images (.img) with libretime already configured, ready to be flashed on a computer and stream music in a few minutes.

In this way, radio operators will be able to test libretime without having to rack their brains to solve problems that they don’t even understand.

The way I’m going to operate will be with virtualbox, and then I convert the vdi disk into .img.xz

I’ll just add a service in systemd to expand root to 100% hard drive capacity the same way rasperryPiOS does.

What do you think about the idea?

First of all: thank you for the interest but:
A) Everything works now as should be.
B) It was not a new station. It was an upgrade from an already existing station so the Postgresql database was not empty.
C) I agree with you that Libretime has weak security when it comes to access to the management system. First we used a subdomain of our website to access Libretime itself but after we found out that there was “strange activity” on that subdomain we moved it to another domain. On the subdomain we left a false libretime access page and we log all activity.

We are using Debian Bullseye since Bookworm is not yet supported and Libretime 3.1.0

I think your project will be very helpful for new starters but not for people who have to upgrade existing installations.

Hi, I’m glad you solved your problems.

I think that to ensure as much as possible to libretime, we would have to use an unused function of icecast. Use a MASTER-SLAVE repeater

Creation of the MASTER
in the icecast.xml of LibreTime put this on

Sources log in with username ‘source’ CONTRASEÑArelay Relays log in with username ‘relay’ CONTRASEÑA Admin logs in with the username given below adminCONTRASEÑAwhere:
source-password is the password
relay-user is the user name that will be connected
relay-password is the password to connect and make a relay
This icecast becomes the MASTER

Creation of SLAVE (can have more than one at a time)
then on another computer exposed to the internet (DMZ or port forward) installs another incecast and connects it to the icecast of Libretime with this configuration:

192.168.0.518000120relayCONTRASEÑA0where:
Master-server is the IP of the LibreTime computer
master-server-port is the port used (8000 by default)
master-username is the user of freetime icecast
master-password is the password

Outcome

With this configuration you can have freetime insurance within your LAN and from the outside you will not be able to access.
From the outside you can access only the SLAVE of icecast and there listen to the music.
You can create a Slave network to expand the bandwidth and nun SLAVE can also be Master at the same time for another SLAVE

Greetings
MaX

You can configure up to 3 icecast streams in Libretime. I configured the two extra streams to the IP of other servers and opened those to the public. The first stream is only used for internal use. Also Icecast can have relay’s. The only problem I still have to solve is how to copy the .pem files you need for secure access (https) to the streams. These .pem files have to be copied with root-privileges and since I have prohibited root-access to ssl I need physical access to the servers. I tried with different configurations with scp but, until now, without any success. Next I will try with the Certbot renew commands post-processing first to create the pem file and then to copy it to the Icecast servers.
And when I fail I know some linux guys at the University of Brussels… :smile:

Serge,
This is how I solved that specific problem.
Instead of copying files into the image etc etc. I leave them in my systems directory (the place where I have the docker-compose.yml file and have made the following change to it.
This way it links the specified location to the file you want to access, and in case I need to update the SSL cert or make a change to the icecast.xml file, the only thing I need to do is make the change and restart. Nice and fast, without any further compiling.

volumes:
  - ${LIBRETIME_CONFIG_FILEPATH:-./icecast.xml}:/etc/icecast.xml:ro
  - ./xxxxxxxxxxxxxx.crt:/etc/ssl/certs/xxxxxxxxxxxxxx.crt:ro
This mounts the icecast XML into /etc/ and the cert into /etc/ssl/certs/ of course this location and filename is specified in the icecast XML file.

Chris.