Expand custom nginx config.

This commit is contained in:
Buster "Silver Eagle" Neece 2022-05-28 23:07:56 -05:00
parent 9791f8a0b7
commit 42e5b5210b
No known key found for this signature in database
GPG Key ID: F1D2E64A0005E80E
9 changed files with 92 additions and 46 deletions

View File

@ -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;
} }

View File

@ -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'),

View File

@ -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);
}
} }
} }

View File

@ -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
);
}
} }

39
src/Nginx/CustomUrls.php Normal file
View File

@ -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;
}
}

View File

@ -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';

View File

@ -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

View File

@ -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;

View File

@ -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 "*";