diff --git a/Dockerfile b/Dockerfile index d768a738d..6f0e32520 100644 --- a/Dockerfile +++ b/Dockerfile @@ -41,33 +41,32 @@ COPY ./util/docker/common /bd_build/ RUN chmod a+x /bd_build/*.sh \ && /bd_build/prepare.sh \ && /bd_build/add_user.sh \ - && /bd_build/cleanup.sh + && /bd_build/cleanup.sh \ + && rm -rf /bd_build # Build each set of dependencies in their own step for cacheability. ARG ARM_FULL_BUILD + +COPY ./util/docker/supervisor /bd_build/supervisor/ +RUN bash /bd_build/supervisor/setup.sh \ + && rm -rf /bd_build/supervisor + COPY ./util/docker/stations /bd_build/stations/ RUN bash /bd_build/stations/setup.sh \ - && bash /bd_build/cleanup.sh \ && rm -rf /bd_build/stations COPY ./util/docker/web /bd_build/web/ RUN bash /bd_build/web/setup.sh \ - && bash /bd_build/cleanup.sh \ && rm -rf /bd_build/web COPY ./util/docker/mariadb /bd_build/mariadb/ RUN bash /bd_build/mariadb/setup.sh \ - && bash /bd_build/cleanup.sh \ && rm -rf /bd_build/mariadb COPY ./util/docker/redis /bd_build/redis/ RUN bash /bd_build/redis/setup.sh \ - && bash /bd_build/cleanup.sh \ && rm -rf /bd_build/redis -RUN bash /bd_build/post_setup.sh \ - && rm -rf /bd_build - # # START Operations as `azuracast` user # @@ -102,6 +101,7 @@ EXPOSE 8000-8999 ENV LANG="en_US.UTF-8" \ DOCKER_IS_STANDALONE="true" \ APPLICATION_ENV="production" \ + MARIADB_AUTO_UPGRADE=1 \ MYSQL_HOST="localhost" \ MYSQL_PORT=3306 \ MYSQL_USER="azuracast" \ @@ -122,5 +122,5 @@ ENV LANG="en_US.UTF-8" \ PROFILING_EXTENSION_HTTP_IP_WHITELIST=* # Entrypoint and default command -ENTRYPOINT ["/usr/local/bin/my_init"] +ENTRYPOINT ["tini", "--", "/usr/local/bin/my_init"] CMD ["--no-main-command"] diff --git a/config/cli.php b/config/cli.php index 43adf1bab..16181ebdb 100644 --- a/config/cli.php +++ b/config/cli.php @@ -7,9 +7,6 @@ return function (App\Event\BuildConsoleCommands $event) { 'azuracast:backup' => Command\Backup\BackupCommand::class, 'azuracast:restore' => Command\Backup\RestoreCommand::class, 'azuracast:debug:optimize-tables' => Command\Debug\OptimizeTablesCommand::class, - 'azuracast:internal:liquidsoap' => Command\Internal\LiquidsoapCommand::class, - 'azuracast:internal:sftp-event' => Command\Internal\SftpEventCommand::class, - 'azuracast:internal:sftp-auth' => Command\Internal\SftpAuthCommand::class, 'azuracast:internal:on-ssl-renewal' => Command\Internal\OnSslRenewal::class, 'azuracast:internal:ip' => Command\Internal\GetIpCommand::class, 'azuracast:locale:generate' => Command\Locale\GenerateCommand::class, diff --git a/config/routes/api.php b/config/routes/api.php index 2963ebafc..5088d654f 100644 --- a/config/routes/api.php +++ b/config/routes/api.php @@ -61,6 +61,12 @@ return static function (RouteCollectorProxy $app) { } )->add(Middleware\GetStation::class); + $group->post('/sftp-auth', Controller\Api\Internal\SftpAuthAction::class) + ->setName('api:internal:sftp-auth'); + + $group->post('/sftp-event', Controller\Api\Internal\SftpEventAction::class) + ->setName('api:internal:sftp-event'); + $group->get('/relays', Controller\Api\Admin\RelaysController::class) ->setName('api:internal:relays') ->add(Middleware\RequireLogin::class); diff --git a/src/Console/Command/Internal/LiquidsoapCommand.php b/src/Console/Command/Internal/LiquidsoapCommand.php deleted file mode 100644 index 90daa2dbf..000000000 --- a/src/Console/Command/Internal/LiquidsoapCommand.php +++ /dev/null @@ -1,100 +0,0 @@ -addArgument('action', InputArgument::REQUIRED) - ->addArgument('station-id', InputArgument::REQUIRED) - ->addOption( - 'as-autodj', - null, - InputOption::VALUE_NONE, - 'Whether the task is executing as the actual AutoDJ or as a test.' - ); - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - $io = new SymfonyStyle($input, $output); - - $stationId = $input->getArgument('station-id'); - $action = $input->getArgument('action'); - $asAutoDj = (bool)$input->getOption('as-autodj'); - - $payload = trim(getenv('PAYLOAD') ?: ''); - if (!empty($payload)) { - $payload = json_decode($payload, true, 512, JSON_THROW_ON_ERROR); - } else { - $payload = []; - } - - try { - $station = $this->stationRepo->findByIdentifier($stationId); - if (!($station instanceof Entity\Station)) { - throw new LogicException('Station not found.'); - } - - $command = LiquidsoapCommands::tryFrom($action); - if (null === $command || !$this->di->has($command->getClass())) { - throw new LogicException('Command not found.'); - } - - /** @var AbstractCommand $commandObj */ - $commandObj = $this->di->get($command->getClass()); - - $result = $commandObj->run($station, $asAutoDj, $payload); - $io->writeln($result); - } catch (Throwable $e) { - $this->logger->error( - sprintf( - 'Liquidsoap command "%s" error: %s', - $action, - $e->getMessage() - ), - [ - 'station' => $stationId, - 'payload' => $payload, - 'as-autodj' => $asAutoDj, - ] - ); - - $io->writeln('false'); - return 1; - } - - return 0; - } -} diff --git a/src/Console/Command/Internal/SftpAuthCommand.php b/src/Controller/Api/Internal/SftpAuthAction.php similarity index 58% rename from src/Console/Command/Internal/SftpAuthCommand.php rename to src/Controller/Api/Internal/SftpAuthAction.php index 76f26c8e8..52b880989 100644 --- a/src/Console/Command/Internal/SftpAuthCommand.php +++ b/src/Controller/Api/Internal/SftpAuthAction.php @@ -2,45 +2,40 @@ declare(strict_types=1); -namespace App\Console\Command\Internal; +namespace App\Controller\Api\Internal; -use App\Console\Command\CommandAbstract; use App\Entity\SftpUser; +use App\Http\Response; +use App\Http\ServerRequest; use Brick\Math\BigInteger; use Doctrine\ORM\EntityManagerInterface; +use Psr\Http\Message\ResponseInterface; use Psr\Log\LoggerInterface; -use Symfony\Component\Console\Attribute\AsCommand; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\SymfonyStyle; -use const JSON_THROW_ON_ERROR; - -#[AsCommand( - name: 'azuracast:internal:sftp-auth', - description: 'Attempt SFTP authentication.', -)] -class SftpAuthCommand extends CommandAbstract +final class SftpAuthAction { public function __construct( - protected EntityManagerInterface $em, - protected LoggerInterface $logger, + private readonly EntityManagerInterface $em, + private readonly LoggerInterface $logger, ) { - parent::__construct(); } - protected function execute(InputInterface $input, OutputInterface $output): int - { - $io = new SymfonyStyle($input, $output); - $errorResponse = json_encode(['username' => ''], JSON_THROW_ON_ERROR); + public function __invoke( + ServerRequest $request, + Response $response + ): ResponseInterface { + $errorResponse = $response + ->withStatus(500) + ->withJson(['username' => '']); - $username = getenv('SFTPGO_AUTHD_USERNAME') ?: ''; - $password = getenv('SFTPGO_AUTHD_PASSWORD') ?: ''; - $pubKey = getenv('SFTPGO_AUTHD_PUBLIC_KEY') ?: ''; + $parsedBody = $request->getParsedBody(); + + $username = $parsedBody['username'] ?? ''; + $password = $parsedBody['password'] ?? ''; + $pubKey = $parsedBody['public_key'] ?? ''; if (empty($username)) { - $io->write($errorResponse); - return 1; + return $errorResponse; } $sftpUser = $this->em->getRepository(SftpUser::class)->findOneBy(['username' => $username]); @@ -52,8 +47,7 @@ class SftpAuthCommand extends CommandAbstract ) ); - $io->write($errorResponse); - return 1; + return $errorResponse; } if (!$sftpUser->authenticate($password, $pubKey)) { @@ -68,8 +62,7 @@ class SftpAuthCommand extends CommandAbstract ] ); - $io->write($errorResponse); - return 1; + return $errorResponse; } $storageLocation = $sftpUser->getStation()->getMediaStorageLocation(); @@ -83,8 +76,7 @@ class SftpAuthCommand extends CommandAbstract ) ); - $io->write($errorResponse); - return 1; + return $errorResponse; } $quotaRaw = $storageLocation->getStorageQuotaBytes(); @@ -105,7 +97,6 @@ class SftpAuthCommand extends CommandAbstract ], ]; - $io->write(json_encode($row, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK)); - return 0; + return $response->withJson($row); } } diff --git a/src/Console/Command/Internal/SftpEventCommand.php b/src/Controller/Api/Internal/SftpEventAction.php similarity index 53% rename from src/Console/Command/Internal/SftpEventCommand.php rename to src/Controller/Api/Internal/SftpEventAction.php index 3a37d8b0f..405bf89ab 100644 --- a/src/Console/Command/Internal/SftpEventCommand.php +++ b/src/Controller/Api/Internal/SftpEventAction.php @@ -2,90 +2,104 @@ declare(strict_types=1); -namespace App\Console\Command\Internal; +namespace App\Controller\Api\Internal; -use App\Console\Command\CommandAbstract; -use App\Entity; +use App\Entity\SftpUser; +use App\Entity\StorageLocation; +use App\Http\Response; +use App\Http\ServerRequest; use App\Media\BatchUtilities; -use App\Message; +use App\Message\AddNewMediaMessage; use Doctrine\ORM\EntityManagerInterface; use League\Flysystem\PathPrefixer; +use Psr\Http\Message\ResponseInterface; use Psr\Log\LoggerInterface; -use Symfony\Component\Console\Attribute\AsCommand; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Messenger\MessageBus; -#[AsCommand( - name: 'azuracast:internal:sftp-event', - description: 'Send upcoming song feedback from the AutoDJ back to AzuraCast.', -)] -class SftpEventCommand extends CommandAbstract +final class SftpEventAction { public function __construct( - protected EntityManagerInterface $em, - protected MessageBus $messageBus, - protected LoggerInterface $logger, - protected BatchUtilities $batchUtilities, + private readonly EntityManagerInterface $em, + private readonly MessageBus $messageBus, + private readonly LoggerInterface $logger, + private readonly BatchUtilities $batchUtilities, ) { - parent::__construct(); } - protected function execute(InputInterface $input, OutputInterface $output): int - { - $action = getenv('SFTPGO_ACTION') ?: null; - $username = getenv('SFTPGO_ACTION_USERNAME') ?: null; - $path = getenv('SFTPGO_ACTION_PATH') ?: null; - $targetPath = getenv('SFTPGO_ACTION_TARGET') ?: null; - $sshCmd = getenv('SFTPGO_ACTION_SSH_CMD') ?: null; + public function __invoke( + ServerRequest $request, + Response $response + ): ResponseInterface { + $errorResponse = $response->withStatus(500)->withJson(['success' => false]); + + $parsedBody = $request->getParsedBody(); + + $action = $parsedBody['action'] ?? null; + $username = $parsedBody['username'] ?? null; + $path = $parsedBody['path'] ?? null; + $targetPath = $parsedBody['target_path'] ?? null; + $sshCmd = $parsedBody['ssh_cmd'] ?? null; $this->logger->notice( 'SFTP file event triggered', [ - 'action' => $action, - 'username' => $username, - 'path' => $path, + 'action' => $action, + 'username' => $username, + 'path' => $path, 'targetPath' => $targetPath, - 'sshCmd' => $sshCmd, + 'sshCmd' => $sshCmd, ] ); // Determine which station the username belongs to. - $sftpUser = $this->em->getRepository(Entity\SftpUser::class)->findOneBy( + $sftpUser = $this->em->getRepository(SftpUser::class)->findOneBy( [ 'username' => $username, ] ); - if (!$sftpUser instanceof Entity\SftpUser) { + if (!$sftpUser instanceof SftpUser) { $this->logger->error('SFTP Username not found.', ['username' => $username]); - return 1; + return $errorResponse; } $storageLocation = $sftpUser->getStation()->getMediaStorageLocation(); if (!$storageLocation->isLocal()) { $this->logger->error(sprintf('Storage location "%s" is not local.', $storageLocation)); - return 1; + return $errorResponse; } if (null === $path) { $this->logger->error('No path specified for action.'); - return 1; + return $errorResponse; } - return match ($action) { - 'upload' => $this->handleNewUpload($storageLocation, $path), - 'pre-delete' => $this->handleDelete($storageLocation, $path), - 'rename' => $this->handleRename($storageLocation, $path, $targetPath), - default => 1, - }; + try { + match ($action) { + 'upload' => $this->handleNewUpload($storageLocation, $path), + 'pre-delete' => $this->handleDelete($storageLocation, $path), + 'rename' => $this->handleRename($storageLocation, $path, $targetPath), + default => null, + }; + + return $response->withJson(['success' => true]); + } catch (\Throwable $e) { + $this->logger->error( + sprintf('SFTP Event: %s', $e->getMessage()), + [ + 'exception' => $e, + ] + ); + + return $errorResponse; + } } - protected function handleNewUpload( - Entity\StorageLocation $storageLocation, + private function handleNewUpload( + StorageLocation $storageLocation, string $path - ): int { + ): void { $pathPrefixer = new PathPrefixer($storageLocation->getPath(), DIRECTORY_SEPARATOR); $relativePath = $pathPrefixer->stripPrefix($path); @@ -93,23 +107,21 @@ class SftpEventCommand extends CommandAbstract 'Processing new SFTP upload.', [ 'storageLocation' => (string)$storageLocation, - 'path' => $relativePath, + 'path' => $relativePath, ] ); - $message = new Message\AddNewMediaMessage(); + $message = new AddNewMediaMessage(); $message->storage_location_id = $storageLocation->getIdRequired(); $message->path = $relativePath; $this->messageBus->dispatch($message); - - return 0; } - protected function handleDelete( - Entity\StorageLocation $storageLocation, + private function handleDelete( + StorageLocation $storageLocation, string $path - ): int { + ): void { $pathPrefixer = new PathPrefixer($storageLocation->getPath(), DIRECTORY_SEPARATOR); $relativePath = $pathPrefixer->stripPrefix($path); @@ -117,7 +129,7 @@ class SftpEventCommand extends CommandAbstract 'Processing SFTP file/folder deletion.', [ 'storageLocation' => (string)$storageLocation, - 'path' => $relativePath, + 'path' => $relativePath, ] ); @@ -140,18 +152,15 @@ class SftpEventCommand extends CommandAbstract ); $fs->delete($relativePath); - - return 0; } - protected function handleRename( - Entity\StorageLocation $storageLocation, + private function handleRename( + StorageLocation $storageLocation, string $path, ?string $newPath - ): int { + ): void { if (null === $newPath) { - $this->logger->error('No new path specified for rename.'); - return 1; + throw new \LogicException('No new path specified for rename.'); } $pathPrefixer = new PathPrefixer($storageLocation->getPath(), DIRECTORY_SEPARATOR); @@ -163,8 +172,8 @@ class SftpEventCommand extends CommandAbstract 'Processing SFTP file/folder rename.', [ 'storageLocation' => (string)$storageLocation, - 'from' => $from, - 'to' => $to, + 'from' => $from, + 'to' => $to, ] ); @@ -173,7 +182,5 @@ class SftpEventCommand extends CommandAbstract $to, $storageLocation ); - - return 0; } } diff --git a/util/docker/common/add_user.sh b/util/docker/common/add_user.sh index b84db1de1..51de8e134 100644 --- a/util/docker/common/add_user.sh +++ b/util/docker/common/add_user.sh @@ -1,16 +1,14 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x -$minimal_apt_get_install sudo +apt-get install -y --no-install-recommends sudo # Workaround for sudo errors in containers, see: https://github.com/sudo-project/sudo/issues/42 echo "Set disable_coredump false" >> /etc/sudo.conf adduser --home /var/azuracast --disabled-password --gecos "" azuracast -usermod -aG docker_env azuracast usermod -aG www-data azuracast mkdir -p /var/azuracast/www /var/azuracast/stations /var/azuracast/servers/shoutcast2 \ diff --git a/util/docker/common/buildconfig b/util/docker/common/buildconfig deleted file mode 100644 index 4820ef9e9..000000000 --- a/util/docker/common/buildconfig +++ /dev/null @@ -1,22 +0,0 @@ -export LC_ALL=C -export DEBIAN_FRONTEND=noninteractive - -minimal_apt_get_install='apt-get install -y --no-install-recommends' - -install_without_postinst() { - local PACKAGE - PACKAGE=$1 - - mkdir -p /tmp/install_$PACKAGE - cd /tmp/install_$PACKAGE - - apt-get download $PACKAGE - dpkg --unpack $PACKAGE*.deb - rm -f /var/lib/dpkg/info/$PACKAGE.postinst - dpkg --configure $PACKAGE - - apt-get install -yf #To fix dependencies - - cd / - rm -rf /tmp/install_$PACKAGE -} diff --git a/util/docker/common/cleanup.sh b/util/docker/common/cleanup.sh index 1919500cd..e80adac18 100644 --- a/util/docker/common/cleanup.sh +++ b/util/docker/common/cleanup.sh @@ -1,11 +1,9 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x apt-get -y autoremove apt-get clean rm -rf /var/lib/apt/lists/* - rm -rf /tmp/tmp* diff --git a/util/docker/common/post_setup.sh b/util/docker/common/post_setup.sh deleted file mode 100644 index 618d53d9a..000000000 --- a/util/docker/common/post_setup.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -set -e -source /bd_build/buildconfig -set -x - -chmod -R a+x /usr/local/bin -chmod -R +x /etc/my_init.d -chmod -R +x /etc/my_init.pre_shutdown.d -chmod -R +x /etc/my_init.post_shutdown.d - -ln -s /etc/service.minimal/* /etc/service -ln -s /etc/service.full/* /etc/service - -chmod -R +x /etc/service.minimal -chmod -R +x /etc/service.full -chmod -R +x /etc/service diff --git a/util/docker/common/prepare.sh b/util/docker/common/prepare.sh index a7186ae92..5617a1dcf 100644 --- a/util/docker/common/prepare.sh +++ b/util/docker/common/prepare.sh @@ -1,14 +1,11 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x ## Prevent initramfs updates from trying to run grub and lilo. ## https://journal.paul.querna.org/articles/2013/10/15/docker-ubuntu-on-rackspace/ ## http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=594189 export INITRD=no -mkdir -p /etc/container_environment -echo -n no > /etc/container_environment/INITRD # Add default timezone. echo "UTC" > /etc/timezone @@ -35,46 +32,29 @@ dpkg-divert --local --rename --add /usr/bin/ischroot ln -sf /bin/true /usr/bin/ischroot # apt-utils fix for Ubuntu 16.04 -$minimal_apt_get_install apt-utils +apt-get install -y --no-install-recommends apt-utils ## Install HTTPS support for APT. -$minimal_apt_get_install apt-transport-https ca-certificates +apt-get install -y --no-install-recommends apt-transport-https ca-certificates ## Install add-apt-repository -$minimal_apt_get_install software-properties-common +apt-get install -y --no-install-recommends software-properties-common ## Upgrade all packages. apt-get dist-upgrade -y --no-install-recommends -o Dpkg::Options::="--force-confold" ## Fix locale. -$minimal_apt_get_install language-pack-en +apt-get install -y --no-install-recommends language-pack-en locale-gen en_US update-locale LANG=en_US.UTF-8 LC_CTYPE=en_US.UTF-8 -echo -n en_US.UTF-8 > /etc/container_environment/LANG -echo -n en_US.UTF-8 > /etc/container_environment/LC_CTYPE - # Make init folders mkdir -p /etc/my_init.d -mkdir -p /etc/my_init.pre_shutdown.d -mkdir -p /etc/my_init.post_shutdown.d -mkdir -p /etc/container_environment -touch /etc/container_environment.sh -touch /etc/container_environment.json -chmod 700 /etc/container_environment -groupadd -g 8377 docker_env -chown :docker_env /etc/container_environment.sh /etc/container_environment.json -chmod 640 /etc/container_environment.sh /etc/container_environment.json -ln -s /etc/container_environment.sh /etc/profile.d/ - -# Install runit and other common scripts. -$minimal_apt_get_install runit gosu curl wget tar zip unzip git rsync tzdata gpg-agent openssh-client +# Install other common scripts. +apt-get install -y --no-install-recommends tini gosu curl wget tar zip unzip git rsync tzdata gpg-agent openssh-client # Add scripts cp -rT /bd_build/scripts/ /usr/local/bin chmod -R a+x /usr/local/bin - -mkdir -p /etc/service.full/ -mkdir -p /etc/service.minimal/ diff --git a/util/docker/common/scripts/my_init b/util/docker/common/scripts/my_init index 4ae505280..86b0b4b5c 100644 --- a/util/docker/common/scripts/my_init +++ b/util/docker/common/scripts/my_init @@ -1,402 +1,29 @@ -#!/usr/bin/python3 -u -# -*- coding: utf-8 -*- +#!/bin/bash -import argparse -import errno -import json -import os -import os.path -import re -import signal -import stat -import sys -import time +# Write environment variables to script +declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env +chmod 744 /container.env -ENV_INIT_DIRECTORY = os.environ.get('ENV_INIT_DIRECTORY', '/etc/my_init.d') +# Run startup scripts +for f in /etc/my_init.d/*.sh; do + echo "** Running startup script '$f'..." + bash "$f" -H + echo "** Startup script complete." +done -KILL_PROCESS_TIMEOUT = int(os.environ.get('KILL_PROCESS_TIMEOUT', 30)) -KILL_ALL_PROCESSES_TIMEOUT = int(os.environ.get('KILL_ALL_PROCESSES_TIMEOUT', 30)) +echo "** Running Supervisord..." -LOG_LEVEL_ERROR = 1 -LOG_LEVEL_WARN = 1 -LOG_LEVEL_INFO = 2 -LOG_LEVEL_DEBUG = 3 +if [ "$1" = '--no-main-command' ]; then + exec /usr/bin/supervisord -c /etc/supervisor/supervisord-full.conf --nodaemon +fi -SHENV_NAME_WHITELIST_REGEX = re.compile('\W') +/usr/bin/supervisord -c /etc/supervisor/supervisord-minimal.conf -log_level = None +echo "** Supervisord started." +echo "** Running uptime_wait..." -terminated_child_processes = {} +uptime_wait -_find_unsafe = re.compile(r'[^\w@%+=:,./-]').search +echo "** Services up and ready!" -class AlarmException(Exception): - pass - -def error(message): - if log_level >= LOG_LEVEL_ERROR: - sys.stderr.write("*** %s\n" % message) - -def warn(message): - if log_level >= LOG_LEVEL_WARN: - sys.stderr.write("*** %s\n" % message) - -def info(message): - if log_level >= LOG_LEVEL_INFO: - sys.stderr.write("*** %s\n" % message) - -def debug(message): - if log_level >= LOG_LEVEL_DEBUG: - sys.stderr.write("*** %s\n" % message) - -def ignore_signals_and_raise_keyboard_interrupt(signame): - signal.signal(signal.SIGTERM, signal.SIG_IGN) - signal.signal(signal.SIGINT, signal.SIG_IGN) - raise KeyboardInterrupt(signame) - -def raise_alarm_exception(): - raise AlarmException('Alarm') - -def listdir(path): - try: - result = os.stat(path) - except OSError: - return [] - if stat.S_ISDIR(result.st_mode): - return sorted(os.listdir(path)) - else: - return [] - -def is_exe(path): - try: - return os.path.isfile(path) and os.access(path, os.X_OK) - except OSError: - return False - -def import_envvars(clear_existing_environment=True, override_existing_environment=True): - if not os.path.exists("/etc/container_environment"): - return - new_env = {} - for envfile in listdir("/etc/container_environment"): - name = os.path.basename(envfile) - with open("/etc/container_environment/" + envfile, "r") as f: - # Text files often end with a trailing newline, which we - # don't want to include in the env variable value. See - # https://github.com/phusion/baseimage-docker/pull/49 - value = re.sub('\n\Z', '', f.read()) - new_env[name] = value - if clear_existing_environment: - os.environ.clear() - for name, value in new_env.items(): - if override_existing_environment or name not in os.environ: - os.environ[name] = value - -def export_envvars(to_dir=True): - if not os.path.exists("/etc/container_environment"): - return - shell_dump = "" - for name, value in os.environ.items(): - if name in ['HOME', 'USER', 'GROUP', 'UID', 'GID', 'SHELL']: - continue - if to_dir: - with open("/etc/container_environment/" + name, "w") as f: - f.write(value) - shell_dump += "export " + sanitize_shenvname(name) + "=" + shquote(value) + "\n" - with open("/etc/container_environment.sh", "w") as f: - f.write(shell_dump) - with open("/etc/container_environment.json", "w") as f: - f.write(json.dumps(dict(os.environ))) - -def shquote(s): - """Return a shell-escaped version of the string *s*.""" - if not s: - return "''" - if _find_unsafe(s) is None: - return s - - # use single quotes, and put single quotes into double quotes - # the string $'b is then quoted as '$'"'"'b' - return "'" + s.replace("'", "'\"'\"'") + "'" - -def sanitize_shenvname(s): - """Return string with [0-9a-zA-Z_] characters""" - return re.sub(SHENV_NAME_WHITELIST_REGEX, "_", s) - -# Waits for the child process with the given PID, while at the same time -# reaping any other child processes that have exited (e.g. adopted child -# processes that have terminated). -def waitpid_reap_other_children(pid): - global terminated_child_processes - - status = terminated_child_processes.get(pid) - if status: - # A previous call to waitpid_reap_other_children(), - # with an argument not equal to the current argument, - # already waited for this process. Return the status - # that was obtained back then. - del terminated_child_processes[pid] - return status - - done = False - status = None - while not done: - try: - # https://github.com/phusion/baseimage-docker/issues/151#issuecomment-92660569 - this_pid, status = os.waitpid(pid, os.WNOHANG) - if this_pid == 0: - this_pid, status = os.waitpid(-1, 0) - if this_pid == pid: - done = True - else: - # Save status for later. - terminated_child_processes[this_pid] = status - except OSError as e: - if e.errno == errno.ECHILD or e.errno == errno.ESRCH: - return None - else: - raise - return status - -def stop_child_process(name, pid, signo=signal.SIGTERM, time_limit=KILL_PROCESS_TIMEOUT): - info("Shutting down %s (PID %d)..." % (name, pid)) - try: - os.kill(pid, signo) - except OSError: - pass - signal.alarm(time_limit) - try: - try: - waitpid_reap_other_children(pid) - except OSError: - pass - except AlarmException: - warn("%s (PID %d) did not shut down in time. Forcing it to exit." % (name, pid)) - try: - os.kill(pid, signal.SIGKILL) - except OSError: - pass - try: - waitpid_reap_other_children(pid) - except OSError: - pass - finally: - signal.alarm(0) - -def run_command_killable(*argv): - filename = argv[0] - status = None - pid = os.spawnvp(os.P_NOWAIT, filename, argv) - try: - status = waitpid_reap_other_children(pid) - except BaseException: - warn("An error occurred. Aborting.") - stop_child_process(filename, pid) - raise - if status != 0: - if status is None: - error("%s exited with unknown status\n" % filename) - else: - error("%s failed with status %d\n" % (filename, os.WEXITSTATUS(status))) - sys.exit(1) - -def run_command_killable_and_import_envvars(*argv): - run_command_killable(*argv) - import_envvars() - export_envvars(False) - -def kill_all_processes(time_limit): - info("Killing all processes...") - try: - os.kill(-1, signal.SIGTERM) - except OSError: - pass - signal.alarm(time_limit) - try: - # Wait until no more child processes exist. - done = False - while not done: - try: - os.waitpid(-1, 0) - except OSError as e: - if e.errno == errno.ECHILD: - done = True - else: - raise - except AlarmException: - warn("Not all processes have exited in time. Forcing them to exit.") - try: - os.kill(-1, signal.SIGKILL) - except OSError: - pass - finally: - signal.alarm(0) - - -def run_startup_files(): - # Run ENV_INIT_DIRECTORY/* - for name in listdir(ENV_INIT_DIRECTORY): - filename = os.path.join(ENV_INIT_DIRECTORY, name) - if is_exe(filename): - info("Running %s..." % filename) - run_command_killable_and_import_envvars(filename) - - # Run /etc/rc.local. - if is_exe("/etc/rc.local"): - info("Running /etc/rc.local...") - run_command_killable_and_import_envvars("/etc/rc.local") - -def run_pre_shutdown_scripts(): - debug("Running pre-shutdown scripts...") - - # Run /etc/my_init.pre_shutdown.d/* - for name in listdir("/etc/my_init.pre_shutdown.d"): - filename = "/etc/my_init.pre_shutdown.d/" + name - if is_exe(filename): - info("Running %s..." % filename) - run_command_killable(filename) - -def run_post_shutdown_scripts(): - debug("Running post-shutdown scripts...") - - # Run /etc/my_init.post_shutdown.d/* - for name in listdir("/etc/my_init.post_shutdown.d"): - filename = "/etc/my_init.post_shutdown.d/" + name - if is_exe(filename): - info("Running %s..." % filename) - run_command_killable(filename) - -def start_runit(runit_services_dir): - info("Booting runit daemon...") - pid = os.spawnl(os.P_NOWAIT, "/usr/bin/runsvdir", "/usr/bin/runsvdir", "-P", runit_services_dir) - info("Runit started as PID %d" % pid) - return pid - -def wait_for_runit_or_interrupt(pid): - status = waitpid_reap_other_children(pid) - return (True, status) - -def shutdown_runit_services(runit_services_dir, quiet=False): - if not quiet: - debug("Begin shutting down runit services...") - os.system("/usr/bin/sv -w %d force-stop %s/* > /dev/null" % (KILL_PROCESS_TIMEOUT, runit_services_dir)) - -def wait_for_runit_services(runit_services_dir): - debug("Waiting for runit services to exit...") - done = False - while not done: - done = os.system("/usr/bin/sv status %s/* | grep -q '^run:'" % runit_services_dir) != 0 - if not done: - time.sleep(0.1) - # According to https://github.com/phusion/baseimage-docker/issues/315 - # there is a bug or race condition in Runit, causing it - # not to shutdown services that are already being started. - # So during shutdown we repeatedly instruct Runit to shutdown - # services. - shutdown_runit_services(runit_services_dir, True) - -def main(args): - import_envvars(False, False) - export_envvars() - - if not args.skip_startup_files: - run_startup_files() - - runit_exited = False - exit_code = None - - if not args.skip_runit: - runit_services_dir = '/etc/service.minimal' - if len(args.main_command) == 0 or args.no_main_command: - runit_services_dir = '/etc/service' - - runit_pid = start_runit(runit_services_dir) - - try: - exit_status = None - if len(args.main_command) == 0 or args.no_main_command: - runit_exited, exit_code = wait_for_runit_or_interrupt(runit_pid) - if runit_exited: - if exit_code is None: - info("Runit exited with unknown status") - exit_status = 1 - else: - exit_status = os.WEXITSTATUS(exit_code) - info("Runit exited with status %d" % exit_status) - else: - main_command = ["uptime_wait"] + args.main_command - - info("Running %s..." % " ".join(main_command)) - pid = os.spawnvp(os.P_NOWAIT, main_command[0], main_command) - try: - exit_code = waitpid_reap_other_children(pid) - if exit_code is None: - info("%s exited with unknown status." % main_command[0]) - exit_status = 1 - else: - exit_status = os.WEXITSTATUS(exit_code) - info("%s exited with status %d." % (main_command[0], exit_status)) - except KeyboardInterrupt: - stop_child_process(main_command[0], pid) - raise - except BaseException: - warn("An error occurred. Aborting.") - stop_child_process(main_command[0], pid) - raise - sys.exit(exit_status) - finally: - if not args.skip_runit: - run_pre_shutdown_scripts() - shutdown_runit_services(runit_services_dir) - - if not runit_exited: - stop_child_process("runit daemon", runit_pid) - - wait_for_runit_services(runit_services_dir) - run_post_shutdown_scripts() - -# Parse options. -parser = argparse.ArgumentParser(description='Initialize the system.') - -parser.add_argument('main_command', metavar='MAIN_COMMAND', type=str, nargs='*', - help='The main command to run. (default: runit)') - -parser.add_argument('--no-main-command', dest='no_main_command', - action='store_const', const=True, default=False, - help='Flag to provide as main command in the absence of one.') - -parser.add_argument('--skip-startup-files', dest='skip_startup_files', - action='store_const', const=True, default=False, - help='Skip running /etc/my_init.d/* and /etc/rc.local') - -parser.add_argument('--skip-runit', dest='skip_runit', - action='store_const', const=True, default=False, - help='Do not run runit services') - -parser.add_argument('--no-kill-all-on-exit', dest='kill_all_on_exit', - action='store_const', const=False, default=True, - help='Don\'t kill all processes on the system upon exiting') - -parser.add_argument('--quiet', dest='log_level', - action='store_const', const=LOG_LEVEL_WARN, default=LOG_LEVEL_INFO, - help='Only print warnings and errors') - -args = parser.parse_args() -log_level = args.log_level - -if args.skip_runit and len(args.main_command) == 0: - error("When --skip-runit is given, you must also pass a main command.") - sys.exit(1) - -# Run main function. -signal.signal(signal.SIGTERM, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGTERM')) -signal.signal(signal.SIGINT, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGINT')) -signal.signal(signal.SIGALRM, lambda signum, frame: raise_alarm_exception()) - -try: - main(args) -except KeyboardInterrupt: - warn("Init system aborted.") - exit(2) -finally: - if args.kill_all_on_exit: - kill_all_processes(KILL_ALL_PROCESSES_TIMEOUT) +exec "$@" diff --git a/util/docker/mariadb/service.minimal/mariadb.conf b/util/docker/mariadb/service.minimal/mariadb.conf new file mode 100644 index 000000000..de895bc7f --- /dev/null +++ b/util/docker/mariadb/service.minimal/mariadb.conf @@ -0,0 +1,12 @@ +[program:mariadb] +command=mysqld +user=mysql +priority=100 +numprocs=1 +autostart=true +autorestart=unexpected + +stdout_logfile=/proc/1/fd/1 +stdout_logfile_maxbytes=0 +stderr_logfile=/proc/1/fd/2 +stderr_logfile_maxbytes=0 diff --git a/util/docker/mariadb/service.minimal/mariadb/check b/util/docker/mariadb/service.minimal/mariadb/check deleted file mode 100644 index 8a76ad12b..000000000 --- a/util/docker/mariadb/service.minimal/mariadb/check +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -exec mysqladmin ping -h localhost diff --git a/util/docker/mariadb/service.minimal/mariadb/run b/util/docker/mariadb/service.minimal/mariadb/run deleted file mode 100644 index 27c3f3d3a..000000000 --- a/util/docker/mariadb/service.minimal/mariadb/run +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -dockerize -template /etc/mysql/db.cnf.tmpl:/etc/mysql/conf.d/db.cnf - -exec gosu mysql mysqld diff --git a/util/docker/mariadb/setup.sh b/util/docker/mariadb/setup.sh index 95ab9b402..b70a48c9b 100644 --- a/util/docker/mariadb/setup.sh +++ b/util/docker/mariadb/setup.sh @@ -1,6 +1,5 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x apt-get update @@ -10,11 +9,20 @@ cp -rT /bd_build/mariadb/scripts/ /usr/local/bin cp -rT /bd_build/mariadb/startup_scripts/. /etc/my_init.d/ -cp -rT /bd_build/mariadb/service.minimal/. /etc/service.minimal/ +cp -rT /bd_build/mariadb/service.minimal/. /etc/supervisor/minimal.conf.d/ -# cp -rT /bd_build/mariadb/service.full/. /etc/service.full/ +# cp -rT /bd_build/mariadb/service.full/. /etc/supervisor/full.conf.d/ # Run service setup for all setup scripts for f in /bd_build/mariadb/setup/*.sh; do bash "$f" -H done + +# Cleanup +apt-get -y autoremove +apt-get clean +rm -rf /var/lib/apt/lists/* +rm -rf /tmp/tmp* + +chmod -R a+x /usr/local/bin +chmod -R +x /etc/my_init.d diff --git a/util/docker/mariadb/setup/mariadb.sh b/util/docker/mariadb/setup/mariadb.sh index 38280b208..5b2a0d2f8 100644 --- a/util/docker/mariadb/setup/mariadb.sh +++ b/util/docker/mariadb/setup/mariadb.sh @@ -1,9 +1,8 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x -$minimal_apt_get_install tzdata libjemalloc2 pwgen xz-utils zstd dirmngr apt-transport-https +apt-get install -y --no-install-recommends tzdata libjemalloc2 pwgen xz-utils zstd dirmngr apt-transport-https sudo apt-key adv --fetch-keys 'https://mariadb.org/mariadb_release_signing_key.asc' sudo add-apt-repository 'deb [arch=amd64,arm64,ppc64el,s390x] https://atl.mirrors.knownhost.com/mariadb/repo/10.7/ubuntu focal main' @@ -17,7 +16,7 @@ export MARIADB_MAJOR=10.7 } | debconf-set-selections; apt update -$minimal_apt_get_install mariadb-server mariadb-backup socat +apt-get install -y --no-install-recommends mariadb-server mariadb-backup socat # Temporary work around for MDEV-27980, closes #417 sed --follow-symlinks -i -e 's/--loose-disable-plugin-file-key-management//' /usr/bin/mysql_install_db @@ -43,9 +42,6 @@ else sed -i -e '/includedir/ {N;s/\(.*\)\n\(.*\)/[mariadbd]\nskip-host-cache\nskip-name-resolve\n\n\2\n\1/}' /etc/mysql/mariadb.cnf; fi -# Customizations to MariaDB -echo "1" >> /etc/container_environment/MARIADB_AUTO_UPGRADE - mkdir /docker-entrypoint-initdb.d cp /bd_build/mariadb/mariadb/db.sql /docker-entrypoint-initdb.d/00-azuracast.sql diff --git a/util/docker/mariadb/startup_scripts/00_disable_mariadb.sh b/util/docker/mariadb/startup_scripts/00_disable_mariadb.sh index b9c769421..edc426aac 100644 --- a/util/docker/mariadb/startup_scripts/00_disable_mariadb.sh +++ b/util/docker/mariadb/startup_scripts/00_disable_mariadb.sh @@ -4,6 +4,5 @@ if [ "$MYSQL_HOST" != "localhost" ]; then echo "MariaDB host is not localhost; disabling MariaDB..." - rm -rf /etc/service/mariadb - rm -rf /etc/service.minimal/mariadb + rm -rf /etc/supervisor/minimal.conf.d/mariadb.conf fi diff --git a/util/docker/mariadb/startup_scripts/04_mariadb_conf.sh b/util/docker/mariadb/startup_scripts/04_mariadb_conf.sh new file mode 100644 index 000000000..4868b1e5b --- /dev/null +++ b/util/docker/mariadb/startup_scripts/04_mariadb_conf.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +if [ ! -f /etc/supervisor/minimal.conf.d/mariadb.conf ]; then + echo "MariaDB disabled. Skipping DB initialization..." + exit 0 +fi + +dockerize -template /etc/mysql/db.cnf.tmpl:/etc/mysql/conf.d/db.cnf diff --git a/util/docker/mariadb/startup_scripts/05_setup_db.sh b/util/docker/mariadb/startup_scripts/05_setup_db.sh index 289d8a558..2dba366c9 100644 --- a/util/docker/mariadb/startup_scripts/05_setup_db.sh +++ b/util/docker/mariadb/startup_scripts/05_setup_db.sh @@ -1,6 +1,6 @@ #!/bin/bash -if [ ! -f /etc/service/mariadb/run ]; then +if [ ! -f /etc/supervisor/minimal.conf.d/mariadb.conf ]; then echo "MariaDB disabled. Skipping DB initialization..." exit 0 fi diff --git a/util/docker/redis/service.minimal/redis.conf b/util/docker/redis/service.minimal/redis.conf new file mode 100644 index 000000000..70be6df6f --- /dev/null +++ b/util/docker/redis/service.minimal/redis.conf @@ -0,0 +1,11 @@ +[program:redis] +command=redis-server /etc/redis/redis.conf +user=redis +numprocs=1 +autostart=true +autorestart=unexpected + +stdout_logfile=/proc/1/fd/1 +stdout_logfile_maxbytes=0 +stderr_logfile=/proc/1/fd/2 +stderr_logfile_maxbytes=0 diff --git a/util/docker/redis/service.minimal/redis/run b/util/docker/redis/service.minimal/redis/run deleted file mode 100644 index ce627af64..000000000 --- a/util/docker/redis/service.minimal/redis/run +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -exec gosu redis redis-server /etc/redis/redis.conf diff --git a/util/docker/redis/setup.sh b/util/docker/redis/setup.sh index ca36e1ef8..f41ea111c 100644 --- a/util/docker/redis/setup.sh +++ b/util/docker/redis/setup.sh @@ -1,6 +1,5 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x apt-get update @@ -10,11 +9,20 @@ apt-get update cp -rT /bd_build/redis/startup_scripts/. /etc/my_init.d/ -cp -rT /bd_build/redis/service.minimal/. /etc/service.minimal/ +cp -rT /bd_build/redis/service.minimal/. /etc/supervisor/minimal.conf.d/ -# cp -rT /bd_build/redis/service.full/. /etc/service.full/ +# cp -rT /bd_build/redis/service.full/. /etc/supervisor/full.conf.d/ # Run service setup for all setup scripts for f in /bd_build/redis/setup/*.sh; do bash "$f" -H done + +# Cleanup +apt-get -y autoremove +apt-get clean +rm -rf /var/lib/apt/lists/* +rm -rf /tmp/tmp* + +chmod -R a+x /usr/local/bin +chmod -R +x /etc/my_init.d diff --git a/util/docker/redis/setup/redis.sh b/util/docker/redis/setup/redis.sh index 8bd153292..31d97c117 100644 --- a/util/docker/redis/setup/redis.sh +++ b/util/docker/redis/setup/redis.sh @@ -1,12 +1,11 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x add-apt-repository -y ppa:chris-lea/redis-server apt-get update -$minimal_apt_get_install redis-server +apt-get install -y --no-install-recommends redis-server cp /bd_build/redis/redis/redis.conf /etc/redis/redis.conf chown redis:redis /etc/redis/redis.conf diff --git a/util/docker/redis/startup_scripts/00_disable_redis.sh b/util/docker/redis/startup_scripts/00_disable_redis.sh index aed531f53..9824f1598 100644 --- a/util/docker/redis/startup_scripts/00_disable_redis.sh +++ b/util/docker/redis/startup_scripts/00_disable_redis.sh @@ -12,6 +12,5 @@ ENABLE_REDIS=${ENABLE_REDIS:-true} if [ "$REDIS_HOST" != "localhost" ] || ! bool "$ENABLE_REDIS"; then echo "Redis is disabled or host is not localhost; disabling Redis..." - rm -rf /etc/service/redis - rm -rf /etc/service.minimal/redis + rm -rf /etc/supervisor/minimal.conf.d/redis.conf fi diff --git a/util/docker/stations/service.full/supervisord/run b/util/docker/stations/service.full/supervisord/run deleted file mode 100644 index e347aa5a0..000000000 --- a/util/docker/stations/service.full/supervisord/run +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -sv -w 45 check php-fpm || exit 1 - -exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf diff --git a/util/docker/stations/setup.sh b/util/docker/stations/setup.sh index e0f139fdc..291d98c83 100644 --- a/util/docker/stations/setup.sh +++ b/util/docker/stations/setup.sh @@ -1,6 +1,5 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x apt-get update @@ -10,11 +9,20 @@ apt-get update # cp -rT /bd_build/stations/startup_scripts/. /etc/my_init.d/ -# cp -rT /bd_build/stations/service.minimal/. /etc/service.minimal/ +# cp -rT /bd_build/stations/service.minimal/. /etc/supervisor/minimal.conf.d/ -cp -rT /bd_build/stations/service.full/. /etc/service.full/ +# cp -rT /bd_build/stations/service.full/. /etc/supervisor/full.conf.d/ # Run service setup for all setup scripts for f in /bd_build/stations/setup/*.sh; do bash "$f" -H done + +# Cleanup +apt-get -y autoremove +apt-get clean +rm -rf /var/lib/apt/lists/* +rm -rf /tmp/tmp* + +chmod -R a+x /usr/local/bin +chmod -R +x /etc/my_init.d diff --git a/util/docker/stations/setup/flac.sh b/util/docker/stations/setup/flac.sh index e20d8e5d8..cb23e7ebd 100644 --- a/util/docker/stations/setup/flac.sh +++ b/util/docker/stations/setup/flac.sh @@ -1,6 +1,5 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x -$minimal_apt_get_install flac +apt-get install -y --no-install-recommends flac diff --git a/util/docker/stations/setup/icecast.sh b/util/docker/stations/setup/icecast.sh index 9d9f71cb0..decc8662c 100644 --- a/util/docker/stations/setup/icecast.sh +++ b/util/docker/stations/setup/icecast.sh @@ -1,10 +1,9 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x # Only install Icecast deps (Icecast is handled by another container). -$minimal_apt_get_install libxml2 libxslt1-dev libvorbis-dev +apt-get install -y --no-install-recommends libxml2 libxslt1-dev libvorbis-dev # SSL self-signed cert generation -$minimal_apt_get_install openssl +apt-get install -y --no-install-recommends openssl diff --git a/util/docker/stations/setup/liquidsoap.sh b/util/docker/stations/setup/liquidsoap.sh index 648637405..5d2bcd4ef 100644 --- a/util/docker/stations/setup/liquidsoap.sh +++ b/util/docker/stations/setup/liquidsoap.sh @@ -1,10 +1,9 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x # Packages required by Liquidsoap -$minimal_apt_get_install libao-dev libasound2-dev libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev \ +apt-get install -y --no-install-recommends libao-dev libasound2-dev libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev \ libavutil-dev libfaad-dev libfdk-aac-dev libflac-dev libfreetype-dev libgd-dev libjack-dev \ libjpeg-dev liblo-dev libmad0-dev libmagic-dev libmp3lame-dev libopus-dev libpng-dev libportaudio2 \ libpulse-dev libsamplerate0-dev libsdl2-dev libsdl2-ttf-dev libsdl2-image-dev libshine-dev libsoundtouch-dev libspeex-dev \ @@ -12,7 +11,7 @@ $minimal_apt_get_install libao-dev libasound2-dev libavcodec-dev libavdevice-dev bubblewrap ffmpeg # Optional audio plugins -$minimal_apt_get_install frei0r-plugins-dev ladspa-sdk multimedia-audio-plugins swh-plugins tap-plugins lsp-plugins-ladspa +apt-get install -y --no-install-recommends frei0r-plugins-dev ladspa-sdk multimedia-audio-plugins swh-plugins tap-plugins lsp-plugins-ladspa # Per-architecture LS installs ARCHITECTURE=amd64 @@ -30,7 +29,7 @@ rm -f /tmp/liquidsoap.deb ln -s /usr/bin/liquidsoap /usr/local/bin/liquidsoap # else -# $minimal_apt_get_install build-essential libssl-dev libcurl4-openssl-dev m4 ocaml opam autoconf automake +# apt-get install -y --no-install-recommends build-essential libssl-dev libcurl4-openssl-dev m4 ocaml opam autoconf automake # sudo -u azuracast bash /bd_build/stations/liquidsoap/build_as_azuracast.sh # ln -s /var/azuracast/.opam/4.13.1/bin/liquidsoap /usr/local/bin/liquidsoap # chmod a+x /usr/local/bin/liquidsoap diff --git a/util/docker/stations/setup/supervisor.sh b/util/docker/stations/setup/supervisor.sh deleted file mode 100644 index 8b4f9b3ce..000000000 --- a/util/docker/stations/setup/supervisor.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -set -e -source /bd_build/buildconfig -set -x - -# $minimal_apt_get_install python3-minimal python3-pip -# pip3 install setuptools supervisor - -$minimal_apt_get_install supervisor - -# mkdir -p /etc/supervisor -cp /bd_build/stations/supervisor/supervisord.conf /etc/supervisor/supervisord.conf diff --git a/util/docker/stations/setup/vorbis.sh b/util/docker/stations/setup/vorbis.sh index 21f8c75b2..8aa9d4e66 100644 --- a/util/docker/stations/setup/vorbis.sh +++ b/util/docker/stations/setup/vorbis.sh @@ -1,6 +1,5 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x -$minimal_apt_get_install vorbis-tools +apt-get install -y --no-install-recommends vorbis-tools diff --git a/util/docker/supervisor/setup.sh b/util/docker/supervisor/setup.sh new file mode 100644 index 000000000..510ba2995 --- /dev/null +++ b/util/docker/supervisor/setup.sh @@ -0,0 +1,28 @@ +#!/bin/bash +set -e +set -x + +apt-get update + +# Install common scripts +# cp -rT /bd_build/supervisor/scripts/ /usr/local/bin + +# cp -rT /bd_build/supervisor/startup_scripts/. /etc/my_init.d/ + +# cp -rT /bd_build/supervisor/service.minimal/. /etc/supervisor/minimal.conf.d/ + +# cp -rT /bd_build/supervisor/service.full/. /etc/supervisor/full.conf.d/ + +# Run service setup for all setup scripts +for f in /bd_build/supervisor/setup/*.sh; do + bash "$f" -H +done + +# Cleanup +apt-get -y autoremove +apt-get clean +rm -rf /var/lib/apt/lists/* +rm -rf /tmp/tmp* + +chmod -R a+x /usr/local/bin +chmod -R +x /etc/my_init.d diff --git a/util/docker/supervisor/setup/supervisor.sh b/util/docker/supervisor/setup/supervisor.sh new file mode 100644 index 000000000..db4a5ce67 --- /dev/null +++ b/util/docker/supervisor/setup/supervisor.sh @@ -0,0 +1,14 @@ +#!/bin/bash +set -e +set -x + +# apt-get install -y --no-install-recommends python3-minimal python3-pip +# pip3 install setuptools supervisor + +apt-get install -y --no-install-recommends supervisor + +mkdir -p /etc/supervisor +mkdir -p /etc/supervisor/full.conf.d/ +mkdir -p /etc/supervisor/minimal.conf.d/ + +cp /bd_build/supervisor/supervisor/supervisord*.conf /etc/supervisor/ diff --git a/util/docker/supervisor/supervisor/supervisord-full.conf b/util/docker/supervisor/supervisor/supervisord-full.conf new file mode 100644 index 000000000..fb9a3857c --- /dev/null +++ b/util/docker/supervisor/supervisor/supervisord-full.conf @@ -0,0 +1,2 @@ +[include] +files = supervisord.conf minimal.conf.d/* full.conf.d/* /var/azuracast/stations/*/config/supervisord.conf diff --git a/util/docker/supervisor/supervisor/supervisord-minimal.conf b/util/docker/supervisor/supervisor/supervisord-minimal.conf new file mode 100644 index 000000000..61ea7a33d --- /dev/null +++ b/util/docker/supervisor/supervisor/supervisord-minimal.conf @@ -0,0 +1,2 @@ +[include] +files = supervisord.conf minimal.conf.d/* diff --git a/util/docker/stations/supervisor/supervisord.conf b/util/docker/supervisor/supervisor/supervisord.conf similarity index 78% rename from util/docker/stations/supervisor/supervisord.conf rename to util/docker/supervisor/supervisor/supervisord.conf index 4808b6d3e..d0a98e421 100644 --- a/util/docker/stations/supervisor/supervisord.conf +++ b/util/docker/supervisor/supervisor/supervisord.conf @@ -10,7 +10,6 @@ logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB) logfile_backups=10 ; (num of main logfile rotation backups;default 10) loglevel=info ; (log level;default info; others: debug,warn,trace) pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) -nodaemon=true ; (start in foreground if true;default false) minfds=1024 ; (min. avail startup file descriptors;default 1024) minprocs=200 ; (min. avail process descriptors;default 200) @@ -18,7 +17,4 @@ minprocs=200 ; (min. avail process descriptors;default 200) supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] -serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket - -[include] -files = /var/azuracast/stations/*/config/supervisord.conf conf.d/* +serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket diff --git a/util/docker/web/cron/azuracast b/util/docker/web/cron/azuracast index a47772dcb..a97015624 100644 --- a/util/docker/web/cron/azuracast +++ b/util/docker/web/cron/azuracast @@ -1,2 +1,4 @@ +SHELL=/bin/bash +BASH_ENV=/container.env * * * * * root /usr/local/bin/cron_task azuracast_cli azuracast:sync:run 30 */6 * * * root /usr/local/bin/temp_cleanup diff --git a/util/docker/web/scripts/azuracast_sftp_auth b/util/docker/web/scripts/azuracast_sftp_auth deleted file mode 100644 index 548abcad6..000000000 --- a/util/docker/web/scripts/azuracast_sftp_auth +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source /etc/container_environment.sh - -exec azuracast_cli azuracast:internal:sftp-auth "$@" diff --git a/util/docker/web/scripts/azuracast_sftp_event b/util/docker/web/scripts/azuracast_sftp_event deleted file mode 100644 index 570b2bdae..000000000 --- a/util/docker/web/scripts/azuracast_sftp_event +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source /etc/container_environment.sh - -exec azuracast_cli azuracast:internal:sftp-event "$@" diff --git a/util/docker/web/scripts/cron_task b/util/docker/web/scripts/cron_task index f46a1f407..dc1a4b879 100644 --- a/util/docker/web/scripts/cron_task +++ b/util/docker/web/scripts/cron_task @@ -1,5 +1,3 @@ #!/usr/bin/env bash -source /etc/container_environment.sh - exec gosu azuracast "$@" >/proc/1/fd/1 2>/proc/1/fd/2 diff --git a/util/docker/web/scripts/liquidsoap_cli b/util/docker/web/scripts/liquidsoap_cli deleted file mode 100644 index fd0e21f85..000000000 --- a/util/docker/web/scripts/liquidsoap_cli +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -if [ `whoami` != 'azuracast' ]; then - exec gosu azuracast liquidsoap_cli "$@" -fi - -source /etc/container_environment.sh - -exec azuracast_cli azuracast:internal:liquidsoap "$@" diff --git a/util/docker/web/scripts/on_ssl_renewal b/util/docker/web/scripts/on_ssl_renewal index 1d7eeef3f..28526cc4e 100644 --- a/util/docker/web/scripts/on_ssl_renewal +++ b/util/docker/web/scripts/on_ssl_renewal @@ -1,5 +1,5 @@ #!/usr/bin/env bash -sv restart nginx +supervisorctl restart nginx azuracast_cli azuracast:internal:on-ssl-renewal diff --git a/util/docker/web/service.full/acme/run b/util/docker/web/scripts/run_acme_sh similarity index 99% rename from util/docker/web/service.full/acme/run rename to util/docker/web/scripts/run_acme_sh index 5804b747e..c84960118 100644 --- a/util/docker/web/service.full/acme/run +++ b/util/docker/web/scripts/run_acme_sh @@ -1,7 +1,5 @@ #!/bin/bash -sv -w 45 check nginx || exit 1 - # Acme loading script # Uses code from: # https://github.com/nginx-proxy/acme-companion/blob/main/app/letsencrypt_service @@ -204,7 +202,7 @@ function update_cert { else # If we did not get any email at all, use the default (empty mail) config config_home="/etc/acme.sh/default" - fi + fi local -n acme_ca_uri="ACME_CA_URI" if [[ -z "$acme_ca_uri" ]]; then @@ -253,7 +251,7 @@ function update_cert { # 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[@]}") @@ -279,7 +277,7 @@ function update_cert { 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) + params_issue_arr+=(--always-force-new-domain-key) fi [[ "${2:-}" == "--force-renew" ]] && params_issue_arr+=(--force) diff --git a/util/docker/web/service.full/php-fpm/run b/util/docker/web/scripts/run_php_fpm similarity index 78% rename from util/docker/web/service.full/php-fpm/run rename to util/docker/web/scripts/run_php_fpm index be807388b..d4d798324 100644 --- a/util/docker/web/service.full/php-fpm/run +++ b/util/docker/web/scripts/run_php_fpm @@ -1,14 +1,6 @@ #!/bin/bash -source /etc/container_environment.sh - -if [ -f /etc/service/mariadb/run ]; then - sv -w 30 check mariadb || exit 1 -fi - -if [ -f /etc/service/redis/run ]; then - sv -w 30 check redis || exit 1 -fi +source /etc/php/.version # Set up PHP config dockerize -template "/etc/php/${PHP_VERSION}/fpm/05-azuracast.ini.tmpl:/etc/php/${PHP_VERSION}/fpm/conf.d/05-azuracast.ini" \ diff --git a/util/docker/web/service.full/acme.conf b/util/docker/web/service.full/acme.conf new file mode 100644 index 000000000..ae212d5cb --- /dev/null +++ b/util/docker/web/service.full/acme.conf @@ -0,0 +1,11 @@ +[program:acme] +command=run_acme_sh +priority=200 +numprocs=1 +autostart=true +autorestart=true + +stdout_logfile=/proc/1/fd/1 +stdout_logfile_maxbytes=0 +stderr_logfile=/proc/1/fd/2 +stderr_logfile_maxbytes=0 diff --git a/util/docker/web/service.full/beanstalkd.conf b/util/docker/web/service.full/beanstalkd.conf new file mode 100644 index 000000000..33a0cf6e0 --- /dev/null +++ b/util/docker/web/service.full/beanstalkd.conf @@ -0,0 +1,11 @@ +[program:beanstalkd] +command=beanstalkd -p 11300 -z 262140 +user=azuracast +numprocs=1 +autostart=true +autorestart=unexpected + +stdout_logfile=/proc/1/fd/1 +stdout_logfile_maxbytes=0 +stderr_logfile=/proc/1/fd/2 +stderr_logfile_maxbytes=0 diff --git a/util/docker/web/service.full/beanstalkd/run b/util/docker/web/service.full/beanstalkd/run deleted file mode 100644 index b527151bc..000000000 --- a/util/docker/web/service.full/beanstalkd/run +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -echo 'Spinning up Beanstalkd process...' - -exec gosu azuracast beanstalkd -p 11300 -z 262140 diff --git a/util/docker/web/service.full/cron.conf b/util/docker/web/service.full/cron.conf new file mode 100644 index 000000000..075deab61 --- /dev/null +++ b/util/docker/web/service.full/cron.conf @@ -0,0 +1,11 @@ +[program:cron] +command=/usr/sbin/cron -f +priority=600 +numprocs=1 +autostart=true +autorestart=unexpected + +stdout_logfile=/proc/1/fd/1 +stdout_logfile_maxbytes=0 +stderr_logfile=/proc/1/fd/2 +stderr_logfile_maxbytes=0 diff --git a/util/docker/web/service.full/nginx.conf b/util/docker/web/service.full/nginx.conf new file mode 100644 index 000000000..943b9be7c --- /dev/null +++ b/util/docker/web/service.full/nginx.conf @@ -0,0 +1,13 @@ +[program:nginx] +command=nginx -g "daemon off;" +priority=100 +numprocs=1 +autostart=true +autorestart=unexpected +stopasgroup=true +killasgroup=true + +stdout_logfile=/proc/1/fd/1 +stdout_logfile_maxbytes=0 +stderr_logfile=/proc/1/fd/2 +stderr_logfile_maxbytes=0 diff --git a/util/docker/web/service.full/php-fpm.conf b/util/docker/web/service.full/php-fpm.conf new file mode 100644 index 000000000..d7e3c2ac0 --- /dev/null +++ b/util/docker/web/service.full/php-fpm.conf @@ -0,0 +1,13 @@ +[program:php-fpm] +command=run_php_fpm +priority=500 +numprocs=1 +autostart=true +autorestart=unexpected +stopasgroup=true +killasgroup=true + +stdout_logfile=/proc/1/fd/1 +stdout_logfile_maxbytes=0 +stderr_logfile=/proc/1/fd/2 +stderr_logfile_maxbytes=0 diff --git a/util/docker/web/service.full/php-fpm/check b/util/docker/web/service.full/php-fpm/check deleted file mode 100644 index 22494e375..000000000 --- a/util/docker/web/service.full/php-fpm/check +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -FCGI_CONNECT=/var/run/php-fpm-www.sock exec php-fpm-healthcheck diff --git a/util/docker/web/service.full/php-nowplaying.conf b/util/docker/web/service.full/php-nowplaying.conf new file mode 100644 index 000000000..93df19d73 --- /dev/null +++ b/util/docker/web/service.full/php-nowplaying.conf @@ -0,0 +1,14 @@ +[program:php-nowplaying] +command=php /var/azuracast/www/bin/console azuracast:sync:nowplaying +user=azuracast +priority=600 +numprocs=1 +autostart=true +autorestart=true +stopasgroup=true +killasgroup=true + +stdout_logfile=/proc/1/fd/1 +stdout_logfile_maxbytes=0 +stderr_logfile=/proc/1/fd/2 +stderr_logfile_maxbytes=0 diff --git a/util/docker/web/service.full/php-nowplaying/run b/util/docker/web/service.full/php-nowplaying/run deleted file mode 100644 index 4ecbbd197..000000000 --- a/util/docker/web/service.full/php-nowplaying/run +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -sv -w 30 check php-fpm || exit 1 - -exec gosu azuracast php /var/azuracast/www/bin/console azuracast:sync:nowplaying diff --git a/util/docker/web/service.full/php-worker.conf b/util/docker/web/service.full/php-worker.conf new file mode 100644 index 000000000..ccebfb727 --- /dev/null +++ b/util/docker/web/service.full/php-worker.conf @@ -0,0 +1,14 @@ +[program:php-worker] +command=php /var/azuracast/www/bin/console queue:process --worker-name=app_worker_0 +user=azuracast +priority=600 +numprocs=1 +autostart=true +autorestart=true +stopasgroup=true +killasgroup=true + +stdout_logfile=/proc/1/fd/1 +stdout_logfile_maxbytes=0 +stderr_logfile=/proc/1/fd/2 +stderr_logfile_maxbytes=0 diff --git a/util/docker/web/service.full/php-worker/run b/util/docker/web/service.full/php-worker/run deleted file mode 100644 index c3a5e4dc7..000000000 --- a/util/docker/web/service.full/php-worker/run +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -sv -w 30 check php-fpm || exit 1 - -exec gosu azuracast php /var/azuracast/www/bin/console queue:process --worker-name=app_worker_0 diff --git a/util/docker/web/service.full/sftpgo.conf b/util/docker/web/service.full/sftpgo.conf new file mode 100644 index 000000000..4eb334b03 --- /dev/null +++ b/util/docker/web/service.full/sftpgo.conf @@ -0,0 +1,15 @@ +[program:sftpgo] +command=sftpgo --config-dir=/var/azuracast/sftpgo serve -l "" +dir=/var/azuracast/sftpgo +user=azuracast +priority=700 +numprocs=1 +autostart=true +autorestart=true +stopasgroup=true +killasgroup=true + +stdout_logfile=/proc/1/fd/1 +stdout_logfile_maxbytes=0 +stderr_logfile=/proc/1/fd/2 +stderr_logfile_maxbytes=0 diff --git a/util/docker/web/setup.sh b/util/docker/web/setup.sh index 54135a24e..f065a2fe0 100644 --- a/util/docker/web/setup.sh +++ b/util/docker/web/setup.sh @@ -1,6 +1,5 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x apt-get update @@ -10,11 +9,20 @@ cp -rT /bd_build/web/scripts/ /usr/local/bin cp -rT /bd_build/web/startup_scripts/. /etc/my_init.d/ -# cp -rT /bd_build/web/service.minimal/. /etc/service.minimal/ +# cp -rT /bd_build/web/service.minimal/. /etc/supervisor/minimal.conf.d/ -cp -rT /bd_build/web/service.full/. /etc/service.full/ +cp -rT /bd_build/web/service.full/. /etc/supervisor/full.conf.d/ # Run service setup for all setup scripts for f in /bd_build/web/setup/*.sh; do bash "$f" -H done + +# Cleanup +apt-get -y autoremove +apt-get clean +rm -rf /var/lib/apt/lists/* +rm -rf /tmp/tmp* + +chmod -R a+x /usr/local/bin +chmod -R +x /etc/my_init.d diff --git a/util/docker/web/setup/acme_sh.sh b/util/docker/web/setup/acme_sh.sh index e25d0a853..65644f992 100644 --- a/util/docker/web/setup/acme_sh.sh +++ b/util/docker/web/setup/acme_sh.sh @@ -1,6 +1,5 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x # Get acme.sh ACME client source diff --git a/util/docker/web/setup/audiowaveform.sh b/util/docker/web/setup/audiowaveform.sh index 5bfc45894..494fc5005 100644 --- a/util/docker/web/setup/audiowaveform.sh +++ b/util/docker/web/setup/audiowaveform.sh @@ -1,9 +1,8 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x add-apt-repository -y ppa:chris-needham/ppa apt-get update -$minimal_apt_get_install audiowaveform +apt-get install -y --no-install-recommends audiowaveform diff --git a/util/docker/web/setup/beanstalkd.sh b/util/docker/web/setup/beanstalkd.sh index 619764d22..ac81bb29b 100644 --- a/util/docker/web/setup/beanstalkd.sh +++ b/util/docker/web/setup/beanstalkd.sh @@ -1,8 +1,25 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x -$minimal_apt_get_install netbase +install_without_postinst() { + local PACKAGE + PACKAGE=$1 + + mkdir -p /tmp/install_$PACKAGE + cd /tmp/install_$PACKAGE + + apt-get download $PACKAGE + dpkg --unpack $PACKAGE*.deb + rm -f /var/lib/dpkg/info/$PACKAGE.postinst + dpkg --configure $PACKAGE + + apt-get install -yf #To fix dependencies + + cd / + rm -rf /tmp/install_$PACKAGE +} + +apt-get install -y --no-install-recommends netbase install_without_postinst beanstalkd diff --git a/util/docker/web/setup/cron.sh b/util/docker/web/setup/cron.sh index 51bf06f20..eeb13f094 100644 --- a/util/docker/web/setup/cron.sh +++ b/util/docker/web/setup/cron.sh @@ -1,8 +1,25 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x +install_without_postinst() { + local PACKAGE + PACKAGE=$1 + + mkdir -p /tmp/install_$PACKAGE + cd /tmp/install_$PACKAGE + + apt-get download $PACKAGE + dpkg --unpack $PACKAGE*.deb + rm -f /var/lib/dpkg/info/$PACKAGE.postinst + dpkg --configure $PACKAGE + + apt-get install -yf #To fix dependencies + + cd / + rm -rf /tmp/install_$PACKAGE +} + install_without_postinst cron chmod 600 /etc/crontab diff --git a/util/docker/web/setup/dbip.sh b/util/docker/web/setup/dbip.sh index ca1d77829..46a06534e 100644 --- a/util/docker/web/setup/dbip.sh +++ b/util/docker/web/setup/dbip.sh @@ -1,6 +1,5 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x cd /tmp diff --git a/util/docker/web/setup/nginx.sh b/util/docker/web/setup/nginx.sh index afe8a8fdd..71530b63b 100644 --- a/util/docker/web/setup/nginx.sh +++ b/util/docker/web/setup/nginx.sh @@ -1,9 +1,8 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x -$minimal_apt_get_install nginx nginx-common nginx-extras openssl +apt-get install -y --no-install-recommends nginx nginx-common nginx-extras openssl # Install nginx and configuration cp /bd_build/web/nginx/proxy_params.conf /etc/nginx/proxy_params diff --git a/util/docker/web/setup/php.sh b/util/docker/web/setup/php.sh index 1e6fbcfc5..f02c48056 100644 --- a/util/docker/web/setup/php.sh +++ b/util/docker/web/setup/php.sh @@ -1,22 +1,21 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x PHP_VERSION=8.1 -echo "${PHP_VERSION}" >> /etc/container_environment/PHP_VERSION - add-apt-repository -y ppa:ondrej/php apt-get update -$minimal_apt_get_install php${PHP_VERSION}-fpm php${PHP_VERSION}-cli php${PHP_VERSION}-gd \ +apt-get install -y --no-install-recommends php${PHP_VERSION}-fpm php${PHP_VERSION}-cli php${PHP_VERSION}-gd \ php${PHP_VERSION}-curl php${PHP_VERSION}-xml php${PHP_VERSION}-zip php${PHP_VERSION}-bcmath \ php${PHP_VERSION}-gmp php${PHP_VERSION}-mysqlnd php${PHP_VERSION}-mbstring php${PHP_VERSION}-intl \ php${PHP_VERSION}-redis php${PHP_VERSION}-maxminddb php${PHP_VERSION}-xdebug \ mariadb-client # Copy PHP configuration +echo "PHP_VERSION=$PHP_VERSION" >> /etc/php/.version + mkdir -p /run/php touch /run/php/php${PHP_VERSION}-fpm.pid @@ -27,14 +26,14 @@ cp /bd_build/web/php/www.conf.tmpl /etc/php/${PHP_VERSION}/fpm/www.conf.tmpl curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer # Download PHP-FPM healthcheck script -$minimal_apt_get_install libfcgi-bin +apt-get install -y --no-install-recommends libfcgi-bin wget -O /usr/local/bin/php-fpm-healthcheck \ https://raw.githubusercontent.com/renatomefi/php-fpm-healthcheck/master/php-fpm-healthcheck \ && chmod +x /usr/local/bin/php-fpm-healthcheck # Install PHP SPX profiler -$minimal_apt_get_install php${PHP_VERSION}-dev zlib1g-dev build-essential +apt-get install -y --no-install-recommends php${PHP_VERSION}-dev zlib1g-dev build-essential cd /bd_build git clone https://github.com/NoiseByNorthwest/php-spx.git diff --git a/util/docker/web/setup/sftpgo.sh b/util/docker/web/setup/sftpgo.sh index 41e54bc2b..c87764480 100644 --- a/util/docker/web/setup/sftpgo.sh +++ b/util/docker/web/setup/sftpgo.sh @@ -1,12 +1,11 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x add-apt-repository -y ppa:sftpgo/sftpgo apt-get update -$minimal_apt_get_install sftpgo +apt-get install -y --no-install-recommends sftpgo mkdir -p /var/azuracast/sftpgo/persist /var/azuracast/sftpgo/backups diff --git a/util/docker/web/setup/tmpreaper.sh b/util/docker/web/setup/tmpreaper.sh index 28992225f..b97592fd3 100644 --- a/util/docker/web/setup/tmpreaper.sh +++ b/util/docker/web/setup/tmpreaper.sh @@ -1,6 +1,5 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x -$minimal_apt_get_install tmpreaper \ No newline at end of file +apt-get install -y --no-install-recommends tmpreaper diff --git a/util/docker/web/setup/zstd.sh b/util/docker/web/setup/zstd.sh index 8238e4d8d..9980fcc0b 100644 --- a/util/docker/web/setup/zstd.sh +++ b/util/docker/web/setup/zstd.sh @@ -1,6 +1,5 @@ #!/bin/bash set -e -source /bd_build/buildconfig set -x -$minimal_apt_get_install zstd +apt-get install -y --no-install-recommends zstd diff --git a/util/docker/web/sftpgo/sftpgo.json b/util/docker/web/sftpgo/sftpgo.json index 30bf00149..d8bb8ae24 100644 --- a/util/docker/web/sftpgo/sftpgo.json +++ b/util/docker/web/sftpgo/sftpgo.json @@ -1,53 +1,53 @@ { - "common": { - "idle_timeout": 15, - "upload_mode": 2, - "setstat_mode": 1, - "actions": { - "execute_on": [ - "upload", - "pre-delete", - "rename" - ], - "hook": "/usr/local/bin/azuracast_sftp_event" - }, - "defender": { - "enabled": true, - "driver": "memory" - } + "common": { + "idle_timeout": 15, + "upload_mode": 2, + "setstat_mode": 1, + "actions": { + "execute_on": [ + "upload", + "pre-delete", + "rename" + ], + "hook": "http://127.0.0.1:6010/api/internal/sftp-event" }, - "sftpd": { - "bindings": [ - { - "port": 2022, - "address": "", - "apply_proxy_config": true - } - ], - "host_keys": [ - "persist/id_rsa", - "persist/id_ecdsa", - "persist/id_ed25519" - ], - "enable_scp": true - }, - "httpd": { - "bindings": [ - { - "port": 0 - } - ], - "templates_path": "/usr/share/sftpgo/templates", - "static_files_path": "/usr/share/sftpgo/static" - }, - "telemetry": { - "bind_port": 0 - }, - "data_provider": { - "driver": "bolt", - "name": "sftpgo.db", - "users_base_dir": "/var/azuracast/stations", - "external_auth_hook": "/usr/local/bin/azuracast_sftp_auth", - "external_auth_scope": 0 + "defender": { + "enabled": true, + "driver": "memory" } + }, + "sftpd": { + "bindings": [ + { + "port": 2022, + "address": "", + "apply_proxy_config": true + } + ], + "host_keys": [ + "persist/id_rsa", + "persist/id_ecdsa", + "persist/id_ed25519" + ], + "enable_scp": true + }, + "httpd": { + "bindings": [ + { + "port": 0 + } + ], + "templates_path": "/usr/share/sftpgo/templates", + "static_files_path": "/usr/share/sftpgo/static" + }, + "telemetry": { + "bind_port": 0 + }, + "data_provider": { + "driver": "bolt", + "name": "sftpgo.db", + "users_base_dir": "/var/azuracast/stations", + "external_auth_hook": "http://127.0.0.1:6010/api/internal/sftp-auth", + "external_auth_scope": 0 + } } diff --git a/util/docker/web/service.full/cron/run b/util/docker/web/startup_scripts/02_prepare_cron.sh similarity index 74% rename from util/docker/web/service.full/cron/run rename to util/docker/web/startup_scripts/02_prepare_cron.sh index 346a19f29..3f6186f72 100644 --- a/util/docker/web/service.full/cron/run +++ b/util/docker/web/startup_scripts/02_prepare_cron.sh @@ -1,10 +1,6 @@ -#!/bin/sh - -sv -w 30 check php-fpm || exit 1 +#!/bin/bash # Touch cron files to fix 'NUMBER OF HARD LINKS > 1' issue. See https://github.com/phusion/baseimage-docker/issues/198 touch -c /var/spool/cron/crontabs/* touch -c /etc/crontab touch -c /etc/cron.*/* - -exec /usr/sbin/cron -f diff --git a/util/docker/web/service.full/nginx/run b/util/docker/web/startup_scripts/05_nginx_conf.sh similarity index 73% rename from util/docker/web/service.full/nginx/run rename to util/docker/web/startup_scripts/05_nginx_conf.sh index 2b87f8027..4fccec116 100644 --- a/util/docker/web/service.full/nginx/run +++ b/util/docker/web/startup_scripts/05_nginx_conf.sh @@ -1,9 +1,7 @@ #!/bin/bash -sv -w 30 check php-fpm || exit 1 - REDIS_LOCAL=false -if [ -f /etc/service/redis/run ]; then +if [ -f /etc/supervisor/minimal.conf.d/redis.conf ]; then REDIS_LOCAL=true fi export REDIS_LOCAL @@ -11,5 +9,3 @@ export REDIS_LOCAL # Copy the nginx template to its destination. dockerize -template "/etc/nginx/nginx.conf.tmpl:/etc/nginx/nginx.conf" \ -template "/etc/nginx/azuracast.conf.tmpl:/etc/nginx/sites-available/default" - -exec nginx -g "daemon off;" diff --git a/util/docker/web/service.full/sftpgo/run b/util/docker/web/startup_scripts/07_sftpgo_conf.sh similarity index 74% rename from util/docker/web/service.full/sftpgo/run rename to util/docker/web/startup_scripts/07_sftpgo_conf.sh index 75894195f..0cff72767 100644 --- a/util/docker/web/service.full/sftpgo/run +++ b/util/docker/web/startup_scripts/07_sftpgo_conf.sh @@ -1,7 +1,5 @@ #!/bin/bash -echo 'Spinning up SFTP process...' - if [[ ! -f /var/azuracast/sftpgo/persist/id_rsa ]]; then ssh-keygen -t rsa -b 4096 -f /var/azuracast/sftpgo/persist/id_rsa -q -N "" fi @@ -15,7 +13,3 @@ if [[ ! -f /var/azuracast/sftpgo/persist/id_ed25519 ]]; then fi chown -R azuracast:azuracast /var/azuracast/sftpgo/persist - -cd /var/azuracast/sftpgo - -exec sudo -E -u azuracast sftpgo --config-dir=/var/azuracast/sftpgo serve -l "" > /proc/1/fd/1 2> /proc/1/fd/2