Expand custom nginx config.
This commit is contained in:
parent
9791f8a0b7
commit
42e5b5210b
|
@ -79,7 +79,7 @@ class RestartRadioCommand extends CommandAbstract
|
||||||
|
|
||||||
$this->nginx->writeConfiguration(
|
$this->nginx->writeConfiguration(
|
||||||
station: $station,
|
station: $station,
|
||||||
reloadIfChanged: !$noSupervisorRestart
|
reloadIfChanged: false
|
||||||
);
|
);
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
$io->error([
|
$io->error([
|
||||||
|
@ -90,6 +90,10 @@ class RestartRadioCommand extends CommandAbstract
|
||||||
$io->progressAdvance();
|
$io->progressAdvance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$noSupervisorRestart) {
|
||||||
|
$this->nginx->reload();
|
||||||
|
}
|
||||||
|
|
||||||
$io->progressFinish();
|
$io->progressFinish();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,12 @@ abstract class AbstractLogViewerController
|
||||||
|
|
||||||
$stationConfigDir = $station->getRadioConfigDir();
|
$stationConfigDir = $station->getRadioConfigDir();
|
||||||
|
|
||||||
|
$log_paths['station_nginx'] = [
|
||||||
|
'name' => __('Station Nginx Configuration'),
|
||||||
|
'path' => $stationConfigDir . '/nginx.conf',
|
||||||
|
'tail' => false,
|
||||||
|
];
|
||||||
|
|
||||||
if (BackendAdapters::Liquidsoap === $station->getBackendTypeEnum()) {
|
if (BackendAdapters::Liquidsoap === $station->getBackendTypeEnum()) {
|
||||||
$log_paths['liquidsoap_log'] = [
|
$log_paths['liquidsoap_log'] = [
|
||||||
'name' => __('Liquidsoap Log'),
|
'name' => __('Liquidsoap Log'),
|
||||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Http;
|
namespace App\Http;
|
||||||
|
|
||||||
|
use App\Nginx\CustomUrls;
|
||||||
use Azura\Files\Adapter\LocalAdapterInterface;
|
use Azura\Files\Adapter\LocalAdapterInterface;
|
||||||
use Azura\Files\ExtendedFilesystemInterface;
|
use Azura\Files\ExtendedFilesystemInterface;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
|
@ -134,21 +135,11 @@ final class Response extends \Slim\Http\Response
|
||||||
|
|
||||||
$adapter = $filesystem->getAdapter();
|
$adapter = $filesystem->getAdapter();
|
||||||
if ($adapter instanceof LocalAdapterInterface) {
|
if ($adapter instanceof LocalAdapterInterface) {
|
||||||
$localPath = $filesystem->getLocalPath($path);
|
|
||||||
|
|
||||||
// Special internal nginx routes to use X-Accel-Redirect for far more performant file serving.
|
// Special internal nginx routes to use X-Accel-Redirect for far more performant file serving.
|
||||||
$specialPaths = [
|
$accelPath = CustomUrls::getXAccelPath($filesystem->getLocalPath($path));
|
||||||
'/var/azuracast/backups' => '/internal/backups',
|
if (null !== $accelPath) {
|
||||||
'/var/azuracast/stations' => '/internal/stations',
|
return $response->withHeader('Content-Type', $fileMeta->mimeType() ?? '')
|
||||||
];
|
->withHeader('X-Accel-Redirect', $accelPath);
|
||||||
|
|
||||||
foreach ($specialPaths as $diskPath => $nginxPath) {
|
|
||||||
if (str_starts_with($localPath, $diskPath)) {
|
|
||||||
$accelPath = str_replace($diskPath, $nginxPath, $localPath);
|
|
||||||
|
|
||||||
return $response->withHeader('Content-Type', $fileMeta->mimeType() ?? '')
|
|
||||||
->withHeader('X-Accel-Redirect', $accelPath);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||||
namespace App\Nginx;
|
namespace App\Nginx;
|
||||||
|
|
||||||
use App\Event\Nginx\WriteNginxConfiguration;
|
use App\Event\Nginx\WriteNginxConfiguration;
|
||||||
|
use App\Radio\Enums\BackendAdapters;
|
||||||
use App\Radio\Enums\FrontendAdapters;
|
use App\Radio\Enums\FrontendAdapters;
|
||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
|
||||||
|
@ -18,6 +19,7 @@ final class ConfigWriter implements EventSubscriberInterface
|
||||||
return [
|
return [
|
||||||
WriteNginxConfiguration::class => [
|
WriteNginxConfiguration::class => [
|
||||||
['writeRadioSection', 35],
|
['writeRadioSection', 35],
|
||||||
|
['writeWebDjSection', 30],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -31,14 +33,14 @@ final class ConfigWriter implements EventSubscriberInterface
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$shortCode = $station->getShortName();
|
$listenBaseUrl = CustomUrls::getListenUrl($station);
|
||||||
|
|
||||||
$port = $station->getFrontendConfig()->getPort();
|
$port = $station->getFrontendConfig()->getPort();
|
||||||
|
|
||||||
$event->appendBlock(
|
$event->appendBlock(
|
||||||
<<<NGINX
|
<<<NGINX
|
||||||
# Reverse proxy the frontend broadcast.
|
# Reverse proxy the frontend broadcast.
|
||||||
location ~ ^/listen/{$shortCode}(/?)(.*)\$ {
|
location ~ ^{$listenBaseUrl}(/?)(.*)\$ {
|
||||||
include proxy_params;
|
include proxy_params;
|
||||||
|
|
||||||
proxy_intercept_errors on;
|
proxy_intercept_errors on;
|
||||||
|
@ -52,4 +54,29 @@ final class ConfigWriter implements EventSubscriberInterface
|
||||||
NGINX
|
NGINX
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function writeWebDjSection(WriteNginxConfiguration $event): void
|
||||||
|
{
|
||||||
|
$station = $event->getStation();
|
||||||
|
|
||||||
|
// Only forward Liquidsoap
|
||||||
|
if (BackendAdapters::Liquidsoap !== $station->getBackendTypeEnum()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$webDjBaseUrl = CustomUrls::getWebDjUrl($station);
|
||||||
|
|
||||||
|
$autoDjPort = $station->getBackendConfig()->getDjPort();
|
||||||
|
|
||||||
|
$event->appendBlock(
|
||||||
|
<<<NGINX
|
||||||
|
# Reverse proxy the WebDJ connection.
|
||||||
|
location ~ ^{$webDjBaseUrl}(/?)(.*)\$ {
|
||||||
|
include proxy_params;
|
||||||
|
|
||||||
|
proxy_pass http://127.0.0.1:{$autoDjPort}/$2;
|
||||||
|
}
|
||||||
|
NGINX
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Nginx;
|
||||||
|
|
||||||
|
use App\Entity\Station;
|
||||||
|
|
||||||
|
final class CustomUrls
|
||||||
|
{
|
||||||
|
public static function getListenUrl(Station $station): string
|
||||||
|
{
|
||||||
|
return '/listen/' . $station->getShortName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getWebDjUrl(Station $station): string
|
||||||
|
{
|
||||||
|
return '/webdj/' . $station->getShortName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a custom path if X-Accel-Redirect is configured for the path provided.
|
||||||
|
*/
|
||||||
|
public static function getXAccelPath(string $path): ?string
|
||||||
|
{
|
||||||
|
$specialPaths = [
|
||||||
|
'/var/azuracast/backups' => '/internal/backups',
|
||||||
|
'/var/azuracast/stations' => '/internal/stations',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($specialPaths as $diskPath => $nginxPath) {
|
||||||
|
if (str_starts_with($path, $diskPath)) {
|
||||||
|
return str_replace($diskPath, $nginxPath, $path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -39,7 +39,7 @@ final class Nginx
|
||||||
(new Filesystem())->dumpFile($configPath, $newConfig);
|
(new Filesystem())->dumpFile($configPath, $newConfig);
|
||||||
|
|
||||||
if ($reloadIfChanged) {
|
if ($reloadIfChanged) {
|
||||||
$this->supervisor->signalProcess(self::PROCESS_NAME, 'HUP');
|
$this->reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +57,11 @@ final class Nginx
|
||||||
return $event->buildConfiguration();
|
return $event->buildConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function reload(): void
|
||||||
|
{
|
||||||
|
$this->supervisor->signalProcess(self::PROCESS_NAME, 'HUP');
|
||||||
|
}
|
||||||
|
|
||||||
private function getConfigPath(Station $station): string
|
private function getConfigPath(Station $station): string
|
||||||
{
|
{
|
||||||
return $station->getRadioConfigDir() . '/nginx.conf';
|
return $station->getRadioConfigDir() . '/nginx.conf';
|
||||||
|
|
|
@ -7,6 +7,7 @@ namespace App\Radio\Backend;
|
||||||
use App\Entity;
|
use App\Entity;
|
||||||
use App\Event\Radio\WriteLiquidsoapConfiguration;
|
use App\Event\Radio\WriteLiquidsoapConfiguration;
|
||||||
use App\Exception;
|
use App\Exception;
|
||||||
|
use App\Nginx\CustomUrls;
|
||||||
use App\Radio\Enums\LiquidsoapQueues;
|
use App\Radio\Enums\LiquidsoapQueues;
|
||||||
use LogicException;
|
use LogicException;
|
||||||
use Psr\Http\Message\UriInterface;
|
use Psr\Http\Message\UriInterface;
|
||||||
|
@ -307,13 +308,11 @@ class Liquidsoap extends AbstractBackend
|
||||||
|
|
||||||
public function getWebStreamingUrl(Entity\Station $station, UriInterface $base_url): UriInterface
|
public function getWebStreamingUrl(Entity\Station $station, UriInterface $base_url): UriInterface
|
||||||
{
|
{
|
||||||
$stream_port = $this->getStreamPort($station);
|
|
||||||
|
|
||||||
$djMount = $station->getBackendConfig()->getDjMountPoint();
|
$djMount = $station->getBackendConfig()->getDjMountPoint();
|
||||||
|
|
||||||
return $base_url
|
return $base_url
|
||||||
->withScheme('wss')
|
->withScheme('wss')
|
||||||
->withPath($base_url->getPath() . '/radio/' . $stream_port . $djMount);
|
->withPath($base_url->getPath() . CustomUrls::getWebDjUrl($station) . $djMount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function verifyConfig(string $config): void
|
public function verifyConfig(string $config): void
|
||||||
|
|
|
@ -144,19 +144,6 @@ server {
|
||||||
proxy_pass http://127.0.0.1:$1/$3?$args;
|
proxy_pass http://127.0.0.1:$1/$3?$args;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Reverse proxy the Liquidsoap harbor inputs to allow for streaming.
|
|
||||||
location ~ ^/radio/(8[0-4][0-9]5)(/?)(.*)$ {
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_ignore_client_abort off;
|
|
||||||
proxy_send_timeout 21600;
|
|
||||||
proxy_read_timeout 21600;
|
|
||||||
|
|
||||||
proxy_pass http://127.0.0.1:$1/$3;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "Upgrade";
|
|
||||||
}
|
|
||||||
|
|
||||||
# pub/sub endpoints
|
# pub/sub endpoints
|
||||||
location ~ /api/live/nowplaying/([^\/]+)$ {
|
location ~ /api/live/nowplaying/([^\/]+)$ {
|
||||||
nchan_subscriber;
|
nchan_subscriber;
|
||||||
|
|
|
@ -159,18 +159,6 @@ server {
|
||||||
proxy_pass http://127.0.0.1:$1/$3?$args;
|
proxy_pass http://127.0.0.1:$1/$3?$args;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Reverse proxy the Liquidsoap harbor inputs to allow for streaming.
|
|
||||||
{{ if eq .Env.NGINX_WEBDJ_PORTS "default" }}
|
|
||||||
location ~ ^/radio/(8[0-9][0-9]5)(/?)(.*)$ {
|
|
||||||
{{ else }}
|
|
||||||
location ~ ^/radio/{{ .Env.NGINX_WEBDJ_PORTS }}(/?)(.*)$ {
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
include proxy_params;
|
|
||||||
|
|
||||||
proxy_pass http://127.0.0.1:$1/$3;
|
|
||||||
}
|
|
||||||
|
|
||||||
# pub/sub endpoints
|
# pub/sub endpoints
|
||||||
location ~ /api/live/nowplaying/([^\/]+)$ {
|
location ~ /api/live/nowplaying/([^\/]+)$ {
|
||||||
nchan_access_control_allow_origin "*";
|
nchan_access_control_allow_origin "*";
|
||||||
|
|
Loading…
Reference in New Issue