diff --git a/Containers/mastercontainer/daily-backup.sh b/Containers/mastercontainer/daily-backup.sh index c68835ea..5c97c0ca 100644 --- a/Containers/mastercontainer/daily-backup.sh +++ b/Containers/mastercontainer/daily-backup.sh @@ -64,6 +64,12 @@ if [ "$AUTOMATIC_UPDATES" = 1 ]; then done fi +# Update container images to reduce downtime later on +if [ "$AUTOMATIC_UPDATES" = 1 ]; then + echo "Updating container images..." + sudo -u www-data php /var/www/docker-aio/php/src/Cron/PullContainerImages.php +fi + # Stop containers if required # shellcheck disable=SC2235 if [ "$CHECK_BACKUP" != 1 ] && ([ "$DAILY_BACKUP" != 1 ] || [ "$STOP_CONTAINERS" = 1 ]); then diff --git a/php/src/Controller/DockerController.php b/php/src/Controller/DockerController.php index e8f9d591..378ddab6 100644 --- a/php/src/Controller/DockerController.php +++ b/php/src/Controller/DockerController.php @@ -34,33 +34,32 @@ readonly class DockerController { return; } - // Skip database image pull if the last shutdown was not clean - if ($id === 'nextcloud-aio-database') { - if ($this->dockerActionManager->GetDatabasecontainerExitCode() > 0) { - $pullImage = false; - error_log('Not pulling the latest database image because the container was not correctly shut down.'); - } - } - - // Check if registry is reachable in order to make sure that we do not try to pull an image if it is down - // and try to mitigate issues that are arising due to that - if ($pullImage) { - if (!$this->dockerActionManager->isRegistryReachable($container)) { - $pullImage = false; - error_log('Not pulling the ' . $container->GetContainerName() . ' image for the ' . $container->GetIdentifier() . ' container because the registry does not seem to be reachable.'); - } - } - $this->dockerActionManager->DeleteContainer($container); $this->dockerActionManager->CreateVolumes($container); - if ($pullImage) { - $this->dockerActionManager->PullImage($container); - } + $this->dockerActionManager->PullImage($container, $pullImage); $this->dockerActionManager->CreateContainer($container); $this->dockerActionManager->StartContainer($container); $this->dockerActionManager->ConnectContainerToNetwork($container); } + private function PerformRecursiveImagePull(string $id) : void { + $container = $this->containerDefinitionFetcher->GetContainerById($id); + + // Pull all dependencies first and then itself + foreach($container->GetDependsOn() as $dependency) { + $this->PerformRecursiveImagePull($dependency); + } + + $this->dockerActionManager->PullImage($container, true); + } + + public function PullAllContainerImages(): void { + + $id = self::TOP_CONTAINER; + + $this->PerformRecursiveImagePull($id); + } + public function GetLogs(Request $request, Response $response, array $args) : Response { $requestParams = $request->getQueryParams(); diff --git a/php/src/Cron/PullContainerImages.php b/php/src/Cron/PullContainerImages.php new file mode 100644 index 00000000..43c87d28 --- /dev/null +++ b/php/src/Cron/PullContainerImages.php @@ -0,0 +1,20 @@ +get(\AIO\Controller\DockerController::class); + +// Pull all containers +$dockerController->PullAllContainerImages(); diff --git a/php/src/Docker/DockerActionManager.php b/php/src/Docker/DockerActionManager.php index 0ccdcf58..2c8e365e 100644 --- a/php/src/Docker/DockerActionManager.php +++ b/php/src/Docker/DockerActionManager.php @@ -450,7 +450,30 @@ readonly class DockerActionManager { } } - public function PullImage(Container $container): void { + public function PullImage(Container $container, bool $pullImage = true): void { + + // Skip database image pull if the last shutdown was not clean + if ($container->GetIdentifier() === 'nextcloud-aio-database') { + if ($this->GetDatabasecontainerExitCode() > 0) { + $pullImage = false; + error_log('Not pulling the latest database image because the container was not correctly shut down.'); + } + } + + // Check if registry is reachable in order to make sure that we do not try to pull an image if it is down + // and try to mitigate issues that are arising due to that + if ($pullImage) { + if (!$this->isRegistryReachable($container)) { + $pullImage = false; + error_log('Not pulling the ' . $container->GetContainerName() . ' image for the ' . $container->GetIdentifier() . ' container because the registry does not seem to be reachable.'); + } + } + + // Do not continue if $pullImage is false + if (!$pullImage) { + return; + } + $imageName = $this->BuildImageName($container); $encodedImageName = urlencode($imageName); $url = $this->BuildApiUrl(sprintf('images/create?fromImage=%s', $encodedImageName));