add vps/DEPLOY.md
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
# VPS deployment
|
||||
|
||||
Target: any VPS with Docker + Docker Compose, ports 80/443 free (and 8000
|
||||
if you want plain HTTP for very old stereos).
|
||||
|
||||
## 1. Lay out the bundle
|
||||
|
||||
```bash
|
||||
ssh root@YOUR_VPS
|
||||
mkdir -p /opt/airstudio/web/ai-radio && cd /opt/airstudio
|
||||
# copy from the repo: docker-compose.yml, Dockerfile.streamer, icecast.xml, Caddyfile
|
||||
```
|
||||
|
||||
## 2. Configure
|
||||
|
||||
```bash
|
||||
cp .env.vps.example .env
|
||||
$EDITOR .env # set ICECAST_SOURCE_PASSWORD, station name, MQTT
|
||||
$EDITOR icecast.xml # set the 3 passwords + hostname
|
||||
$EDITOR Caddyfile # set your domain
|
||||
```
|
||||
|
||||
`ICECAST_SOURCE_PASSWORD` in `.env` **must** match `<source-password>` in
|
||||
`icecast.xml` — the streamer authenticates with it.
|
||||
|
||||
## 3. Firewall
|
||||
|
||||
```bash
|
||||
ufw allow 22,80,443/tcp
|
||||
# optional plain-HTTP fallback for old stereos:
|
||||
ufw allow 8000/tcp
|
||||
```
|
||||
|
||||
## 4. Boot
|
||||
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
docker compose ps # icecast, radio-streamer, caddy all Up
|
||||
docker compose logs -f radio-streamer
|
||||
```
|
||||
|
||||
Expected streamer log: `live on icecast:8000/ai-radio.mp3` then
|
||||
`played <id>.mp3` lines as songs roll.
|
||||
|
||||
## 5. Verify
|
||||
|
||||
```bash
|
||||
# direct icecast:
|
||||
curl -sI http://localhost:8000/ai-radio.mp3 | head -1
|
||||
# via caddy (after DNS + cert issuance):
|
||||
curl -sI https://radio.example.com/ai-radio.mp3 | head -1
|
||||
```
|
||||
|
||||
In a desktop player: open the URL — you should hear the shipped playlist
|
||||
looping. (Empty web root → streamer waits; run the shipper once first.)
|
||||
|
||||
## 6. Ship from the generator
|
||||
|
||||
On the generator machine:
|
||||
|
||||
```bash
|
||||
SHIP_REMOTE_TARGET=root@YOUR_VPS:/opt/airstudio/web/ai-radio/ \
|
||||
SHIP_SSH_KEY=~/.ssh/id_ed25519_vps \
|
||||
LIBRARY_DIR=~/ai-radio/library \
|
||||
go run ./cmd/shipper
|
||||
```
|
||||
|
||||
New songs appear on air within one playlist lap.
|
||||
|
||||
## Operations
|
||||
|
||||
- **Restart everything:** `docker compose restart`
|
||||
- **Update streamer code:** `docker compose build streamer && docker compose up -d streamer`
|
||||
- **Admin UI:** `http://<vps>:8000/admin/` (user `admin`, your admin password)
|
||||
— shows listeners, mount status, kick sources.
|
||||
- **Logs:** `docker compose logs -f icecast radio-streamer caddy`
|
||||
- **MQTT check:** `mosquitto_sub -h BROKER -t airstudio/nowplaying -v`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Cause / fix |
|
||||
|---|---|
|
||||
| streamer: `icecast rejected source 401` | password mismatch between `.env` and `icecast.xml` |
|
||||
| streamer: `no playable files` | shipper hasn't run; check `web/ai-radio/` contents |
|
||||
| silence but stream "connected" | stale playlist pointing at missing mp3s — re-run shipper |
|
||||
| caddy 502 | icecast container down: `docker compose ps` |
|
||||
| no HTTPS cert | DNS not pointing at this VPS yet; check `docker compose logs caddy` |
|
||||
| stereo shows garbage titles | very old ID3v1-only player: titles come from ID3v1 — re-transcode (already written by shipper) |
|
||||
Reference in New Issue
Block a user