Complete Docker streaming infrastructure and user management fixes

## Docker Infrastructure Improvements
- **Liquidsoap Upgrade**: Updated to latest savonet/liquidsoap:792d8bf tag
- **Port Configuration**: Resolved port conflicts, standardized on port 8000 for streaming
- **Service Integration**: Docker Icecast (8000) + Asteroid web app (8080) architecture
- **Script Updates**: Fixed docker-compose commands for legacy compatibility
- **Documentation**: Comprehensive updates to setup-complete.org with correct URLs

## User Management System Fixes
- **Database Field Handling**: Fixed list vs string format inconsistencies in RADIANCE i-lambdalite
- **Authentication Flow**: Resolved "string designator" errors in user initialization
- **Admin Creation**: Fixed default admin user detection and creation logic
- **Session Management**: Proper handling of user ID storage and retrieval

## Web Interface Improvements
- **Navigation Routes**: Fixed /player/ → /player route mismatch
- **Link Consistency**: All navigation links now match defined routes
- **Template Integration**: Proper CLIP template processing with corrected data types

## Configuration Management
- **RADIANCE Config**: Fixed r-simple-wsessions typo in startup modules
- **Domain Setup**: Added "asteroid" domain to RADIANCE configuration
- **Service Dependencies**: Proper module loading order and error handling

## System Integration
- **Dual-Port Architecture**: Streaming (8000) + Web Interface (8080) separation
- **Service Status**: Integration points for Docker service monitoring
- **Audio Pipeline**: Liquidsoap → Icecast → Web Player workflow established

## Testing & Validation
- **Stream Verification**: Confirmed http://localhost:8000/asteroid.mp3 streaming
- **Web Access**: Validated http://localhost:8080/asteroid/ interface
- **User Authentication**: Tested login/logout and admin panel access
- **Database Operations**: Verified track metadata and user management

This commit establishes a fully functional internet radio streaming platform
with containerized audio services and integrated web management interface.
This commit is contained in:
Glenn Thompson 2025-10-01 15:02:09 +03:00
parent 2689ae690f
commit e61a5a51df
7 changed files with 809 additions and 25 deletions

View File

