LetsEncrypt/Nginx Container Consolidation (#4995)
This commit is contained in:
parent
ce0e9cc78d
commit
ed65f0d785
|
@ -51,10 +51,6 @@ USER root
|
||||||
|
|
||||||
EXPOSE 80 2022
|
EXPOSE 80 2022
|
||||||
|
|
||||||
# Nginx Proxy environment variables.
|
|
||||||
ENV VIRTUAL_HOST="azuracast.local" \
|
|
||||||
HTTPS_METHOD="noredirect"
|
|
||||||
|
|
||||||
# Sensible default environment variables.
|
# Sensible default environment variables.
|
||||||
ENV LANG="en_US.UTF-8" \
|
ENV LANG="en_US.UTF-8" \
|
||||||
APPLICATION_ENV="production" \
|
APPLICATION_ENV="production" \
|
||||||
|
|
|
@ -14,6 +14,7 @@ return function (App\Event\BuildConsoleCommands $event) {
|
||||||
'azuracast:internal:sftp-event' => Command\Internal\SftpEventCommand::class,
|
'azuracast:internal:sftp-event' => Command\Internal\SftpEventCommand::class,
|
||||||
'azuracast:internal:sftp-auth' => Command\Internal\SftpAuthCommand::class,
|
'azuracast:internal:sftp-auth' => Command\Internal\SftpAuthCommand::class,
|
||||||
'azuracast:internal:nextsong' => Command\Internal\NextSongCommand::class,
|
'azuracast:internal:nextsong' => Command\Internal\NextSongCommand::class,
|
||||||
|
'azuracast:internal:on-ssl-renewal' => Command\Internal\OnSslRenewal::class,
|
||||||
'azuracast:internal:ip' => Command\Internal\GetIpCommand::class,
|
'azuracast:internal:ip' => Command\Internal\GetIpCommand::class,
|
||||||
'azuracast:locale:generate' => Command\Locale\GenerateCommand::class,
|
'azuracast:locale:generate' => Command\Locale\GenerateCommand::class,
|
||||||
'azuracast:locale:import' => Command\Locale\ImportCommand::class,
|
'azuracast:locale:import' => Command\Locale\ImportCommand::class,
|
||||||
|
|
|
@ -138,7 +138,6 @@ return function (CallableEventDispatcherInterface $dispatcher) {
|
||||||
App\Sync\Task\CleanupStorageTask::class,
|
App\Sync\Task\CleanupStorageTask::class,
|
||||||
App\Sync\Task\MoveBroadcastsTask::class,
|
App\Sync\Task\MoveBroadcastsTask::class,
|
||||||
App\Sync\Task\ReactivateStreamerTask::class,
|
App\Sync\Task\ReactivateStreamerTask::class,
|
||||||
App\Sync\Task\ReloadFrontendAfterSslChangeTask::class,
|
|
||||||
App\Sync\Task\RotateLogsTask::class,
|
App\Sync\Task\RotateLogsTask::class,
|
||||||
App\Sync\Task\RunAnalyticsTask::class,
|
App\Sync\Task\RunAnalyticsTask::class,
|
||||||
App\Sync\Task\RunAutomatedAssignmentTask::class,
|
App\Sync\Task\RunAutomatedAssignmentTask::class,
|
||||||
|
|
|
@ -1,17 +1,4 @@
|
||||||
services :
|
services :
|
||||||
nginx_proxy :
|
|
||||||
build :
|
|
||||||
context : ../docker-azuracast-nginx-proxy
|
|
||||||
volumes :
|
|
||||||
- ./util/local_ssl:/etc/nginx/certs
|
|
||||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
|
||||||
|
|
||||||
nginx_proxy_letsencrypt :
|
|
||||||
build :
|
|
||||||
context : ../docker-azuracast-nginx-proxy-letsencrypt
|
|
||||||
volumes :
|
|
||||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
|
||||||
|
|
||||||
web :
|
web :
|
||||||
build :
|
build :
|
||||||
context : .
|
context : .
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
environment:
|
||||||
|
VIRTUAL_HOST: ${LETSENCRYPT_HOST:-azuracast.local}
|
||||||
|
HTTPS_METHOD: noredirect
|
||||||
|
|
||||||
|
nginx_proxy:
|
||||||
|
container_name: nginx_proxy
|
||||||
|
image: "ghcr.io/azuracast/nginx_proxy:${AZURACAST_VERSION:-latest}"
|
||||||
|
ports:
|
||||||
|
- '80:80'
|
||||||
|
- '443:443'
|
||||||
|
volumes:
|
||||||
|
- letsencrypt:/etc/nginx/certs
|
||||||
|
- nginx_proxy_vhosts:/etc/nginx/vhost.d
|
||||||
|
- letsencrypt_html:/usr/share/nginx/html
|
||||||
|
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||||
|
environment:
|
||||||
|
NGINX_TIMEOUT: ${NGINX_TIMEOUT:-1800}
|
||||||
|
DEFAULT_HOST: ${LETSENCRYPT_HOST:-azuracast.local}
|
||||||
|
networks:
|
||||||
|
- frontend
|
||||||
|
depends_on:
|
||||||
|
- web
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
nginx_proxy_letsencrypt:
|
||||||
|
container_name: nginx_proxy_letsencrypt
|
||||||
|
image: "ghcr.io/azuracast/nginx_proxy_letsencrypt:${AZURACAST_VERSION:-latest}"
|
||||||
|
volumes_from:
|
||||||
|
- nginx_proxy
|
||||||
|
volumes:
|
||||||
|
- letsencrypt_acme:/etc/acme.sh
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
letsencrypt_html: { }
|
||||||
|
letsencrypt_acme: { }
|
||||||
|
nginx_proxy_vhosts: { }
|
|
@ -10,66 +10,34 @@
|
||||||
# with any changes you need to make.
|
# with any changes you need to make.
|
||||||
#
|
#
|
||||||
|
|
||||||
services :
|
services:
|
||||||
nginx_proxy :
|
web:
|
||||||
container_name : nginx_proxy
|
container_name: azuracast_web
|
||||||
image : "ghcr.io/azuracast/nginx_proxy:${AZURACAST_VERSION:-latest}"
|
image: "ghcr.io/azuracast/web:${AZURACAST_VERSION:-latest}"
|
||||||
ports :
|
|
||||||
- '${AZURACAST_HTTP_PORT:-80}:80'
|
|
||||||
- '${AZURACAST_HTTPS_PORT:-443}:443'
|
|
||||||
volumes :
|
|
||||||
- letsencrypt:/etc/nginx/certs
|
|
||||||
- nginx_proxy_vhosts:/etc/nginx/vhost.d
|
|
||||||
- letsencrypt_html:/usr/share/nginx/html
|
|
||||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
|
||||||
environment :
|
|
||||||
NGINX_TIMEOUT : ${NGINX_TIMEOUT:-1800}
|
|
||||||
DEFAULT_HOST : ${LETSENCRYPT_HOST:-azuracast.local}
|
|
||||||
networks :
|
|
||||||
- frontend
|
|
||||||
depends_on :
|
|
||||||
- web
|
|
||||||
restart : unless-stopped
|
|
||||||
|
|
||||||
nginx_proxy_letsencrypt :
|
|
||||||
container_name : nginx_proxy_letsencrypt
|
|
||||||
image : "ghcr.io/azuracast/nginx_proxy_letsencrypt:${AZURACAST_VERSION:-latest}"
|
|
||||||
volumes_from :
|
|
||||||
- nginx_proxy
|
|
||||||
volumes :
|
|
||||||
- letsencrypt_acme:/etc/acme.sh
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
||||||
environment :
|
|
||||||
DEFAULT_EMAIL: ${LETSENCRYPT_EMAIL:-}
|
|
||||||
networks :
|
|
||||||
- frontend
|
|
||||||
restart : unless-stopped
|
|
||||||
|
|
||||||
web :
|
|
||||||
container_name : azuracast_web
|
|
||||||
image : "ghcr.io/azuracast/web:${AZURACAST_VERSION:-latest}"
|
|
||||||
# Want to customize the HTTP/S ports? Follow the instructions here:
|
# Want to customize the HTTP/S ports? Follow the instructions here:
|
||||||
# https://docs.azuracast.com/en/administration/docker#using-non-standard-ports
|
# https://docs.azuracast.com/en/administration/docker#using-non-standard-ports
|
||||||
ports :
|
ports:
|
||||||
|
- '${AZURACAST_HTTP_PORT:-80}:80'
|
||||||
|
- '${AZURACAST_HTTPS_PORT:-443}:443'
|
||||||
- '${AZURACAST_SFTP_PORT:-2022}:2022'
|
- '${AZURACAST_SFTP_PORT:-2022}:2022'
|
||||||
depends_on :
|
depends_on:
|
||||||
- mariadb
|
- mariadb
|
||||||
- stations
|
- stations
|
||||||
- redis
|
- redis
|
||||||
env_file : azuracast.env
|
env_file: azuracast.env
|
||||||
environment :
|
environment:
|
||||||
LANG: ${LANG:-en_US.UTF-8}
|
LANG: ${LANG:-en_US.UTF-8}
|
||||||
AZURACAST_DC_REVISION: 12
|
AZURACAST_DC_REVISION: 13
|
||||||
AZURACAST_VERSION: ${AZURACAST_VERSION:-latest}
|
AZURACAST_VERSION: ${AZURACAST_VERSION:-latest}
|
||||||
AZURACAST_SFTP_PORT: ${AZURACAST_SFTP_PORT:-2022}
|
AZURACAST_SFTP_PORT: ${AZURACAST_SFTP_PORT:-2022}
|
||||||
VIRTUAL_HOST: ${LETSENCRYPT_HOST:-azuracast.local}
|
|
||||||
NGINX_TIMEOUT: ${NGINX_TIMEOUT:-1800}
|
NGINX_TIMEOUT: ${NGINX_TIMEOUT:-1800}
|
||||||
LETSENCRYPT_HOST: ${LETSENCRYPT_HOST:-}
|
LETSENCRYPT_HOST: ${LETSENCRYPT_HOST:-}
|
||||||
LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL:-}
|
LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL:-}
|
||||||
PUID: ${AZURACAST_PUID:-1000}
|
PUID: ${AZURACAST_PUID:-1000}
|
||||||
PGID: ${AZURACAST_PGID:-1000}
|
PGID: ${AZURACAST_PGID:-1000}
|
||||||
volumes :
|
volumes:
|
||||||
- letsencrypt:/etc/nginx/certs:ro
|
- letsencrypt:/etc/nginx/certs
|
||||||
|
- letsencrypt_acme:/etc/acme.sh
|
||||||
- www_vendor:/var/azuracast/www/vendor
|
- www_vendor:/var/azuracast/www/vendor
|
||||||
- www_uploads:/var/azuracast/uploads
|
- www_uploads:/var/azuracast/uploads
|
||||||
- tmp_data:/var/azuracast/www_tmp
|
- tmp_data:/var/azuracast/www_tmp
|
||||||
|
@ -78,49 +46,49 @@ services :
|
||||||
- geolite_install:/var/azuracast/geoip
|
- geolite_install:/var/azuracast/geoip
|
||||||
- sftpgo_data:/var/azuracast/sftpgo/persist
|
- sftpgo_data:/var/azuracast/sftpgo/persist
|
||||||
- backups:/var/azuracast/backups
|
- backups:/var/azuracast/backups
|
||||||
networks :
|
networks:
|
||||||
- frontend
|
- frontend
|
||||||
- backend
|
- backend
|
||||||
restart : unless-stopped
|
restart: unless-stopped
|
||||||
ulimits : &default-ulimits
|
ulimits: &default-ulimits
|
||||||
nofile :
|
nofile:
|
||||||
soft : 65536
|
soft: 65536
|
||||||
hard : 65536
|
hard: 65536
|
||||||
logging : &default-logging
|
logging: &default-logging
|
||||||
options :
|
options:
|
||||||
max-size : "1m"
|
max-size: "1m"
|
||||||
max-file : "5"
|
max-file: "5"
|
||||||
|
|
||||||
mariadb :
|
mariadb:
|
||||||
container_name : azuracast_mariadb
|
container_name: azuracast_mariadb
|
||||||
image : "ghcr.io/azuracast/db:${AZURACAST_VERSION:-latest}"
|
image: "ghcr.io/azuracast/db:${AZURACAST_VERSION:-latest}"
|
||||||
volumes :
|
volumes:
|
||||||
- db_data:/var/lib/mysql
|
- db_data:/var/lib/mysql
|
||||||
env_file : azuracast.env
|
env_file: azuracast.env
|
||||||
networks :
|
networks:
|
||||||
- backend
|
- backend
|
||||||
restart : unless-stopped
|
restart: unless-stopped
|
||||||
logging : *default-logging
|
logging: *default-logging
|
||||||
|
|
||||||
redis :
|
redis:
|
||||||
container_name : azuracast_redis
|
container_name: azuracast_redis
|
||||||
image : "ghcr.io/azuracast/redis:${AZURACAST_VERSION:-latest}"
|
image: "ghcr.io/azuracast/redis:${AZURACAST_VERSION:-latest}"
|
||||||
sysctls :
|
sysctls:
|
||||||
net.core.somaxconn : 1024
|
net.core.somaxconn: 1024
|
||||||
volumes :
|
volumes:
|
||||||
- redis_data:/data
|
- redis_data:/data
|
||||||
networks :
|
networks:
|
||||||
- backend
|
- backend
|
||||||
restart : unless-stopped
|
restart: unless-stopped
|
||||||
logging : *default-logging
|
logging: *default-logging
|
||||||
|
|
||||||
stations :
|
stations:
|
||||||
container_name : azuracast_stations
|
container_name: azuracast_stations
|
||||||
image : "ghcr.io/azuracast/radio:${AZURACAST_VERSION:-latest}"
|
image: "ghcr.io/azuracast/radio:${AZURACAST_VERSION:-latest}"
|
||||||
environment :
|
environment:
|
||||||
PUID : ${AZURACAST_PUID:-1000}
|
PUID: ${AZURACAST_PUID:-1000}
|
||||||
PGID : ${AZURACAST_PGID:-1000}
|
PGID: ${AZURACAST_PGID:-1000}
|
||||||
ports :
|
ports:
|
||||||
# This default mapping is the outgoing and incoming ports for the first 50 stations.
|
# This default mapping is the outgoing and incoming ports for the first 50 stations.
|
||||||
# You can override this port mapping in your own docker-compose.override.yml file.
|
# You can override this port mapping in your own docker-compose.override.yml file.
|
||||||
# For instructions, see:
|
# For instructions, see:
|
||||||
|
@ -272,37 +240,35 @@ services :
|
||||||
- '8490:8490'
|
- '8490:8490'
|
||||||
- '8495:8495'
|
- '8495:8495'
|
||||||
- '8496:8496'
|
- '8496:8496'
|
||||||
volumes :
|
volumes:
|
||||||
- station_data:/var/azuracast/stations
|
- station_data:/var/azuracast/stations
|
||||||
- shoutcast2_install:/var/azuracast/servers/shoutcast2
|
- shoutcast2_install:/var/azuracast/servers/shoutcast2
|
||||||
- letsencrypt:/etc/nginx/certs
|
- letsencrypt:/etc/nginx/certs
|
||||||
- tmp_data:/var/azuracast/www_tmp
|
- tmp_data:/var/azuracast/www_tmp
|
||||||
networks :
|
networks:
|
||||||
- frontend
|
- frontend
|
||||||
- backend
|
- backend
|
||||||
init : true
|
init: true
|
||||||
restart : unless-stopped
|
restart: unless-stopped
|
||||||
ulimits : *default-ulimits
|
ulimits: *default-ulimits
|
||||||
logging : *default-logging
|
logging: *default-logging
|
||||||
|
|
||||||
networks :
|
networks:
|
||||||
frontend :
|
frontend:
|
||||||
driver : bridge
|
driver: bridge
|
||||||
backend :
|
backend:
|
||||||
driver : bridge
|
driver: bridge
|
||||||
|
|
||||||
volumes :
|
volumes:
|
||||||
nginx_proxy_vhosts : { }
|
db_data: { }
|
||||||
db_data : { }
|
letsencrypt: { }
|
||||||
letsencrypt : { }
|
letsencrypt_acme: { }
|
||||||
letsencrypt_html : { }
|
shoutcast2_install: { }
|
||||||
letsencrypt_acme : { }
|
geolite_install: { }
|
||||||
shoutcast2_install : { }
|
sftpgo_data: { }
|
||||||
geolite_install : { }
|
station_data: { }
|
||||||
sftpgo_data : { }
|
www_vendor: { }
|
||||||
station_data : { }
|
www_uploads: { }
|
||||||
www_vendor : { }
|
tmp_data: { }
|
||||||
www_uploads : { }
|
redis_data: { }
|
||||||
tmp_data : { }
|
backups: { }
|
||||||
redis_data : { }
|
|
||||||
backups : { }
|
|
||||||
|
|
|
@ -444,8 +444,6 @@ install-dev() {
|
||||||
|
|
||||||
if [[ ! -d ../docker-azuracast-nginx-proxy ]]; then
|
if [[ ! -d ../docker-azuracast-nginx-proxy ]]; then
|
||||||
if ask "Clone related repositories?" Y; then
|
if ask "Clone related repositories?" Y; then
|
||||||
git clone https://github.com/AzuraCast/docker-azuracast-nginx-proxy.git ../docker-azuracast-nginx-proxy
|
|
||||||
git clone https://github.com/AzuraCast/docker-azuracast-nginx-proxy-letsencrypt.git ../docker-azuracast-nginx-proxy-letsencrypt
|
|
||||||
git clone https://github.com/AzuraCast/docker-azuracast-db.git ../docker-azuracast-db
|
git clone https://github.com/AzuraCast/docker-azuracast-db.git ../docker-azuracast-db
|
||||||
git clone https://github.com/AzuraCast/docker-azuracast-redis.git ../docker-azuracast-redis
|
git clone https://github.com/AzuraCast/docker-azuracast-redis.git ../docker-azuracast-redis
|
||||||
git clone https://github.com/AzuraCast/docker-azuracast-radio.git ../docker-azuracast-radio
|
git clone https://github.com/AzuraCast/docker-azuracast-radio.git ../docker-azuracast-radio
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Console\Command\Internal;
|
||||||
|
|
||||||
|
use App\Console\Command\CommandAbstract;
|
||||||
|
use App\Entity;
|
||||||
|
use App\Radio\Adapters;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
#[AsCommand(
|
||||||
|
name: 'azuracast:internal:on-ssl-renewal',
|
||||||
|
description: 'Reload broadcast frontends when an SSL certificate changes.',
|
||||||
|
)]
|
||||||
|
class OnSslRenewal extends CommandAbstract
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
protected EntityManagerInterface $em,
|
||||||
|
protected Adapters $adapters,
|
||||||
|
) {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
|
{
|
||||||
|
$stations = $this->em->createQuery(
|
||||||
|
<<<'DQL'
|
||||||
|
SELECT s FROM App\Entity\Station s
|
||||||
|
DQL
|
||||||
|
)->toIterable();
|
||||||
|
|
||||||
|
foreach ($stations as $station) {
|
||||||
|
/** @var Entity\Station $station */
|
||||||
|
$frontend = $this->adapters->getFrontendAdapter($station);
|
||||||
|
if ($frontend->supportsReload()) {
|
||||||
|
$frontend->reload($station);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,19 +12,20 @@ class CertificateLocator
|
||||||
{
|
{
|
||||||
$environment = Environment::getInstance();
|
$environment = Environment::getInstance();
|
||||||
|
|
||||||
if (!empty($_ENV['VIRTUAL_HOST']) && $environment->isDockerRevisionAtLeast(10)) {
|
if ($environment->isDockerRevisionAtLeast(10)) {
|
||||||
$vhost = $_ENV['VIRTUAL_HOST'];
|
|
||||||
|
|
||||||
// Check environment variable for a virtual host.
|
// Check environment variable for a virtual host.
|
||||||
$certBase = '/etc/nginx/certs';
|
$certBase = '/etc/nginx/certs';
|
||||||
|
|
||||||
if (is_dir($certBase)) {
|
if (is_dir($certBase)) {
|
||||||
|
if (!empty($_ENV['VIRTUAL_HOST'])) {
|
||||||
|
$vhost = $_ENV['VIRTUAL_HOST'];
|
||||||
$domainKey = $certBase . '/' . $vhost . '.key';
|
$domainKey = $certBase . '/' . $vhost . '.key';
|
||||||
$domainCert = $certBase . '/' . $vhost . '.crt';
|
$domainCert = $certBase . '/' . $vhost . '.crt';
|
||||||
|
|
||||||
if (file_exists($domainKey) && file_exists($domainCert)) {
|
if (file_exists($domainKey) && file_exists($domainCert)) {
|
||||||
return new Certificate($domainKey, $domainCert);
|
return new Certificate($domainKey, $domainCert);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$defaultKey = $certBase . '/default.key';
|
$defaultKey = $certBase . '/default.key';
|
||||||
$defaultCert = $certBase . '/default.crt';
|
$defaultCert = $certBase . '/default.crt';
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\Sync\Task;
|
|
||||||
|
|
||||||
use App\Doctrine\ReloadableEntityManagerInterface;
|
|
||||||
use App\Entity\Repository\SettingsRepository;
|
|
||||||
use App\Radio\Adapters;
|
|
||||||
use App\Radio\CertificateLocator;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
|
|
||||||
class ReloadFrontendAfterSslChangeTask extends AbstractTask
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
protected Adapters $adapters,
|
|
||||||
protected SettingsRepository $settingsRepo,
|
|
||||||
ReloadableEntityManagerInterface $em,
|
|
||||||
LoggerInterface $logger
|
|
||||||
) {
|
|
||||||
parent::__construct($em, $logger);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getSchedulePattern(): string
|
|
||||||
{
|
|
||||||
return '2,19,32,47 * * * *';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function run(bool $force = false): void
|
|
||||||
{
|
|
||||||
$threshold = time() - 15;
|
|
||||||
|
|
||||||
$certs = CertificateLocator::findCertificate();
|
|
||||||
|
|
||||||
$pathsToCheck = [
|
|
||||||
$certs->getCertPath(),
|
|
||||||
$certs->getKeyPath(),
|
|
||||||
];
|
|
||||||
|
|
||||||
$certsUpdated = false;
|
|
||||||
foreach ($pathsToCheck as $path) {
|
|
||||||
if (file_exists($path) && filemtime($path) > $threshold) {
|
|
||||||
$certsUpdated = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($certsUpdated) {
|
|
||||||
$this->logger->info('SSL certificates have updated; hot-reloading stations that support it.');
|
|
||||||
|
|
||||||
foreach ($this->iterateStations() as $station) {
|
|
||||||
$frontend = $this->adapters->getFrontendAdapter($station);
|
|
||||||
if ($frontend->supportsReload()) {
|
|
||||||
$frontend->reload($station);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$this->logger->info('SSL certificates have not updated.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -66,6 +66,18 @@ server {
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
|
listen 443 default_server http2 ssl;
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/certs/default.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/certs/default.key;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.3 TLSv1.2;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_ecdh_curve secp521r1:secp384r1;
|
||||||
|
ssl_ciphers EECDH+AESGCM:EECDH+AES256;
|
||||||
|
|
||||||
|
ssl_session_cache shared:TLS:2m;
|
||||||
|
ssl_buffer_size 4k;
|
||||||
|
|
||||||
root /var/azuracast/www/web;
|
root /var/azuracast/www/web;
|
||||||
index index.php;
|
index index.php;
|
||||||
|
@ -76,6 +88,12 @@ server {
|
||||||
add_header X-Content-Type-Options nosniff;
|
add_header X-Content-Type-Options nosniff;
|
||||||
add_header Referrer-Policy no-referrer-when-downgrade;
|
add_header Referrer-Policy no-referrer-when-downgrade;
|
||||||
|
|
||||||
|
# LetsEncrypt handling
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
|
||||||
# Serve a static version of the nowplaying data for non-PHP-blocking delivery.
|
# Serve a static version of the nowplaying data for non-PHP-blocking delivery.
|
||||||
location /api/nowplaying_static {
|
location /api/nowplaying_static {
|
||||||
expires 10s;
|
expires 10s;
|
||||||
|
|
|
@ -0,0 +1,190 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Acme loading script
|
||||||
|
# Uses code from:
|
||||||
|
# https://github.com/nginx-proxy/acme-companion/blob/main/app/letsencrypt_service
|
||||||
|
|
||||||
|
# We set a "LOG_LEVEL" that is incompatible with acme.sh. Overwrite it.
|
||||||
|
export LOG_LEVEL=1
|
||||||
|
export DEBUG=1
|
||||||
|
|
||||||
|
shopt -s expand_aliases
|
||||||
|
. /usr/local/acme.sh/acme.sh.env
|
||||||
|
|
||||||
|
# Convert argument to lowercase (bash 4 only)
|
||||||
|
function lc() {
|
||||||
|
echo "${@,,}"
|
||||||
|
}
|
||||||
|
|
||||||
|
CERTS_UPDATE_INTERVAL="${CERTS_UPDATE_INTERVAL:-3600}"
|
||||||
|
ACME_CA_URI="${ACME_CA_URI:-"https://acme-v02.api.letsencrypt.org/directory"}"
|
||||||
|
ACME_CA_TEST_URI="https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||||
|
DEFAULT_KEY_SIZE="${DEFAULT_KEY_SIZE:-4096}"
|
||||||
|
RENEW_PRIVATE_KEYS="$(lc "${RENEW_PRIVATE_KEYS:-true}")"
|
||||||
|
|
||||||
|
# Backward compatibility environment variable
|
||||||
|
REUSE_PRIVATE_KEYS="$(lc "${REUSE_PRIVATE_KEYS:-false}")"
|
||||||
|
|
||||||
|
function update_cert {
|
||||||
|
local hosts_array
|
||||||
|
IFS=',' read -ra hosts_array <<< "$LETSENCRYPT_HOST"
|
||||||
|
|
||||||
|
local base_domain="${hosts_array[0]}"
|
||||||
|
|
||||||
|
# Base CLI parameters array, used for both --register-account and --issue
|
||||||
|
local -a params_base_arr
|
||||||
|
|
||||||
|
params_base_arr+=(--log /dev/null)
|
||||||
|
[[ "$DEBUG" == 1 ]] && params_base_arr+=(--debug 2)
|
||||||
|
|
||||||
|
# Alternative trusted root CA path, used for test with Pebble
|
||||||
|
if [[ -n "${CA_BUNDLE// }" ]]; then
|
||||||
|
if [[ -f "$CA_BUNDLE" ]]; then
|
||||||
|
params_base_arr+=(--ca-bundle "$CA_BUNDLE")
|
||||||
|
[[ "$DEBUG" == 1 ]] && echo "Debug: acme.sh will use $CA_BUNDLE as trusted root CA."
|
||||||
|
else
|
||||||
|
echo "Warning: the path to the alternate CA bundle ($CA_BUNDLE) is not valid, using default Alpine trust store."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# CLI parameters array used for --register-account
|
||||||
|
local -a params_register_arr
|
||||||
|
|
||||||
|
# CLI parameters array used for --issue
|
||||||
|
local -a params_issue_arr
|
||||||
|
params_issue_arr+=(--webroot /usr/share/nginx/html)
|
||||||
|
|
||||||
|
local -n cert_keysize="LETSENCRYPT_KEYSIZE"
|
||||||
|
if [[ -z "$cert_keysize" ]] || \
|
||||||
|
[[ ! "$cert_keysize" =~ ^(2048|3072|4096|ec-256|ec-384)$ ]]; then
|
||||||
|
cert_keysize=$DEFAULT_KEY_SIZE
|
||||||
|
fi
|
||||||
|
params_issue_arr+=(--keylength "$cert_keysize")
|
||||||
|
|
||||||
|
# OCSP-Must-Staple extension
|
||||||
|
local -n ocsp="ACME_OCSP"
|
||||||
|
if [[ $(lc "$ocsp") == true ]]; then
|
||||||
|
params_issue_arr+=(--ocsp-must-staple)
|
||||||
|
fi
|
||||||
|
|
||||||
|
local -n accountemail="LETSENCRYPT_EMAIL"
|
||||||
|
local config_home
|
||||||
|
# If we don't have a LETSENCRYPT_EMAIL from the proxied container
|
||||||
|
# and DEFAULT_EMAIL is set to a non empty value, use the latter.
|
||||||
|
if [[ -z "$accountemail" ]]; then
|
||||||
|
if [[ -n "${DEFAULT_EMAIL// }" ]]; then
|
||||||
|
accountemail="$DEFAULT_EMAIL"
|
||||||
|
else
|
||||||
|
unset accountemail
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "${accountemail// }" ]]; then
|
||||||
|
# If we got an email, use it with the corresponding config home
|
||||||
|
config_home="/etc/acme.sh/$accountemail"
|
||||||
|
else
|
||||||
|
# If we did not get any email at all, use the default (empty mail) config
|
||||||
|
config_home="/etc/acme.sh/default"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local -n acme_ca_uri="ACME_CA_URI"
|
||||||
|
if [[ -z "$acme_ca_uri" ]]; then
|
||||||
|
# Use default or user provided ACME end point
|
||||||
|
acme_ca_uri="$ACME_CA_URI"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# LETSENCRYPT_TEST overrides LETSENCRYPT_ACME_CA_URI
|
||||||
|
local -n test_certificate="LETSENCRYPT_TEST"
|
||||||
|
if [[ $(lc "$test_certificate") == true ]]; then
|
||||||
|
# Use Let's Encrypt ACME V2 staging end point
|
||||||
|
acme_ca_uri="$ACME_CA_TEST_URI"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set relevant --server parameter and ca folder name
|
||||||
|
params_base_arr+=(--server "$acme_ca_uri")
|
||||||
|
local ca_dir="${acme_ca_uri##*://}" \
|
||||||
|
&& ca_dir="${ca_dir%%:*}"
|
||||||
|
|
||||||
|
local certificate_dir
|
||||||
|
# If we're going to use one of LE stating endpoints ...
|
||||||
|
if [[ "$acme_ca_uri" =~ ^https://acme-staging.* ]]; then
|
||||||
|
# Unset accountemail
|
||||||
|
# force config dir to 'staging'
|
||||||
|
unset accountemail
|
||||||
|
config_home="/etc/acme.sh/staging"
|
||||||
|
# Prefix test certificate directory with _test_
|
||||||
|
certificate_dir="/etc/nginx/certs/_test_"
|
||||||
|
else
|
||||||
|
certificate_dir="/etc/nginx/certs"
|
||||||
|
fi
|
||||||
|
|
||||||
|
params_issue_arr+=( \
|
||||||
|
--cert-file "${certificate_dir}/default.crt" \
|
||||||
|
--key-file "${certificate_dir}/default.key" \
|
||||||
|
--reloadcmd "/usr/local/bin/on_ssl_renewal" \
|
||||||
|
)
|
||||||
|
|
||||||
|
[[ ! -d "$config_home" ]] && mkdir -p "$config_home"
|
||||||
|
|
||||||
|
params_base_arr+=(--config-home "$config_home")
|
||||||
|
local account_file="${config_home}/ca/${ca_dir}/account.json"
|
||||||
|
|
||||||
|
if [[ -n "${accountemail// }" ]]; then
|
||||||
|
# We're not using Zero SSL, register the ACME account using the provided email.
|
||||||
|
params_register_arr+=(--accountemail "$accountemail")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Account registration and update if required
|
||||||
|
if [[ ! -f "$account_file" ]]; then
|
||||||
|
params_register_arr=("${params_base_arr[@]}" "${params_register_arr[@]}")
|
||||||
|
[[ "$DEBUG" == 1 ]] && echo "Calling acme.sh --register-account with the following parameters : ${params_register_arr[*]}"
|
||||||
|
acme.sh --register-account "${params_register_arr[@]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "${accountemail// }" ]] && ! grep -q "mailto:$accountemail" "$account_file"; then
|
||||||
|
local -a params_update_arr=("${params_base_arr[@]}" --accountemail "$accountemail")
|
||||||
|
[[ "$DEBUG" == 1 ]] && echo "Calling acme.sh --update-account with the following parameters : ${params_update_arr[*]}"
|
||||||
|
acme.sh --update-account "${params_update_arr[@]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If we still don't have an account.json file by this point, we've got an issue
|
||||||
|
if [[ ! -f "$account_file" ]]; then
|
||||||
|
echo "Error: no ACME account was found or registered for $accountemail and $acme_ca_uri, certificate creation aborted."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local -n acme_preferred_chain="ACME_PREFERRED_CHAIN"
|
||||||
|
if [[ -n "${acme_preferred_chain}" ]]; then
|
||||||
|
# Using amce.sh --preferred-chain to select alternate chain.
|
||||||
|
params_issue_arr+=(--preferred-chain "$acme_preferred_chain")
|
||||||
|
fi
|
||||||
|
if [[ "$RENEW_PRIVATE_KEYS" != 'false' && "$REUSE_PRIVATE_KEYS" != 'true' ]]; then
|
||||||
|
params_issue_arr+=(--always-force-new-domain-key)
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ "${2:-}" == "--force-renew" ]] && params_issue_arr+=(--force)
|
||||||
|
|
||||||
|
# Create directory for the first domain
|
||||||
|
mkdir -p "$certificate_dir"
|
||||||
|
|
||||||
|
for domain in "${hosts_array[@]}"; do
|
||||||
|
# Add all the domains to certificate
|
||||||
|
params_issue_arr+=(--domain "$domain")
|
||||||
|
done
|
||||||
|
|
||||||
|
params_issue_arr=("${params_base_arr[@]}" "${params_issue_arr[@]}")
|
||||||
|
[[ "$DEBUG" == 1 ]] && echo "Calling acme.sh --issue with the following parameters : ${params_issue_arr[*]}"
|
||||||
|
echo "Creating/renewal $base_domain certificates... (${hosts_array[*]})"
|
||||||
|
acme.sh --issue "${params_issue_arr[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ ! -z "$VIRTUAL_HOST" ]; then
|
||||||
|
echo "Multi-site configuration detected; skipping local ACME setup."
|
||||||
|
elif [ ! -z "$LETSENCRYPT_HOST" -a "$LETSENCRYPT_HOST" != " " ]; then
|
||||||
|
update_cert "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Wait some amount of time
|
||||||
|
echo "Sleep for ${CERTS_UPDATE_INTERVAL}s"
|
||||||
|
sleep $CERTS_UPDATE_INTERVAL
|
||||||
|
exit
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
echo 'Spinning up Beanstalkd process...'
|
echo 'Spinning up Beanstalkd process...'
|
||||||
|
|
||||||
setuser azuracast beanstalkd -p 11300 -z 262140
|
exec sudo -E -u azuracast beanstalkd -p 11300 -z 262140
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
nginx -g "daemon off;"
|
exec nginx -g "daemon off;"
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
source /etc/php/.version
|
source /etc/php/.version
|
||||||
|
|
||||||
/usr/sbin/php-fpm${PHP_VERSION} -F --fpm-config /etc/php/${PHP_VERSION}/fpm/php-fpm.conf -c /etc/php/${PHP_VERSION}/fpm/
|
exec /usr/sbin/php-fpm${PHP_VERSION} -F --fpm-config /etc/php/${PHP_VERSION}/fpm/php-fpm.conf -c /etc/php/${PHP_VERSION}/fpm/
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
sudo -E -u azuracast php /var/azuracast/www/bin/console azuracast:sync:nowplaying
|
exec sudo -E -u azuracast php /var/azuracast/www/bin/console azuracast:sync:nowplaying
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
sudo -E -u azuracast php /var/azuracast/www/bin/console queue:process --worker-name=app_worker_0
|
exec sudo -E -u azuracast php /var/azuracast/www/bin/console queue:process --worker-name=app_worker_0
|
||||||
|
|
|
@ -4,4 +4,4 @@ echo 'Spinning up SFTP process...'
|
||||||
|
|
||||||
cd /var/azuracast/sftpgo
|
cd /var/azuracast/sftpgo
|
||||||
|
|
||||||
sudo -E -u azuracast sftpgo --config-dir=/var/azuracast/sftpgo serve -l "" > /proc/1/fd/1 2> /proc/1/fd/2
|
exec sudo -E -u azuracast sftpgo --config-dir=/var/azuracast/sftpgo serve -l "" > /proc/1/fd/1 2> /proc/1/fd/2
|
||||||
|
|
|
@ -2,9 +2,8 @@
|
||||||
|
|
||||||
if [ `whoami` != 'azuracast' ]; then
|
if [ `whoami` != 'azuracast' ]; then
|
||||||
echo 'This script must be run as the "azuracast" user. Rerunning...'
|
echo 'This script must be run as the "azuracast" user. Rerunning...'
|
||||||
setuser azuracast azuracast_cli "$@"
|
exec sudo -E -u azuracast azuracast azuracast_cli "$@"
|
||||||
exit $?
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd /var/azuracast/www
|
cd /var/azuracast/www
|
||||||
php bin/console "$@"
|
exec php bin/console "$@"
|
||||||
|
|
|
@ -32,4 +32,4 @@ else
|
||||||
composer install
|
composer install
|
||||||
fi
|
fi
|
||||||
|
|
||||||
azuracast_cli azuracast:setup "$@"
|
exec azuracast_cli azuracast:setup "$@"
|
||||||
|
|
|
@ -26,4 +26,4 @@ else
|
||||||
composer install
|
composer install
|
||||||
fi
|
fi
|
||||||
|
|
||||||
azuracast_cli azuracast:restore "$@"
|
exec azuracast_cli azuracast:restore "$@"
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
source /etc/container_environment.sh
|
source /etc/container_environment.sh
|
||||||
|
|
||||||
azuracast_cli azuracast:internal:sftp-auth "$@"
|
exec azuracast_cli azuracast:internal:sftp-auth "$@"
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
source /etc/container_environment.sh
|
source /etc/container_environment.sh
|
||||||
|
|
||||||
azuracast_cli azuracast:internal:sftp-event "$@"
|
exec azuracast_cli azuracast:internal:sftp-event "$@"
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
azuracast_install --update "$@"
|
exec azuracast_install --update "$@"
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
source /etc/container_environment.sh
|
source /etc/container_environment.sh
|
||||||
|
|
||||||
setuser azuracast "$@" >/proc/1/fd/1 2>/proc/1/fd/2
|
exec sudo -E -u azuracast "$@" >/proc/1/fd/1 2>/proc/1/fd/2
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
cd /var/azuracast/www
|
cd /var/azuracast/www
|
||||||
php bin/installer "$@"
|
exec php bin/installer "$@"
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
sv restart nginx
|
||||||
|
|
||||||
|
azuracast_cli azuracast:internal:on-ssl-renewal
|
|
@ -1,61 +0,0 @@
|
||||||
#!/usr/bin/python3
|
|
||||||
|
|
||||||
'''
|
|
||||||
Copyright (c) 2013-2015 Phusion Holding B.V.
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
'''
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import pwd
|
|
||||||
|
|
||||||
|
|
||||||
def abort(message):
|
|
||||||
sys.stderr.write("setuser: %s\n" % message)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
'''
|
|
||||||
A simple alternative to sudo that executes a command as a user by setting
|
|
||||||
the user ID and user parameters to those described by the system and then
|
|
||||||
using execvp(3) to execute the command without the necessity of a TTY
|
|
||||||
'''
|
|
||||||
|
|
||||||
username = sys.argv[1]
|
|
||||||
try:
|
|
||||||
user = pwd.getpwnam(username)
|
|
||||||
except KeyError:
|
|
||||||
abort("user %s not found" % username)
|
|
||||||
os.initgroups(username, user.pw_gid)
|
|
||||||
os.setgid(user.pw_gid)
|
|
||||||
os.setuid(user.pw_uid)
|
|
||||||
os.environ['USER'] = username
|
|
||||||
os.environ['HOME'] = user.pw_dir
|
|
||||||
os.environ['UID'] = str(user.pw_uid)
|
|
||||||
try:
|
|
||||||
os.execvp(sys.argv[2], sys.argv[2:])
|
|
||||||
except OSError as e:
|
|
||||||
abort("cannot execute %s: %s" % (sys.argv[2], str(e)))
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
|
||||||
if len(sys.argv) < 3:
|
|
||||||
sys.stderr.write("Usage: /sbin/setuser USERNAME COMMAND [args..]\n")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
main()
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
/usr/sbin/tmpreaper 12h --protect '.tmpreaper' --verbose \
|
exec /usr/sbin/tmpreaper 12h --protect '.tmpreaper' --verbose \
|
||||||
/tmp/azuracast_nginx_client \
|
/tmp/azuracast_nginx_client \
|
||||||
/tmp/azuracast_fastcgi_temp \
|
/tmp/azuracast_fastcgi_temp \
|
||||||
> /proc/1/fd/1 2> /proc/1/fd/2
|
> /proc/1/fd/1 2> /proc/1/fd/2
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
source /bd_build/buildconfig
|
||||||
|
set -x
|
||||||
|
|
||||||
|
# Get acme.sh ACME client source
|
||||||
|
mkdir /src
|
||||||
|
git -C /src clone https://github.com/acmesh-official/acme.sh.git
|
||||||
|
cd /src/acme.sh
|
||||||
|
|
||||||
|
# Install acme.sh in /app
|
||||||
|
./acme.sh --install \
|
||||||
|
--nocron \
|
||||||
|
--auto-upgrade 0 \
|
||||||
|
--home /usr/local/acme.sh \
|
||||||
|
--config-home /etc/acme.sh/default
|
||||||
|
|
||||||
|
# Make house cleaning
|
||||||
|
cd /
|
||||||
|
rm -rf /src
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Generate a self-signed certificate if one doesn't exist in the certs path.
|
||||||
|
if [ ! -f /etc/nginx/certs/default.crt ]; then
|
||||||
|
echo "Generating self-signed certificate..."
|
||||||
|
|
||||||
|
openssl req -new -nodes -x509 -subj "/C=US/ST=Texas/L=Austin/O=IT/CN=localhost" \
|
||||||
|
-days 365 -extensions v3_ca \
|
||||||
|
-keyout /etc/nginx/certs/default.key \
|
||||||
|
-out /etc/nginx/certs/default.crt
|
||||||
|
fi
|
Loading…
Reference in New Issue