diff --git a/Containers/mastercontainer/Dockerfile b/Containers/mastercontainer/Dockerfile
index e35a0d49..352bb64f 100644
--- a/Containers/mastercontainer/Dockerfile
+++ b/Containers/mastercontainer/Dockerfile
@@ -88,11 +88,13 @@ COPY start.sh /usr/bin/
COPY backup-time-file-watcher.sh /
COPY session-deduplicator.sh /
COPY cron.sh /
+COPY daily-backup.sh /
COPY supervisord.conf /
RUN chmod +x /usr/bin/start.sh; \
chmod +x /cron.sh; \
chmod +x /session-deduplicator.sh; \
chmod +x /backup-time-file-watcher.sh; \
+ chmod +x /daily-backup.sh; \
chmod a+r /Caddyfile
USER root
diff --git a/Containers/mastercontainer/backup-time-file-watcher.sh b/Containers/mastercontainer/backup-time-file-watcher.sh
index e7e34d16..ec9154ab 100644
--- a/Containers/mastercontainer/backup-time-file-watcher.sh
+++ b/Containers/mastercontainer/backup-time-file-watcher.sh
@@ -10,12 +10,12 @@ file_present() {
if [ "$FILE_PRESENT" = 0 ]; then
restart_process
else
- if [ -n "$BACKUP_TIME" ] && [ "$(cat "/mnt/docker-aio-config/data/daily_backup_time")" != "$BACKUP_TIME" ]; then
+ if [ -n "$BACKUP_TIME" ] && [ "$(head -1 "/mnt/docker-aio-config/data/daily_backup_time")" != "$BACKUP_TIME" ]; then
restart_process
fi
fi
FILE_PRESENT=1
- BACKUP_TIME="$(cat "/mnt/docker-aio-config/data/daily_backup_time")"
+ BACKUP_TIME="$(head -1 "/mnt/docker-aio-config/data/daily_backup_time")"
else
if [ "$FILE_PRESENT" = 1 ]; then
restart_process
diff --git a/Containers/mastercontainer/cron.sh b/Containers/mastercontainer/cron.sh
index 8d0df12f..1fe5ff8d 100644
--- a/Containers/mastercontainer/cron.sh
+++ b/Containers/mastercontainer/cron.sh
@@ -3,18 +3,25 @@
while true; do
if [ -f "/mnt/docker-aio-config/data/daily_backup_time" ]; then
set -x
- BACKUP_TIME="$(cat "/mnt/docker-aio-config/data/daily_backup_time")"
- DAILY_BACKUP=1
+ BACKUP_TIME="$(head -1 "/mnt/docker-aio-config/data/daily_backup_time")"
+ export BACKUP_TIME
+ export DAILY_BACKUP=1
+ if [ "$(sed -n '2p' "/mnt/docker-aio-config/data/daily_backup_time")" != 'automaticUpdatesAreNotEnabled' ]; then
+ export AUTOMATIC_UPDATES=1
+ else
+ export AUTOMATIC_UPDATES=0
+ export START_CONTAINERS=1
+ fi
set +x
else
- BACKUP_TIME="04:00"
- DAILY_BACKUP=0
+ export BACKUP_TIME="04:00"
+ export DAILY_BACKUP=0
fi
if [ -f "/mnt/docker-aio-config/data/daily_backup_running" ]; then
- LOCK_FILE_PRESENT=1
+ export LOCK_FILE_PRESENT=1
else
- LOCK_FILE_PRESENT=0
+ export LOCK_FILE_PRESENT=0
fi
# Allow to continue directly if e.g. the mastercontainer was updated. Otherwise wait for the next execution
@@ -25,61 +32,7 @@ while true; do
fi
if [ "$DAILY_BACKUP" = 1 ]; then
- echo "Daily backup has started"
-
- # Delete all active sessions and create a lock file
- # But don't kick out the user if the mastercontainer was just updated since we block the interface either way with the lock file
- if [ "$LOCK_FILE_PRESENT" = 0 ]; then
- rm -f "/mnt/docker-aio-config/session/"*
- fi
- sudo -u www-data touch "/mnt/docker-aio-config/data/daily_backup_running"
-
- # Check if apache is running/stopped, watchtower is stopped and backupcontainer is stopped
- APACHE_PORT="$(docker inspect nextcloud-aio-apache --format "{{.HostConfig.PortBindings}}" | grep -oP '[0-9]+' | head -1)"
- while docker ps --format "{{.Names}}" | grep -q "^nextcloud-aio-apache$" && ! nc -z nextcloud-aio-apache "$APACHE_PORT"; do
- echo "Waiting for apache to become available"
- sleep 30
- done
- while docker ps --format "{{.Names}}" | grep -q "^nextcloud-aio-watchtower$"; do
- echo "Waiting for watchtower to stop"
- sleep 30
- done
- while docker ps --format "{{.Names}}" | grep -q "^nextcloud-aio-borgbackup$"; do
- echo "Waiting for borgbackup to stop"
- sleep 30
- done
-
- # Update the mastercontainer
- sudo -u www-data php /var/www/docker-aio/php/src/Cron/UpdateMastercontainer.php
-
- # Wait for watchtower to stop
- if ! docker ps --format "{{.Names}}" | grep -q "^nextcloud-aio-watchtower$"; then
- echo "Something seems to be wrong: Watchtower should be started at this step."
- else
- while docker ps --format "{{.Names}}" | grep -q "^nextcloud-aio-watchtower$"; do
- echo "Waiting for watchtower to stop"
- sleep 30
- done
- fi
-
- # Execute the backup itself and some related tasks
- sudo -u www-data php /var/www/docker-aio/php/src/Cron/DailyBackup.php
-
- # Delete the lock file
- rm -f "/mnt/docker-aio-config/data/daily_backup_running"
-
- # Wait for the nextcloud container to start and send if the backup was successful
- if ! docker ps --format "{{.Names}}" | grep -q "^nextcloud-aio-nextcloud$"; then
- echo "Something seems to be wrong: Nextcloud should be started at this step."
- else
- while docker ps --format "{{.Names}}" | grep -q "^nextcloud-aio-nextcloud$" && ! nc -z nextcloud-aio-nextcloud 9000; do
- echo "Waiting for the Nextcloud container to start"
- sleep 30
- done
- fi
- sudo -u www-data php /var/www/docker-aio/php/src/Cron/BackupNotification.php
-
- echo "Daily backup has finished"
+ bash /daily-backup.sh
fi
# Make sure to delete the lock file always
diff --git a/Containers/mastercontainer/daily-backup.sh b/Containers/mastercontainer/daily-backup.sh
new file mode 100644
index 00000000..ac6a4867
--- /dev/null
+++ b/Containers/mastercontainer/daily-backup.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+
+echo "Daily backup has started"
+
+# Delete all active sessions and create a lock file
+# But don't kick out the user if the mastercontainer was just updated since we block the interface either way with the lock file
+if [ "$LOCK_FILE_PRESENT" = 0 ]; then
+ rm -f "/mnt/docker-aio-config/session/"*
+fi
+sudo -u www-data touch "/mnt/docker-aio-config/data/daily_backup_running"
+
+# Check if apache is running/stopped, watchtower is stopped and backupcontainer is stopped
+APACHE_PORT="$(docker inspect nextcloud-aio-apache --format "{{.HostConfig.PortBindings}}" | grep -oP '[0-9]+' | head -1)"
+while docker ps --format "{{.Names}}" | grep -q "^nextcloud-aio-apache$" && ! nc -z nextcloud-aio-apache "$APACHE_PORT"; do
+ echo "Waiting for apache to become available"
+ sleep 30
+done
+while docker ps --format "{{.Names}}" | grep -q "^nextcloud-aio-watchtower$"; do
+ echo "Waiting for watchtower to stop"
+ sleep 30
+done
+while docker ps --format "{{.Names}}" | grep -q "^nextcloud-aio-borgbackup$"; do
+ echo "Waiting for borgbackup to stop"
+ sleep 30
+done
+
+# Update the mastercontainer
+if [ "$AUTOMATIC_UPDATES" = 1 ]; then
+ sudo -u www-data php /var/www/docker-aio/php/src/Cron/UpdateMastercontainer.php
+fi
+
+# Wait for watchtower to stop
+if [ "$AUTOMATIC_UPDATES" = 1 ] && ! docker ps --format "{{.Names}}" | grep -q "^nextcloud-aio-watchtower$"; then
+ echo "Something seems to be wrong: Watchtower should be started at this step."
+else
+ while docker ps --format "{{.Names}}" | grep -q "^nextcloud-aio-watchtower$"; do
+ echo "Waiting for watchtower to stop"
+ sleep 30
+ done
+fi
+
+# Stop containers if required
+if [ "$DAILY_BACKUP" != 1 ] || [ "$STOP_CONTAINERS" = 1 ]; then
+ sudo -u www-data php /var/www/docker-aio/php/src/Cron/StopContainers.php
+fi
+
+# Execute the backup itself and some related tasks (also stops the containers)
+if [ "$DAILY_BACKUP" = 1 ]; then
+ sudo -u www-data php /var/www/docker-aio/php/src/Cron/CreateBackup.php
+fi
+
+# Start and/or update containers
+if [ "$AUTOMATIC_UPDATES" = 1 ]; then
+ sudo -u www-data php /var/www/docker-aio/php/src/Cron/StartAndUpdateContainers.php
+else
+ if [ "$START_CONTAINERS" = 1 ]; then
+ sudo -u www-data php /var/www/docker-aio/php/src/Cron/StartContainers.php
+ fi
+fi
+
+# Delete the lock file
+rm -f "/mnt/docker-aio-config/data/daily_backup_running"
+
+if [ "$DAILY_BACKUP" = 1 ]; then
+ # Wait for the nextcloud container to start and send if the backup was successful
+ if ! docker ps --format "{{.Names}}" | grep -q "^nextcloud-aio-nextcloud$"; then
+ echo "Something seems to be wrong: Nextcloud should be started at this step."
+ else
+ while docker ps --format "{{.Names}}" | grep -q "^nextcloud-aio-nextcloud$" && ! nc -z nextcloud-aio-nextcloud 9000; do
+ echo "Waiting for the Nextcloud container to start"
+ sleep 30
+ done
+ fi
+ sudo -u www-data php /var/www/docker-aio/php/src/Cron/BackupNotification.php
+fi
+
+echo "Daily backup has finished"
diff --git a/Containers/nextcloud/entrypoint.sh b/Containers/nextcloud/entrypoint.sh
index d6a0ea58..2c4d8c0d 100644
--- a/Containers/nextcloud/entrypoint.sh
+++ b/Containers/nextcloud/entrypoint.sh
@@ -246,7 +246,7 @@ if ! [ -f "/mnt/ncdata/skip.update" ]; then
fi
# Performing update of all apps if daily backups are enabled, running and successful and if it is saturday
- if [ "$DAILY_BACKUP_RUNNING" = 'yes' ] && [ "$(date +%u)" = 6 ]; then
+ if [ "$UPDATE_NEXTCLOUD_APPS" = 'yes' ] && [ "$(date +%u)" = 6 ]; then
UPDATED_APPS="$(php /var/www/html/occ app:update --all)"
if [ -n "$UPDATED_APPS" ]; then
bash /notify.sh "Your apps just got updated!" "$UPDATED_APPS"
diff --git a/manual-install/update-yaml.sh b/manual-install/update-yaml.sh
index e30f937a..d12f3ed0 100644
--- a/manual-install/update-yaml.sh
+++ b/manual-install/update-yaml.sh
@@ -62,7 +62,7 @@ sed -i 's|COLLABORA_ENABLED=no|COLLABORA_ENABLED=yes|' sample.conf
sed -i 's|COLLABORA_DICTIONARIES=|COLLABORA_DICTIONARIES=de_DE en_GB en_US es_ES fr_FR it nl pt_BR pt_PT ru # You can change this in order to enable other dictionaries for collabora|' sample.conf
sed -i 's|NEXTCLOUD_DATADIR=|NEXTCLOUD_DATADIR=nextcloud_aio_nextcloud_data # You can change this to e.g. "/mnt/ncdata" to map it to a location on your host. It needs to be adjusted before the first startup and never afterwards!|' sample.conf
sed -i 's|NEXTCLOUD_MOUNT=|NEXTCLOUD_MOUNT=/mnt/ # This allows the Nextcloud container to access directories on the host. It must never be equal to the value of NEXTCLOUD_DATADIR!|' sample.conf
-sed -i 's|DAILY_BACKUP_RUNNING=|DAILY_BACKUP_RUNNING=no # When setting to yes, it will automatically update all installed Nextcloud apps upon container startup on saturdays.|' sample.conf
+sed -i 's|UPDATE_NEXTCLOUD_APPS=|UPDATE_NEXTCLOUD_APPS=no # When setting to yes, it will automatically update all installed Nextcloud apps upon container startup.|' sample.conf
sed -i 's|APACHE_PORT=|APACHE_PORT=443 # Changing this to a different value than 443 will allow you to run it behind a reverse proxy.|' sample.conf
sed -i 's|TALK_PORT=|TALK_PORT=3478 # This allows to adjust the port that the talk container is using.|' sample.conf
sed -i 's|AIO_TOKEN=|AIO_TOKEN=123456 # Has no function but needs to be set!|' sample.conf
diff --git a/php/containers.json b/php/containers.json
index 39c2fca1..4f7a84a6 100644
--- a/php/containers.json
+++ b/php/containers.json
@@ -138,7 +138,7 @@
"COLLABORA_HOST=nextcloud-aio-collabora",
"TALK_ENABLED=%TALK_ENABLED%",
"ONLYOFFICE_HOST=nextcloud-aio-onlyoffice",
- "DAILY_BACKUP_RUNNING=%DAILY_BACKUP_RUNNING%",
+ "UPDATE_NEXTCLOUD_APPS=%UPDATE_NEXTCLOUD_APPS%",
"TZ=%TIMEZONE%",
"TALK_PORT=%TALK_PORT%"
],
diff --git a/php/public/index.php b/php/public/index.php
index abc1d17f..2a483da9 100644
--- a/php/public/index.php
+++ b/php/public/index.php
@@ -99,7 +99,8 @@ $app->get('/containers', function ($request, $response, $args) use ($container)
'timezone' => $configurationManager->GetTimezone(),
'skip_domain_validation' => $configurationManager->shouldDomainValidationBeSkipped(),
'talk_port' => $configurationManager->GetTalkPort(),
- 'collabora_dictionaries' => $configurationManager->GetCollaboraDictionaries(),
+ 'collabora_dictionaries' => $configurationManager->GetCollaboraDictionaries(),
+ 'automatic_updates' => $configurationManager->areAutomaticUpdatesEnabled(),
]);
})->setName('profile');
$app->get('/login', function ($request, $response, $args) use ($container) {
diff --git a/php/src/Controller/ConfigurationController.php b/php/src/Controller/ConfigurationController.php
index cf8c5031..109626e9 100644
--- a/php/src/Controller/ConfigurationController.php
+++ b/php/src/Controller/ConfigurationController.php
@@ -44,8 +44,13 @@ class ConfigurationController
}
if (isset($request->getParsedBody()['daily_backup_time'])) {
+ if (isset($request->getParsedBody()['automatic_updates'])) {
+ $enableAutomaticUpdates = true;
+ } else {
+ $enableAutomaticUpdates = false;
+ }
$dailyBackupTime = $request->getParsedBody()['daily_backup_time'] ?? '';
- $this->configurationManager->SetDailyBackupTime($dailyBackupTime);
+ $this->configurationManager->SetDailyBackupTime($dailyBackupTime, $enableAutomaticUpdates);
}
if (isset($request->getParsedBody()['delete_daily_backup_time'])) {
diff --git a/php/src/Controller/DockerController.php b/php/src/Controller/DockerController.php
index dafe6748..9db7d627 100644
--- a/php/src/Controller/DockerController.php
+++ b/php/src/Controller/DockerController.php
@@ -26,22 +26,21 @@ class DockerController
$this->configurationManager = $configurationManager;
}
- private function PerformRecursiveContainerStart(string $id) : void {
+ private function PerformRecursiveContainerStart(string $id, bool $pullContainer = true) : void {
$container = $this->containerDefinitionFetcher->GetContainerById($id);
foreach($container->GetDependsOn() as $dependency) {
$this->PerformRecursiveContainerStart($dependency);
}
- $pullcontainer = true;
if ($id === 'nextcloud-aio-database') {
if ($this->dockerActionManager->GetDatabasecontainerExitCode() > 0) {
- $pullcontainer = false;
+ $pullContainer = false;
}
}
$this->dockerActionManager->DeleteContainer($container);
$this->dockerActionManager->CreateVolumes($container);
- if ($pullcontainer) {
+ if ($pullContainer) {
$this->dockerActionManager->PullContainer($container);
} else {
error_log('Not pulling the latest database image because the container was not correctly shut down.');
@@ -145,12 +144,12 @@ class DockerController
$this->configurationManager->WriteConfig($config);
// Start container
- $this->startTopContainer();
+ $this->startTopContainer(true);
return $response->withStatus(201)->withHeader('Location', '/');
}
- public function startTopContainer() : void {
+ public function startTopContainer(bool $pullContainer) : void {
$config = $this->configurationManager->GetConfig();
// set AIO_TOKEN
$config['AIO_TOKEN'] = bin2hex(random_bytes(24));
@@ -161,7 +160,7 @@ class DockerController
$id = self::TOP_CONTAINER;
- $this->PerformRecursiveContainerStart($id);
+ $this->PerformRecursiveContainerStart($id, $pullContainer);
}
public function StartWatchtowerContainer(Request $request, Response $response, $args) : Response {
@@ -195,6 +194,11 @@ class DockerController
return $response->withStatus(201)->withHeader('Location', '/');
}
+ public function stopTopContainer() : void {
+ $id = self::TOP_CONTAINER;
+ $this->PerformRecursiveContainerStop($id);
+ }
+
public function StartDomaincheckContainer() : void
{
# Don't start if domain is already set
diff --git a/php/src/Cron/DailyBackup.php b/php/src/Cron/CreateBackup.php
similarity index 84%
rename from php/src/Cron/DailyBackup.php
rename to php/src/Cron/CreateBackup.php
index 932bd04f..60366973 100644
--- a/php/src/Cron/DailyBackup.php
+++ b/php/src/Cron/CreateBackup.php
@@ -15,6 +15,3 @@ $dockerController = $container->get(\AIO\Controller\DockerController::class);
// Stop container and start backup
$dockerController->startBackup();
-
-// Start apache
-$dockerController->startTopContainer();
diff --git a/php/src/Cron/StartAndUpdateContainers.php b/php/src/Cron/StartAndUpdateContainers.php
new file mode 100644
index 00000000..e72ae804
--- /dev/null
+++ b/php/src/Cron/StartAndUpdateContainers.php
@@ -0,0 +1,17 @@
+get(\AIO\Controller\DockerController::class);
+
+// Start apache
+$dockerController->startTopContainer(true);
diff --git a/php/src/Cron/StartContainers.php b/php/src/Cron/StartContainers.php
new file mode 100644
index 00000000..98f9ae8f
--- /dev/null
+++ b/php/src/Cron/StartContainers.php
@@ -0,0 +1,17 @@
+get(\AIO\Controller\DockerController::class);
+
+// Start apache
+$dockerController->startTopContainer(false);
diff --git a/php/src/Cron/StopContainers.php b/php/src/Cron/StopContainers.php
new file mode 100644
index 00000000..89cf9798
--- /dev/null
+++ b/php/src/Cron/StopContainers.php
@@ -0,0 +1,17 @@
+get(\AIO\Controller\DockerController::class);
+
+// Start apache
+$dockerController->stopTopContainer();
diff --git a/php/src/Data/ConfigurationManager.php b/php/src/Data/ConfigurationManager.php
index d740a6c8..17f0b9cf 100644
--- a/php/src/Data/ConfigurationManager.php
+++ b/php/src/Data/ConfigurationManager.php
@@ -497,7 +497,7 @@ class ConfigurationManager
/**
* @throws InvalidSettingConfigurationException
*/
- public function SetDailyBackupTime(string $time) : void {
+ public function SetDailyBackupTime(string $time, bool $enableAutomaticUpdates) : void {
if ($time === "") {
throw new InvalidSettingConfigurationException("The daily backup time must not be empty!");
}
@@ -506,6 +506,9 @@ class ConfigurationManager
throw new InvalidSettingConfigurationException("You did not enter a correct time! One correct example is '04:00'!");
}
+ if ($enableAutomaticUpdates === false) {
+ $time .= '\nautomaticUpdatesAreNotEnabled';
+ }
file_put_contents(DataConst::GetDailyBackupTimeFile(), $time);
}
@@ -513,7 +516,22 @@ class ConfigurationManager
if (!file_exists(DataConst::GetDailyBackupTimeFile())) {
return '';
}
- return file_get_contents(DataConst::GetDailyBackupTimeFile());
+ $dailyBackupFile = file_get_contents(DataConst::GetDailyBackupTimeFile());
+ $dailyBackupFileArray = explode("\n", $dailyBackupFile);
+ return $dailyBackupFileArray[0];
+ }
+
+ public function areAutomaticUpdatesEnabled() : bool {
+ if (!file_exists(DataConst::GetDailyBackupTimeFile())) {
+ return false;
+ }
+ $dailyBackupFile = file_get_contents(DataConst::GetDailyBackupTimeFile());
+ $dailyBackupFileArray = explode("\n", $dailyBackupFile);
+ if (isset($dailyBackupFileArray[1]) && $dailyBackupFileArray[1] === 'automaticUpdatesAreNotEnabled') {
+ return false;
+ } else {
+ return true;
+ }
}
public function DeleteDailyBackupTime() : void {
diff --git a/php/src/Docker/DockerActionManager.php b/php/src/Docker/DockerActionManager.php
index ffd74ef7..8fb85fe3 100644
--- a/php/src/Docker/DockerActionManager.php
+++ b/php/src/Docker/DockerActionManager.php
@@ -280,8 +280,8 @@ class DockerActionManager
} else {
$replacements[1] = '';
}
- } elseif ($out[1] === 'DAILY_BACKUP_RUNNING') {
- if ($this->configurationManager->isDailyBackupRunning()) {
+ } elseif ($out[1] === 'UPDATE_NEXTCLOUD_APPS') {
+ if ($this->configurationManager->isDailyBackupRunning() && $this->configurationManager->areAutomaticUpdatesEnabled()) {
$replacements[1] = 'yes';
} else {
$replacements[1] = '';
diff --git a/php/templates/containers.twig b/php/templates/containers.twig
index a11a6cd7..d5bc0cef 100644
--- a/php/templates/containers.twig
+++ b/php/templates/containers.twig
@@ -51,13 +51,15 @@
{% if is_daily_backup_running == true %}
Daily backup currently running. (Logs)
- It will update your containers, the mastercontainer and on saturdays your Nextcloud apps if the backup is successful.
- {% if is_mastercontainer_update_available == true %}
- Since the mastercontainer gets updated, it will restart the container which will make it unavailable for a moment. (Logs)
+ {% if automatic_updates == true %}
+ It will update your containers, the mastercontainer and on saturdays your Nextcloud apps if the backup is successful.
+ {% if is_mastercontainer_update_available == true %}
+ Since the mastercontainer gets updated, it will restart the container which will make it unavailable for a moment. (Logs)
+ {% endif %}
{% endif %}
{% if has_update_available == false %}
The whole process should not take more than a few minutes.
- {% else %}
+ {% elseif automatic_updates == true %}
The whole process can take a while because your containers get updated.
{% endif %}
Reload ↻
@@ -380,11 +382,15 @@
-
+
+
- This option will also automatically update your containers, the mastercontainer and on saturdays your Nextcloud apps and will send a notification about the result of the backup.
{% else %}
- Daily backups will be created at {{ daily_backup_time }} UTC which includes a notification about the result of the backup and automatic updates of your containers, the mastercontainer and on saturdays your Nextcloud apps. You can disable this option again by clicking on the button below.
+ Daily backups will be created at {{ daily_backup_time }} UTC which includes a notification about the result of the backup.
+ {% if automatic_updates == true %}
+ Also your containers, the mastercontainer and on saturdays your Nextcloud apps will be automatically updated.
+ {% endif %}
+ You can disable this option again by clicking on the button below.