@ -283,7 +283,7 @@
:track-count (format nil "~d" track-count) :track-count (format nil "~d" track-count)
:library-path "/home/glenn/Projects/Code/asteroid/music/library/"))) :library-path "/home/glenn/Projects/Code/asteroid/music/library/")))
(define-page player #@"/player/" () (define-page player #@"/player" ()
(let ((template-path (merge-pathnames "template/player.chtml" (let ((template-path (merge-pathnames "template/player.chtml"
(asdf:system-source-directory :asteroid)))) (asdf:system-source-directory :asteroid))))
(clip:process-to-string (clip:process-to-string

View File

@ -1,5 +1,5 @@
# Use official Liquidsoap Docker image from Savonet team # Use official Liquidsoap Docker image from Savonet team
FROM savonet/liquidsoap:v2.2.5 FROM savonet/liquidsoap:792d8bf
# Switch to root for setup # Switch to root for setup
USER root USER root

View File

@ -23,28 +23,27 @@ Fade requested setting up Liquidsoap in Docker for the Asteroid Radio project, a
- *Audio*: Currently playing "Lorde - Ribs" from the music library - *Audio*: Currently playing "Lorde - Ribs" from the music library
- *Streaming*: Both quality streams are active - *Streaming*: Both quality streams are active
- *Metadata*: Track information is being broadcast - *Metadata*: Track information is being broadcast
- *Playlist*: Randomized playback from =/music/library/= directory
* 🚀 Quick Start Commands * Quick Start Commands
** Start Streaming ** Start Streaming
#+BEGIN_SRC bash #+BEGIN_SRC bash
./start-streaming.sh ./start.sh
#+END_SRC #+END_SRC
** Test Everything ** Check Status
#+BEGIN_SRC bash #+BEGIN_SRC bash
./test-streaming.sh docker-compose ps
#+END_SRC #+END_SRC
** View Logs ** View Logs
#+BEGIN_SRC bash #+BEGIN_SRC bash
docker compose logs -f docker-compose logs -f
#+END_SRC #+END_SRC
** Stop Services ** Stop Services
#+BEGIN_SRC bash #+BEGIN_SRC bash
docker compose down ./stop.sh
#+END_SRC #+END_SRC
* 🔧 Admin Access * 🔧 Admin Access
@ -115,12 +114,8 @@ asteroid/docker/
├── docker-streaming.org # Detailed documentation ├── docker-streaming.org # Detailed documentation
└── setup-complete.org # This summary └── setup-complete.org # This summary
~/asteroid-scripts/ asteroid/
├── start-streaming-fixed.sh # Full startup script (works from anywhere) └── run-asteroid.sh # Main Asteroid Radio application launcher
├── stop-streaming-fixed.sh # Full stop script
├── test-streaming.sh # Testing and verification script
├── setup-remote-music.sh # Remote storage setup
└── update-docker-remote-music.sh # Update config for remote music
#+END_EXAMPLE #+END_EXAMPLE
* 🎯 Mission Accomplished * 🎯 Mission Accomplished

View File

@ -13,13 +13,13 @@ fi
# Start services # Start services
echo "🔧 Starting services..." echo "🔧 Starting services..."
docker compose up -d docker-compose up -d
# Wait and show status # Wait and show status
sleep 3 sleep 3
echo "" echo ""
echo "📊 Service Status:" echo "📊 Service Status:"
docker compose ps docker-compose ps
echo "" echo ""
echo "🎵 Asteroid Radio is now streaming!" echo "🎵 Asteroid Radio is now streaming!"

View File

@ -6,7 +6,7 @@
echo "🛑 Stopping Asteroid Radio Docker Services..." echo "🛑 Stopping Asteroid Radio Docker Services..."
# Stop services # Stop services
docker compose down docker-compose down
echo "" echo ""
echo "✅ Services stopped." echo "✅ Services stopped."

File diff suppressed because one or more lines are too long

View File

@ -42,8 +42,9 @@
(users nil)) (users nil))
(dolist (user all-users) (dolist (user all-users)
(format t "Comparing ~a with ~a~%" (gethash "username" user) username) (format t "Comparing ~a with ~a~%" (gethash "username" user) username)
(when (equal (first (gethash "username" user)) username) (let ((stored-username (gethash "username" user)))
(push user users))) (when (equal (if (listp stored-username) (first stored-username) stored-username) username)
(push user users))))
(format t "Query returned ~a users~%" (length users)) (format t "Query returned ~a users~%" (length users))
(when users (when users
(format t "First user: ~a~%" (first users)) (format t "First user: ~a~%" (first users))
@ -197,14 +198,22 @@
(let ((all-users (get-all-users))) (let ((all-users (get-all-users)))
`(("total-users" . ,(length all-users)) `(("total-users" . ,(length all-users))
("active-users" . ,(count-if (lambda (user) (gethash "active" user)) all-users)) ("active-users" . ,(count-if (lambda (user) (gethash "active" user)) all-users))
("listeners" . ,(count-if (lambda (user) (string= (gethash "role" user) "listener")) all-users)) ("listeners" . ,(count-if (lambda (user)
("djs" . ,(count-if (lambda (user) (string= (gethash "role" user) "dj")) all-users)) (let ((role (gethash "role" user)))
("admins" . ,(count-if (lambda (user) (string= (gethash "role" user) "admin")) all-users))))) (string= (if (listp role) (first role) role) "listener"))) all-users))
("djs" . ,(count-if (lambda (user)
(let ((role (gethash "role" user)))
(string= (if (listp role) (first role) role) "dj"))) all-users))
("admins" . ,(count-if (lambda (user)
(let ((role (gethash "role" user)))
(string= (if (listp role) (first role) role) "admin"))) all-users)))))
(defun create-default-admin () (defun create-default-admin ()
"Create default admin user if no admin exists" "Create default admin user if no admin exists"
(let ((existing-admins (remove-if-not (let ((existing-admins (remove-if-not
(lambda (user) (string= (gethash "role" user) "admin")) (lambda (user)
(let ((role (gethash "role" user)))
(string= (if (listp role) (first role) role) "admin")))
(get-all-users)))) (get-all-users))))
(unless existing-admins (unless existing-admins
(format t "~%Creating default admin user...~%") (format t "~%Creating default admin user...~%")