Встроенный веб-сервер: почему ваш сайт и радио должны быть в одном процессе

Как файловая структура вместо админки, встроенная обработка форм и единый порт меняют подход к управлению интернет-радио.

Когда вы запускаете интернет-радио, вы неизбежно сталкиваетесь с вопросом: «А где будет жить сайт?». Классический подход подразумевает разделение ответственности. Icecast работает на одном порту, отдавая аудиопоток. Nginx или Apache — на другом, раздавая HTML-страницы, PHP-скрипты для плеера, формы обратной связи и, возможно, WordPress для блога. Между ними — мосты, прокси, CORS-настройки и куча мест, где всё может пойти не так.

Мы пошли другим путем. В нашем решении на Go веб-сервер встроен в радио-ядро. Это не просто «удобная фича», это архитектурное решение, которое меняет подход к управлению станцией. Никаких больше sudo apt install apache php mysql, никаких виртуальных хостов и танцев с FastCGI. Просто запустили приложение — и у вас есть и радио, и сайт, и API.

Но самое интересное — это то, как мы реализовали управление контентом. Без админки, без базы данных для текстов, без сложных CMS. Всё строится на простой файловой структуре.

Почему классический стек разделяет сайт и радио

Исторически сложилось, что Icecast — это специализированный инструмент, который умеет только отдавать аудио. Всё, что связано с веб-интерфейсом, ложится на плечи сторонних решений:

  1. Icecast + Nginx/Apache: Вам нужно поднимать отдельный веб-сервер. Настроить виртуальные хосты, пробросить порты, обеспечить, чтобы плеер на сайте мог обращаться к Icecast без CORS-ошибок. Это означает дополнительные файлы конфигурации, отдельные сервисы в systemd, отдельные логи.
  2. CMS для сайта: Если вы хотите вести блог, публиковать новости, вам понадобится WordPress, Jekyll или что-то подобное. Это база данных, PHP-интерпретатор, настройка прав доступа, обновления безопасности. Всё это — дополнительная поверхность для атак и головная боль.
  3. Обработка форм: Форма обратной связи? Подписка на уведомления? В классической схеме вам нужен PHP-скрипт (или Python/Node.js), который примет POST-запрос, отправит письмо через SMTP и сохранит данные в базу. Это ещё один компонент, который может упасть.
  4. Проблема связности: Каждый дополнительный компонент — это точка отказа. Если Nginx упал, сайт недоступен, но радио может работать. Если упал Icecast — радио молчит, а сайт висит. Вы получаете два независимых сервиса, за которыми нужно следить.
«Классический подход превращает радиостанцию в распределенную систему из 3–5 компонентов, каждый из которых требует отдельной настройки, мониторинга и обновлений. Вы приходили делать радио, а стали DevOps-инженером.»

Наш подход: один бинарник, один процесс, один порт

Наше Go-приложение объединяет в себе всё необходимое. При запуске оно поднимает HTTP-сервер, который одновременно:

Всё это работает на одном порту (обычно 8080), что упрощает настройку SSL (один сертификат на всё), проксирование и фаерволы. Но главное — это организация контента.

Сайт — это просто папка с файлами

Мы отказались от идеи «админки для сайта» (но в будущем при спросе может появится). Вы не заходите в редактор, не сохраняете посты в базу данных. Вы просто создаете файлы в определенной структуре папок на сервере. И они становятся доступны по HTTP. Мгновенно. Без перезагрузки, без кэширования, без лишних телодвижений.

/var/radio/
├── radio_app          # бинарник приложения
├── config.toml        # конфигурация
├── data/              # папка с музыкой, плейлистами
└── www/               # 👈 ЭТО ВАШ САЙТ
    ├── index.html     # главная страница
    ├── about.html     # страница "о радио"
    ├── blog/          # папка для блога
    │   ├── 2025-03-20-novinki.html
    │   ├── 2025-03-15-intervyu.html
    │   └── index.html # архив записей
    ├── contacts.html  # страница с формой
    ├── css/
    │   └── style.css
    └── js/
        └── player.js

