mirror of
https://github.com/nextcloud/all-in-one.git
synced 2026-05-21 10:50:10 +00:00
Compare commits
88 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c642f03d43 | ||
|
|
1c172b4dd7 | ||
|
|
3a79002322 | ||
|
|
8aeee368d4 | ||
|
|
541aa9c6c0 | ||
|
|
627e9d325f | ||
|
|
1c85e3e825 | ||
|
|
c4a8fef8e9 | ||
|
|
76cbefafb5 | ||
|
|
68447c9211 | ||
|
|
810d0590eb | ||
|
|
3c81a90920 | ||
|
|
d2cadf6b9f | ||
|
|
18b3c76a67 | ||
|
|
7312dac0f8 | ||
|
|
dfafec2314 | ||
|
|
947be33fcf | ||
|
|
340f7450ca | ||
|
|
09bbe2fd87 | ||
|
|
e8d66a06d1 | ||
|
|
c66b31901a | ||
|
|
94f0a799fc | ||
|
|
c00a1efdac | ||
|
|
73227b4f9d | ||
|
|
1a65c49331 | ||
|
|
9ce1434f34 | ||
|
|
8a62b4a2ea | ||
|
|
9febf2bade | ||
|
|
098e1347a1 | ||
|
|
74579ba7ea | ||
|
|
5dc4fbdb21 | ||
|
|
931b92b8b9 | ||
|
|
888d16d790 | ||
|
|
21086df922 | ||
|
|
5185a9f4ae | ||
|
|
7eba523e86 | ||
|
|
bcf36406a8 | ||
|
|
abf9684d0d | ||
|
|
cbb5e8f359 | ||
|
|
64c3f61b48 | ||
|
|
936b4ebb0f | ||
|
|
7db547732d | ||
|
|
912fa0697d | ||
|
|
68fd14bc86 | ||
|
|
0d4152a7f9 | ||
|
|
78fc3c1343 | ||
|
|
b4e18256a6 | ||
|
|
f9b13a7786 | ||
|
|
37b33c7f4b | ||
|
|
1f819e403b | ||
|
|
e3826f85b9 | ||
|
|
3e5ab69512 | ||
|
|
7d6695de7e | ||
|
|
06dd83f07a | ||
|
|
cd055c0838 | ||
|
|
1e3bb9ccfe | ||
|
|
7144eb84ff | ||
|
|
def87f38e8 | ||
|
|
0a63b49504 | ||
|
|
e672a5029b | ||
|
|
e22c6d6cef | ||
|
|
2290c0aede | ||
|
|
e448bc1f64 | ||
|
|
fb898b0ab3 | ||
|
|
9cb2801e0f | ||
|
|
d7a528075a | ||
|
|
9c80cc1bb3 | ||
|
|
8d93da24d6 | ||
|
|
faaa59e29a | ||
|
|
3b1014d34d | ||
|
|
3e9b191f94 | ||
|
|
b95bb65af8 | ||
|
|
b72a1c0e59 | ||
|
|
8c7e0bc63a | ||
|
|
f5e8e5630d | ||
|
|
89ff6ea408 | ||
|
|
814f4942f5 | ||
|
|
0941b6dee0 | ||
|
|
ae36403762 | ||
|
|
30eaaaa5f9 | ||
|
|
92a96ca245 | ||
|
|
59a49c62b4 | ||
|
|
0b9108f566 | ||
|
|
7c04f844a1 | ||
|
|
c2056ec215 | ||
|
|
8032f5b966 | ||
|
|
c79d46b868 | ||
|
|
1e7161d524 |
2
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@@ -27,6 +27,6 @@ labels: bug, 0. Needs triage
|
||||
|
||||
#### Nextcloud AIO version <!--- (see Nextcloud AIO interface) -->
|
||||
|
||||
#### Current channel <!--- (see the channel name in the Mastercontainer section) -->
|
||||
#### Current channel <!--- (see the channel name in the AIO interface) -->
|
||||
|
||||
#### Other valuable info <!--- (like logs, screenshots & Co.) -->
|
||||
|
||||
7
.github/ISSUE_TEMPLATE/config.yml
vendored
7
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,9 +1,12 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 💡 Suggest a new feature or discuss one
|
||||
url: https://github.com/nextcloud/all-in-one/discussions
|
||||
url: https://github.com/nextcloud/all-in-one/discussions/categories/ideas
|
||||
about: For new feature requests and discussion of existing ones
|
||||
- name: ❓ Community Support and Help
|
||||
- name: ❓ Questions on AIO
|
||||
url: https://github.com/nextcloud/all-in-one/discussions/categories/questions
|
||||
about: For questions regarding AIO
|
||||
- name: ⛑️ Community Support and Help
|
||||
url: https://help.nextcloud.com/tag/aio
|
||||
about: For other types of questions
|
||||
- name: 💼 Nextcloud Enterprise
|
||||
|
||||
7
.github/dependabot.yml
vendored
7
.github/dependabot.yml
vendored
@@ -1,9 +1,14 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
open-pull-requests-limit: 10
|
||||
- package-ecosystem: composer
|
||||
directory: "/php/"
|
||||
schedule:
|
||||
interval: daily
|
||||
interval: "daily"
|
||||
time: "12:00"
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
|
||||
4
.github/workflows/dependency-updates.yml
vendored
4
.github/workflows/dependency-updates.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
name: Run dependency update script
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: nanasess/setup-php@master
|
||||
with:
|
||||
php-version: '8.0'
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
)"
|
||||
sed -i "s|pecl install APCu.*\;|pecl install APCu-$apcu_version\;|" ./Containers/mastercontainer/Dockerfile
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
commit-message: dependency updates
|
||||
signoff: true
|
||||
|
||||
4
.github/workflows/nextcloud-update.yml
vendored
4
.github/workflows/nextcloud-update.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
name: Run nextcloud-update script
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Run nextcloud-update script
|
||||
run: |
|
||||
# Inspired by https://github.com/nextcloud/docker/blob/master/update.sh
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
sed -i "s|^ENV NEXTCLOUD_VERSION.*|ENV NEXTCLOUD_VERSION $NCVERSION|" ./Containers/nextcloud/Dockerfile
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
commit-message: nextcloud-update automated change
|
||||
signoff: true
|
||||
|
||||
2
.github/workflows/psalm-analysis.yml
vendored
2
.github/workflows/psalm-analysis.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Psalm
|
||||
uses: docker://ghcr.io/nextcloud/all-in-one-psalm
|
||||
with:
|
||||
|
||||
2
.github/workflows/psalm-security.yml
vendored
2
.github/workflows/psalm-security.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Psalm
|
||||
uses: docker://ghcr.io/nextcloud/all-in-one-psalm
|
||||
with:
|
||||
|
||||
4
.github/workflows/psalm-update-baseline.yml
vendored
4
.github/workflows/psalm-update-baseline.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up php8.0
|
||||
uses: shivammathur/setup-php@v2
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
commit-message: Update psalm baseline
|
||||
|
||||
2
.github/workflows/shellcheck.yml
vendored
2
.github/workflows/shellcheck.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
name: Github Actions
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Run Shellcheck
|
||||
uses: ludeeus/action-shellcheck@master
|
||||
with:
|
||||
|
||||
4
.github/workflows/spellcheck.yml
vendored
4
.github/workflows/spellcheck.yml
vendored
@@ -10,7 +10,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: spelling or typos
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: fix permission for reviewdog
|
||||
run: sudo chown -R root:root $GITHUB_WORKSPACE
|
||||
- name: misspell
|
||||
uses: reviewdog/action-misspell@v1
|
||||
with:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Caddy is a requirement
|
||||
FROM caddy:2.4.6-alpine as caddy
|
||||
|
||||
FROM debian:bullseye-20220316-slim
|
||||
FROM debian:bullseye-20220328-slim
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM debian:bullseye-20220316-slim
|
||||
FROM debian:bullseye-20220328-slim
|
||||
|
||||
RUN set -ex; \
|
||||
\
|
||||
@@ -8,6 +8,7 @@ RUN set -ex; \
|
||||
rsync \
|
||||
fuse \
|
||||
python3-llfuse \
|
||||
jq \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
@@ -174,24 +174,56 @@ if [ "$BORG_MODE" = restore ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Save current aio password
|
||||
AIO_PASSWORD="$(grep -oP '"password":"[a-zA-Z0-9 ]+"' /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json)"
|
||||
AIO_PASSWORD="${AIO_PASSWORD##\"password\":\"}"
|
||||
AIO_PASSWORD="${AIO_PASSWORD%\"}"
|
||||
|
||||
# Save current path
|
||||
BORG_LOCATION="$(grep -oP '"borg_backup_host_location":"[\\/a-zA-Z0-9 ]+"' /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json)"
|
||||
BORG_LOCATION="${BORG_LOCATION##\"borg_backup_host_location\":\"}"
|
||||
BORG_LOCATION="${BORG_LOCATION%\"}"
|
||||
|
||||
# Restore everything except the configuration file
|
||||
if ! rsync --stats --archive --human-readable -vv --delete \
|
||||
--exclude "nextcloud_aio_mastercontainer/session/"** \
|
||||
--exclude "nextcloud_aio_mastercontainer/certs/"** \
|
||||
--exclude "nextcloud_aio_mastercontainer/data/daily_backup_running" \
|
||||
--exclude "nextcloud_aio_mastercontainer/data/configuration.json" \
|
||||
/tmp/borg/nextcloud_aio_volumes/ /nextcloud_aio_volumes; then
|
||||
echo "Something failed while restoring the boot partition."
|
||||
echo "Something failed while restoring from backup."
|
||||
umount /tmp/borg
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Save current aio password
|
||||
AIO_PASSWORD="$(jq '.password' /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json)"
|
||||
|
||||
# Save current path
|
||||
BORG_LOCATION="$(jq '.borg_backup_host_location' /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json)"
|
||||
|
||||
# Save current nextcloud datadir
|
||||
if grep -q '"nextcloud_datadir":' /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json; then
|
||||
NEXTCLOUD_DATADIR="$(jq '.nextcloud_datadir' /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json)"
|
||||
else
|
||||
NEXTCLOUD_DATADIR='""'
|
||||
fi
|
||||
|
||||
# Restore the configuration file
|
||||
if ! rsync --archive --human-readable -vv \
|
||||
/tmp/borg/nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json \
|
||||
/nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json; then
|
||||
echo "Something failed while restoring the configuration.json."
|
||||
umount /tmp/borg
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set backup-mode to restore since it was a restore
|
||||
CONTENTS="$(jq '."backup-mode" = "restore"' /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json)"
|
||||
echo -E "${CONTENTS}" > /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json
|
||||
|
||||
# Reset the backup path to the currently used one
|
||||
CONTENTS="$(jq ".borg_backup_host_location = $BORG_LOCATION" /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json)"
|
||||
echo -E "${CONTENTS}" > /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json
|
||||
|
||||
# Reset the AIO password to the currently used one
|
||||
CONTENTS="$(jq ".password = $AIO_PASSWORD" /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json)"
|
||||
echo -E "${CONTENTS}" > /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json
|
||||
|
||||
# Reset the datadir to the one that was used for the restore
|
||||
CONTENTS="$(jq ".nextcloud_datadir = $NEXTCLOUD_DATADIR" /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json)"
|
||||
echo -E "${CONTENTS}" > /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json
|
||||
|
||||
umount /tmp/borg
|
||||
|
||||
# Inform user
|
||||
@@ -201,27 +233,6 @@ if [ "$BORG_MODE" = restore ]; then
|
||||
# Add file to Nextcloud container so that it skips any update the next time
|
||||
touch "/nextcloud_aio_volumes/nextcloud_aio_nextcloud_data/skip.update"
|
||||
chmod 777 "/nextcloud_aio_volumes/nextcloud_aio_nextcloud_data/skip.update"
|
||||
|
||||
# Set backup-mode to restore since it was a restore
|
||||
sed -i 's/"backup-mode":"[a-z]\+"/"backup-mode":"restore"/g' /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json
|
||||
|
||||
# Reset the AIO password to the currently used one
|
||||
sed -i "s/\"password\":\"[a-zA-Z0-9 ]\+\"/\"password\":\"$AIO_PASSWORD\"/g" /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json
|
||||
|
||||
# Reset the backup path to the currently used one
|
||||
if [ -n "$BORG_LOCATION" ]; then
|
||||
# shellcheck disable=SC2143
|
||||
if [ -n "$(grep -oP '"borg_backup_host_location":"[\\/a-zA-Z0-9 ]+"' /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json)" ]; then
|
||||
sed -i "s/\"borg_backup_host_location\":\"[\\/a-zA-Z0-9 ]\+\"/\"borg_backup_host_location\":\"$BORG_LOCATION\"/g" /nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/configuration.json
|
||||
else
|
||||
echo "Could not set the borg_backup_host_location as it was empty."
|
||||
echo "Probably the regex did not match."
|
||||
fi
|
||||
else
|
||||
echo "Could not get the borg_backup_host_location as it was empty."
|
||||
echo "Probably the regex did not match."
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Do the Backup check
|
||||
|
||||
@@ -35,10 +35,8 @@ fi
|
||||
rm -f "/nextcloud_aio_volumes/nextcloud_aio_database_dump/backup-is-running"
|
||||
|
||||
# Get a list of all available borg archives
|
||||
set -x
|
||||
borg list "$BORG_BACKUP_DIRECTORY" | grep "nextcloud-aio" | awk -F " " '{print $1","$3,$4}' > "/nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/backup_archives.list"
|
||||
chmod +r "/nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/backup_archives.list"
|
||||
set +x
|
||||
|
||||
if [ -n "$FAILED" ]; then
|
||||
if [ "$BORG_MODE" = backup ]; then
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Probably from this file: https://github.com/Cisco-Talos/clamav/blob/main/Dockerfile
|
||||
FROM clamav/clamav:0.104.2-2
|
||||
FROM clamav/clamav:0.104.2-3
|
||||
|
||||
COPY clamav.conf /tmp/
|
||||
RUN cat /tmp/clamav.conf >> /etc/clamav/clamd.conf
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
# From a file located probably somewhere here: https://github.com/CollaboraOnline/online/tree/master/docker
|
||||
FROM collabora/code:21.11.2.4.1
|
||||
FROM collabora/code:21.11.3.6.1
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM alpine:3.15.1
|
||||
FROM alpine:3.15.4
|
||||
RUN apk add --update --no-cache lighttpd bash
|
||||
|
||||
RUN adduser -S www-data -G www-data
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Docker CLI is a requirement
|
||||
FROM docker:20.10.13-dind-alpine3.15 as dind
|
||||
FROM docker:20.10.14-dind-alpine3.15 as dind
|
||||
|
||||
# Caddy is a requirement
|
||||
FROM caddy:2.4.6-alpine as caddy
|
||||
@@ -26,6 +26,7 @@ RUN apt-get update; \
|
||||
openssl \
|
||||
sudo \
|
||||
dpkg-dev \
|
||||
netcat \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
@@ -84,10 +85,14 @@ RUN mkdir /var/log/supervisord; \
|
||||
|
||||
COPY Caddyfile /
|
||||
COPY start.sh /usr/bin/
|
||||
COPY backup-time-file-watcher.sh /
|
||||
COPY session-deduplicator.sh /
|
||||
COPY cron.sh /
|
||||
COPY supervisord.conf /
|
||||
RUN chmod +x /usr/bin/start.sh; \
|
||||
chmod +x /cron.sh
|
||||
chmod +x /cron.sh; \
|
||||
chmod +x /session-deduplicator.sh; \
|
||||
chmod +x /backup-time-file-watcher.sh
|
||||
|
||||
USER root
|
||||
|
||||
|
||||
30
Containers/mastercontainer/backup-time-file-watcher.sh
Normal file
30
Containers/mastercontainer/backup-time-file-watcher.sh
Normal file
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
restart_process() {
|
||||
echo "Restarting cron.sh because daily backup time was set, changed or unset."
|
||||
pkill cron.sh
|
||||
}
|
||||
|
||||
file_present() {
|
||||
if [ -f "/mnt/docker-aio-config/data/daily_backup_time" ]; then
|
||||
if [ "$FILE_PRESENT" = 0 ]; then
|
||||
restart_process
|
||||
else
|
||||
if [ -n "$BACKUP_TIME" ] && [ "$(cat "/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")"
|
||||
else
|
||||
if [ "$FILE_PRESENT" = 1 ]; then
|
||||
restart_process
|
||||
fi
|
||||
FILE_PRESENT=0
|
||||
fi
|
||||
}
|
||||
|
||||
while true; do
|
||||
file_present
|
||||
sleep 2
|
||||
done
|
||||
@@ -1,12 +1,96 @@
|
||||
#!/bin/sh
|
||||
set -eux
|
||||
#!/bin/bash
|
||||
|
||||
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
|
||||
set +x
|
||||
else
|
||||
BACKUP_TIME="04:00"
|
||||
DAILY_BACKUP=0
|
||||
fi
|
||||
|
||||
if [ -f "/mnt/docker-aio-config/data/daily_backup_running" ]; then
|
||||
LOCK_FILE_PRESENT=1
|
||||
else
|
||||
LOCK_FILE_PRESENT=0
|
||||
fi
|
||||
|
||||
# Allow to continue directly if e.g. the mastercontainer was updated. Otherwise wait for the next execution
|
||||
if [ "$LOCK_FILE_PRESENT" = 0 ]; then
|
||||
while [ "$(date +%H:%M)" != "$BACKUP_TIME" ]; do
|
||||
sleep 1
|
||||
done
|
||||
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"
|
||||
fi
|
||||
|
||||
# Make sure to delete the lock file always
|
||||
rm -f "/mnt/docker-aio-config/data/daily_backup_running"
|
||||
|
||||
# Check for updates and send notification if yes
|
||||
sudo -u www-data php /var/www/docker-aio/php/src/Cron/cron.php
|
||||
# Remove dangling images
|
||||
sudo -u www-data docker image prune -f
|
||||
sudo -u www-data php /var/www/docker-aio/php/src/Cron/UpdateNotification.php
|
||||
|
||||
# Remove sessions older than 24h
|
||||
find "/mnt/docker-aio-config/session/" -mindepth 1 -mmin +1440 -delete
|
||||
sleep 1d
|
||||
|
||||
# Remove dangling images
|
||||
sudo -u www-data docker image prune -f
|
||||
done
|
||||
|
||||
23
Containers/mastercontainer/session-deduplicator.sh
Normal file
23
Containers/mastercontainer/session-deduplicator.sh
Normal file
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
while true; do
|
||||
while [ "$(find "/mnt/docker-aio-config/session/" -mindepth 1 -exec grep "aio_authenticated|[a-z]:1" {} \; | wc -l)" -gt 1 ]; do
|
||||
unset SESSION_FILES
|
||||
SESSION_FILES="$(find "/mnt/docker-aio-config/session/" -mindepth 1)"
|
||||
unset SESSION_FILES_ARRAY
|
||||
mapfile -t SESSION_FILES_ARRAY <<< "$SESSION_FILES"
|
||||
for SESSION_FILE in "${SESSION_FILES_ARRAY[@]}"; do
|
||||
if ! grep -q "aio_authenticated|[a-z]:1" "$SESSION_FILE"; then
|
||||
rm "$SESSION_FILE"
|
||||
fi
|
||||
done
|
||||
echo "Deleting duplicate sessions"
|
||||
unset OLDEST_FILE
|
||||
set -x
|
||||
# shellcheck disable=SC2012
|
||||
OLDEST_FILE="$(ls -t "/mnt/docker-aio-config/session/" | tail -1)"
|
||||
rm "/mnt/docker-aio-config/session/$OLDEST_FILE"
|
||||
set +x
|
||||
done
|
||||
sleep 5
|
||||
done
|
||||
@@ -28,3 +28,17 @@ stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
command=/cron.sh
|
||||
|
||||
[program:backup-time-file-watcher]
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
command=/backup-time-file-watcher.sh
|
||||
|
||||
[program:session-deduplicator]
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
command=/session-deduplicator.sh
|
||||
|
||||
@@ -233,7 +233,8 @@ RUN set -ex; \
|
||||
chmod +x /entrypoint.sh && \
|
||||
chmod +r /upgrade.exclude && \
|
||||
chmod +x /cron.sh && \
|
||||
chmod +x /notify.sh
|
||||
chmod +x /notify.sh && \
|
||||
chmod +x /activate-collabora.sh
|
||||
|
||||
RUN set -ex; \
|
||||
mkdir /mnt/ncdata; \
|
||||
|
||||
20
Containers/nextcloud/activate-collabora.sh
Normal file
20
Containers/nextcloud/activate-collabora.sh
Normal file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
COLLABORA_ACTIVATED=0
|
||||
|
||||
while true; do
|
||||
if [ "$COLLABORA_ENABLED" != yes ]; then
|
||||
# Basically sleep for forever if collabora is not enabled
|
||||
sleep 365d
|
||||
fi
|
||||
if [ "$COLLABORA_ACTIVATED" != 0 ]; then
|
||||
# Basically sleep for forever if collabora was activated
|
||||
sleep 365d
|
||||
fi
|
||||
while ! nc -z "$NC_DOMAIN" 443; do
|
||||
sleep 5
|
||||
done
|
||||
echo "Activating collabora config"
|
||||
php /var/www/html/occ richdocuments:activate-config
|
||||
COLLABORA_ACTIVATED=1
|
||||
done
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
set -eu
|
||||
|
||||
while true; do
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
# version_greater A B returns whether A > B
|
||||
version_greater() {
|
||||
@@ -230,6 +230,11 @@ if ! [ -f "/mnt/ncdata/skip.update" ]; then
|
||||
php /var/www/html/occ maintenance:mimetype:update-db
|
||||
fi
|
||||
fi
|
||||
|
||||
# Performing update of all apps if daily backups are enabled, running and successful
|
||||
if [ "$DAILY_BACKUP_RUNNING" = 'yes' ]; then
|
||||
php /var/www/html/occ app:update --all
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if appdata is present
|
||||
@@ -286,11 +291,11 @@ if [ "$COLLABORA_ENABLED" = 'yes' ]; then
|
||||
php /var/www/html/occ app:update richdocuments
|
||||
fi
|
||||
php /var/www/html/occ config:app:set richdocuments wopi_url --value="https://$NC_DOMAIN/"
|
||||
# php /var/www/html/occ richdocuments:activate-config
|
||||
# Fix https://github.com/nextcloud/all-in-one/issues/188:
|
||||
php /var/www/html/occ config:system:set allow_local_remote_servers --type=bool --value=true
|
||||
else
|
||||
if [ -d "/var/www/html/custom_apps/richdocuments" ]; then
|
||||
php /var/www/html/occ config:system:delete allow_local_remote_servers
|
||||
php /var/www/html/occ app:remove richdocuments
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -28,3 +28,10 @@ stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
command=/var/www/html/custom_apps/notify_push/bin/%(ENV_CPU_ARCH)s/notify_push /var/www/html/config/config.php --port 7867 --redis-url redis://:%(ENV_REDIS_HOST_PASSWORD)s@%(ENV_REDIS_HOST)s
|
||||
|
||||
[program:activate-collabora]
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
command=/activate-collabora.sh
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:focal-20220316
|
||||
FROM ubuntu:focal-20220404
|
||||
|
||||
EXPOSE 3478
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# From https://github.com/containrrr/watchtower/blob/main/dockerfiles/Dockerfile.self-contained
|
||||
FROM containrrr/watchtower:1.4.0 as watchtower
|
||||
|
||||
FROM alpine:3.15.1
|
||||
FROM alpine:3.15.4
|
||||
|
||||
RUN apk add --update --no-cache bash
|
||||
COPY --from=watchtower /watchtower /
|
||||
|
||||
@@ -18,7 +18,12 @@ It will now also select the developer channel for all other containers automatic
|
||||
|
||||
Go to https://github.com/nextcloud-releases/all-in-one/actions/workflows/repo-sync.yml and run the workflow that will first sync the repo and then build new container that automatically get published to `develop` and `develop-arm64`.
|
||||
|
||||
## How to promote builds from develop to latest
|
||||
## How to promote builds from develop to beta
|
||||
|
||||
1. Verify that no job is running here: https://github.com/nextcloud-releases/all-in-one/actions/workflows/build_images.yml
|
||||
2. Go to https://github.com/nextcloud-releases/all-in-one/actions/workflows/promote-to-latest.yml, click on `Run workflow` and enter your desired container image name that you want to publish from develop to latest. Available image names are listed here: https://github.com/nextcloud-releases/all-in-one/blob/main/.github/workflows/build_images.yml#L21-L30
|
||||
2. Go to https://github.com/nextcloud-releases/all-in-one/actions/workflows/promote-to-beta.yml, click on `Run workflow`.
|
||||
|
||||
## How to promote builds from beta to latest
|
||||
|
||||
1. Verify that no job is running here: https://github.com/nextcloud-releases/all-in-one/actions/workflows/promote-to-beta.yml
|
||||
2. Go to https://github.com/nextcloud-releases/all-in-one/actions/workflows/promote-to-latest.yml, click on `Run workflow`.
|
||||
|
||||
176
php/composer.lock
generated
176
php/composer.lock
generated
@@ -387,6 +387,65 @@
|
||||
},
|
||||
"time": "2021-07-21T13:50:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/serializable-closure",
|
||||
"version": "v1.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/serializable-closure.git",
|
||||
"reference": "9e4b005daa20b0c161f3845040046dc9ddc1d74e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/9e4b005daa20b0c161f3845040046dc9ddc1d74e",
|
||||
"reference": "9e4b005daa20b0c161f3845040046dc9ddc1d74e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"pestphp/pest": "^1.18",
|
||||
"phpstan/phpstan": "^0.12.98",
|
||||
"symfony/var-dumper": "^5.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Laravel\\SerializableClosure\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
},
|
||||
{
|
||||
"name": "Nuno Maduro",
|
||||
"email": "nuno@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.",
|
||||
"keywords": [
|
||||
"closure",
|
||||
"laravel",
|
||||
"serializable"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/serializable-closure/issues",
|
||||
"source": "https://github.com/laravel/serializable-closure"
|
||||
},
|
||||
"time": "2022-02-11T19:23:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/fast-route",
|
||||
"version": "v1.3.0",
|
||||
@@ -437,71 +496,6 @@
|
||||
},
|
||||
"time": "2018-02-13T20:26:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "opis/closure",
|
||||
"version": "3.6.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/opis/closure.git",
|
||||
"reference": "3d81e4309d2a927abbe66df935f4bb60082805ad"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/opis/closure/zipball/3d81e4309d2a927abbe66df935f4bb60082805ad",
|
||||
"reference": "3d81e4309d2a927abbe66df935f4bb60082805ad",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.4 || ^7.0 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"jeremeamia/superclosure": "^2.0",
|
||||
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.6.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Opis\\Closure\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Marius Sarca",
|
||||
"email": "marius.sarca@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Sorin Sarca",
|
||||
"email": "sarca_sorin@hotmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.",
|
||||
"homepage": "https://opis.io/closure",
|
||||
"keywords": [
|
||||
"anonymous functions",
|
||||
"closure",
|
||||
"function",
|
||||
"serializable",
|
||||
"serialization",
|
||||
"serialize"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/opis/closure/issues",
|
||||
"source": "https://github.com/opis/closure/tree/3.6.3"
|
||||
},
|
||||
"time": "2022-01-27T09:35:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-di/invoker",
|
||||
"version": "2.3.3",
|
||||
@@ -559,21 +553,21 @@
|
||||
},
|
||||
{
|
||||
"name": "php-di/php-di",
|
||||
"version": "6.3.5",
|
||||
"version": "6.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-DI/PHP-DI.git",
|
||||
"reference": "b8126d066ce144765300ee0ab040c1ed6c9ef588"
|
||||
"reference": "ae0f1b3b03d8b29dff81747063cbfd6276246cc4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/b8126d066ce144765300ee0ab040c1ed6c9ef588",
|
||||
"reference": "b8126d066ce144765300ee0ab040c1ed6c9ef588",
|
||||
"url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/ae0f1b3b03d8b29dff81747063cbfd6276246cc4",
|
||||
"reference": "ae0f1b3b03d8b29dff81747063cbfd6276246cc4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"opis/closure": "^3.5.5",
|
||||
"php": ">=7.2.0",
|
||||
"laravel/serializable-closure": "^1.0",
|
||||
"php": ">=7.4.0",
|
||||
"php-di/invoker": "^2.0",
|
||||
"php-di/phpdoc-reader": "^2.0.1",
|
||||
"psr/container": "^1.0"
|
||||
@@ -582,12 +576,12 @@
|
||||
"psr/container-implementation": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/annotations": "~1.2",
|
||||
"doctrine/annotations": "~1.10",
|
||||
"friendsofphp/php-cs-fixer": "^2.4",
|
||||
"mnapoli/phpunit-easymock": "^1.2",
|
||||
"ocramius/proxy-manager": "^2.0.2",
|
||||
"ocramius/proxy-manager": "^2.11.2",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpunit/phpunit": "^8.5|^9.0"
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"suggest": {
|
||||
"doctrine/annotations": "Install it if you want to use annotations (version ~1.2)",
|
||||
@@ -619,7 +613,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-DI/PHP-DI/issues",
|
||||
"source": "https://github.com/PHP-DI/PHP-DI/tree/6.3.5"
|
||||
"source": "https://github.com/PHP-DI/PHP-DI/tree/6.4.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -631,7 +625,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-09-02T09:49:58+00:00"
|
||||
"time": "2022-04-09T16:46:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-di/phpdoc-reader",
|
||||
@@ -1372,25 +1366,25 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
"version": "v2.5.0",
|
||||
"version": "v3.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/deprecation-contracts.git",
|
||||
"reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8"
|
||||
"reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8",
|
||||
"reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c",
|
||||
"reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
"php": ">=8.0.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.5-dev"
|
||||
"dev-main": "3.0-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
@@ -1419,7 +1413,7 @@
|
||||
"description": "A generic function and convention to trigger deprecation notices",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0"
|
||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1435,7 +1429,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-07-12T14:48:14+00:00"
|
||||
"time": "2022-01-02T09:55:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
@@ -1683,16 +1677,16 @@
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v3.3.8",
|
||||
"version": "v3.3.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "972d8604a92b7054828b539f2febb0211dd5945c"
|
||||
"reference": "8442df056c51b706793adf80a9fd363406dd3674"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/972d8604a92b7054828b539f2febb0211dd5945c",
|
||||
"reference": "972d8604a92b7054828b539f2febb0211dd5945c",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/8442df056c51b706793adf80a9fd363406dd3674",
|
||||
"reference": "8442df056c51b706793adf80a9fd363406dd3674",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1743,7 +1737,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/twigphp/Twig/issues",
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.3.8"
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.3.10"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1755,7 +1749,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-02-04T06:59:48+00:00"
|
||||
"time": "2022-04-06T06:47:41+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
@@ -1772,5 +1766,5 @@
|
||||
"ext-apcu": "*"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.2.0"
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
||||
@@ -131,8 +131,10 @@
|
||||
"CLAMAV_HOST=nextcloud-aio-clamav",
|
||||
"ONLYOFFICE_ENABLED=%ONLYOFFICE_ENABLED%",
|
||||
"COLLABORA_ENABLED=%COLLABORA_ENABLED%",
|
||||
"COLLABORA_HOST=nextcloud-aio-collabora",
|
||||
"TALK_ENABLED=%TALK_ENABLED%",
|
||||
"ONLYOFFICE_HOST=nextcloud-aio-onlyoffice"
|
||||
"ONLYOFFICE_HOST=nextcloud-aio-onlyoffice",
|
||||
"DAILY_BACKUP_RUNNING=%DAILY_BACKUP_RUNNING%"
|
||||
],
|
||||
"maxShutdownTime": 10,
|
||||
"restartPolicy": "unless-stopped"
|
||||
@@ -166,7 +168,7 @@
|
||||
"9980"
|
||||
],
|
||||
"environmentVariables": [
|
||||
"domain=%NC_DOMAIN%",
|
||||
"aliasgroup1=https://%NC_DOMAIN%:443",
|
||||
"extra_params=--o:ssl.enable=false --o:ssl.termination=true --o:logging.level=warning"
|
||||
],
|
||||
"volumes": [],
|
||||
|
||||
@@ -10,4 +10,8 @@ if (document.hasFocus()) {
|
||||
setTimeout(function(){
|
||||
window.location.reload(1);
|
||||
}, 5000);
|
||||
} else {
|
||||
window.addEventListener("beforeunload", function() {
|
||||
document.getElementById('overlay').classList.add('loading')
|
||||
});
|
||||
}
|
||||
3
php/public/before-unload.js
Normal file
3
php/public/before-unload.js
Normal file
@@ -0,0 +1,3 @@
|
||||
window.addEventListener("beforeunload", function() {
|
||||
document.getElementById('overlay').classList.add('loading')
|
||||
});
|
||||
@@ -74,13 +74,14 @@ $app->get('/containers', function ($request, $response, $args) use ($container)
|
||||
return $view->render($response, 'containers.twig', [
|
||||
'domain' => $configurationManager->GetDomain(),
|
||||
'borg_backup_host_location' => $configurationManager->GetBorgBackupHostLocation(),
|
||||
'borg_backup_mode' => $configurationManager->GetBorgBackupMode(),
|
||||
'nextcloud_password' => $configurationManager->GetSecret('NEXTCLOUD_PASSWORD'),
|
||||
'containers' => (new \AIO\ContainerDefinitionFetcher($container->get(\AIO\Data\ConfigurationManager::class), $container))->FetchDefinition(),
|
||||
'borgbackup_password' => $configurationManager->GetSecret('BORGBACKUP_PASSWORD'),
|
||||
'is_mastercontainer_update_available' => $dockerActionManger->IsMastercontainerUpdateAvailable(),
|
||||
'has_backup_run_once' => $configurationManager->hasBackupRunOnce(),
|
||||
'is_backup_container_running' => $dockerActionManger->isBackupContainerRunning(),
|
||||
'backup_exit_code' => $dockerActionManger->GetBackupcontainerExitCode(),
|
||||
'borg_backup_mode' => $configurationManager->GetBorgBackupMode(),
|
||||
'was_start_button_clicked' => $configurationManager->wasStartButtonClicked(),
|
||||
'has_update_available' => $dockerActionManger->isAnyUpdateAvailable(),
|
||||
'last_backup_time' => $configurationManager->GetLastBackupTime(),
|
||||
@@ -92,6 +93,8 @@ $app->get('/containers', function ($request, $response, $args) use ($container)
|
||||
'is_collabora_enabled' => $configurationManager->isCollaboraEnabled(),
|
||||
'is_talk_enabled' => $configurationManager->isTalkEnabled(),
|
||||
'borg_restore_password' => $configurationManager->GetBorgRestorePassword(),
|
||||
'daily_backup_time' => $configurationManager->GetDailyBackupTime(),
|
||||
'is_daily_backup_running' => $configurationManager->isDailyBackupRunning(),
|
||||
]);
|
||||
})->setName('profile');
|
||||
$app->get('/login', function ($request, $response, $args) use ($container) {
|
||||
|
||||
@@ -43,6 +43,15 @@ class ConfigurationController
|
||||
$this->configurationManager->SetBorgRestoreHostLocationAndPassword($restoreLocation, $borgPassword);
|
||||
}
|
||||
|
||||
if (isset($request->getParsedBody()['daily_backup_time'])) {
|
||||
$dailyBackupTime = $request->getParsedBody()['daily_backup_time'] ?? '';
|
||||
$this->configurationManager->SetDailyBackupTime($dailyBackupTime);
|
||||
}
|
||||
|
||||
if (isset($request->getParsedBody()['delete_daily_backup_time'])) {
|
||||
$this->configurationManager->DeleteDailyBackupTime();
|
||||
}
|
||||
|
||||
if (isset($request->getParsedBody()['options-form'])) {
|
||||
if (isset($request->getParsedBody()['collabora']) && isset($request->getParsedBody()['onlyoffice'])) {
|
||||
throw new InvalidSettingConfigurationException("Collabora and Onlyoffice are not allowed to be enabled at the same time!");
|
||||
|
||||
@@ -70,6 +70,11 @@ class DockerController
|
||||
}
|
||||
|
||||
public function StartBackupContainerBackup(Request $request, Response $response, $args) : Response {
|
||||
$this->startBackup();
|
||||
return $response->withStatus(201)->withHeader('Location', '/');
|
||||
}
|
||||
|
||||
public function startBackup() : void {
|
||||
$config = $this->configurationManager->GetConfig();
|
||||
$config['backup-mode'] = 'backup';
|
||||
$this->configurationManager->WriteConfig($config);
|
||||
@@ -79,8 +84,6 @@ class DockerController
|
||||
|
||||
$id = 'nextcloud-aio-borgbackup';
|
||||
$this->PerformRecursiveContainerStart($id);
|
||||
|
||||
return $response->withStatus(201)->withHeader('Location', '/');
|
||||
}
|
||||
|
||||
public function StartBackupContainerCheck(Request $request, Response $response, $args) : Response {
|
||||
@@ -134,6 +137,16 @@ class DockerController
|
||||
$config['AIO_URL'] = $host . ':' . $port;
|
||||
// set wasStartButtonClicked
|
||||
$config['wasStartButtonClicked'] = 1;
|
||||
$this->configurationManager->WriteConfig($config);
|
||||
|
||||
// Start container
|
||||
$this->startTopContainer();
|
||||
|
||||
return $response->withStatus(201)->withHeader('Location', '/');
|
||||
}
|
||||
|
||||
public function startTopContainer() : void {
|
||||
$config = $this->configurationManager->GetConfig();
|
||||
// set AIO_TOKEN
|
||||
$config['AIO_TOKEN'] = bin2hex(random_bytes(24));
|
||||
$this->configurationManager->WriteConfig($config);
|
||||
@@ -144,14 +157,17 @@ class DockerController
|
||||
$id = self::TOP_CONTAINER;
|
||||
|
||||
$this->PerformRecursiveContainerStart($id);
|
||||
return $response->withStatus(201)->withHeader('Location', '/');
|
||||
}
|
||||
|
||||
public function StartWatchtowerContainer(Request $request, Response $response, $args) : Response {
|
||||
$this->startWatchtower();
|
||||
return $response->withStatus(201)->withHeader('Location', '/');
|
||||
}
|
||||
|
||||
public function startWatchtower() : void {
|
||||
$id = 'nextcloud-aio-watchtower';
|
||||
|
||||
$this->PerformRecursiveContainerStart($id);
|
||||
return $response->withStatus(201)->withHeader('Location', '/');
|
||||
}
|
||||
|
||||
private function PerformRecursiveContainerStop(string $id) : void
|
||||
|
||||
29
php/src/Cron/BackupNotification.php
Normal file
29
php/src/Cron/BackupNotification.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
// increase memory limit to 2GB
|
||||
ini_set('memory_limit', '2048M');
|
||||
|
||||
use DI\Container;
|
||||
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
$container = \AIO\DependencyInjection::GetContainer();
|
||||
|
||||
/** @var \AIO\Docker\DockerActionManager $dockerActionManger */
|
||||
$dockerActionManger = $container->get(\AIO\Docker\DockerActionManager::class);
|
||||
/** @var \AIO\ContainerDefinitionFetcher $containerDefinitionFetcher */
|
||||
$containerDefinitionFetcher = $container->get(\AIO\ContainerDefinitionFetcher::class);
|
||||
|
||||
$id = 'nextcloud-aio-nextcloud';
|
||||
$nextcloudContainer = $containerDefinitionFetcher->GetContainerById($id);
|
||||
|
||||
$backupExitCode = $dockerActionManger->GetBackupcontainerExitCode();
|
||||
|
||||
if ($backupExitCode === 0) {
|
||||
$dockerActionManger->sendNotification($nextcloudContainer, 'Daily backup successful!', 'You can get further info by looking at the backup logs in the AIO interface.');
|
||||
}
|
||||
|
||||
if ($backupExitCode > 0) {
|
||||
$dockerActionManger->sendNotification($nextcloudContainer, 'Daily backup failed!', 'You can get further info by looking at the backup logs in the AIO interface.');
|
||||
}
|
||||
20
php/src/Cron/DailyBackup.php
Normal file
20
php/src/Cron/DailyBackup.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
// increase memory limit to 2GB
|
||||
ini_set('memory_limit', '2048M');
|
||||
|
||||
use DI\Container;
|
||||
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
$container = \AIO\DependencyInjection::GetContainer();
|
||||
|
||||
/** @var \AIO\Controller\DockerController $dockerController */
|
||||
$dockerController = $container->get(\AIO\Controller\DockerController::class);
|
||||
|
||||
// Stop container and start backup
|
||||
$dockerController->startBackup();
|
||||
|
||||
// Start apache
|
||||
$dockerController->startTopContainer();
|
||||
17
php/src/Cron/UpdateMastercontainer.php
Normal file
17
php/src/Cron/UpdateMastercontainer.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
// increase memory limit to 2GB
|
||||
ini_set('memory_limit', '2048M');
|
||||
|
||||
use DI\Container;
|
||||
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
$container = \AIO\DependencyInjection::GetContainer();
|
||||
|
||||
/** @var \AIO\Controller\DockerController $dockerController */
|
||||
$dockerController = $container->get(\AIO\Controller\DockerController::class);
|
||||
|
||||
# Update the mastercontainer
|
||||
$dockerController->startWatchtower();
|
||||
@@ -444,4 +444,39 @@ class ConfigurationManager
|
||||
$defaultValue = 'nextcloud_aio_nextcloud_data';
|
||||
return $this->GetEnvironmentalVariableOrConfig($envVariableName, $configName, $defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidSettingConfigurationException
|
||||
*/
|
||||
public function SetDailyBackupTime(string $time) : void {
|
||||
if ($time === "") {
|
||||
throw new InvalidSettingConfigurationException("The daily backup time must not be empty!");
|
||||
}
|
||||
|
||||
if (!preg_match("#^[0-1][0-9]:[0-5][0-9]$#", $time) && !preg_match("#^2[0-3]:[0-5][0-9]$#", $time)) {
|
||||
throw new InvalidSettingConfigurationException("You did not enter a correct time! One correct example is '04:00'!");
|
||||
}
|
||||
|
||||
file_put_contents(DataConst::GetDailyBackupTimeFile(), $time);
|
||||
}
|
||||
|
||||
public function GetDailyBackupTime() : string {
|
||||
if (!file_exists(DataConst::GetDailyBackupTimeFile())) {
|
||||
return '';
|
||||
}
|
||||
return file_get_contents(DataConst::GetDailyBackupTimeFile());
|
||||
}
|
||||
|
||||
public function DeleteDailyBackupTime() : void {
|
||||
if (file_exists(DataConst::GetDailyBackupTimeFile())) {
|
||||
unlink(DataConst::GetDailyBackupTimeFile());
|
||||
}
|
||||
}
|
||||
|
||||
public function isDailyBackupRunning() : bool {
|
||||
if (file_exists(DataConst::GetDailyBackupBlockFile())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,14 @@ class DataConst {
|
||||
return self::GetDataDirectory() . '/backupsecret';
|
||||
}
|
||||
|
||||
public static function GetDailyBackupTimeFile() : string {
|
||||
return self::GetDataDirectory() . '/daily_backup_time';
|
||||
}
|
||||
|
||||
public static function GetDailyBackupBlockFile() : string {
|
||||
return self::GetDataDirectory() . '/daily_backup_running';
|
||||
}
|
||||
|
||||
public static function GetBackupKeyFile() : string {
|
||||
return self::GetDataDirectory() . '/borg.config';
|
||||
}
|
||||
|
||||
@@ -267,6 +267,12 @@ class DockerActionManager
|
||||
} else {
|
||||
$replacements[1] = '';
|
||||
}
|
||||
} elseif ($out[1] === 'DAILY_BACKUP_RUNNING') {
|
||||
if ($this->configurationManager->isDailyBackupRunning()) {
|
||||
$replacements[1] = 'yes';
|
||||
} else {
|
||||
$replacements[1] = '';
|
||||
}
|
||||
} else {
|
||||
$replacements[1] = $this->configurationManager->GetSecret($out[1]);
|
||||
}
|
||||
@@ -369,7 +375,6 @@ class DockerActionManager
|
||||
|
||||
return null;
|
||||
} catch (\Exception $e) {
|
||||
error_log('Could not get digest of container ' . $this->BuildApiUrl($containerName) . ' ' . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -407,7 +412,7 @@ class DockerActionManager
|
||||
$runningDigest = $this->GetRepoDigestOfContainer($containerName);
|
||||
$remoteDigest = $this->dockerHubManager->GetLatestDigestOfTag($imageName, $tag);
|
||||
|
||||
if ($remoteDigest === $runningDigest || $remoteDigest === null || $runningDigest === null) {
|
||||
if ($remoteDigest === $runningDigest || $remoteDigest === null) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
@@ -600,4 +605,13 @@ class DockerActionManager
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isBackupContainerRunning() : bool {
|
||||
$id = 'nextcloud-aio-borgbackup';
|
||||
$backupContainer = $this->containerDefinitionFetcher->GetContainerById($id);
|
||||
if ($this->GetContainerRunningState($backupContainer) instanceof RunningState) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,8 +52,10 @@ class DockerHubManager
|
||||
}
|
||||
}
|
||||
|
||||
error_log('Could not get digest of container ' . $name . ':' . $tag);
|
||||
return null;
|
||||
} catch (\Exception $e) {
|
||||
error_log('Could not get digest of container ' . $name . ':' . $tag . ' ' . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,17 +16,24 @@
|
||||
</header>
|
||||
|
||||
<div class="content">
|
||||
<h1>Nextcloud AIO Beta v0.9.0</h1>
|
||||
This is beta software and not production ready.<br><br>
|
||||
<h1>Nextcloud AIO v1.0.0</h1>
|
||||
|
||||
{% set isAnyRunning = false %}
|
||||
{% set isAnyRestarting = false %}
|
||||
{% set isWatchtowerRunning = false %}
|
||||
{% set isBackupContainerRunning = false %}
|
||||
{% set isRestoreRunning = false %}
|
||||
{% set isBackupOrRestoreRunning = false %}
|
||||
{% set isApacheStarting = false %}
|
||||
|
||||
{% if is_backup_container_running == true %}
|
||||
{% if borg_backup_mode == 'restore' %}
|
||||
{% set isRestoreRunning = true %}
|
||||
{% endif %}
|
||||
{% if borg_backup_mode == 'backup' or borg_backup_mode == 'restore' %}
|
||||
{% set isBackupOrRestoreRunning = true %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% for container in containers %}
|
||||
{% if container.GetIdentifier() not in ['nextcloud-aio-domaincheck', 'nextcloud-aio-borgbackup', 'nextcloud-aio-watchtower'] and class(container.GetRunningState()) == 'AIO\\Container\\State\\RunningState' %}
|
||||
{% set isAnyRunning = true %}
|
||||
@@ -40,23 +47,25 @@
|
||||
{% if container.GetIdentifier() == 'nextcloud-aio-apache' and class(container.GetStartingState()) == 'AIO\\Container\\State\\StartingState' %}
|
||||
{% set isApacheStarting = true %}
|
||||
{% endif %}
|
||||
{% if container.GetIdentifier() == 'nextcloud-aio-borgbackup' and class(container.GetRunningState()) == 'AIO\\Container\\State\\RunningState' %}
|
||||
{% set isBackupContainerRunning = true %}
|
||||
{% if borg_backup_mode == 'restore' %}
|
||||
{% set isRestoreRunning = true %}
|
||||
{% endif %}
|
||||
{% if borg_backup_mode == 'backup' or borg_backup_mode == 'restore' %}
|
||||
{% set isBackupOrRestoreRunning = true %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if isWatchtowerRunning == true %}
|
||||
Mastercontainer update currently running. It will restart the mastercontainer soon which will make it unavailable for a moment. Please wait until that's done.<br /><br />
|
||||
{% if is_daily_backup_running == true %}
|
||||
<span class="status running"></span> Daily backup currently running. (<a href="/api/docker/logs?id=nextcloud-aio-mastercontainer">Logs</a>)<br /><br />
|
||||
It will update all containers and all apps if the backup is successful.<br /><br />
|
||||
{% if is_mastercontainer_update_available == true %}
|
||||
Since the mastercontainer gets updated, it will restart the container which will make it unavailable for a moment. (<a href="/api/docker/logs?id=nextcloud-aio-watchtower">Logs</a>)<br /><br />
|
||||
{% endif %}
|
||||
{% if has_update_available == false %}
|
||||
The whole process should not take more than a few minutes.<br /><br />
|
||||
{% else %}
|
||||
The whole process can take a while because your containers get updated.<br /><br />
|
||||
{% endif %}
|
||||
<a href="" class="button reload">Reload ↻</a><br/>
|
||||
{% elseif isWatchtowerRunning == true %}
|
||||
<span class="status running"></span> Mastercontainer update currently running. It will restart the mastercontainer soon which will make it unavailable for a moment. Please wait until that's done. (<a href="/api/docker/logs?id=nextcloud-aio-watchtower">Logs</a>)<br /><br />
|
||||
<a href="" class="button reload">Reload ↻</a><br/>
|
||||
{% else %}
|
||||
You are currently running the {{ current_channel }} channel. (<a href="/api/docker/logs?id=nextcloud-aio-mastercontainer">Logs</a>)<br><br>
|
||||
{% if isBackupContainerRunning == false and domain == "" %}
|
||||
{% if is_backup_container_running == false and domain == "" %}
|
||||
{% if is_mastercontainer_update_available == true %}
|
||||
<h2>Mastercontainer update</h2>
|
||||
⚠ A mastercontainer update is available. Please click on the button below to update it. Afterwards, you will be able to proceed with the setup.<br><br>
|
||||
@@ -66,8 +75,8 @@
|
||||
<input class="button" type="submit" value="Update mastercontainer" />
|
||||
</form>
|
||||
{% else %}
|
||||
Nextcloud AIO stands for Nextcloud All In One and provides easy deployment and maintenance with most features included in this one Nextcloud instance.<br><br>
|
||||
{% if borg_backup_host_location == '' and borg_restore_password == '' %}
|
||||
Nextcloud AIO stands for Nextcloud All In One and provides easy deployment and maintenance with most features included in this one Nextcloud instance.<br><br>
|
||||
<h2>New AIO instance</h2>
|
||||
Please type in the domain that will be used for Nextcloud if you want to create a new instance:<br><br />
|
||||
<form method="POST" action="/api/configuration" class="xhr">
|
||||
@@ -78,17 +87,17 @@
|
||||
</form>
|
||||
Make sure that this server is reachable on Port 443 and you've correctly set up the DNS config for the domain that you enter. <br><br>
|
||||
If you have a dynamic IP-address, you can use e.g. <a href="https://ddclient.net/">DDclient</a> with a compatible domain provider for DNS updates. <br /><br/>
|
||||
{% endif %}
|
||||
|
||||
<h2>Restore AIO instance from backup</h2>
|
||||
You can alternatively restore an AIO instance from backup.<br><br>
|
||||
<h2>Restore AIO instance from backup</h2>
|
||||
You can alternatively restore an AIO instance from backup.<br><br>
|
||||
{% endif %}
|
||||
|
||||
{% if borg_backup_host_location != '' and borg_restore_password != '' %}
|
||||
{% if borg_backup_mode in ['test', 'check'] %}
|
||||
{% if backup_exit_code > 0 %}
|
||||
<span class="status error"></span> Last {{ borg_backup_mode }} failed! (<a href="/api/docker/logs?id=nextcloud-aio-borgbackup">Logs</a>)<br /><br />
|
||||
{% if borg_backup_mode == 'test' %}
|
||||
Please adjust the path and/or password in order to make it work! Afterwards click on 'Test path and password' button to verify the settings!<br><br>
|
||||
Please adjust the path and/or password in order to make it work! After changing and submitting the values, click on 'Test path and password' button at the bottom of this page to verify and test the new settings!<br><br>
|
||||
{% elseif borg_backup_mode == 'check' %}
|
||||
The backup archive seems to be corrupt. Please try to use a different intact backup archive or try to fix it by following <a href="https://borgbackup.readthedocs.io/en/stable/faq.html?highlight=repair#:~:text=repairing%20a%20damaged%20repository"><b>this documentation</b></a>
|
||||
{% endif %}
|
||||
@@ -108,7 +117,7 @@
|
||||
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
||||
<select id="selected_restore_time" name="selected_restore_time" form="restore_selection">
|
||||
{% for restore_time in backup_times %}
|
||||
<option value="{{ restore_time }}">{{ restore_time }}</option>
|
||||
<option value="{{ restore_time }}">{{ restore_time }} UTC</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input class="button" type="submit" value="Restore selected backup"/>
|
||||
@@ -146,24 +155,28 @@
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if isBackupContainerRunning == true and domain == "" %}
|
||||
Backup container is currently running.<br /><br />
|
||||
|
||||
{% if domain != "" and was_start_button_clicked == true %}
|
||||
You are running the <a href="https://github.com/nextcloud/all-in-one#how-to-switch-the-channel"><b>{{ current_channel }}</b></a> channel. (<a href="/api/docker/logs?id=nextcloud-aio-mastercontainer">Logs</a>)<br><br>
|
||||
{% endif %}
|
||||
|
||||
{% if is_backup_container_running == true %}
|
||||
<span class="status running"></span> Backup container is currently running. (<a href="/api/docker/logs?id=nextcloud-aio-borgbackup">Logs</a>)<br /><br />
|
||||
<a href="" class="button reload">Reload ↻</a><br/><br>
|
||||
{% endif %}
|
||||
|
||||
{% if domain != "" %}
|
||||
|
||||
{% if isAnyRunning == true %}
|
||||
{% if isApacheStarting != true %}
|
||||
<details>
|
||||
<summary>Click here to reveal the initial Nextcloud credentials</summary><br />
|
||||
Initial Nextcloud username: admin<br />
|
||||
Initial Nextcloud password: {{ nextcloud_password }}
|
||||
Initial Nextcloud username: <b>admin</b><br />
|
||||
Initial Nextcloud password: <b>{{ nextcloud_password }}</b>
|
||||
</details><br /><br />
|
||||
<a href="https://{{ domain }}" class="button" target="_blank" rel="noopener">Open your Nextcloud ↗</a><br/>
|
||||
{% else %}
|
||||
{% if isAnyRestarting == false %}
|
||||
Containers are currently starting.<br /><br />
|
||||
<span class="status running"></span> Containers are currently starting.<br /><br />
|
||||
<a href="" class="button reload">Reload ↻</a><br/><br>
|
||||
{% else %}
|
||||
It seems like at least one container is currently restarting which means it is not able to start correctly.<br><br>
|
||||
@@ -264,7 +277,7 @@
|
||||
|
||||
{% if was_start_button_clicked == true %}
|
||||
|
||||
{% if isBackupContainerRunning == false and borg_backup_host_location == "" and isApacheStarting != true %}
|
||||
{% if is_backup_container_running == false and borg_backup_host_location == "" and isApacheStarting != true %}
|
||||
<h2>Backup and restore</h2>
|
||||
Please type in the directory where backups will get created on the host system:<br><br>
|
||||
<form method="POST" action="/api/configuration" class="xhr">
|
||||
@@ -277,30 +290,30 @@
|
||||
{% endif %}
|
||||
|
||||
{% if borg_backup_host_location != "" %}
|
||||
<h2>Backup and restore</h2>
|
||||
{% if isBackupContainerRunning == false %}
|
||||
{% if is_backup_container_running == false %}
|
||||
<h2>Backup and restore</h2>
|
||||
{% if backup_exit_code > 0 %}
|
||||
<span class="status error"></span> Last {{ borg_backup_mode }} failed! (<a href="/api/docker/logs?id=nextcloud-aio-borgbackup">Logs</a>)<br /><br />
|
||||
{% elseif backup_exit_code == 0 %}
|
||||
{% if borg_backup_mode == "backup" %}
|
||||
<span class="status success"></span> Last {{ borg_backup_mode }} successful on {{ last_backup_time }}! (<a href="/api/docker/logs?id=nextcloud-aio-borgbackup">Logs</a>)<br /><br />
|
||||
<span class="status success"></span> Last {{ borg_backup_mode }} successful on {{ last_backup_time }} UTC! (<a href="/api/docker/logs?id=nextcloud-aio-borgbackup">Logs</a>)<br /><br />
|
||||
{% else %}
|
||||
<span class="status success"></span> Last {{ borg_backup_mode }} successful! (<a href="/api/docker/logs?id=nextcloud-aio-borgbackup">Logs</a>)<br /><br />
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if isBackupContainerRunning == false %}
|
||||
{% if is_backup_container_running == false and isApacheStarting == false %}
|
||||
{% if has_backup_run_once == true %}
|
||||
<details>
|
||||
<summary>Click here to reveal all backup options</summary><br />
|
||||
{% endif %}
|
||||
<h3>Backup information</h3>
|
||||
This is your encryption password for backups: {{ borgbackup_password }} <br /><br/>
|
||||
This is your encryption password for backups: <b>{{ borgbackup_password }}</b><br /><br/>
|
||||
Please save it at a safe place since you won't be able to restore from backup if you loose this password! <br /><br/>
|
||||
Backed up will get all important data of your Nextcloud AIO instance like the database, your files and configuration files of the mastercontainer and else. <br /><br/>
|
||||
The backup itself will use a tool that is called <a href="https://github.com/borgbackup/borg#what-is-borgbackup">BorgBackup<a/> which is a well-known server backup tool that efficiently backs up your files and encrypts them on the fly. <br /><br/>
|
||||
Backups get created in the following directory on the host: {{ borg_backup_host_location }}/borg <br /><br/>
|
||||
The backup itself will use a tool that is called <a href="https://github.com/borgbackup/borg#what-is-borgbackup"><b>BorgBackup</b><a/> which is a well-known server backup tool that efficiently backs up your files and encrypts them on the fly. <br /><br/>
|
||||
Backups get created in the following directory on the host: <b>{{ borg_backup_host_location }}/borg</b> <br /><br/>
|
||||
Be aware that this solution does not back up files and folders that are mounted into Nextcloud using the external storage app.
|
||||
|
||||
{% if isApacheStarting != true %}
|
||||
@@ -328,11 +341,31 @@
|
||||
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
||||
<select id="selected_restore_time" name="selected_restore_time" form="restore_selection">
|
||||
{% for restore_time in backup_times %}
|
||||
<option value="{{ restore_time }}">{{ restore_time }}</option>
|
||||
<option value="{{ restore_time }}">{{ restore_time }} UTC</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input class="button" type="submit" value="Restore selected backup" onclick="return confirm('Restore the selected backup? Are you sure that you want to restore the selected backup? This will stop all running containers and restore the selected backup. It is recommended to create a backup first. You might also want to check the backup integrity.')" />
|
||||
</form>
|
||||
|
||||
<h3>Daily backup creation</h3>
|
||||
{% if daily_backup_time == "" %}
|
||||
By entering a time below, you can enable daily backups. It will create them at the entered time in 24h format. E.g. <b>04:00</b> will create backups at 4 am UTC and <b>16:00</b> at 4 pm UTC.<br><br/>
|
||||
<form method="POST" action="/api/configuration" class="xhr">
|
||||
<input type="text" name="daily_backup_time" value="04:00" placeholder="04:00"/>
|
||||
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
||||
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
||||
<input class="button" type="submit" value="Submit" />
|
||||
</form>
|
||||
This option will also automatically update your containers and apps and will send a notification about the result of the backup.<br><br/>
|
||||
{% else %}
|
||||
Daily backups will be created at <b>{{ daily_backup_time }} UTC</b> which includes a notification about the result of the backup and automatic updates of your containers and apps. You can disable this option again by clicking on the button below.<br><br/>
|
||||
<form method="POST" action="/api/configuration" class="xhr">
|
||||
<input type="hidden" name="delete_daily_backup_time" value="yes"/>
|
||||
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
||||
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
||||
<input class="button" type="submit" value="Disable daily backups" />
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if has_backup_run_once == false %}
|
||||
@@ -340,14 +373,10 @@
|
||||
{% else %}
|
||||
</details><br /><br />
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
<span class="status running"></span> Backup container currently running. (<a href="/api/docker/logs?id=nextcloud-aio-borgbackup">Logs</a>)<br /><br />
|
||||
<a href="" class="button reload">Reload ↻</a><br/>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if isBackupContainerRunning == false %}
|
||||
{% if is_backup_container_running == false %}
|
||||
{% if isApacheStarting == false %}
|
||||
<h2>AIO password change</h2>
|
||||
You can change your AIO password below:<br><br />
|
||||
@@ -362,10 +391,10 @@
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if isBackupContainerRunning == false %}
|
||||
{% if is_backup_container_running == false %}
|
||||
<h2>Optional addons</h2>
|
||||
In this section, you can find optional addons.<br>
|
||||
You can enable or disaable them when your containers are stopped.<br><br>
|
||||
In this section you can find optional addons.<br>
|
||||
You can enable or disable them when your containers are stopped.<br><br>
|
||||
<form id="options-form" method="POST" action="/api/configuration" class="xhr">
|
||||
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
||||
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
||||
@@ -404,8 +433,10 @@
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if isApacheStarting == true or isBackupContainerRunning == true or isWatchtowerRunning == true %}
|
||||
{% if isApacheStarting == true or is_backup_container_running == true or isWatchtowerRunning == true or is_daily_backup_running == true %}
|
||||
<script type="text/javascript" src="automatic_reload.js"></script>
|
||||
{% else %}
|
||||
<script type="text/javascript" src="before-unload.js"></script>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="login-wrapper">
|
||||
<div class="login">
|
||||
<img src="/img/logo-blue.svg" style="margin-left: auto;margin-right: auto;display: block;">
|
||||
<h1>Your password for Nextcloud AIO Beta</h1>
|
||||
<h1>Your password for Nextcloud AIO</h1>
|
||||
<p>Please note down the password to access the AIO interface and don't loose it!</p>
|
||||
<strong>Password</strong><br/> <span class="monospace">{{ password }}</span><br>
|
||||
<a href="/" class="button" target="_blank" rel="noopener">Open Nextcloud AIO login ↗</a>
|
||||
|
||||
44
readme.md
44
readme.md
@@ -1,8 +1,4 @@
|
||||
# Nextcloud All In One Beta
|
||||
This is beta software and not production ready.
|
||||
But feel free to use it at your own risk!
|
||||
We expect there to be rough edges and potentially serious bugs.
|
||||
|
||||
# Nextcloud All In One
|
||||
Nextcloud AIO stands for Nextcloud All In One and provides easy deployment and maintenance with most features included in this one Nextcloud instance.
|
||||
|
||||
Included are:
|
||||
@@ -11,6 +7,8 @@ Included are:
|
||||
- High performance backend for Nextcloud Files
|
||||
- High performance backend for Nextcloud Talk
|
||||
- Backup solution (based on [BorgBackup](https://github.com/borgbackup/borg#what-is-borgbackup))
|
||||
- OnlyOffice
|
||||
- ClamAV
|
||||
|
||||
**Found a bug?** Please file an issue at https://github.com/nextcloud/all-in-one
|
||||
|
||||
@@ -21,7 +19,8 @@ The following instructions are especially meant for Linux. For macOS see [this](
|
||||
curl -fsSL get.docker.com | sudo sh
|
||||
```
|
||||
|
||||
2. Run the following command in order to start the container:
|
||||
2. Run the following command in order to start the container:<br>
|
||||
(For people that cannot use ports 80 and/or 443 on this server, please follow [this documentation](https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md). Otherwise please run the command below!)
|
||||
```
|
||||
# For x64 CPUs:
|
||||
sudo docker run -it \
|
||||
@@ -105,6 +104,9 @@ Simply run the following: `sudo docker exec -it nextcloud-aio-nextcloud php occ
|
||||
### How to resolve `Security & setup warnings displays the "missing default phone region" after initial install`?
|
||||
Simply run the following command: `sudo docker exec -it nextcloud-aio-nextcloud php occ config:system:set default_phone_region --value="yourvalue"`. Of course you need to modify `yourvalue` based on your location. Examples are `DE`, `EN` and `GB`. See this list for more codes: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements
|
||||
|
||||
### How to switch the channel?
|
||||
You can switch to a different channel like e.g. the beta channel or from the beta channel back to the latest channel by stopping the mastercontainer, removing it (no data will be lost) and recreating the container using the same command that you used initially to create the mastercontainer. For the beta channel on x64 you need to change the last line `nextcloud/all-in-one:latest` to `nextcloud/all-in-one:beta` and vice versa. For arm64 it is `nextcloud/all-in-one:latest-arm64` and `nextcloud/all-in-one:beta-arm64`, respectively.
|
||||
|
||||
### How to update the containers?
|
||||
If we push new containers to `latest`, you will see in the AIO interface below the `containers` section that new container updates were found. In this case, just press `Stop containers` and `Start containers` in order to update the containers. The mastercontainer has its own update procedure though. See below. And don't forget to back up the current state of your instance using the built-in backup solution before starting the containers again! Otherwise you won't be able to restore your instance easily if something should break during the update.
|
||||
|
||||
@@ -116,12 +118,25 @@ Additionally, there is a cronjob that runs once a day that checks for container
|
||||
If your Nextcloud is running and you are logged in as admin in your Nextcloud, you can easily log in to the AIO interface by opening `https://yourdomain.tld/settings/admin/overview` which will show a button on top that enables you to log in to the AIO interface by just clicking on this button. **Note:** You can change the domain/ip-address/port of the button by simply stopping the containers, visiting the AIO interface from the correct and desired domain/ip-address/port and clicking once on `Start containers`.
|
||||
|
||||
### Backup solution
|
||||
Nextcloud AIO provides a local backup solution based on BorgBackup. These backups act as a local restore point in case the installation gets corrupted.
|
||||
Nextcloud AIO provides a local backup solution based on [BorgBackup](https://github.com/borgbackup/borg#what-is-borgbackup). These backups act as a local restore point in case the installation gets corrupted.
|
||||
|
||||
It is recommended to create a backup before any container update. By doing this, you will be safe regarding any possible complication during updates because you will be able to restore the whole instance with basically one click.
|
||||
|
||||
If you connect an external drive to your host, and choose the backup directory to be on that drive, you are also kind of save against drive failures of the drive where the docker volumes are stored on.
|
||||
|
||||
<details>
|
||||
<summary>How to do the above step for step</summary>
|
||||
|
||||
<br>
|
||||
|
||||
1. Mount an external/backup HDD to the host OS using the built-in functionality or udev rules or whatever way you prefer. (E.g. follow this video: https://www.youtube.com/watch?v=2lSyX4D3v_s) and mount the drive in best case in `/mnt/backup`.
|
||||
2. If not already done, fire up the docker container and set up Nextcloud as per the guide.
|
||||
3. Now open the AIO interface.
|
||||
4. Under backup section, add your external disk mountpoint as backup directory, e.g. `/mnt/backup`.
|
||||
5. Click on `Create Backup` which should create the first backup on the external disk.
|
||||
|
||||
</details>
|
||||
|
||||
Backups can be created and restored in the AIO interface using the buttons `Create Backup` and `Restore selected backup`. Additionally, a backup check is provided that checks the integrity of your backups but it shouldn't be needed in most situations.
|
||||
|
||||
The backups itself get encrypted with an encryption key that gets shown to you in the AIO interface. Please save that at a safe place as you will not be able to restore from backup without this key.
|
||||
@@ -209,6 +224,11 @@ if ! [ -d "$SOURCE_DIRECTORY" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$(ls -A "$SOURCE_DIRECTORY/")" ]; then
|
||||
echo "The source directory is empty which is not allowed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ -d "$DRIVE_MOUNTPOINT" ]; then
|
||||
echo "The drive mountpoint must be an existing directory"
|
||||
exit 1
|
||||
@@ -244,13 +264,13 @@ if ! rsync --stats --archive --human-readable --delete "$SOURCE_DIRECTORY/" "$TA
|
||||
fi
|
||||
|
||||
umount "$DRIVE_MOUNTPOINT"
|
||||
if mountpoint -q "$DRIVE_MOUNTPOINT"; then
|
||||
echo "Synced the backup repository successfully but failed to unmount the target drive."
|
||||
exit 0
|
||||
|
||||
if docker ps --format "{{.Names}}" | grep "^nextcloud-aio-nextcloud$"; then
|
||||
docker exec -it nextcloud-aio-nextcloud bash /notify.sh "Rsync backup successful!" "Synced the backup repository successfully."
|
||||
else
|
||||
echo "Synced the backup repository successfully."
|
||||
fi
|
||||
|
||||
echo "Synced the backup repository successfully and unmounted the target drive."
|
||||
exit 0
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
## Reverse Proxy Config
|
||||
## Reverse Proxy Documentation
|
||||
|
||||
Basically, you need to specify the port that the apache container shall use and modify the startup command a bit.
|
||||
|
||||
All examples below will use port `11000` as example apache port. Also it is supposed that the reverse proxy runs on the same server like AIO, hence `localhost` is used and not an internal ip-address to point to the AIO instance. Modify both to your needings.
|
||||
|
||||
### Caddy reverse proxy config example
|
||||
### Reverse proxy config examples
|
||||
|
||||
#### Caddy
|
||||
|
||||
<details>
|
||||
|
||||
<summary>click here to expand</summary>
|
||||
<br>
|
||||
Add this to your Caddyfile:
|
||||
|
||||
```
|
||||
@@ -17,8 +23,38 @@ https://<your-nc-domain>:443 {
|
||||
|
||||
Of course you need to modify `<your-nc-domain>` to the domain on which you want to run Nextcloud.
|
||||
|
||||
</details>
|
||||
|
||||
#### Nginx
|
||||
|
||||
<details>
|
||||
|
||||
<summary>click here to expand</summary>
|
||||
<br>
|
||||
Add this to you nginx config:
|
||||
|
||||
```
|
||||
location / {
|
||||
proxy_pass http://localhost:11000;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# Websocket
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
}
|
||||
```
|
||||
|
||||
Of course SSL needs to be set up as well e.g. by using certbot and your domain must be also added inside the nginx config.
|
||||
|
||||
</details>
|
||||
|
||||
### Startup command
|
||||
|
||||
After adjusting your reverse proxy config, use the following command to start AIO:
|
||||
|
||||
```
|
||||
# For x64 CPUs:
|
||||
sudo docker run -it \
|
||||
|
||||
Reference in New Issue
Block a user