diff --git a/Dockerfile b/Dockerfile index 3ef9683..5cfd25d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -63,8 +63,8 @@ RUN npm install -g yarn && yarn install --frozen-lockfile || yarn install COPY index.js ./ COPY src/ ./src/ -# Expose both ports -EXPOSE 3000 8080 +# Expose streaming app port (WS4KP port only exposed when explicitly configured) +EXPOSE 3000 # Start both services using JSON array format CMD ["/bin/sh", "-c", "cd /app && node index.js & cd /streaming-app && yarn start"] diff --git a/README.md b/README.md index 8684625..994feeb 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ docker-compose pull docker-compose up # The service runs on http://localhost:3000 -# ws4kp interface available at http://localhost:8080 +# WS4KP interface available at http://localhost:8080 (if port is exposed) ``` ### Environment Variables @@ -26,20 +26,25 @@ Configure ports and services via environment variables: ```bash # Default values -PORT=3000 # Main streaming server port -WS4KP_PORT=8080 # WS4KP weather service port -MUSIC_PATH=/music # Path to music files +PORT=3000 # Main streaming server port +WS4KP_EXTERNAL_PORT=8080 # External port for WS4KP interface (optional) +MUSIC_PATH=/music # Path to music files # Example with custom ports -PORT=8000 WS4KP_PORT=9090 docker-compose up +PORT=8000 WS4KP_EXTERNAL_PORT=9090 docker-compose up + +# Run without exposing WS4KP externally (only accessible internally to the streaming app) +# Comment out the WS4KP port line in docker-compose.yml ``` Or use a `.env` file with docker-compose: ```env PORT=8000 -WS4KP_PORT=9090 +WS4KP_EXTERNAL_PORT=9090 ``` +**Note**: The WS4KP weather service runs internally on port 8080 inside the container and is always accessible to the streaming app. The `WS4KP_EXTERNAL_PORT` controls whether it's exposed externally. If you don't need direct access to the WS4KP interface, you can comment out the WS4KP port mapping in `docker-compose.yml` to keep it internal-only. + ### Persistent Geocoding Cache Geocoding results are cached in the `./cache` directory. When using docker-compose, this directory is automatically mounted to persist between container restarts. If using Docker directly, mount the cache volume to persist data: @@ -51,7 +56,11 @@ docker run -p 3000:3000 -p 8080:8080 -v $(pwd)/cache:/streaming-app/cache ghcr.i ### Using Docker directly ```bash +# With WS4KP interface exposed docker run -p 3000:3000 -p 8080:8080 ghcr.io/sethwv/ws4kp-to-hls:latest + +# Without exposing WS4KP interface (internal only) +docker run -p 3000:3000 ghcr.io/sethwv/ws4kp-to-hls:latest ``` **Note**: Initial build takes an additional ~90 seconds due to downloading and processing the Weatherscan music collection (~500MB, processed to VBR q6 quality with normalization). diff --git a/build-commands.txt b/build-commands.txt index 849cf1b..b2759ba 100644 --- a/build-commands.txt +++ b/build-commands.txt @@ -1,5 +1,14 @@ # Docker Build Commands +## Setup buildx builder (one-time setup) + +# Create and use the multiplatform builder +docker buildx create --name multiplatform --driver docker-container --use +docker buildx inspect --bootstrap + +# Or if builder exists, just switch to it +docker buildx use multiplatform + ## Build and push multi-platform image (AMD64 + ARM64) docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/sethwv/ws4kp-to-hls:latest --push . diff --git a/docker-compose.yml b/docker-compose.yml index 39042fe..2ba7078 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,11 +3,12 @@ services: build: . ports: - "${PORT:-3000}:${PORT:-3000}" - - "${WS4KP_PORT:-8080}:${WS4KP_PORT:-8080}" + # WS4KP port - comment out this line if you don't need external access to WS4KP + # - "${WS4KP_EXTERNAL_PORT:-8080}:8080" shm_size: 2gb environment: - PORT=${PORT:-3000} - - WS4KP_PORT=${WS4KP_PORT:-8080} + - WS4KP_PORT=8080 volumes: - ./cache:/streaming-app/cache restart: unless-stopped diff --git a/src/geocode.js b/src/geocode.js index be38161..a0711ce 100644 --- a/src/geocode.js +++ b/src/geocode.js @@ -31,8 +31,11 @@ function getCachedGeocode(cityQuery) { if (fs.existsSync(cacheFile)) { const data = fs.readFileSync(cacheFile, 'utf8'); const cached = JSON.parse(data); - console.log(`Using cached geocode for: ${cityQuery}`); - return cached; + // Verify the query matches + if (cached.query && cached.query.toLowerCase().trim() === cityQuery.toLowerCase().trim()) { + console.log(`Using cached geocode for: ${cityQuery}`); + return cached; + } } } catch (error) { console.warn(`Cache read error for ${cityQuery}:`, error.message); @@ -88,6 +91,7 @@ async function geocodeCity(cityQuery) { const results = JSON.parse(data); if (results && results.length > 0) { const geocodeResult = { + query: cityQuery, lat: parseFloat(results[0].lat), lon: parseFloat(results[0].lon), displayName: results[0].display_name