Чтобы добавить новую статью в блог, вы просто:

  1. Создаете HTML-файл в папке www/content/blog/.
  2. Готово. Статья доступна по адресу http://ваше-радио/blog/2025-03-20-novinki.html.

Никакой базы данных, никаких SQL-инъекций, никаких обновлений WordPress. Просто файлы. Это надежно, прозрачно и легко поддается бэкапам.

Встроенная система обработки форм

Это отдельная история. Мы понимаем, что просто раздавать статику — мало. Нужно получать сообщения от слушателей: заявки на ротацию, вопросы, поздравления.

В наше приложение встроен обработчик форм. Вы просто добавляете на любую HTML-страницу форму с определенным классом или атрибутом, и система автоматически:

  • Принимает POST-запрос.
  • Валидирует поля (CSRF-защита, проверка email).
  • Сохраняет сообщение во встроенную админку.
  • Отправляет уведомление на email администратора.

Пример формы:

<form action="/api/form/submit" method="POST">
    <input type="text" name="name" placeholder="Ваше имя" required>
    <input type="email" name="email" placeholder="Email" required>
    <textarea name="message" placeholder="Ваше сообщение"></textarea>
    <button type="submit">Отправить</button>
</form>

Всю остальную логику (сохранение, отправку почты, защиту от спама) берет на себя приложение.

Встроенная админка для сообщений

Все присланные через формы сообщения попадают в админку вашего радио. Вам не нужно заходить в почтовый ящик или смотреть логи.

  • Список сообщений — хронология обращений, статусы (прочитано/не прочитано).
  • Просмотр — имя, email, текст сообщения, время отправки, IP-адрес.
  • Управление — можно посмотреть и пометить как обработанное.

И да, уведомления на почту приходят автоматически. Но даже если вы не проверили почту — сообщение никуда не денется, оно будет ждать вас в админке.

Почему файловая структура — это не «упрощение», а осознанный выбор

Может показаться, что отсутствие веб-админки для контента — это шаг назад. Но давайте посмотрим правде в глаза:

Что насчет динамического контента?

Вы можете спросить: «А если мне нужен не просто блог, а что-то сложнее — например, голосования, комментарии, личные кабинеты?»

Для этого у нас есть встроенное API. Вы можете писать любую клиентскую логику на JavaScript, которая будет обращаться к эндпоинтам нашего приложения:

Если вам нужна полноценная CMS — никто не мешает поставить ее отдельно, на поддомене, и проксировать через Nginx. Но наш опыт показывает: для 90% радиостанций возможностей встроенного веб-сервера более чем достаточно. Вы получаете сайт, блог, формы обратной связи, плеер и админку в одном флаконе, без необходимости разбираться в связке из пяти разных технологий.

Итог: радиовещание как монолит — это удобно

Мы не боимся слова «монолит». В эпоху микросервисов и распределенных систем часто забывают, что для маленьких и средних проектов монолит — это спасение. Один процесс, который умеет всё:

Вы устанавливаете один бинарник, кладете рядом папку www/ с вашим сайтом, запускаете — и готово. Сервер работает. Не нужно настраивать Nginx, писать PHP-обработчики форм, мучиться с CORS, поднимать отдельную базу данных для сообщений.

И главное: вы всегда знаете, как это устроено. Файловая структура прозрачна. Если через год вы решите переехать на другой хостинг — просто копируете папку. Никаких «а где у нас лежит база данных от WordPress?» и «какой пароль от SMTP был прописан в том скрипте, который мы написали в 2023-м?».

Мы сделали так, чтобы радио было не сложнее, чем запустить личный блог на статическом генераторе. Но с мощью профессионального аудиосервера внутри.

Сайт и радио в одном процессе

Забудьте о связке из Nginx, PHP, MySQL и Icecast. Один бинарник — вся инфраструктура. Попробуйте сами.

Попробовать DIY Радио со встроенным веб-сервером