mirror of
https://github.com/migatu/conjurer.git
synced 2026-07-14 13:34:40 +00:00
docker: dedicated musician entrypoint + fuller runbook section
- docker/entrypoint.musician.sh: on a fresh /data volume, create the managed playlists and touch radio_log.log/persistence.log empty so the track-forwarding thread waits instead of crashing when Liquidsoap runs elsewhere; never overwrites preserved files - Dockerfile.musician: wire the entrypoint, default CONJURER_MUSICIAN_BASE =/data (persist playlists/logs) and CONJURER_STREAM_TEMPLATE=/app/stream.html; declare the /data volume - DOCKER_PROXMOX.md: expand the musician section (two volumes, preserving existing playlists, radio-log coupling, stream template) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -17,14 +17,19 @@ RUN pip install --no-cache-dir --upgrade pip \
|
||||
&& pip install --no-cache-dir -r requirements_musician.txt
|
||||
|
||||
COPY conjurer_musician/ ./
|
||||
COPY docker/entrypoint.musician.sh /usr/local/bin/entrypoint.sh
|
||||
RUN chmod +x /usr/local/bin/entrypoint.sh
|
||||
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
CONJURER_MUSICIAN_HOST=0.0.0.0 \
|
||||
CONJURER_MUSICIAN_PORT=5000 \
|
||||
CONJURER_MUSIC_FOLDER=/music
|
||||
CONJURER_MUSIC_FOLDER=/music \
|
||||
CONJURER_MUSICIAN_BASE=/data \
|
||||
CONJURER_STREAM_TEMPLATE=/app/stream.html
|
||||
|
||||
# The mp3 library is mounted here (read-only is fine for serving).
|
||||
VOLUME ["/music"]
|
||||
# /music = the mp3 library (read-only ok); /data = writable playlists + logs.
|
||||
VOLUME ["/music", "/data"]
|
||||
EXPOSE 5000
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||
CMD ["python", "conjurer_musician.py"]
|
||||
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/bin/sh
|
||||
# Prepare the musician's writable volume so the web service starts cleanly on a
|
||||
# fresh container. Existing files are never overwritten (preserves your data).
|
||||
set -e
|
||||
|
||||
DATA="${CONJURER_MUSICIAN_BASE:-/data}"
|
||||
MUSIC="${CONJURER_MUSIC_FOLDER:-/music}"
|
||||
mkdir -p "$DATA" "$DATA/logs" "$MUSIC"
|
||||
|
||||
# The track-forwarding thread tails the Liquidsoap radio logs. When the radio
|
||||
# runs separately (or hasn't started yet) these files may not exist; create
|
||||
# them empty so the tailer waits instead of crashing.
|
||||
for f in radio_log.log persistence.log; do
|
||||
[ -e "$DATA/$f" ] || : > "$DATA/$f"
|
||||
done
|
||||
|
||||
# Ensure the managed playlists exist (routes/rescan also create them; this just
|
||||
# avoids a first-tick race before the initial scan).
|
||||
for f in all_playlist.playlist hit.playlist request.playlist priority_queue.playlist; do
|
||||
[ -e "$DATA/$f" ] || : > "$DATA/$f"
|
||||
done
|
||||
|
||||
exec "$@"
|
||||
@@ -130,22 +130,60 @@ docker logs -f conjurer-librarian
|
||||
|
||||
---
|
||||
|
||||
## 3. Musician (VM-musician) — you will adapt this
|
||||
## 3. Musician (VM-musician)
|
||||
|
||||
The web service is container-ready (`docker/Dockerfile.musician` +
|
||||
`compose.musician.yaml`). Note it containerises the **Flask file/playlist
|
||||
service only**; the Liquidsoap radio (`radio_conjurer.liq`) and any
|
||||
`compose.musician.yaml`). It containerises the **Flask file/playlist service
|
||||
only** — the Liquidsoap radio (`radio_conjurer.liq`), `script.params` and any
|
||||
Samba/NFS share tooling are separate and typically stay on the host or a
|
||||
dedicated setup.
|
||||
dedicated setup (you'll adapt those yourself).
|
||||
|
||||
### 3a. Two volumes: the library and the writable state
|
||||
|
||||
| Mount | Container path | Holds |
|
||||
|-------|---------------|-------|
|
||||
| `/srv/musician/music` | `/music` (`CONJURER_MUSIC_FOLDER`) | your mp3 library (indexed/served) |
|
||||
| `/srv/musician/data` | `/data` (`CONJURER_MUSICIAN_BASE`) | playlists, logs, `radio_log.log`/`persistence.log` |
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /srv/musician/music /srv/musician/data
|
||||
# point /srv/musician/music at (or copy in) your mp3s
|
||||
```
|
||||
|
||||
### 3b. Preserve existing playlists/state (optional)
|
||||
|
||||
If you already run the musician, copy its working playlists into the data
|
||||
volume so nothing is regenerated from scratch:
|
||||
|
||||
```bash
|
||||
sudo cp all_playlist.playlist hit.playlist request.playlist \
|
||||
priority_queue.playlist playlist.json /srv/musician/data/ 2>/dev/null || true
|
||||
```
|
||||
|
||||
The container's entrypoint (`docker/entrypoint.musician.sh`) creates any
|
||||
missing playlists and touches `radio_log.log` / `persistence.log` empty so the
|
||||
track-forwarding thread waits instead of crashing when the radio runs
|
||||
elsewhere. It never overwrites files you copied in.
|
||||
|
||||
### 3c. Configure and launch
|
||||
|
||||
```bash
|
||||
cp docker/env/musician.env.example docker/env/musician.env
|
||||
# edit: CONJURER_MAIN_BOT=http://BOT_VM_IP:5000, CONJURER_API_KEY, mount your mp3s at /music
|
||||
# edit: CONJURER_MAIN_BOT=http://BOT_VM_IP:5000 and CONJURER_API_KEY (match the bot)
|
||||
|
||||
docker compose -f docker/compose.musician.yaml up -d --build
|
||||
docker logs -f conjurer-musician
|
||||
```
|
||||
|
||||
### 3d. Radio coupling (if you keep Liquidsoap separate)
|
||||
|
||||
The musician only forwards "now playing" to the bot by tailing the radio's
|
||||
`radio_log.log` / `persistence.log`. To wire them up, have Liquidsoap write
|
||||
those two files into the same `/srv/musician/data` directory (or set
|
||||
`CONJURER_RADIO_LOG` / `CONJURER_PERSISTENCE_LOG` to wherever it writes). The
|
||||
`/stream` page template is served from the baked-in `/app/stream.html`
|
||||
(override with `CONJURER_STREAM_TEMPLATE` if you customise it).
|
||||
|
||||
---
|
||||
|
||||
## 4. Networking & auth
|
||||
|
||||
Reference in New Issue
Block a user