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
|
&& pip install --no-cache-dir -r requirements_musician.txt
|
||||||
|
|
||||||
COPY conjurer_musician/ ./
|
COPY conjurer_musician/ ./
|
||||||
|
COPY docker/entrypoint.musician.sh /usr/local/bin/entrypoint.sh
|
||||||
|
RUN chmod +x /usr/local/bin/entrypoint.sh
|
||||||
|
|
||||||
ENV PYTHONUNBUFFERED=1 \
|
ENV PYTHONUNBUFFERED=1 \
|
||||||
CONJURER_MUSICIAN_HOST=0.0.0.0 \
|
CONJURER_MUSICIAN_HOST=0.0.0.0 \
|
||||||
CONJURER_MUSICIAN_PORT=5000 \
|
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).
|
# /music = the mp3 library (read-only ok); /data = writable playlists + logs.
|
||||||
VOLUME ["/music"]
|
VOLUME ["/music", "/data"]
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||||
CMD ["python", "conjurer_musician.py"]
|
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` +
|
The web service is container-ready (`docker/Dockerfile.musician` +
|
||||||
`compose.musician.yaml`). Note it containerises the **Flask file/playlist
|
`compose.musician.yaml`). It containerises the **Flask file/playlist service
|
||||||
service only**; the Liquidsoap radio (`radio_conjurer.liq`) and any
|
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
|
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
|
```bash
|
||||||
sudo mkdir -p /srv/musician/music /srv/musician/data
|
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
|
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 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
|
## 4. Networking & auth
|
||||||
|
|||||||
Reference in New Issue
Block a user