Skip to content

Запуск власного сервера ​

Мінімальна конфігурація не потребує ні хмарного сховища, ні бази даних — достатньо Node.js і теки з музикою.

Вимоги ​

  • Node.js 18+
  • FFmpeg — лише для stream-режиму і завантаження з YouTube
  • Python 3 + pip install -r server/src/tools/ytbdown/requirements.txt — лише для завантаження з YouTube

Установка ​

bash
git clone <репозиторій>
cd Radio
npm run install-all
cp server/.env.example server/.env
cp client/.env.example client/.env

Мінімальний server/.env ​

Три обов'язкові значення, решта має робочі типові:

ini
JWT_SECRET=<довгий випадковий рядок>
ADMIN_LOGIN=admin
ADMIN_PASS=<bcrypt-хеш>

DATA_PROVIDER=json
MEDIA_STORAGE=local

Хеш пароля генерується скриптом:

bash
cd server && node scripts/hash-password.js

ADMIN_PASS має бути саме хешем — сервер не приймає пароль у відкритому вигляді. Без JWT_SECRET сервер відмовиться стартувати.

Дозвольте походження свого клієнта ​

Це той крок, який найчастіше пропускають:

ini
CLIENT_ORIGIN=http://localhost:3000,http://localhost:5173

Значення перелічуються через кому й застосовуються і до HTTP, і до Socket.io. Клієнт з іншого походження буде заблокований браузером. Після зміни — перезапуск.

Музика ​

Покладіть аудіофайли у теки за режимами:

server/media/music/day/     ← денна ротація
server/media/music/night/   ← нічна ротація

Ідентифікатор треку в API — це шлях виду day/Виконавець - Назва.mp3.

Якщо нічний режим не потрібен, вимкніть його й радіо працюватиме цілодобово в денному:

ini
NIGHT_MODE=false

Запуск ​

bash
npm run dev --prefix server    # бекенд у режимі стеження
npm run dev --prefix client    # Vite dev-сервер

У продакшені клієнт збирається і роздається самим сервером:

bash
npm run build-client
npm start

Що вмикати далі ​

ХочуТреба
Кілька адмінів з роляминічого — обидва провайдери зберігають облікові записи
Завантаження пісень з адмінкинічого — працює і на локальному диску
Джингли між піснямиSTREAM_MODE=true (сховище будь-яке)
Живий ефір з мікрофономSTREAM_MODE=true + RADIO_HOSTS_MODE=true
Автоматичні тексти пісеньнічого — LRCLIB не потребує ні акаунта, ні ключа
Імпорт з YouTubeFFmpeg + python3 з pip-залежностями ytbdown (сховище будь-яке)

Як налаштувати кожен пункт — у Повній конфігурації. Зверніть увагу: жодна з можливостей не потребує хмарних сервісів — увесь функціонал доступний на локальному диску й локальній базі. Хмара і зовнішня база потрібні лише тоді, коли хостинг стирає файлову систему при деплої (див. Ефемерний хостинг).

RADIO_HOSTS_MODE=true без STREAM_MODE=true не спиняє сервер: живий ефір просто лишається вимкненим, а решта радіо працює.

Повний перелік змінних — у server/.env.example, кожна з коментарем.

Документація на своєму піддомені ​

Цю документацію віддає той самий сервіс, що й радіо: запити розводяться за іменем хоста. Що прийшло на документаційний хост — отримує зібраний VitePress з docs/.vitepress/dist, решта — клієнт радіо.

ini
DOCS_HOST=docs.example.com

Змінну можна не задавати: тоді документація віддається на будь-якому хості, перша мітка якого — docs.

Збирати треба обидва боки:

bash
npm run build     # клієнт + документація
npm start

Сенс тримати їх в одному деплої не лише в зручності. Довідник API генерується з коду сервера, тож спільне розгортання — це те, що гарантує: довідник описує саме той сервер, який зараз працює.

Розгортання на Render

Один Web Service, Build Command — npm run install-all && npm run build, Start Command — npm start. До цього ж сервісу додаються обидва домени (основний і docs.), сертифікати видаються автоматично.

install-all передає --include=dev для клієнта й документації: Render виставляє NODE_ENV=production, а без цього прапорця npm пропускає devDependencies, де й живуть Vite та VitePress.