Compare commits

...

195 Commits

Author SHA1 Message Date
szaimen
b5e45e270b increase version to v0.8.0
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-16 16:02:01 +01:00
Simon L
1fc8f2dd0f Merge pull request #339 from nextcloud/enh/noid/improve-logging
improve error logging in dockeractionmanager
2022-03-16 15:49:00 +01:00
Julius Härtl
8317b30658 Add error middleware
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2022-03-16 15:43:48 +01:00
szaimen
1a62857df7 improve error logging in dockeractionmanager
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-16 15:43:48 +01:00
szaimen
172ae49cdf improve/fix some things
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-16 14:41:52 +01:00
szaimen
d385d43af0 fix clamav build
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-16 13:38:23 +01:00
Simon L
064ea0f931 Merge pull request #378 from nextcloud/enh/376/add-clamav
add clamav as option
2022-03-16 13:17:33 +01:00
szaimen
7f645b1c1a fix psalm like this as no idea how to fix that
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-16 13:14:05 +01:00
szaimen
38726f039a add clamav as option
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-16 13:14:05 +01:00
Simon L
79fdbee6b4 Merge pull request #347 from nextcloud/enh/noid/move-inline-js-to-file
move inline javascript to its own file
2022-03-16 13:08:51 +01:00
szaimen
4c304d8775 move inline javascript to its own file
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-16 13:07:13 +01:00
Simon L
8a21f2a8f5 Merge pull request #377 from nextcloud/enh/noid/move-mastercontainer
move the mastercontainer section
2022-03-16 13:02:33 +01:00
Simon L
1be6c725c2 Merge pull request #379 from nextcloud/automated/noid/psalm-baseline-update-1647404662
[Automated] Update psalm-baseline.xml
2022-03-16 13:01:19 +01:00
nextcloud-command
c6d40e91e0 Update psalm baseline
Signed-off-by: GitHub <noreply@github.com>
2022-03-16 04:24:21 +00:00
szaimen
4fc4ca1e3e move the mastercontainer section
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-15 19:28:01 +01:00
Simon L
31f86c1570 Merge pull request #375 from nextcloud/enh/374/list-newest-backups-first
list newest backups first
2022-03-15 16:46:42 +01:00
Simon L
a8d380ec7a Merge pull request #370 from nextcloud/enh/noid/allow-upgrades-always
allow to upgrade the mastercontainer even if no update was found
2022-03-15 16:46:34 +01:00
Simon L
6dd88239d1 Merge pull request #372 from nextcloud/enh/noid/restarting-state
allow to check for restarting state
2022-03-15 16:46:02 +01:00
szaimen
ead69baae3 simplify syntax to make it better understandable
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-15 16:30:09 +01:00
szaimen
6be1154914 list newest backups first
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-15 16:02:43 +01:00
Simon L
f9772a856c Merge pull request #373 from nextcloud/aio-dependency-update
Dependency updates
2022-03-15 13:21:54 +01:00
szaimen
83ae27ef76 allow to check for restarting state
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-15 13:19:26 +01:00
szaimen
e60949aec9 dependency updates
Signed-off-by: GitHub <noreply@github.com>
2022-03-15 12:14:50 +00:00
Simon L
817df30465 Merge pull request #352 from nextcloud/enh/fix-domaincheck-startup
fix domaincheck startup
2022-03-15 12:25:55 +01:00
Simon L
07ad9a7eb8 Merge pull request #371 from nextcloud/automated/noid/psalm-baseline-update-1647318331
[Automated] Update psalm-baseline.xml
2022-03-15 10:25:07 +01:00
nextcloud-command
9c96806084 Update psalm baseline
Signed-off-by: GitHub <noreply@github.com>
2022-03-15 04:25:31 +00:00
szaimen
0e1edde3a7 allow to upgrade the mastercontainer even if no update was found
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-14 22:40:13 +01:00
szaimen
8661bdf020 run locking once a day
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-14 20:47:37 +01:00
szaimen
c3579476c6 improve logging of rate limit issues
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-14 17:20:45 +01:00
szaimen
ae349b8afb log if not pulling the latest database image
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-14 17:11:36 +01:00
Simon L
20bf2cfa7e Merge pull request #369 from nextcloud/enh/345/get-caddy-apcu-correctly
get caddy and apcu correctly
2022-03-14 16:43:21 +01:00
Simon L
0cbffeb90a Merge pull request #368 from nextcloud/enh/55/disallow-local-external-storage
Disallow creation of local external storage in some cases
2022-03-14 16:43:13 +01:00
szaimen
8983a97ef6 get caddy and apcu correctly
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-14 16:28:07 +01:00
szaimen
0670c7cedf Disallow creation of local external storage in some cases
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-14 15:35:37 +01:00
Simon L
cd00e5af83 Merge pull request #348 from nextcloud/enh/noid/refactor-some-logic
refactor some config logic
2022-03-14 15:17:48 +01:00
Simon L
2c7146b15f Merge pull request #343 from nextcloud/enh/340/add-headings
add some sensible headings
2022-03-14 15:02:38 +01:00
Simon L
975f4220d4 Merge pull request #338 from nextcloud/enh/noid/domain-change-docs
add docs for how to change domain in button
2022-03-14 15:01:47 +01:00
Simon L
6beaa3b391 Merge pull request #336 from nextcloud/enh/noid/allow-to-get-mastercontainer-logs
allow to get the mastercontainer logs from the frontend
2022-03-14 15:01:08 +01:00
Simon L
6b3cba411e Merge pull request #335 from nextcloud/enh/noid/disallow-database-update-if-failed
correctly disable database update if it failed before
2022-03-14 15:00:55 +01:00
szaimen
ab747de69d adress review
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-14 14:59:46 +01:00
szaimen
480b57178b lock closed issues after 14 days of inactivity
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-13 20:42:39 +01:00
szaimen
c9650aa0ef add issue templates and config
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-13 19:30:10 +01:00
szaimen
0e660f4c04 don't wait for collabora since we might allow to disable it in the future
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-13 18:31:07 +01:00
szaimen
6722dee1d6 fix attempt
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-12 22:50:34 +01:00
szaimen
79af222c2d fix startdomaincheckcontainer logic
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-12 22:50:34 +01:00
szaimen
79473fac76 refactor some config logic
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-11 17:28:55 +01:00
Simon L
9b11c817b2 Merge pull request #344 from nextcloud/dependabot/docker/Containers/mastercontainer/docker-20.10.13-dind-alpine3.15
Bump docker from 20.10.12-dind-alpine3.15 to 20.10.13-dind-alpine3.15 in /Containers/mastercontainer
2022-03-11 13:25:49 +01:00
dependabot[bot]
fb05818764 Bump docker in /Containers/mastercontainer
Bumps docker from 20.10.12-dind-alpine3.15 to 20.10.13-dind-alpine3.15.

---
updated-dependencies:
- dependency-name: docker
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-11 12:23:54 +00:00
szaimen
15a289e820 fix typo in backup script
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-11 09:27:38 +01:00
szaimen
d5868a9626 add some sensible headings
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-11 09:25:38 +01:00
szaimen
22d3b0ba30 allow to get the mastercontainer logs from the frontend
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-09 19:00:04 +01:00
szaimen
2b98a936b9 correctly disable database update if it failed before
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-09 18:31:44 +01:00
szaimen
3263184e8f add docs for how to change domain in button
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-09 17:12:16 +01:00
Simon L
85b445d576 Merge pull request #327 from nextcloud/enh/271/add-docs-for-datadir
add docs for changing the datadir
2022-03-09 15:29:16 +01:00
szaimen
52651559de don't allow to change the password if apache is starting
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-09 14:28:03 +01:00
szaimen
36fd28da6f fix styling for password change
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-09 14:18:51 +01:00
Simon L
77979aaa4a Merge pull request #334 from nextcloud/enh/noid/revert-migrating-borg-to-alpine
revert migrating borg to alpine
2022-03-09 13:52:42 +01:00
szaimen
5f753665ac revert migrating borg to alpine
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-09 13:49:09 +01:00
szaimen
e7ec998913 fix backup container build
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-09 13:23:44 +01:00
Simon L
91c7f13171 Merge pull request #332 from nextcloud/enh/noid/0.7.0
increase version to 0.7.0
2022-03-09 12:42:12 +01:00
Simon L
d170feb1e7 Merge pull request #326 from nextcloud/enh/271/allow-to-change-datadir
allow to change the location of Nextclouds datadir
2022-03-09 12:41:58 +01:00
Simon L
1a55b94b93 Merge pull request #330 from nextcloud/enh/noid/add-optional-section
add optional section
2022-03-09 12:41:38 +01:00
Simon L
a0656364b1 Merge pull request #329 from nextcloud/enh/272/allow-to-change-the-password
allow to change the password
2022-03-09 12:41:18 +01:00
Simon L
20c46a3809 Merge pull request #328 from nextcloud/enh/noid/check-startup-command
check if the startup command was executed successfully
2022-03-09 12:40:44 +01:00
Simon L
866519be88 Merge pull request #331 from nextcloud/enh/310/improve-domain-check
improve domain check
2022-03-09 12:40:22 +01:00
szaimen
cfc157f672 increase version to 0.7.0
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-09 12:39:51 +01:00
szaimen
8b813fe950 fix backup restore
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-09 12:37:43 +01:00
szaimen
c1a5262769 fix collabora
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-09 12:21:37 +01:00
szaimen
5b8de658c7 improve domain check
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-09 11:59:44 +01:00
szaimen
0b51eab553 add optional section
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-08 22:09:12 +01:00
szaimen
c8854ab1e3 allow to change the password
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-08 21:23:55 +01:00
szaimen
7a18cf766d check if the startup command was executed successfully
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-08 18:36:08 +01:00
szaimen
213de472a6 add docs for changing the datadir
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-08 17:53:03 +01:00
szaimen
c9be73601d catch the case that datadir and mount are equal
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-08 17:20:28 +01:00
szaimen
e2a6231257 allow to change the location of Nextclouds datadir
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-08 17:20:27 +01:00
Simon L
b929d57a77 Merge pull request #325 from nextcloud/enh/noid/correctly-delete-old-sessions
correctly delete sessions older than 24h
2022-03-08 15:50:56 +01:00
Simon L
0168b29882 Merge pull request #313 from nextcloud/enh/noid/database-safeguard
don't update database container if it failed before
2022-03-08 15:47:38 +01:00
Simon L
8836a884fb Merge pull request #306 from nextcloud/enh/205/migrate-borg-to-alpine
migrate borgbackup to alpine
2022-03-08 15:44:22 +01:00
Simon L
6adae6db3e Merge pull request #307 from nextcloud/enh/276/channel-and-changelog
show the current channel and add links to the changelogs
2022-03-08 15:43:37 +01:00
Simon L
0071703a24 Merge pull request #311 from nextcloud/aio-dependency-update
Dependency updates
2022-03-08 15:42:40 +01:00
Simon L
3af23d5a5c Merge pull request #312 from nextcloud/dependabot/docker/Containers/talk/ubuntu-focal-20220302
Bump ubuntu from focal-20220113 to focal-20220302 in /Containers/talk
2022-03-08 15:41:41 +01:00
szaimen
17eb732a89 correctly delete sessions older than 24h
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-08 15:32:09 +01:00
szaimen
68ddc72e9b don't update database container if it failed before
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-04 15:36:08 +01:00
dependabot[bot]
a03478c5d0 Bump ubuntu from focal-20220113 to focal-20220302 in /Containers/talk
Bumps ubuntu from focal-20220113 to focal-20220302.

---
updated-dependencies:
- dependency-name: ubuntu
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-04 13:00:16 +00:00
szaimen
6e8aea3aeb dependency updates
Signed-off-by: GitHub <noreply@github.com>
2022-03-04 12:14:44 +00:00
dependabot[bot]
2caa883453 Merge pull request #309 from nextcloud/dependabot/docker/Containers/collabora/collabora/code-21.11.2.4.1 2022-03-03 12:38:25 +00:00
dependabot[bot]
1edcc4ef5f Bump collabora/code in /Containers/collabora
Bumps collabora/code from 21.11.2.3.1 to 21.11.2.4.1.

---
updated-dependencies:
- dependency-name: collabora/code
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-03 12:27:42 +00:00
Simon L
10f62ac401 Merge pull request #301 from nextcloud/enh/noid/improve-update-check
also show up-to-date if the checks return null
2022-03-02 18:28:47 +01:00
Simon L
f8f50e9186 Merge pull request #305 from nextcloud/enh/299/sync-to-other-drive
add docs for additional backup sync to another drive
2022-03-02 18:28:32 +01:00
Simon L
a3e3dd4534 Merge pull request #297 from nextcloud/dependabot/docker/Containers/apache/debian-bullseye-20220228-slim
Bump debian from bullseye-20220125-slim to bullseye-20220228-slim in /Containers/apache
2022-03-02 18:27:27 +01:00
Simon L
a6286a291f Merge pull request #298 from nextcloud/dependabot/docker/Containers/collabora/collabora/code-21.11.2.3.1
Bump collabora/code from 21.11.2.2.1 to 21.11.2.3.1 in /Containers/collabora
2022-03-02 18:25:54 +01:00
Simon L
2dbd3a5f71 Merge pull request #252 from nextcloud/enh/1902/customize-collabora
customize collabora a bit
2022-03-02 17:23:31 +01:00
szaimen
c1e2446d22 customize collabora a bit
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-02 17:15:00 +01:00
szaimen
6232000e31 show the current channel and add links to the changelogs
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-02 15:49:34 +01:00
szaimen
7c20d54dd0 add docs for additional backup sync to another drive
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-02 15:30:02 +01:00
szaimen
8ce55a1334 migrate borgbackup to alpine
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-02 15:21:34 +01:00
Simon L
853a880c9d Merge pull request #286 from nextcloud/enh/noid/reverse-proxy-docs
add reverse proxy docs
2022-03-01 15:12:58 +01:00
Simon L
0ecd2c8f78 Merge pull request #289 from nextcloud/enh/273/lxc-docs
Add docs on backup container inside LXC containers
2022-03-01 15:12:38 +01:00
Simon L
24d1451325 Merge pull request #294 from nextcloud/automated/noid/psalm-baseline-update-1646132431
[Automated] Update psalm-baseline.xml
2022-03-01 15:12:27 +01:00
szaimen
8149c0de75 also show up-to-date if the checks return null
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-01 15:11:46 +01:00
dependabot[bot]
34660f3d17 Bump debian in /Containers/apache
Bumps debian from bullseye-20220125-slim to bullseye-20220228-slim.

---
updated-dependencies:
- dependency-name: debian
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-01 12:29:23 +00:00
dependabot[bot]
d360031f12 Bump collabora/code in /Containers/collabora
Bumps collabora/code from 21.11.2.2.1 to 21.11.2.3.1.

---
updated-dependencies:
- dependency-name: collabora/code
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-01 12:29:23 +00:00
Simon L
efde2ab41a Merge pull request #295 from nextcloud/enh/noid/increase-version
increase version to v0.6.0
2022-03-01 12:06:26 +01:00
szaimen
a89c183508 increase version to v0.6.0
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-01 12:05:54 +01:00
nextcloud-command
301b6e6297 Update psalm baseline
Signed-off-by: GitHub <noreply@github.com>
2022-03-01 11:00:30 +00:00
Simon L
6e839f5baf Merge pull request #293 from nextcloud/enh/noid/fix-some-psalm-issues
fix some psalm issues
2022-03-01 11:57:24 +01:00
szaimen
edb8bd228b fix some psalm issues
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-01 11:44:59 +01:00
Simon L
23429f3e59 Merge pull request #291 from nextcloud/enh/265/upgrade-postgres
update postgres to 14.2
2022-03-01 11:20:19 +01:00
Simon L
f4130a8475 Merge pull request #290 from nextcloud/enh/278/delete-backup-archives
add docs on how to delete backup archives manually
2022-03-01 11:10:30 +01:00
szaimen
e5aa3757d5 add docs on how to delete backup archives manually
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-01 11:07:38 +01:00
szaimen
12f1549221 update postgres to 14.2
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-01 10:16:32 +01:00
szaimen
d34167b30f Add docs on backup container inside LXC containers
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-01 09:38:51 +01:00
Simon L
5e0118a3b5 Merge pull request #287 from nextcloud/automated/noid/psalm-baseline-update-1646108969
[Automated] Update psalm-baseline.xml
2022-03-01 09:11:37 +01:00
nextcloud-command
220194b409 Update psalm baseline
Signed-off-by: GitHub <noreply@github.com>
2022-03-01 04:29:29 +00:00
szaimen
2943c6cf08 add reverse proxy docs
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-01 00:25:03 +01:00
szaimen
2040553822 fix the access rights
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-28 19:36:19 +01:00
Simon L
d1656a0fcb Merge pull request #70 from nextcloud/enh/noid/allow-reverse-proxies
allow to run this behind a reverse proxy
2022-02-28 18:55:03 +01:00
szaimen
6e9261f306 allow to run this behind a reverse proxy
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-28 18:44:35 +01:00
szaimen
269f62615f update psalm container regularly
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-28 18:13:26 +01:00
szaimen
704c4ad331 fix sarif upload
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-28 17:49:42 +01:00
Simon L
9afec142f3 Merge pull request #285 from nextcloud/automated/noid/psalm-baseline-update-1646065523
[Automated] Update psalm-baseline.xml
2022-02-28 17:45:16 +01:00
nextcloud-command
9fbcaae567 Update psalm baseline
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-28 17:42:45 +01:00
szaimen
82c371b519 fix the update-baseline-workflow
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-28 17:30:45 +01:00
Simon L
2afc711983 Merge pull request #283 from nextcloud/enh/noid/update-baseline
add workflow that updates psalm baseline regularly
2022-02-28 17:02:52 +01:00
szaimen
a42f21555a add workflow that updates psalm baseline regularly
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-28 17:01:12 +01:00
Simon L
d6ece6cad8 Merge pull request #210 from nextcloud/enh/207/set-up-psalm
set up psalm
2022-02-28 16:58:21 +01:00
szaimen
6f1da5fc5d set up psalm
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-28 16:55:06 +01:00
szaimen
2024cb8f26 add apcu into the psalm container
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-28 15:45:02 +01:00
Simon L
1c01e9e21f Merge pull request #282 from nextcloud/enh/noid/create-psalm-container
create our own psalm container
2022-02-28 15:30:30 +01:00
szaimen
628e55f076 create our own psalm container
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-28 15:27:02 +01:00
Simon L
5b49faf3b7 Merge pull request #274 from nextcloud/aio-dependency-update
Dependency updates
2022-02-28 14:43:12 +01:00
szaimen
33a73a7b95 dependency updates
Signed-off-by: GitHub <noreply@github.com>
2022-02-27 12:15:24 +00:00
szaimen
e2086ada2b make clear that the external storage app is not covered by the built-in backup solution
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-24 01:27:14 +01:00
szaimen
c15bc86e06 make clear that the external mount point will not be covered by the built-in backup solution
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-24 01:10:25 +01:00
Simon L
ccc80c44cc Merge pull request #255 from nextcloud/enh/76/add-docs
add some docs on how to allow the Nextcloud container to access direc…
2022-02-23 19:32:50 +01:00
Simon L
d12df52864 Merge pull request #269 from nextcloud/increase-to-0.5.0
increase version to v0.5.0
2022-02-23 18:48:24 +01:00
szaimen
5ed19687e2 increase version to v0.5.0
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-23 18:47:29 +01:00
Simon L
af93aeebd7 Merge pull request #254 from nextcloud/enh/76/allow-to-define-a-nextcloud-mountpoint
allow nextcloud to access outside directories
2022-02-23 18:11:35 +01:00
Simon L
aa366556f5 Merge pull request #266 from nextcloud/enh/263/move-trusted-proxies
move trusted_proxies to entrypoint
2022-02-23 18:09:42 +01:00
Simon L
a88000095a Merge pull request #253 from nextcloud/enh/244/enforce-startup-order
enforce startup order
2022-02-23 18:09:27 +01:00
Simon L
15e914e3f4 Merge pull request #267 from nextcloud/aio-dependency-update
Dependency updates
2022-02-23 18:08:38 +01:00
Simon L
472334948c Merge pull request #256 from nextcloud/dependabot/docker/Containers/collabora/collabora/code-21.11.2.2.1
Bump collabora/code from 21.11.1.4.1 to 21.11.2.2.1 in /Containers/collabora
2022-02-23 18:08:02 +01:00
Simon L
663901cacd Merge pull request #260 from nextcloud/dependabot/docker/Containers/mastercontainer/php-8.0.16-apache-bullseye
Bump php from 8.0.15-apache-bullseye to 8.0.16-apache-bullseye in /Containers/mastercontainer
2022-02-23 18:07:49 +01:00
Simon L
6f0e4dc175 Merge pull request #261 from nextcloud/dependabot/docker/Containers/nextcloud/php-8.0.16-fpm-alpine3.15
Bump php from 8.0.15-fpm-alpine3.15 to 8.0.16-fpm-alpine3.15 in /Containers/nextcloud
2022-02-23 18:07:35 +01:00
Simon L
b0894992b4 Merge pull request #262 from nextcloud/dependabot/docker/Containers/postgresql/postgres-13.6-alpine3.15
Bump postgres from 13.5-alpine3.15 to 13.6-alpine3.15 in /Containers/postgresql
2022-02-23 18:07:18 +01:00
Simon L
748dcea39e Merge pull request #246 from nextcloud/enh/219/do-not-disconnect-from-network
Do not disconnect containers from network
2022-02-23 18:05:02 +01:00
Simon L
5b278ca261 Merge pull request #268 from nextcloud/fix/241/validate-ip-address
ip-addresses are not supported as domain
2022-02-23 18:04:10 +01:00
szaimen
d988706ae0 ip-addresses are not supported as domain
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-23 18:01:56 +01:00
szaimen
73193ee2d5 dependency updates
Signed-off-by: GitHub <noreply@github.com>
2022-02-23 12:16:38 +00:00
szaimen
e955b0a96f move trusted_proxies to entrypoint
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-22 13:26:48 +01:00
Simon L
11edcfe142 Merge pull request #250 from nextcloud/enh/234/skeleton-dir-docs
add documentation for skeleton directory
2022-02-22 11:30:07 +01:00
szaimen
c779c91ef6 enforce startup order
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-21 20:00:35 +01:00
dependabot[bot]
3b177a5f55 Bump php in /Containers/nextcloud
Bumps php from 8.0.15-fpm-alpine3.15 to 8.0.16-fpm-alpine3.15.

---
updated-dependencies:
- dependency-name: php
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-21 17:59:20 +00:00
dependabot[bot]
72f7106911 Bump php in /Containers/mastercontainer
Bumps php from 8.0.15-apache-bullseye to 8.0.16-apache-bullseye.

---
updated-dependencies:
- dependency-name: php
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-21 17:59:14 +00:00
dependabot[bot]
cbfe9c1907 Bump postgres in /Containers/postgresql
Bumps postgres from 13.5-alpine3.15 to 13.6-alpine3.15.

---
updated-dependencies:
- dependency-name: postgres
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-21 17:54:31 +00:00
szaimen
db12a9a90b ignore major version updates for specific containers
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-21 18:53:51 +01:00
dependabot[bot]
c777971906 Bump collabora/code in /Containers/collabora
Bumps collabora/code from 21.11.1.4.1 to 21.11.2.2.1.

---
updated-dependencies:
- dependency-name: collabora/code
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-21 17:26:52 +00:00
szaimen
0b8caa8cea fix dependabot formatting
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-21 18:26:00 +01:00
szaimen
eafe011ae9 add some docs on how to allow the Nextcloud container to access directories on the host
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-21 18:08:31 +01:00
szaimen
bc50b0cc4f allow nextcloud to access outside directories
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-21 17:31:05 +01:00
Simon L
a2f60ba765 Merge pull request #248 from nextcloud/fix/2200/fix-dependabot
fix dependabot
2022-02-21 15:54:16 +01:00
szaimen
487688d000 add documentation for skeleton directory
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-21 14:33:14 +01:00
szaimen
30e2c6be25 fix typo in readme
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-21 14:18:46 +01:00
szaimen
777666cf11 fix dependabot
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-21 14:09:22 +01:00
szaimen
221ab2515d Do not disconnect containers from network
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-21 14:01:27 +01:00
Simon L
ac3b8bc963 Merge pull request #238 from nextcloud/enh/noid/add-backup-pro-tip
Add instructions how to open the backup archives on the host
2022-02-21 13:32:53 +01:00
szaimen
1df46bb805 Add instructions how to open the backup archives on the host
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-21 13:32:18 +01:00
Simon L
89830a1b81 Merge pull request #237 from nextcloud/fix/235/fix-database-import
fix database import by waiting for the database to start
2022-02-18 11:44:12 +01:00
szaimen
48e60872b3 fix database import by waiting for the database to start
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-18 11:41:52 +01:00
Simon L
9d9da9e47c Merge pull request #230 from nextcloud/enh/noid/update-version
update version to 0.4.0
2022-02-16 16:30:44 +01:00
szaimen
3a9c305758 update version to 0.4.0
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-16 16:29:47 +01:00
szaimen
8f1fcde006 fix selecting a backup container
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-16 16:26:35 +01:00
Simon L
8a6de8f63c Merge pull request #65 from nextcloud/enh/39/allow-to-select-archive
allow to select the archive to restore from
2022-02-16 14:43:10 +01:00
szaimen
0880aff7ea adress review
Signed-off-by: szaimen <szaimen@e.mail.de>
Co-Authored-By: Carl Schwan <carl@carlschwan.eu>
2022-02-16 14:34:21 +01:00
Simon L
2c3db2fd40 Merge pull request #229 from nextcloud/nextcloud-container-update
Nextcloud update
2022-02-16 13:39:37 +01:00
szaimen
e357fc8bb9 nextcloud-update automated change
Signed-off-by: GitHub <noreply@github.com>
2022-02-16 12:33:48 +00:00
Simon L
a82b86b915 Merge pull request #222 from nextcloud/aio-dependency-update
Dependency updates
2022-02-16 13:28:10 +01:00
szaimen
67705134cf dependency updates
Signed-off-by: GitHub <noreply@github.com>
2022-02-16 12:13:04 +00:00
Simon L
ce15c64cd9 Merge pull request #228 from nextcloud/enh/noid/update-nextcloud
update nextcloud to 23.0.2
2022-02-16 12:19:41 +01:00
szaimen
92492affe4 update nextcloud to 23.0.2
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-16 12:18:46 +01:00
szaimen
63e0849215 allow to select the archive to restore from
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-16 12:00:54 +01:00
szaimen
1515d0c210 another attempt to fix the database import
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-15 18:57:39 +01:00
Simon L
4359792a48 Merge pull request #226 from nextcloud/enh/noid/fix-database-import
fix database import
2022-02-15 17:44:36 +01:00
szaimen
3887275808 fix database import
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-15 17:44:00 +01:00
szaimen
badd8d02a9 update to 0.3.1
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-15 12:56:44 +01:00
Simon L
5bc10a56ed Merge pull request #218 from nextcloud/enh/noid/fix-database-connection
fix the database connection
2022-02-15 12:15:39 +01:00
Simon L
222dcd3317 Merge pull request #221 from nextcloud/aio-dependency-update
Dependency updates
2022-02-13 13:43:13 +01:00
szaimen
cec86aa825 dependency updates
Signed-off-by: GitHub <noreply@github.com>
2022-02-13 12:11:36 +00:00
szaimen
e7dfb2514b fix the database connection
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-13 11:44:59 +01:00
szaimen
b0e570176b fix redis build
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-12 14:24:11 +01:00
szaimen
7756826eb3 revert the removal for now since it would break all instances
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-12 01:02:39 +01:00
szaimen
836552e1a7 verbose output
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-12 00:26:12 +01:00
szaimen
6e22b364ae postgresql - delete the datadir once
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-11 23:53:50 +01:00
Simon L
4979d1d90e Merge pull request #214 from nextcloud/enh/131/use-dependabot-to-update-containers
use dependabot to update containers
2022-02-11 18:42:45 +01:00
szaimen
3029b277f1 use dependabot to update containers
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-02-11 15:47:49 +01:00
59 changed files with 1548 additions and 264 deletions

30
.github/ISSUE_TEMPLATE/Bug_report.md vendored Normal file
View File

@@ -0,0 +1,30 @@
---
name: 🐛 Bug report
about: Help us improving by reporting a bug
labels: bug, 0. Needs triage
---
<!--- Please keep this note for other contributors -->
### How to use GitHub
* Please use the 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to show that you are affected by the same issue.
* Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
* Subscribe to receive notifications on status change and new comments.
<!--- Please fill out the whole template below -->
### Steps to reproduce
1.
2.
3.
### Expected behaviour <!--- Tell us what should happen -->
### Actual behaviour <!--- Tell us what happens instead -->
---
#### Nextcloud AIO version <!--- (see Nextcloud AIO interface) -->
#### Current channel <!--- (see the channel name in the Mastercontainer section) -->
#### Other valuable info <!--- (like logs, screenshots & Co.) -->

View File

@@ -0,0 +1,24 @@
---
name: 📖 Existing feature/documentation enhancement
about: Suggest an enhancement of an existing feature/documentation - for other types, please use the feature request option below
labels: enhancement, 0. Needs triage
---
<!--- Please keep this note for other contributors -->
### How to use GitHub
* Please use the 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to show that you are interested into the same feature.
* Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
* Subscribe to receive notifications on status change and new comments.
<!--- Please fill out the whole template below -->
### Is your feature request related to a problem? Please describe.
<!--- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
### Describe the solution you'd like
<!--- A clear and concise description of what you want to happen. -->
### Describe alternatives you've considered
<!--- A clear and concise description of any alternative solutions or features you've considered. -->
#### Additional context
<!--- Add any other context or screenshots about the feature request below. -->

11
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: 💡 Suggest a new feature or discuss one
url: https://github.com/nextcloud/all-in-one/discussions
about: For new feature requests and discussion of existing ones
- name: ❓ Community Support and Help
url: https://help.nextcloud.com/tag/aio
about: For other types of questions
- name: 💼 Nextcloud Enterprise
url: https://portal.nextcloud.com/
about: If you are a Nextcloud Enterprise customer, or need Professional support, so it can be resolved directly by our dedicated engineers more quickly

114
.github/dependabot.yml vendored
View File

@@ -3,10 +3,116 @@ updates:
- package-ecosystem: composer
directory: "/php/"
schedule:
interval: weekly
day: saturday
time: "03:00"
timezone: Europe/Paris
interval: daily
time: "12:00"
open-pull-requests-limit: 10
labels:
- 3. to review
- dependencies
- package-ecosystem: "docker"
directory: "/Containers/apache"
schedule:
interval: "daily"
time: "12:00"
open-pull-requests-limit: 10
labels:
- 3. to review
- dependencies
- package-ecosystem: "docker"
directory: "/Containers/borgbackup"
schedule:
interval: "daily"
time: "12:00"
open-pull-requests-limit: 10
labels:
- 3. to review
- dependencies
- package-ecosystem: "docker"
directory: "/Containers/collabora"
schedule:
interval: "daily"
time: "12:00"
open-pull-requests-limit: 10
labels:
- 3. to review
- dependencies
- package-ecosystem: "docker"
directory: "/Containers/domaincheck"
schedule:
interval: "daily"
time: "12:00"
open-pull-requests-limit: 10
labels:
- 3. to review
- dependencies
- package-ecosystem: "docker"
directory: "/Containers/mastercontainer"
schedule:
interval: "daily"
time: "12:00"
ignore:
- dependency-name: "php"
update-types: ["version-update:semver-major", "version-update:semver-minor"]
open-pull-requests-limit: 10
labels:
- 3. to review
- dependencies
- package-ecosystem: "docker"
directory: "/Containers/nextcloud"
schedule:
interval: "daily"
time: "12:00"
ignore:
- dependency-name: "php"
update-types: ["version-update:semver-major", "version-update:semver-minor"]
open-pull-requests-limit: 10
labels:
- 3. to review
- dependencies
- package-ecosystem: "docker"
directory: "/Containers/postgresql"
schedule:
interval: "daily"
time: "12:00"
ignore:
- dependency-name: "postgres"
update-types: ["version-update:semver-major"]
open-pull-requests-limit: 10
labels:
- 3. to review
- dependencies
- package-ecosystem: "docker"
directory: "/Containers/redis"
schedule:
interval: "daily"
time: "12:00"
open-pull-requests-limit: 10
labels:
- 3. to review
- dependencies
- package-ecosystem: "docker"
directory: "/Containers/talk"
schedule:
interval: "daily"
time: "12:00"
open-pull-requests-limit: 10
labels:
- 3. to review
- dependencies
- package-ecosystem: "docker"
directory: "/Containers/watchtower"
schedule:
interval: "daily"
time: "12:00"
open-pull-requests-limit: 10
labels:
- 3. to review
- dependencies
- package-ecosystem: "docker"
directory: "/Containers/clamav"
schedule:
interval: "daily"
time: "12:00"
open-pull-requests-limit: 10
labels:
- 3. to review

View File

@@ -0,0 +1,54 @@
name: Create Psalm Container
on:
workflow_dispatch:
schedule:
- cron: '5 4 * * *'
jobs:
push_to_registry:
runs-on: ubuntu-latest
name: Create Psalm Container
permissions:
packages: write
contents: read
steps:
- name: Check out the repo
run: |
git clone https://github.com/psalm/psalm-github-actions.git
- name: Modify the Dockerfile
run: |
set -x
sed -i 's|FROM php:7.4-alpine|FROM php:8.0-alpine|' "psalm-github-actions/Dockerfile"
cat << APCU >> "psalm-github-actions/Dockerfile"
RUN mkdir -p /usr/src/php/ext/apcu && \
curl -fsSL https://pecl.php.net/get/apcu | tar xvz -C "/usr/src/php/ext/apcu" --strip 1 && \
docker-php-ext-install apcu
APCU
- name: Log in to GitHub Docker Registry
uses: docker/login-action@v1
with:
registry: docker.pkg.github.com
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build container image
uses: docker/build-push-action@v2
with:
push: true
context: 'psalm-github-actions'
file: 'psalm-github-actions/Dockerfile'
tags: |
ghcr.io/nextcloud/all-in-one-psalm:latest

View File

@@ -31,6 +31,18 @@ jobs:
done
echo "outdated dependencies:
$(composer outdated)"
- name: Update apcu
run: |
# APCU
apcu_version="$(
git ls-remote --tags https://github.com/krakjoe/apcu.git \
| cut -d/ -f3 \
| grep -vE -- '-rc|-b' \
| sed -E 's/^v//' \
| sort -V \
| tail -1
)"
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
with:

20
.github/workflows/lock-threads.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: 'Lock Threads'
on:
schedule:
- cron: '0 0 * * *'
permissions:
issues: write
concurrency:
group: lock
jobs:
action:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v3
with:
issue-inactive-days: '14'
process-only: 'issues'

18
.github/workflows/psalm-analysis.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
name: Psalm Analysis
on:
pull_request:
push:
jobs:
psalm:
name: Psalm
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Psalm
uses: docker://ghcr.io/nextcloud/all-in-one-psalm
with:
composer_ignore_platform_reqs: false
relative_dir: php

25
.github/workflows/psalm-security.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: Psalm Security Analysis
on:
push:
branches:
- main
jobs:
psalm:
name: Psalm
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Psalm
uses: docker://ghcr.io/nextcloud/all-in-one-psalm
with:
relative_dir: php
security_analysis: true
composer_ignore_platform_reqs: false
report_file: results.sarif
- name: Upload Security Analysis results to GitHub
uses: github/codeql-action/upload-sarif@v1
with:
sarif_file: php/results.sarif

View File

@@ -0,0 +1,48 @@
name: Update Psalm baseline
on:
workflow_dispatch:
schedule:
- cron: '5 4 * * *'
jobs:
update-psalm-baseline:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up php8.0
uses: shivammathur/setup-php@v2
with:
php-version: 8.0
extensions: apcu
coverage: none
- name: Run script
run: |
set -x
cd php
composer global require vimeo/psalm --prefer-dist --no-progress --dev
composer install
composer run psalm -- --monochrome --no-progress --output-format=text --update-baseline
git clean -f lib/composer
git checkout composer.json composer.lock lib/composer
continue-on-error: true
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.COMMAND_BOT_PAT }}
commit-message: Update psalm baseline
committer: GitHub <noreply@github.com>
author: nextcloud-command <nextcloud-command@users.noreply.github.com>
signoff: true
branch: automated/noid/psalm-baseline-update
# Make sure we can open multiple PRs
branch-suffix: timestamp
title: '[Automated] Update psalm-baseline.xml'
body: |
Auto-generated update psalm-baseline.xml with fixed psalm warnings
labels: |
3. to review

View File

@@ -6,7 +6,7 @@
}
}
https://{$NC_DOMAIN}:443 {
{$PROTOCOL}://{$NC_DOMAIN}:{$APACHE_PORT} {
# Notify Push
route /push/* {
@@ -22,25 +22,13 @@ https://{$NC_DOMAIN}:443 {
# Collabora
route /browser/* {
reverse_proxy https://{$COLLABORA_HOST}:9980 {
transport http {
tls_insecure_skip_verify
}
}
reverse_proxy {$COLLABORA_HOST}:9980
}
route /hosting/* {
reverse_proxy https://{$COLLABORA_HOST}:9980 {
transport http {
tls_insecure_skip_verify
}
}
reverse_proxy {$COLLABORA_HOST}:9980
}
route /cool/* {
reverse_proxy https://{$COLLABORA_HOST}:9980 {
transport http {
tls_insecure_skip_verify
}
}
reverse_proxy {$COLLABORA_HOST}:9980
}
# Nextcloud

View File

@@ -1,4 +1,7 @@
FROM debian:bullseye-slim
# Caddy is a requirement
FROM caddy:2.4.6-alpine as caddy
FROM debian:bullseye-20220228-slim
EXPOSE 80
@@ -21,10 +24,8 @@ RUN set -ex; \
; \
rm -rf /var/lib/apt/lists/*
RUN set -ex; \
wget "https://caddyserver.com/api/download?os=linux&arch=$(dpkg-architecture --query DEB_BUILD_ARCH)" -O "/usr/bin/caddy" \
&& chmod +x /usr/bin/caddy \
&& /usr/bin/caddy version
COPY --from=caddy /usr/bin/caddy /usr/bin/
RUN chmod +x /usr/bin/caddy
RUN a2enmod rewrite \
headers \
@@ -59,7 +60,8 @@ COPY start.sh /usr/bin/
COPY supervisord.conf /
RUN chmod +x /usr/bin/start.sh; \
chmod +r /supervisord.conf; \
chmod +r /Caddyfile;
chmod a+w /Caddyfile; \
chmod a+w /
# Give root a random password
RUN echo "root:$(openssl rand -base64 12)" | chpasswd

View File

@@ -17,11 +17,18 @@ while ! nc -z "$NEXTCLOUD_HOST" 9000; do
sleep 5
done
# Only start container if collabora is started
while ! nc -z "$COLLABORA_HOST" 9980; do
echo "Waiting for Collabora to start..."
sleep 5
done
if [ -z "$APACHE_PORT" ]; then
export APACHE_PORT="443"
fi
if [ "$APACHE_PORT" != '443' ]; then
export PROTOCOL="http"
export NC_DOMAIN=""
sed -i 's|auto_https.*|auto_https off|' /Caddyfile
else
export PROTOCOL="https"
sed -i 's|auto_https.*|auto_https disable_redirects|' /Caddyfile
fi
# Add caddy path
mkdir -p /mnt/data/caddy/

View File

@@ -1,4 +1,4 @@
FROM debian:bullseye-slim
FROM debian:bullseye-20220125-slim
RUN set -ex; \
\

View File

@@ -1,13 +1,9 @@
#!/bin/bash
# Variables
BORG_BACKUP_DIRECTORY="/mnt/borgbackup/borg"
# Functions
get_start_time(){
START_TIME=$(date +%s)
CURRENT_DATE=$(date --date @"$START_TIME" +"%Y%m%d_%H%M%S")
CURRENT_DATE_READABLE=$(date --date @"$START_TIME" +"%d.%m.%Y - %H:%M:%S")
}
get_expiration_time() {
END_TIME=$(date +%s)
@@ -19,11 +15,6 @@ get_expiration_time() {
DURATION_READABLE=$(printf "%02d hours %02d minutes %02d seconds" $DURATION_HOUR $DURATION_MIN $DURATION_SEC)
}
# Export defaults
export BORG_PASSPHRASE="$BORG_PASSWORD"
export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes
export BORG_RELOCATED_REPO_ACCESS_IS_OK=yes
# Test if all volumes aren't empty
VOLUME_DIRS="$(find /nextcloud_aio_volumes -mindepth 1 -maxdepth 1 -type d)"
mapfile -t VOLUME_DIRS <<< "$VOLUME_DIRS"
@@ -150,9 +141,6 @@ if [ "$BORG_MODE" = backup ]; then
# Remove the update skip file because the backup was successful
rm -f "/nextcloud_aio_volumes/nextcloud_aio_nextcloud_data/skip.update"
echo "$CURRENT_DATE,$CURRENT_DATE_READABLE" >> "/nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/backup_archives.list"
chmod +r "/nextcloud_aio_volumes/nextcloud_aio_mastercontainer/data/backup_archives.list"
# Prune options
BORG_PRUNE_OPTS=(--stats --progress --keep-within=7d --keep-weekly=4 --keep-monthly=6 "$BORG_BACKUP_DIRECTORY")
@@ -172,17 +160,20 @@ fi
# Do the restore
if [ "$BORG_MODE" = restore ]; then
get_start_time
echo "Restoring the last backup..."
# Perform the restore
FIRST_ARCHIVE="$(borg list "$BORG_BACKUP_DIRECTORY" | grep "nextcloud-aio" | awk -F " " '{print $1}' | sort -r | head -1)"
if [ -n "$SELECTED_RESTORE_TIME" ]; then
SELECTED_ARCHIVE="$(borg list "$BORG_BACKUP_DIRECTORY" | grep "nextcloud-aio" | grep "$SELECTED_RESTORE_TIME" | awk -F " " '{print $1}' | head -1)"
else
SELECTED_ARCHIVE="$(borg list "$BORG_BACKUP_DIRECTORY" | grep "nextcloud-aio" | awk -F " " '{print $1}' | sort -r | head -1)"
fi
echo "Restoring '$SELECTED_ARCHIVE'..."
mkdir -p /tmp/borg
if ! borg mount "$BORG_BACKUP_DIRECTORY::$FIRST_ARCHIVE" /tmp/borg; then
if ! borg mount "$BORG_BACKUP_DIRECTORY::$SELECTED_ARCHIVE" /tmp/borg; then
echo "Could not mount the backup!"
exit 1
fi
if ! rsync --stats --archive --human-readable -vv --delete \
--exclude "nextcloud_aio_mastercontainer/data/backup_archives.list" \
--exclude "nextcloud_aio_mastercontainer/session/"** \
--exclude "nextcloud_aio_mastercontainer/certs/"** \
/tmp/borg/nextcloud_aio_volumes/ /nextcloud_aio_volumes; then
@@ -211,7 +202,7 @@ fi
# Do the Backup check
if [ "$BORG_MODE" = check ]; then
get_start_time
echo "Checking the backup integity..."
echo "Checking the backup integrity..."
# Perform the check
if ! borg check --verify-data --progress "$BORG_BACKUP_DIRECTORY"; then

View File

@@ -1,12 +1,18 @@
#!/bin/bash
# Variables
export BORG_BACKUP_DIRECTORY="/mnt/borgbackup/borg"
# Validate BORG_PASSWORD
if [ -z "$BORG_PASSWORD" ]; then
echo "BORG_PASSWORD is not allowed to be empty."
exit 1
fi
export BORG_PASSWORD
# Export defaults
export BORG_PASSPHRASE="$BORG_PASSWORD"
export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes
export BORG_RELOCATED_REPO_ACCESS_IS_OK=yes
# Validate BORG_MODE
if [ "$BORG_MODE" != backup ] && [ "$BORG_MODE" != restore ] && [ "$BORG_MODE" != check ]; then
@@ -24,6 +30,12 @@ fi
# Remove lockfile
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
# Add file to Nextcloud container so that it skips any update the next time

View File

@@ -0,0 +1,5 @@
# Probably from this file: https://github.com/Cisco-Talos/clamav/blob/main/Dockerfile
FROM clamav/clamav:0.104.2-2
COPY clamav.conf /tmp/
RUN cat /tmp/clamav.conf >> /etc/clamav/clamd.conf

View File

@@ -0,0 +1,4 @@
MaxDirectoryRecursion 30
MaxFileSize 100M
PCREMaxFileSize 100M
StreamMaxLength 100M

View File

@@ -1,2 +1,2 @@
# From a file located probably somewhere here: https://github.com/CollaboraOnline/online/tree/master/docker
FROM collabora/code:latest
FROM collabora/code:21.11.2.4.1

View File

@@ -1,4 +1,4 @@
FROM alpine
FROM alpine:3.15.0
RUN apk add --update --no-cache lighttpd bash
RUN adduser -S www-data -G www-data

View File

@@ -1,6 +1,6 @@
server.document-root = "/var/www/domaincheck/"
server.port = 443
server.port = env.APACHE_PORT
server.username = "www-data"
server.groupname = "www-data"

View File

@@ -7,6 +7,10 @@ fi
echo "$INSTANCE_ID" > /var/www/domaincheck/index.html
if [ -z "$APACHE_PORT" ]; then
export APACHE_PORT="443"
fi
# Check config file
lighttpd -tt -f /etc/lighttpd/lighttpd.conf

View File

@@ -1,5 +1,11 @@
# Docker CLI is a requirement
FROM docker:20.10.13-dind-alpine3.15 as dind
# Caddy is a requirement
FROM caddy:2.4.6-alpine as caddy
# From https://github.com/docker-library/php/blob/master/8.0/bullseye/apache/Dockerfile
FROM php:8.0-apache-bullseye
FROM php:8.0.16-apache-bullseye
EXPOSE 80
EXPOSE 8080
@@ -23,17 +29,15 @@ RUN apt-get update; \
; \
rm -rf /var/lib/apt/lists/*
RUN set -ex; \
curl "https://caddyserver.com/api/download?os=linux&arch=$(dpkg-architecture --query DEB_BUILD_ARCH)" -o "/usr/bin/caddy" \
&& chmod +x /usr/bin/caddy \
&& /usr/bin/caddy version
COPY --from=caddy /usr/bin/caddy /usr/bin/
RUN chmod +x /usr/bin/caddy
COPY --from=docker:dind /usr/local/bin/docker /usr/local/bin/
COPY --from=dind /usr/local/bin/docker /usr/local/bin/
RUN chmod +x /usr/local/bin/docker
RUN mkdir -p /usr/src/php/ext/apcu && \
curl -fsSL https://pecl.php.net/get/apcu | tar xvz -C "/usr/src/php/ext/apcu" --strip 1 && \
docker-php-ext-install apcu
RUN set -ex; \
pecl install APCu-5.1.21; \
docker-php-ext-enable apcu
RUN set -e && \
curl -sS https://getcomposer.org/installer | php && \

View File

@@ -6,5 +6,7 @@ while true; do
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
# Remove sessions older than 24h
find "/mnt/docker-aio-config/session/" -mindepth 1 -mmin +1440 -delete
sleep 1d
done

View File

@@ -6,6 +6,14 @@ print_green() {
printf "%b%s%b\n" "\e[0;92m" "$TEXT" "\e[0m"
}
# Function to check if number was provided
check_if_number() {
case "${1}" in
''|*[!0-9]*) return 1 ;;
*) return 0 ;;
esac
}
# Check if socket is available and readable
if ! [ -a "/var/run/docker.sock" ]; then
echo "Docker socket is not available. Cannot continue."
@@ -54,6 +62,58 @@ else
sleep 10
fi
# Check if startup command was executed correctly
if ! docker ps | grep -q "nextcloud-aio-mastercontainer"; then
echo "It seems like you did not give the mastercontainer the correct name?"
exit 1
elif ! docker volume ls | grep -q "nextcloud_aio_mastercontainer"; then
echo "It seems like you did not give the mastercontainer volume the correct name?"
exit 1
fi
# Check for other options
if [ -n "$NEXTCLOUD_DATADIR" ]; then
if ! echo "$NEXTCLOUD_DATADIR" | grep -q "^/mnt/" \
&& ! echo "$NEXTCLOUD_DATADIR" | grep -q "^/media/"
then
echo "You've set NEXTCLOUD_DATADIR but not to an allowed value.
The string must start with '/mnt/' or '/media/'. E.g. '/mnt/ncdata'"
exit 1
elif [ "$NEXTCLOUD_DATADIR" = "/mnt/" ] || [ "$NEXTCLOUD_DATADIR" = "/media/" ]; then
echo "You've set NEXTCLOUD_DATADIR but not to an allowed value.
The string must start with '/mnt/' or '/media/' and not be equal to these."
exit 1
fi
fi
if [ -n "$NEXTCLOUD_MOUNT" ]; then
if ! echo "$NEXTCLOUD_MOUNT" | grep -q "^/mnt/" \
&& ! echo "$NEXTCLOUD_MOUNT" | grep -q "^/media/" \
&& ! echo "$NEXTCLOUD_MOUNT" | grep -q "^/var/backups$"
then
echo "You've set NEXCLOUD_MOUNT but not to an allowed value.
The string must be equal to/start with '/mnt/' or '/media/' or be equal to '/var/backups'."
exit 1
elif [ "$NEXTCLOUD_MOUNT" = "/mnt/ncdata" ] || echo "$NEXTCLOUD_MOUNT" | grep -q "^/mnt/ncdata/"; then
echo "/mnt/ncdata and /mnt/ncdata/ are not allowed for NEXTCLOUD_MOUNT."
exit 1
fi
fi
if [ -n "$NEXTCLOUD_DATADIR" ] && [ -n "$NEXTCLOUD_MOUNT" ]; then
if [ "$NEXTCLOUD_DATADIR" = "$NEXTCLOUD_MOUNT" ]; then
echo "NEXTCLOUD_DATADIR and NEXTCLOUD_MOUNT are not allowed to be equal."
exit 1
fi
fi
if [ -n "$APACHE_PORT" ]; then
if ! check_if_number "$APACHE_PORT"; then
echo "You provided an Apache port but did not only use numbers"
exit 1
elif ! [ "$APACHE_PORT" -le 65535 ] || ! [ "$APACHE_PORT" -ge 1 ]; then
echo "The provided Apache port is invalid. It must be between 1 and 65535"
exit 1
fi
fi
# Add important folders
mkdir -p /mnt/docker-aio-config/data/
mkdir -p /mnt/docker-aio-config/session/

View File

@@ -1,5 +1,5 @@
# From https://github.com/nextcloud/docker/blob/master/23/fpm-alpine/Dockerfile
FROM php:8.0-fpm-alpine
FROM php:8.0.16-fpm-alpine3.15
# Custom: change id of www-data user as it needs to be the same like on old installations
RUN set -ex; \
@@ -62,7 +62,7 @@ RUN set -ex; \
# pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-5.1.21; \
pecl install memcached-3.1.5; \
pecl install redis-5.3.6; \
pecl install redis-5.3.7; \
pecl install imagick-3.7.0; \
\
docker-php-ext-enable \
@@ -105,7 +105,7 @@ RUN { \
VOLUME /var/www/html
ENV NEXTCLOUD_VERSION 23.0.1
ENV NEXTCLOUD_VERSION 23.0.2
RUN set -ex; \
apk add --no-cache --virtual .fetch-deps \

View File

@@ -18,8 +18,3 @@ $overwriteCondAddr = getenv('OVERWRITECONDADDR');
if ($overwriteCondAddr) {
$CONFIG['overwritecondaddr'] = $overwriteCondAddr;
}
$trustedProxies = getenv('TRUSTED_PROXIES');
if ($trustedProxies) {
$CONFIG['trusted_proxies'] = array_filter(array_map('trim', explode(' ', $trustedProxies)));
}

View File

@@ -21,6 +21,15 @@ redis.session.lock_retries = -1
redis.session.lock_wait_time = 10000
REDIS_CONF
# Check permissions in ncdata
touch "/mnt/ncdata/this-is-a-test-file"
if ! [ -f "/mnt/ncdata/this-is-a-test-file" ]; then
echo "The www-data user doesn't seem to have access rights in /mnt/ncdata.
Did you maybe change the datadir and did forget to apply the correct permissions?"
exit 1
fi
rm "/mnt/ncdata/this-is-a-test-file"
if [ -f /var/www/html/version.php ]; then
# shellcheck disable=SC2016
installed_version="$(php -r 'require "/var/www/html/version.php"; echo implode(".", $OC_Version);')"
@@ -223,6 +232,13 @@ if ! [ -f "/mnt/ncdata/skip.update" ]; then
fi
fi
# Check if appdata is present
# If not, something broke (e.g. changing ncdatadir after aio was first started)
if [ -z "$(find "/mnt/ncdata/" -maxdepth 1 -mindepth 1 -type d -name "appdata_*")" ]; then
echo "Appdata is not present. Did you maybe change the datadir after aio was first started?"
exit 1
fi
# Apply one-click-instance settings
echo "Applying one-click-instance settings..."
php /var/www/html/occ config:system:set one-click-instance --value=true --type=bool
@@ -235,6 +251,13 @@ php /var/www/html/occ config:system:set overwrite.cli.url --value="https://$NC_D
php /var/www/html/occ config:system:set htaccess.RewriteBase --value="/"
php /var/www/html/occ maintenance:update:htaccess
# Disallow creating local external storages when nothing was mounted
if [ -z "$NEXTCLOUD_MOUNT" ]; then
php /var/www/html/occ config:system:set files_external_allow_create_new_local --type=bool --value=false
else
php /var/www/html/occ config:system:set files_external_allow_create_new_local --type=bool --value=true
fi
# AIO app
if [ "$(php /var/www/html/occ config:app:get nextcloud-aio enabled)" = "" ]; then
php /var/www/html/occ app:enable nextcloud-aio
@@ -250,6 +273,7 @@ elif [ "$(php /var/www/html/occ config:app:get notify_push enabled)" = "no" ]; t
else
php /var/www/html/occ app:update notify_push
fi
php /var/www/html/occ config:system:set trusted_proxies 0 --value="127.0.0.1"
php /var/www/html/occ config:app:set notify_push base_endpoint --value="https://$NC_DOMAIN/push"
# Collabora
@@ -280,5 +304,26 @@ php /var/www/html/occ config:app:set spreed stun_servers --value="$STUN_SERVERS"
php /var/www/html/occ config:app:set spreed turn_servers --value="$TURN_SERVERS" --output json
php /var/www/html/occ config:app:set spreed signaling_servers --value="$SIGNALING_SERVERS" --output json
# Clamav
if [ "$CLAMAV_ENABLED" = 'yes' ]; then
if ! [ -d "/var/www/html/custom_apps/files_antivirus" ]; then
php /var/www/html/occ app:install files_antivirus
elif [ "$(php /var/www/html/occ config:app:get files_antivirus enabled)" = "no" ]; then
php /var/www/html/occ app:enable files_antivirus
else
php /var/www/html/occ app:update files_antivirus
fi
php /var/www/html/occ config:app:set files_antivirus av_mode --value="daemon"
php /var/www/html/occ config:app:set files_antivirus av_port --value="3310"
php /var/www/html/occ config:app:set files_antivirus av_host --value="$CLAMAV_HOST"
php /var/www/html/occ config:app:set files_antivirus av_stream_max_length --value="104857600"
php /var/www/html/occ config:app:set files_antivirus av_max_file_size --value="-1"
php /var/www/html/occ config:app:set files_antivirus av_infected_action --value="only_log"
else
if [ -d "/var/www/html/custom_apps/files_antivirus" ]; then
php /var/www/html/occ app:remove files_antivirus
fi
fi
# Remove the update skip file always
rm -f /mnt/ncdata/skip.update

View File

@@ -6,6 +6,16 @@ while ! nc -z "$POSTGRES_HOST" 5432; do
sleep 5
done
# Use the correct Postgres username
POSTGRES_USER="oc_$POSTGRES_USER"
export POSTGRES_USER
# Fix false database connection on old instances
if [ -f "/var/www/html/config/config.php" ] && sleep 2 && psql -d "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST:5432/$POSTGRES_DB" -c "select now()"; then
sed -i "s|'dbuser'.*=>.*$|'dbuser' => '$POSTGRES_USER',|" /var/www/html/config/config.php
sed -i "s|'dbpassword'.*=>.*$|'dbpassword' => '$POSTGRES_PASSWORD',|" /var/www/html/config/config.php
fi
# Run original entrypoint
if ! bash /entrypoint.sh; then
exit 1

View File

@@ -1,7 +1,7 @@
# From https://github.com/docker-library/postgres/blob/master/13/alpine/Dockerfile
FROM postgres:13-alpine
FROM postgres:14.2-alpine3.15
RUN apk add --update --no-cache bash openssl shadow
RUN apk add --update --no-cache bash openssl shadow netcat-openbsd
# We need to use the same gid and uid as on old installations
RUN set -ex; \
@@ -17,7 +17,9 @@ RUN set -ex; \
chown -R postgres:postgres "$PGDATA"
COPY start.sh /usr/bin/
RUN chmod +x /usr/bin/start.sh
COPY init-user-db.sh /docker-entrypoint-initdb.d/
RUN chmod +x /usr/bin/start.sh; \
chmod +xr /docker-entrypoint-initdb.d/init-user-db.sh
RUN mkdir /mnt/data; \
chown postgres:postgres /mnt/data;

View File

@@ -0,0 +1,9 @@
#!/bin/bash
set -ex
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE USER "oc_$POSTGRES_USER" WITH PASSWORD '$POSTGRES_PASSWORD' CREATEDB;
ALTER DATABASE "$POSTGRES_DB" OWNER TO "oc_$POSTGRES_USER";
EOSQL
set +ex

View File

@@ -18,10 +18,18 @@ if ! [ -w "$DUMP_DIR" ]; then
exit 1
fi
# Delete the datadir once (needed for setting the correct credentials on old instances once)
if ! [ -f "$DUMP_DIR/export.failed" ] && ! [ -f "$DUMP_DIR/initial-cleanup-done" ]; then
set -ex
rm -rf "${DATADIR:?}/"*
touch "$DUMP_DIR/initial-cleanup-done"
set +ex
fi
# Test if some things match
# shellcheck disable=SC2235
if ( [ -f "$DATADIR/PG_VERSION" ] && [ "$PG_MAJOR" != "$(cat "$DATADIR/PG_VERSION")" ] ) \
|| ( ! [ -f "$DATADIR/PG_VERSION" ] && [ -f "$DUMP_FILE" ] ); then
|| ( ! [ -f "$DATADIR/PG_VERSION" ] && ( [ -f "$DUMP_FILE" ] || [ -f "$DUMP_DIR/export.failed" ] ) ); then
# The DUMP_file must be provided
if ! [ -f "$DUMP_FILE" ]; then
echo "Unable to restore the database because the database dump is missing."
@@ -39,7 +47,7 @@ if ( [ -f "$DATADIR/PG_VERSION" ] && [ "$PG_MAJOR" != "$(cat "$DATADIR/PG_VERSIO
echo "Restoring from database dump."
# Exit if any command fails
set -e
set -ex
# Remove old database files
rm -rf "${DATADIR:?}/"*
@@ -50,13 +58,33 @@ if ( [ -f "$DATADIR/PG_VERSION" ] && [ "$PG_MAJOR" != "$(cat "$DATADIR/PG_VERSIO
# Create new database
exec docker-entrypoint.sh postgres &
# Wait 2s for creation
sleep 2s
# Wait for creation
while ! nc -z localhost 11000; do
echo "Waiting for the database to start."
sleep 5
done
# Set correct permissions
if grep -q "Owner: oc_admin" "$DUMP_FILE" && ! grep -q "Owner: oc_$POSTGRES_USER" "$DUMP_FILE"; then
OC_ADMIN_EXISTS=1
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE USER oc_admin WITH PASSWORD '$POSTGRES_PASSWORD' CREATEDB;
ALTER DATABASE "$POSTGRES_DB" OWNER TO oc_admin;
EOSQL
fi
# Restore database
echo "Restoring the database from database dump"
psql "$POSTGRES_DB" -U "$POSTGRES_USER" < "$DUMP_FILE"
# Correct permissions
if [ -n "$OC_ADMIN_EXISTS" ]; then
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
ALTER DATABASE "$POSTGRES_DB" OWNER TO "oc_$POSTGRES_USER";
REASSIGN OWNED BY oc_admin TO "oc_$POSTGRES_USER";
EOSQL
fi
# Shut down the database to be able to start it again
pg_ctl stop -m fast
@@ -64,7 +92,7 @@ if ( [ -f "$DATADIR/PG_VERSION" ] && [ "$PG_MAJOR" != "$(cat "$DATADIR/PG_VERSIO
export PGPORT=5432
# Don't exit if command fails anymore
set +e
set +ex
fi
# Cover the last case

View File

@@ -1,5 +1,5 @@
# From https://github.com/docker-library/redis/blob/master/6.2/alpine/Dockerfile
FROM redis:6.2-alpine
FROM redis:6.2.6-alpine3.15
RUN apk add --update --no-cache openssl bash

View File

@@ -1,4 +1,4 @@
FROM ubuntu:focal
FROM ubuntu:focal-20220302
EXPOSE 3478

View File

@@ -1,7 +1,7 @@
# From https://github.com/containrrr/watchtower/blob/main/dockerfiles/Dockerfile.self-contained
FROM containrrr/watchtower:latest as watchtower
FROM containrrr/watchtower:1.4.0 as watchtower
FROM alpine:latest
FROM alpine:3.15.0
RUN apk add --update --no-cache bash
COPY --from=watchtower /watchtower /

View File

@@ -17,5 +17,9 @@
"slim/twig-view": "^3.2",
"slim/csrf": "^1.2",
"ext-apcu": "*"
}
},
"scripts": {
"psalm": "psalm --threads=1",
"psalm:update-baseline": "psalm --threads=1 --update-baseline"
}
}

82
php/composer.lock generated
View File

@@ -50,12 +50,12 @@
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\": "src/"
},
"files": [
"src/functions_include.php"
]
],
"psr-4": {
"GuzzleHttp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -157,12 +157,12 @@
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
},
"files": [
"src/functions_include.php"
]
],
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -465,12 +465,12 @@
}
},
"autoload": {
"psr-4": {
"Opis\\Closure\\": "src/"
},
"files": [
"functions.php"
]
],
"psr-4": {
"Opis\\Closure\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -595,12 +595,12 @@
},
"type": "library",
"autoload": {
"psr-4": {
"DI\\": "src/"
},
"files": [
"src/functions.php"
]
],
"psr-4": {
"DI\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -1192,22 +1192,22 @@
},
{
"name": "slim/slim",
"version": "4.9.0",
"version": "4.10.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim.git",
"reference": "44d3c9c0bfcc47e52e42b097b6062689d21b904b"
"reference": "0dfc7d2fdf2553b361d864d51af3fe8a6ad168b0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Slim/zipball/44d3c9c0bfcc47e52e42b097b6062689d21b904b",
"reference": "44d3c9c0bfcc47e52e42b097b6062689d21b904b",
"url": "https://api.github.com/repos/slimphp/Slim/zipball/0dfc7d2fdf2553b361d864d51af3fe8a6ad168b0",
"reference": "0dfc7d2fdf2553b361d864d51af3fe8a6ad168b0",
"shasum": ""
},
"require": {
"ext-json": "*",
"nikic/fast-route": "^1.3",
"php": "^7.3 || ^8.0",
"php": "^7.4 || ^8.0",
"psr/container": "^1.0 || ^2.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.0",
@@ -1218,13 +1218,15 @@
"require-dev": {
"adriansuter/php-autoload-override": "^1.2",
"ext-simplexml": "*",
"guzzlehttp/psr7": "^2.0",
"guzzlehttp/psr7": "^2.1",
"httpsoft/http-message": "^1.0",
"httpsoft/http-server-request": "^1.0",
"laminas/laminas-diactoros": "^2.8",
"nyholm/psr7": "^1.4",
"nyholm/psr7": "^1.5",
"nyholm/psr7-server": "^1.0",
"phpspec/prophecy": "^1.14",
"phpspec/prophecy": "^1.15",
"phpspec/prophecy-phpunit": "^2.0",
"phpstan/phpstan": "^0.12.99",
"phpstan/phpstan": "^1.4",
"phpunit/phpunit": "^9.5",
"slim/http": "^1.2",
"slim/psr7": "^1.5",
@@ -1301,7 +1303,7 @@
"type": "tidelift"
}
],
"time": "2021-10-05T03:00:00+00:00"
"time": "2022-03-14T14:18:23+00:00"
},
{
"name": "slim/twig-view",
@@ -1437,7 +1439,7 @@
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.24.0",
"version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
@@ -1469,12 +1471,12 @@
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
},
"files": [
"bootstrap.php"
]
],
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -1499,7 +1501,7 @@
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0"
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0"
},
"funding": [
{
@@ -1519,7 +1521,7 @@
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.24.0",
"version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
@@ -1551,12 +1553,12 @@
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
},
"files": [
"bootstrap.php"
]
],
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -1582,7 +1584,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0"
},
"funding": [
{
@@ -1602,7 +1604,7 @@
},
{
"name": "symfony/polyfill-php81",
"version": "v1.24.0",
"version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php81.git",
@@ -1661,7 +1663,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php81/tree/v1.24.0"
"source": "https://github.com/symfony/polyfill-php81/tree/v1.25.0"
},
"funding": [
{

View File

@@ -4,23 +4,25 @@
"dependsOn": [
"nextcloud-aio-nextcloud",
"nextcloud-aio-collabora",
"nextcloud-aio-talk"
"nextcloud-aio-talk",
"nextcloud-aio-clamav"
],
"identifier": "nextcloud-aio-apache",
"displayName": "Apache",
"containerName": "nextcloud/aio-apache",
"ports": [
"443/tcp"
"%APACHE_PORT%/tcp"
],
"internalPorts": [
"443"
"%APACHE_PORT%"
],
"secrets": [],
"environmentVariables": [
"NC_DOMAIN=%NC_DOMAIN%",
"NEXTCLOUD_HOST=nextcloud-aio-nextcloud",
"COLLABORA_HOST=nextcloud-aio-collabora",
"TALK_HOST=nextcloud-aio-talk"
"TALK_HOST=nextcloud-aio-talk",
"APACHE_PORT=%APACHE_PORT%"
],
"volumes": [
{
@@ -95,9 +97,14 @@
"writeable": true
},
{
"name": "nextcloud_aio_nextcloud_data",
"name": "%NEXTCLOUD_DATADIR%",
"location": "/mnt/ncdata",
"writeable": true
},
{
"name": "%NEXTCLOUD_MOUNT%",
"location": "%NEXTCLOUD_MOUNT%",
"writeable": true
}
],
"environmentVariables": [
@@ -114,10 +121,12 @@
"NEXTCLOUD_DATA_DIR=/mnt/ncdata",
"OVERWRITEHOST=%NC_DOMAIN%",
"OVERWRITEPROTOCOL=https",
"TRUSTED_PROXIES=127.0.0.1",
"TURN_SECRET=%TURN_SECRET%",
"SIGNALING_SECRET=%SIGNALING_SECRET%",
"AIO_URL=%AIO_URL%"
"AIO_URL=%AIO_URL%",
"NEXTCLOUD_MOUNT=%NEXTCLOUD_MOUNT%",
"CLAMAV_ENABLED=%CLAMAV_ENABLED%",
"CLAMAV_HOST=nextcloud-aio-clamav"
],
"maxShutdownTime": 10,
"restartPolicy": "unless-stopped"
@@ -151,7 +160,8 @@
"9980"
],
"environmentVariables": [
"domain=%NC_DOMAIN%"
"domain=%NC_DOMAIN%",
"extra_params=--o:ssl.enable=false --o:ssl.termination=true --o:logging.level=warning"
],
"volumes": [],
"secrets": [],
@@ -194,7 +204,8 @@
"internalPorts": [],
"environmentVariables": [
"BORG_PASSWORD=%BORGBACKUP_PASSWORD%",
"BORG_MODE=%BORGBACKUP_MODE%"
"BORG_MODE=%BORGBACKUP_MODE%",
"SELECTED_RESTORE_TIME=%SELECTED_RESTORE_TIME%"
],
"volumes": [
{
@@ -208,7 +219,7 @@
"writeable": true
},
{
"name": "nextcloud_aio_nextcloud_data",
"name": "%NEXTCLOUD_DATADIR%",
"location": "/nextcloud_aio_volumes/nextcloud_aio_nextcloud_data",
"writeable": true
},
@@ -271,11 +282,12 @@
"displayName": "Domaincheck",
"containerName": "nextcloud/aio-domaincheck",
"ports": [
"443/tcp"
"%APACHE_PORT%/tcp"
],
"internalPorts": [],
"environmentVariables": [
"INSTANCE_ID=%INSTANCE_ID%"
"INSTANCE_ID=%INSTANCE_ID%",
"APACHE_PORT=%APACHE_PORT%"
],
"volumes": [],
"secrets": [
@@ -283,6 +295,27 @@
],
"maxShutdownTime": 1,
"restartPolicy": ""
},
{
"dependsOn": [],
"identifier": "nextcloud-aio-clamav",
"displayName": "ClamAV",
"containerName": "nextcloud/aio-clamav",
"ports": [],
"internalPorts": [
"3310"
],
"environmentVariables": [],
"volumes": [
{
"name": "nextcloud_aio_clamav",
"location": "/var/lib/clamav",
"writeable": true
}
],
"secrets": [],
"maxShutdownTime": 10,
"restartPolicy": "unless-stopped"
}
]
}

95
php/psalm-baseline.xml Normal file
View File

@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="4.22.0@fc2c6ab4d5fa5d644d8617089f012f3bb84b8703">
<file src="public/index.php">
<MissingClosureParamType occurrences="10">
<code>$args</code>
<code>$args</code>
<code>$args</code>
<code>$args</code>
<code>$request</code>
<code>$request</code>
<code>$request</code>
<code>$response</code>
<code>$response</code>
<code>$response</code>
</MissingClosureParamType>
</file>
<file src="src/Controller/ConfigurationController.php">
<MissingParamType occurrences="1">
<code>$args</code>
</MissingParamType>
<PossiblyInvalidArrayAccess occurrences="4">
<code>$request-&gt;getParsedBody()['borg_backup_host_location']</code>
<code>$request-&gt;getParsedBody()['domain']</code>
<code>$request-&gt;getParsedBody()['clamav']</code>
<code>$request-&gt;getParsedBody()['options-form']</code>
</PossiblyInvalidArrayAccess>
<PossiblyNullArgument occurrences="2">
<code>$request-&gt;getParsedBody()['borg_backup_host_location']</code>
<code>$request-&gt;getParsedBody()['domain']</code>
</PossiblyNullArgument>
<PossiblyNullArrayAccess occurrences="4">
<code>$request-&gt;getParsedBody()['borg_backup_host_location']</code>
<code>$request-&gt;getParsedBody()['domain']</code>
<code>$request-&gt;getParsedBody()['clamav']</code>
<code>$request-&gt;getParsedBody()['options-form']</code>
</PossiblyNullArrayAccess>
</file>
<file src="src/Controller/DockerController.php">
<MissingParamType occurrences="7">
<code>$args</code>
<code>$args</code>
<code>$args</code>
<code>$args</code>
<code>$args</code>
<code>$args</code>
<code>$args</code>
</MissingParamType>
<PossiblyInvalidArrayAccess occurrences="1">
<code>$request-&gt;getParsedBody()['selected_restore_time']</code>
</PossiblyInvalidArrayAccess>
<PossiblyNullArrayAccess occurrences="1">
<code>$request-&gt;getParsedBody()['selected_restore_time']</code>
</PossiblyNullArrayAccess>
</file>
<file src="src/Controller/LoginController.php">
<MissingParamType occurrences="3">
<code>$args</code>
<code>$args</code>
<code>$args</code>
</MissingParamType>
<PossiblyInvalidArrayAccess occurrences="1">
<code>$request-&gt;getParsedBody()['password']</code>
</PossiblyInvalidArrayAccess>
<PossiblyNullArgument occurrences="1">
<code>$password</code>
</PossiblyNullArgument>
<PossiblyNullArrayAccess occurrences="1">
<code>$request-&gt;getParsedBody()['password']</code>
</PossiblyNullArrayAccess>
</file>
<file src="src/Docker/DockerActionManager.php">
<InvalidReturnType occurrences="1">
<code>IContainerState</code>
</InvalidReturnType>
<InvalidScalarArgument occurrences="1">
<code>$internalPort</code>
</InvalidScalarArgument>
<PossiblyFalseOperand occurrences="1">
<code>strpos($fullDigest, "@")</code>
</PossiblyFalseOperand>
<RedundantCondition occurrences="1">
<code>$container-&gt;GetInternalPorts() !== null</code>
</RedundantCondition>
</file>
<file src="src/Middleware/AuthMiddleware.php">
<UndefinedInterfaceMethod occurrences="1">
<code>withStatus</code>
</UndefinedInterfaceMethod>
</file>
<file src="src/Twig/ClassExtension.php">
<MissingParamType occurrences="1">
<code>$object</code>
</MissingParamType>
</file>
</files>

15
php/psalm.xml Normal file
View File

@@ -0,0 +1,15 @@
<?xml version="1.0"?>
<psalm
errorLevel="2"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config"
errorBaseline="psalm-baseline.xml"
>
<projectFiles>
<directory name="templates"/>
<directory name="src"/>
<file name="public/index.php"/>
</projectFiles>
</psalm>

View File

@@ -0,0 +1,13 @@
if (document.hasFocus()) {
// hide reload button if the site reloads automatically
var list = document.getElementsByClassName("reload button");
for (var i = 0; i < list.length; i++) {
// list[i] is a node with the desired class name
list[i].style.display = 'none';
}
// set timeout for reload
setTimeout(function(){
window.location.reload(1);
}, 5000);
}

View File

@@ -0,0 +1,5 @@
document.addEventListener("DOMContentLoaded", function(event) {
// Clamav
var clamav = document.getElementById("clamav");
clamav.disabled = true;
});

View File

@@ -22,11 +22,6 @@ ini_set('session.save_path', $dataConst->GetSessionDirectory());
// Auto logout on browser close
ini_set('session.cookie_lifetime', '0');
// Make sure to delete all stale sessions after at least one day
ini_set('session.gc_maxlifetime', '86400');
ini_set('session.gc_probability', '1');
ini_set('session.gc_divisor', '1');
// Create app
AppFactory::setContainer($container);
$app = AppFactory::create();
@@ -53,6 +48,7 @@ $app->add(new \AIO\Middleware\AuthMiddleware($container->get(\AIO\Auth\AuthManag
// API
$app->post('/api/docker/watchtower', AIO\Controller\DockerController::class . ':StartWatchtowerContainer');
$app->get('/api/docker/getwatchtower', AIO\Controller\DockerController::class . ':StartWatchtowerContainer');
$app->post('/api/docker/start', AIO\Controller\DockerController::class . ':StartContainer');
$app->post('/api/docker/backup', AIO\Controller\DockerController::class . ':StartBackupContainerBackup');
$app->post('/api/docker/backup-check', AIO\Controller\DockerController::class . ':StartBackupContainerCheck');
@@ -87,6 +83,10 @@ $app->get('/containers', function ($request, $response, $args) use ($container)
'was_start_button_clicked' => $configurationManager->wasStartButtonClicked(),
'has_update_available' => $dockerActionManger->isAnyUpdateAvailable(),
'last_backup_time' => $configurationManager->GetLastBackupTime(),
'backup_times' => $configurationManager->GetBackupTimes(),
'current_channel' => $dockerActionManger->GetCurrentChannel(),
'is_x64_platform' => $configurationManager->isx64Platform(),
'is_clamav_enabled' => $configurationManager->isClamavEnabled(),
]);
})->setName('profile');
$app->get('/login', function ($request, $response, $args) use ($container) {
@@ -141,4 +141,6 @@ $app->get('/', function (\Psr\Http\Message\RequestInterface $request, \Psr\Http\
}
});
$errorMiddleware = $app->addErrorMiddleware(true, true, true);
$app->run();

View File

@@ -0,0 +1,14 @@
function makeOptionsFormSubmitVisible() {
var optionsFormSubmit = document.getElementById("options-form-submit");
optionsFormSubmit.style.display = 'block';
}
document.addEventListener("DOMContentLoaded", function(event) {
// handle submit button for options form
var optionsFormSubmit = document.getElementById("options-form-submit");
optionsFormSubmit.style.display = 'none';
// Clamav
var clamav = document.getElementById("clamav");
clamav.addEventListener('change', makeOptionsFormSubmitVisible);
});

View File

@@ -136,7 +136,7 @@ input {
padding: 20px;
max-width: 100%;
word-break: break-word;
max-width: 450px;
max-width: 470px;
margin: 0 auto;
}

View File

@@ -91,6 +91,10 @@ class Container {
return $this->dockerActionManager->GetContainerRunningState($this);
}
public function GetRestartingState() : IContainerState {
return $this->dockerActionManager->GetContainerRestartingState($this);
}
public function GetUpdateState() : IContainerState {
return $this->dockerActionManager->GetContainerUpdateState($this);
}

View File

@@ -6,7 +6,7 @@ class ContainerVolumes {
/** @var ContainerVolume[] */
private array $volumes = [];
public function AddVolume(ContainerVolume $volume) {
public function AddVolume(ContainerVolume $volume) : void {
$this->volumes[] = $volume;
}

View File

@@ -0,0 +1,6 @@
<?php
namespace AIO\Container\State;
class NotRestartingState implements IContainerState
{}

View File

@@ -0,0 +1,6 @@
<?php
namespace AIO\Container\State;
class RestartingState implements IContainerState
{}

View File

@@ -27,7 +27,7 @@ class ContainerDefinitionFetcher
$this->container = $container;
}
public function GetContainerById(string $id): ?Container
public function GetContainerById(string $id): Container
{
$containers = $this->FetchDefinition();
@@ -37,7 +37,7 @@ class ContainerDefinitionFetcher
}
}
return null;
throw new \Exception("The provided id " . $id . " was not found in the container definition.");
}
/**
@@ -49,13 +49,25 @@ class ContainerDefinitionFetcher
$containers = [];
foreach ($data['production'] as $entry) {
if ($entry['identifier'] === 'nextcloud-aio-clamav') {
if (!$this->configurationManager->isClamavEnabled()) {
continue;
}
}
$ports = new ContainerPorts();
foreach ($entry['ports'] as $port) {
if($port === '%APACHE_PORT%/tcp') {
$port = $this->configurationManager->GetApachePort() . '/tcp';
}
$ports->AddPort($port);
}
$internalPorts = new ContainerInternalPorts();
foreach ($entry['internalPorts'] as $internalPort) {
if($internalPort === '%APACHE_PORT%') {
$internalPort = $this->configurationManager->GetApachePort();
}
$internalPorts->AddInternalPort($internalPort);
}
@@ -67,6 +79,23 @@ class ContainerDefinitionFetcher
continue;
}
}
if($value['name'] === '%NEXTCLOUD_MOUNT%') {
$value['name'] = $this->configurationManager->GetNextcloudMount();
if($value['name'] === '') {
continue;
}
} elseif ($value['name'] === '%NEXTCLOUD_DATADIR%') {
$value['name'] = $this->configurationManager->GetNextcloudDatadirMount();
if ($value['name'] === '') {
continue;
}
}
if($value['location'] === '%NEXTCLOUD_MOUNT%') {
$value['location'] = $this->configurationManager->GetNextcloudMount();
if($value['location'] === '') {
continue;
}
}
$volumes->AddVolume(
new ContainerVolume(
$value['name'],
@@ -76,6 +105,16 @@ class ContainerDefinitionFetcher
);
}
$dependsOn = [];
foreach ($entry['dependsOn'] as $value) {
if ($value === 'nextcloud-aio-clamav') {
if (!$this->configurationManager->isClamavEnabled()) {
continue;
}
}
$dependsOn[] = $value;
}
$variables = new ContainerEnvironmentVariables();
foreach ($entry['environmentVariables'] as $value) {
$variables->AddVariable($value);
@@ -91,7 +130,7 @@ class ContainerDefinitionFetcher
$internalPorts,
$volumes,
$variables,
$entry['dependsOn'],
$dependsOn,
$entry['secrets'],
$this->container->get(DockerActionManager::class)
);

View File

@@ -25,10 +25,24 @@ class ConfigurationController
$this->configurationManager->SetDomain($request->getParsedBody()['domain']);
}
if (isset($request->getParsedBody()['current-master-password']) || isset($request->getParsedBody()['new-master-password'])) {
$currentMasterPassword = $request->getParsedBody()['current-master-password'] ?? '';
$newMasterPassword = $request->getParsedBody()['new-master-password'] ?? '';
$this->configurationManager->ChangeMasterPassword($currentMasterPassword, $newMasterPassword);
}
if (isset($request->getParsedBody()['borg_backup_host_location'])) {
$this->configurationManager->SetBorgBackupHostLocation($request->getParsedBody()['borg_backup_host_location']);
}
if (isset($request->getParsedBody()['options-form'])) {
if (isset($request->getParsedBody()['clamav'])) {
$this->configurationManager->SetClamavEnabledState(1);
} else {
$this->configurationManager->SetClamavEnabledState(0);
}
}
return $response->withStatus(201)->withHeader('Location', '/');
} catch (InvalidSettingConfigurationException $ex) {
$response->getBody()->write($ex->getMessage());

View File

@@ -26,16 +26,26 @@ class DockerController
$this->configurationManager = $configurationManager;
}
private function PerformRecursiveContainerStart(string $id) {
private function PerformRecursiveContainerStart(string $id) : 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;
}
}
$this->dockerActionManager->DeleteContainer($container);
$this->dockerActionManager->CreateVolumes($container);
$this->dockerActionManager->PullContainer($container);
if ($pullcontainer) {
$this->dockerActionManager->PullContainer($container);
} else {
error_log('Not pulling the latest database image because the container was not correctly shut down.');
}
$this->dockerActionManager->CreateContainer($container);
$this->dockerActionManager->StartContainer($container);
$this->dockerActionManager->ConnectContainerToNetwork($container);
@@ -44,8 +54,12 @@ class DockerController
public function GetLogs(Request $request, Response $response, $args) : Response
{
$id = $request->getQueryParams()['id'];
$container = $this->containerDefinitionFetcher->GetContainerById($id);
$logs = $this->dockerActionManager->GetLogs($container);
if (str_starts_with($id, 'nextcloud-aio-')) {
$logs = $this->dockerActionManager->GetLogs($id);
} else {
$logs = 'Container not found.';
}
$body = $response->getBody();
$body->write($logs);
@@ -83,6 +97,7 @@ class DockerController
public function StartBackupContainerRestore(Request $request, Response $response, $args) : Response {
$config = $this->configurationManager->GetConfig();
$config['backup-mode'] = 'restore';
$config['selected-restore-time'] = $request->getParsedBody()['selected_restore_time'];
$this->configurationManager->WriteConfig($config);
$id = self::TOP_CONTAINER;
@@ -125,14 +140,15 @@ class DockerController
return $response->withStatus(201)->withHeader('Location', '/');
}
private function PerformRecursiveContainerStop(string $id)
private function PerformRecursiveContainerStop(string $id) : void
{
$container = $this->containerDefinitionFetcher->GetContainerById($id);
foreach($container->GetDependsOn() as $dependency) {
$this->PerformRecursiveContainerStop($dependency);
}
$this->dockerActionManager->DisconnectContainerFromNetwork($container);
// Disconnecting is not needed. This also allows to start the containers manually via docker-cli
//$this->dockerActionManager->DisconnectContainerFromNetwork($container);
$this->dockerActionManager->StopContainer($container);
}
@@ -144,28 +160,38 @@ class DockerController
return $response->withStatus(201)->withHeader('Location', '/');
}
public function StartDomaincheckContainer()
public function StartDomaincheckContainer() : void
{
# Don't start if domain is already set
if ($this->configurationManager->GetDomain() != '') {
if ($this->configurationManager->GetDomain() !== '' || $this->configurationManager->wasStartButtonClicked()) {
return;
}
$id = 'nextcloud-aio-domaincheck';
$container = $this->containerDefinitionFetcher->GetContainerById($id);
// don't start if the domaincheck is already running
if ($container->GetIdentifier() === $id && $container->GetRunningState() instanceof RunningState) {
return;
// don't start if apache is already running
} elseif ($container->GetIdentifier() === self::TOP_CONTAINER && $container->GetRunningState() instanceof RunningState) {
$cacheKey = 'domaincheckWasStarted';
$domaincheckContainer = $this->containerDefinitionFetcher->GetContainerById($id);
$apacheContainer = $this->containerDefinitionFetcher->GetContainerById(self::TOP_CONTAINER);
// Don't start if apache is already running
if ($apacheContainer->GetRunningState() instanceof RunningState) {
return;
// Don't start if domaincheck is already running
} elseif ($domaincheckContainer->GetRunningState() instanceof RunningState) {
$domaincheckWasStarted = apcu_fetch($cacheKey);
// Start domaincheck again when 10 minutes are over by not returning here
if($domaincheckWasStarted !== false && is_string($domaincheckWasStarted)) {
return;
}
}
$this->PerformRecursiveContainerStart($id);
// Cache the start for 10 minutes
apcu_add($cacheKey, '1', 600);
}
private function StopDomaincheckContainer()
private function StopDomaincheckContainer() : void
{
$id = 'nextcloud-aio-domaincheck';
$this->PerformRecursiveContainerStop($id);

View File

@@ -46,7 +46,7 @@ class ConfigurationManager
return $config['secrets'][$secretId];
}
private function DoubleSafeBackupSecret(string $borgBackupPassword) {
private function DoubleSafeBackupSecret(string $borgBackupPassword) : void {
file_put_contents(DataConst::GetBackupSecretFile(), $borgBackupPassword);
}
@@ -64,7 +64,7 @@ class ConfigurationManager
}
$content = file_get_contents(DataConst::GetBackupArchivesList());
if ($content === "") {
if ($content === '') {
return '';
}
@@ -83,6 +83,31 @@ class ConfigurationManager
return $lastBackupTime;
}
public function GetBackupTimes() : array {
if (!file_exists(DataConst::GetBackupArchivesList())) {
return [];
}
$content = file_get_contents(DataConst::GetBackupArchivesList());
if ($content === '') {
return [];
}
$backupLines = explode("\n", $content);
$backupTimes = [];
foreach($backupLines as $lines) {
if ($lines !== "") {
$backupTimesTemp = explode(',', $lines);
$backupTimes[] = $backupTimesTemp[1];
}
}
// Reverse the array to list newest backup first
$backupTimes = array_reverse($backupTimes);
return $backupTimes;
}
public function wasStartButtonClicked() : bool {
if (isset($this->GetConfig()['wasStartButtonClicked'])) {
return true;
@@ -91,15 +116,43 @@ class ConfigurationManager
}
}
public function isx64Platform() : bool {
if (php_uname('m') === 'x86_64') {
return true;
} else {
return false;
}
}
public function isClamavEnabled() : bool {
$config = $this->GetConfig();
if (isset($config['isClamavEnabled']) && $config['isClamavEnabled'] === 1) {
return true;
} else {
return false;
}
}
public function SetClamavEnabledState(int $value) : void {
$config = $this->GetConfig();
$config['isClamavEnabled'] = $value;
$this->WriteConfig($config);
}
/**
* @throws InvalidSettingConfigurationException
*/
public function SetDomain(string $domain) : void {
// Validate URL
if (!filter_var('http://' . $domain, FILTER_VALIDATE_URL)) {
// Validate domain
if (!filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) {
throw new InvalidSettingConfigurationException("Domain is not in a valid format!");
}
// Validate that it is not an IP-address
if(filter_var($domain, FILTER_VALIDATE_IP)) {
throw new InvalidSettingConfigurationException("Please enter a domain and not an IP-address!");
}
$dnsRecordIP = gethostbyname($domain);
// Validate IP
@@ -117,15 +170,23 @@ class ConfigurationManager
// Get Instance ID
$instanceID = $this->GetSecret('INSTANCE_ID');
// set protocol
$port = $this->GetApachePort();
if ($port !== '443') {
$protocol = 'https://';
} else {
$protocol = 'http://';
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,'http://' . $domain . ':443');
curl_setopt($ch, CURLOPT_URL, $protocol . $domain . ':443');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$response = (string)curl_exec($ch);
# Get rid of trailing \n
$response = str_replace("\n", "", $response);
if($response !== $instanceID) {
throw new InvalidSettingConfigurationException("Domain does not point to this server.");
throw new InvalidSettingConfigurationException("Domain does not point to this server or reverse proxy not configured correctly.");
}
// Write domain
@@ -152,6 +213,15 @@ class ConfigurationManager
return $config['backup-mode'];
}
public function GetSelectedRestoreTime() : string {
$config = $this->GetConfig();
if(!isset($config['selected-restore-time'])) {
$config['selected-restore-time'] = '';
}
return $config['selected-restore-time'];
}
public function GetAIOURL() : string {
$config = $this->GetConfig();
if(!isset($config['AIO_URL'])) {
@@ -192,6 +262,41 @@ class ConfigurationManager
$this->WriteConfig($config);
}
/**
* @throws InvalidSettingConfigurationException
*/
public function ChangeMasterPassword(string $currentPassword, string $newPassword) : void {
if ($currentPassword === '') {
throw new InvalidSettingConfigurationException("Please enter your current password.");
}
if ($currentPassword !== $this->GetPassword()) {
throw new InvalidSettingConfigurationException("The entered current password is not correct.");
}
if ($newPassword === '') {
throw new InvalidSettingConfigurationException("Please enter a new password.");
}
if (strlen($newPassword) < 24) {
throw new InvalidSettingConfigurationException("New passwords must be >= 24 digits.");
}
if (!preg_match("#^[a-zA-Z0-9 ]+$#", $newPassword)) {
throw new InvalidSettingConfigurationException('Not allowed characters in the new password.');
}
// All checks pass so set the password
$this->SetPassword($newPassword);
}
public function GetApachePort() : string {
$envVariableName = 'APACHE_PORT';
$configName = 'apache_port';
$defaultValue = '443';
return $this->GetEnvironmentalVariableOrConfig($envVariableName, $configName, $defaultValue);
}
/**
* @throws InvalidSettingConfigurationException
*/
@@ -202,6 +307,28 @@ class ConfigurationManager
file_put_contents(DataConst::GetConfigFile(), json_encode($config));
}
private function GetEnvironmentalVariableOrConfig(string $envVariableName, string $configName, string $defaultValue) : string {
$envVariableOutput = getenv($envVariableName);
if ($envVariableOutput === false) {
$config = $this->GetConfig();
if (!isset($config[$configName]) || $config[$configName] === '') {
$config[$configName] = $defaultValue;
}
return $config[$configName];
}
if(file_exists(DataConst::GetConfigFile())) {
$config = $this->GetConfig();
if (!isset($config[$configName])) {
$config[$configName] = '';
}
if ($envVariableOutput !== $config[$configName]) {
$config[$configName] = $envVariableOutput;
$this->WriteConfig($config);
}
}
return $envVariableOutput;
}
public function GetBorgBackupHostLocation() : string {
$config = $this->GetConfig();
if(!isset($config['borg_backup_host_location'])) {
@@ -219,4 +346,18 @@ class ConfigurationManager
return $config['backup-mode'];
}
public function GetNextcloudMount() : string {
$envVariableName = 'NEXTCLOUD_MOUNT';
$configName = 'nextcloud_mount';
$defaultValue = '';
return $this->GetEnvironmentalVariableOrConfig($envVariableName, $configName, $defaultValue);
}
public function GetNextcloudDatadirMount() : string {
$envVariableName = 'NEXTCLOUD_DATADIR';
$configName = 'nextcloud_datadir';
$defaultValue = 'nextcloud_aio_nextcloud_data';
return $this->GetEnvironmentalVariableOrConfig($envVariableName, $configName, $defaultValue);
}
}

View File

@@ -7,6 +7,8 @@ use AIO\Container\State\IContainerState;
use AIO\Container\State\ImageDoesNotExistState;
use AIO\Container\State\StartingState;
use AIO\Container\State\RunningState;
use AIO\Container\State\RestartingState;
use AIO\Container\State\NotRestartingState;
use AIO\Container\State\VersionDifferentState;
use AIO\Container\State\StoppedState;
use AIO\Container\State\VersionEqualState;
@@ -70,6 +72,27 @@ class DockerActionManager
}
}
public function GetContainerRestartingState(Container $container) : IContainerState
{
$url = $this->BuildApiUrl(sprintf('containers/%s/json', urlencode($container->GetIdentifier())));
try {
$response = $this->guzzleClient->get($url);
} catch (RequestException $e) {
if ($e->getCode() === 404) {
return new ImageDoesNotExistState();
}
throw $e;
}
$responseBody = json_decode((string)$response->getBody(), true);
if ($responseBody['State']['Restarting'] === true) {
return new RestartingState();
} else {
return new NotRestartingState();
}
}
public function GetContainerUpdateState(Container $container) : IContainerState
{
$tag = $this->GetCurrentChannel();
@@ -77,7 +100,7 @@ class DockerActionManager
$runningDigest = $this->GetRepoDigestOfContainer($container->GetIdentifier());
$remoteDigest = $this->dockerHubManager->GetLatestDigestOfTag($container->GetContainerName(), $tag);
if ($runningDigest === $remoteDigest) {
if ($runningDigest === $remoteDigest || $remoteDigest === null || $runningDigest === null) {
return new VersionEqualState();
} else {
return new VersionDifferentState();
@@ -109,7 +132,7 @@ class DockerActionManager
}
}
public function DeleteContainer(Container $container) {
public function DeleteContainer(Container $container) : void {
$url = $this->BuildApiUrl(sprintf('containers/%s?v=true', urlencode($container->GetIdentifier())));
try {
$this->guzzleClient->delete($url);
@@ -120,12 +143,12 @@ class DockerActionManager
}
}
public function GetLogs(Container $container) : string
public function GetLogs(string $id) : string
{
$url = $this->BuildApiUrl(
sprintf(
'containers/%s/logs?stdout=true&stderr=true',
urlencode($container->GetIdentifier())
urlencode($id)
));
$responseBody = (string)$this->guzzleClient->get($url)->getBody();
@@ -142,12 +165,12 @@ class DockerActionManager
return $response;
}
public function StartContainer(Container $container) {
public function StartContainer(Container $container) : void {
$url = $this->BuildApiUrl(sprintf('containers/%s/start', urlencode($container->GetIdentifier())));
$this->guzzleClient->post($url);
}
public function CreateVolumes(Container $container)
public function CreateVolumes(Container $container): void
{
$url = $this->BuildApiUrl('volumes/create');
foreach($container->GetVolumes()->GetVolumes() as $volume) {
@@ -170,7 +193,7 @@ class DockerActionManager
}
}
public function CreateContainer(Container $container) {
public function CreateContainer(Container $container) : void {
$volumes = [];
foreach($container->GetVolumes()->GetVolumes() as $volume) {
$volumeEntry = $volume->name . ':' . $volume->mountPoint;
@@ -212,6 +235,18 @@ class DockerActionManager
$replacements[1] = $this->configurationManager->GetBackupMode();
} elseif ($out[1] === 'AIO_URL') {
$replacements[1] = $this->configurationManager->GetAIOURL();
} elseif ($out[1] === 'SELECTED_RESTORE_TIME') {
$replacements[1] = $this->configurationManager->GetSelectedRestoreTime();
} elseif ($out[1] === 'APACHE_PORT') {
$replacements[1] = $this->configurationManager->GetApachePort();
} elseif ($out[1] === 'NEXTCLOUD_MOUNT') {
$replacements[1] = $this->configurationManager->GetNextcloudMount();
} elseif ($out[1] === 'CLAMAV_ENABLED') {
if ($this->configurationManager->isClamavEnabled()) {
$replacements[1] = 'yes';
} else {
$replacements[1] = '';
}
} else {
$replacements[1] = $this->configurationManager->GetSecret($out[1]);
}
@@ -246,22 +281,30 @@ class DockerActionManager
}
$url = $this->BuildApiUrl('containers/create?name=' . $container->GetIdentifier());
$this->guzzleClient->request(
'POST',
$url,
[
'json' => $requestBody
]
);
try {
$this->guzzleClient->request(
'POST',
$url,
[
'json' => $requestBody
]
);
} catch (RequestException $e) {
throw $e;
}
}
public function PullContainer(Container $container)
public function PullContainer(Container $container) : void
{
$url = $this->BuildApiUrl(sprintf('images/create?fromImage=%s', urlencode($this->BuildImageName($container))));
try {
$this->guzzleClient->post($url);
} catch (RequestException $e) {
throw $e;
error_log('Could not get image ' . $this->BuildImageName($container) . ' from docker hub. Probably due to rate limits. ' . $e->getMessage());
// Don't exit here because it is possible that the image is already present
// and we ran into docker hub limits.
// We will exit later if not image should be available.
}
}
@@ -279,10 +322,9 @@ class DockerActionManager
return $updateAvailable;
}
public function isAnyUpdateAvailable() {
public function isAnyUpdateAvailable() : bool {
$id = 'nextcloud-aio-apache';
if ($this->isContainerUpdateAvailable($id) !== "") {
return true;
} else {
@@ -307,6 +349,7 @@ class DockerActionManager
return null;
} catch (\Exception $e) {
error_log('Could not get digest of container ' . $this->BuildApiUrl($containerName) . ' ' . $e->getMessage());
return null;
}
}
@@ -328,6 +371,7 @@ class DockerActionManager
apcu_add($cacheKey, $tag);
return $tag;
} catch (\Exception $e) {
error_log('Could not get current channel ' . $e->getMessage());
}
return 'latest';
@@ -343,14 +387,14 @@ class DockerActionManager
$runningDigest = $this->GetRepoDigestOfContainer($containerName);
$remoteDigest = $this->dockerHubManager->GetLatestDigestOfTag($imageName, $tag);
if ($remoteDigest === $runningDigest) {
if ($remoteDigest === $runningDigest || $remoteDigest === null || $runningDigest === null) {
return false;
} else {
return true;
}
}
public function sendNotification(Container $container, string $subject, string $message)
public function sendNotification(Container $container, string $subject, string $message) : void
{
if ($this->GetContainerStartingState($container) instanceof RunningState) {
@@ -396,7 +440,7 @@ class DockerActionManager
}
}
public function DisconnectContainerFromNetwork(Container $container)
public function DisconnectContainerFromNetwork(Container $container) : void
{
$url = $this->BuildApiUrl(
@@ -414,10 +458,11 @@ class DockerActionManager
]
);
} catch (RequestException $e) {
error_log('Could not disconnect container from network ' . $e->getMessage());
}
}
private function ConnectContainerIdToNetwork(string $id)
private function ConnectContainerIdToNetwork(string $id) : void
{
$url = $this->BuildApiUrl('networks/create');
try {
@@ -460,17 +505,17 @@ class DockerActionManager
}
}
public function ConnectMasterContainerToNetwork()
public function ConnectMasterContainerToNetwork() : void
{
$this->ConnectContainerIdToNetwork('nextcloud-aio-mastercontainer');
}
public function ConnectContainerToNetwork(Container $container)
public function ConnectContainerToNetwork(Container $container) : void
{
$this->ConnectContainerIdToNetwork($container->GetIdentifier());
}
public function StopContainer(Container $container) {
public function StopContainer(Container $container) : void {
$url = $this->BuildApiUrl(sprintf('containers/%s/stop?t=%s', urlencode($container->GetIdentifier()), $container->GetMaxShutdownTime()));
try {
$this->guzzleClient->post($url);
@@ -504,6 +549,29 @@ class DockerActionManager
}
}
public function GetDatabasecontainerExitCode() : int
{
$containerName = 'nextcloud-aio-database';
$url = $this->BuildApiUrl(sprintf('containers/%s/json', urlencode($containerName)));
try {
$response = $this->guzzleClient->get($url);
} catch (RequestException $e) {
if ($e->getCode() === 404) {
return -1;
}
throw $e;
}
$responseBody = json_decode((string)$response->getBody(), true);
$exitCode = $responseBody['State']['ExitCode'];
if (is_int($exitCode)) {
return $exitCode;
} else {
return -1;
}
}
public function isLoginAllowed() : bool {
$id = 'nextcloud-aio-apache';
$apacheContainer = $this->containerDefinitionFetcher->GetContainerById($id);

View File

@@ -23,6 +23,8 @@ class DockerHubManager
return $cachedVersion;
}
// If one of the links below should ever become outdated, we can still upgrade the mastercontainer via the webinterface manually by opening '/api/docker/getwatchtower'
try {
$authTokenRequest = $this->guzzleClient->request(
'GET',

View File

@@ -16,10 +16,11 @@
</header>
<div class="content">
<h1>Nextcloud AIO Beta v0.3.0</h1>
<h1>Nextcloud AIO Beta v0.8.0</h1>
This is beta software and not production ready.<br><br>
{% set isAnyRunning = false %}
{% set isAnyRestarting = false %}
{% set isWatchtowerRunning = false %}
{% set isBackupContainerRunning = false %}
{% set isRestoreRunning = false %}
@@ -27,9 +28,12 @@
{% set isApacheStarting = false %}
{% for container in containers %}
{% if class(container.GetRunningState()) == 'AIO\\Container\\State\\RunningState' and container.GetIdentifier() != 'nextcloud-aio-domaincheck' and container.GetIdentifier() != 'nextcloud-aio-borgbackup' and container.GetIdentifier() != 'nextcloud-aio-watchtower' %}
{% 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 %}
{% endif %}
{% if container.GetIdentifier() in ['nextcloud-aio-redis', 'nextcloud-aio-database', 'nextcloud-aio-nextcloud', 'nextcloud-aio-apache'] and class(container.GetRestartingState()) == 'AIO\\Container\\State\\RestartingState' %}
{% set isAnyRestarting = true %}
{% endif %}
{% if container.GetIdentifier() == 'nextcloud-aio-watchtower' and class(container.GetRunningState()) == 'AIO\\Container\\State\\RunningState' %}
{% set isWatchtowerRunning = true %}
{% endif %}
@@ -48,19 +52,29 @@
{% endfor %}
{% if isWatchtowerRunning == true %}
Mastercontainer updpate currently running. It will restart the mastercontainer soon which will make it unavailable for a moment. Please wait until thats done.<br /><br />
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 />
<a href="" class="button reload">Reload ↻</a><br/>
{% else %}
{% if isBackupOrRestoreRunning == false and domain == "" %}
Please type in the domain that will be used for Nextcloud:<br><br />
<form method="POST" action="/api/configuration" class="xhr">
<input type="text" name="domain" value="{{ domain }}" placeholder="nextcloud.yourdomain.com"/>
<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>
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.
{% 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>
<form method="POST" action="/api/docker/watchtower" class="xhr">
<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="Update mastercontainer" />
</form>
{% else %}
Please type in the domain that will be used for Nextcloud:<br><br />
<form method="POST" action="/api/configuration" class="xhr">
<input type="text" name="domain" value="{{ domain }}" placeholder="nextcloud.yourdomain.com"/>
<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>
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.
{% endif %}
{% endif %}
{% if domain != "" %}
@@ -71,8 +85,18 @@
Initial Nextcloud password: {{ nextcloud_password }}<br /><br/>
<a href="https://{{ domain }}" class="button" target="_blank" rel="noopener">Open your Nextcloud ↗</a><br/>
{% else %}
Containers are currently starting.<br /><br />
<a href="" class="button reload">Reload ↻</a><br/>
{% if isAnyRestarting == false %}
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>
To break out this endless loop, you can stop the containers below and investigate the issue by having a look at the container logs before starting them again.<br><br>
<form method="POST" action="/api/docker/stop" class="xhr">
<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="Stop containers" />
</form>
{% endif %}
{% endif %}
{% endif %}
@@ -81,7 +105,7 @@
<ul>
{# @var containers \AIO\Container\Container[] #}
{% for container in containers %}
{% if container.GetIdentifier() != 'nextcloud-aio-borgbackup' and container.GetIdentifier() != 'nextcloud-aio-watchtower' and container.GetIdentifier() != 'nextcloud-aio-domaincheck' %}
{% if container.GetIdentifier() not in ['nextcloud-aio-borgbackup', 'nextcloud-aio-watchtower', 'nextcloud-aio-domaincheck'] %}
<li>
{% if class(container.GetStartingState()) == 'AIO\\Container\\State\\StartingState' %}
<span class="status running"></span>
@@ -99,18 +123,21 @@
</ul>
{% if has_update_available == true %}
⚠ Container updates are available. Click on `Stop Containers` and `Start Containers` to update them. You should consider creating a backup first. The mastercontainer gets updated with a different procedure though and has its own update button which is visible if an update is available.<br><br>
{% if is_mastercontainer_update_available == false %}
⚠ Container updates are available. Click on 'Stop Containers' and 'Start Containers' to update them. You should consider creating a backup first.<br><br>
{% endif %}
{% else %}
{% if is_mastercontainer_update_available == false %}
Your containers are up-to-date.<br><br>
{% else %}
Your containers are up-to-date. (Except the mastercontainer. See the section below.)<br><br>
{% endif %}
{% endif %}
{% endif %}
{% if isAnyRunning == true %}
{% if isApacheStarting != true %}
{% if is_mastercontainer_update_available == true %}
⚠ A mastercontainer update is available. Please click on the button below to stop your containers in order to be able to update the mastercontainer.<br /><br />
{% endif %}
<form method="POST" action="/api/docker/stop" class="xhr">
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
@@ -126,37 +153,27 @@
{% if was_start_button_clicked == false %}
Clicking on the button below will download all docker containers and start them. This can take a lot of time depending on your internect connection. Since the overall size is a few GB, this will take around 5-10 min or more. So be aware and patient!<br><br>
{% endif %}
{% if was_start_button_clicked == false or has_update_available == false %}
<form method="POST" action="/api/docker/start" class="xhr">
<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="Start containers" />
</form>
{% if is_mastercontainer_update_available == true %}
⚠ Please update your mastercontainer. (The update button is in the Mastercontainer section below the Backup section. Click <a href="#mastercontainer"><b>here</b><a/> to go there.) Afterwards, you will be able to start your containers again.<br><br>
{% else %}
<form method="POST" action="/api/docker/start" class="xhr">
<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="Start and update containers" onclick="return confirm('Start and update containers? You should consider creating a backup first.')" />
</form>
{% if was_start_button_clicked == false or has_update_available == false %}
<form method="POST" action="/api/docker/start" class="xhr">
<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="Start containers" />
</form>
{% else %}
<form method="POST" action="/api/docker/start" class="xhr">
<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="Start and update containers" onclick="return confirm('Start and update containers? You should consider creating a backup first.')" />
</form>
{% endif %}
{% endif %}
{% endif %}
{% endif %}
{% if is_mastercontainer_update_available == true %}
{% if isBackupOrRestoreRunning == false %}
<h2>Mastercontainer update</h2>
⚠ A mastercontainer update is available. Please click on the button below to update it. All other containers get updated independently from the mastercontainer by simply clicking on `Stop containers` and clicking on `Start containers` if a new update is available.<br><br>
<form method="POST" action="/api/docker/watchtower" class="xhr">
<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="Update mastercontainer" />
</form>
{% endif %}
{% endif %}
{% if was_start_button_clicked == true %}
{% if isBackupOrRestoreRunning == false and borg_backup_host_location == "" and isApacheStarting != true %}
<h2>Backup and restore</h2>
@@ -185,13 +202,17 @@
{% endif %}
{% if isBackupContainerRunning == false %}
<h3>Backup information</h3>
This is your encryption password for backups: {{ borgbackup_password }} <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/>
Be aware that this solution does not back up files and folders that are mounted into Nextcloud using the external storage app. <br /><br/>
{% if isApacheStarting != true %}
<h3>Backup creation</h3>
Clicking on the button below will create a backup.<br><br/>
<form method="POST" action="/api/docker/backup" class="xhr">
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
@@ -199,6 +220,7 @@
</form>
{% if has_backup_run_once == true %}
<h3>Backup check</h3>
Click on the button below to perform a backup integrity check. This is an option that verifies that your backup is intact but it should't be needed in most situtations.<br><br/>
<form method="POST" action="/api/docker/backup-check" class="xhr">
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
@@ -206,11 +228,17 @@
<input class="button" type="submit" value="Check backup integrity" onclick="return confirm('Check backup integrity? Are you sure that you want to check the backup? This can take a long time depending on the size of your backup.')" /><br/>
</form>
Click on the button below to restore the last backup from {{ last_backup_time }}. This will overwrite all your files with the state of the backup. It makes sense to run an integrity check before restoring your files but is not mandatory since it shouldn't be needed in most situations.<br><br>
<form method="POST" action="/api/docker/restore" class="xhr">
<h3>Backup restore</h3>
Choose the backup that you want to restore and click on the button below to restore the selected backup. This will overwrite all your files with the state of the backup so you should consider creating a backup first. It also makes sense to run an integrity check before restoring your files but is not mandatory since it shouldn't be needed in most situations.<br><br>
<form method="POST" action="/api/docker/restore" class="xhr" id="restore_selection">
<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="Restore last backup" onclick="return confirm('Restore last backup? Are you sure that you want to restore the last backup? This will stop all running containers and restore the last backup from {{ last_backup_time }}. You might want to check the backup integrity first.')" />
<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>
{% 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>
{% endif %}
{% endif %}
@@ -220,26 +248,68 @@
<a href="" class="button reload">Reload ↻</a><br/>
{% endif %}
{% endif %}
{% if isBackupContainerRunning == false %}
<h2 id="mastercontainer">Mastercontainer</h2>
You are currently running the {{ current_channel }} channel. (<a href="/api/docker/logs?id=nextcloud-aio-mastercontainer">Logs</a>)<br><br>
{% if is_mastercontainer_update_available == true %}
{% if isAnyRunning == false %}
⚠ A mastercontainer update is available. Please click on the button below to update it.<br><br>
<form method="POST" action="/api/docker/watchtower" class="xhr">
<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="Update mastercontainer" />
</form>
{% else %}
⚠ A mastercontainer update is available. Please stop your containers in order to be able to update the mastercontainer.<br><br>
{% endif %}
{% if current_channel starts with 'latest' %}
You can find the changelog <a href="https://github.com/nextcloud/all-in-one/releases/latest">here</a><br><br>
{% elseif current_channel starts with 'beta' %}
You can find the changelog <a href="https://github.com/nextcloud/all-in-one/releases">here</a><br><br>
{% elseif current_channel starts with 'develop' %}
You can find all changes <a href="https://github.com/nextcloud-releases/all-in-one/commits/main">here</a><br><br>
{% endif %}
{% endif %}
{% if isApacheStarting == false %}
<h3>AIO password change</h3>
You can change your AIO password below:<br><br />
<form method="POST" action="/api/configuration" class="xhr">
<input type="text" autocomplete="current-password" name="current-master-password" placeholder="your current aio password"/>
<input type="text" autocomplete="new-password" name="new-master-password" placeholder="your new aio password"/>
<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>
The new password needs to be at least 24 characters long. Allowed characters are the <a href="https://en.wikipedia.org/wiki/Latin_alphabet#/media/File:Abecedarium.png">latin characters</a> 'a-z', 'A-Z', '0-9' and spaces.<br><br>
{% endif %}
{% endif %}
{% endif %}
{% if isBackupContainerRunning == false %}
<h2>Optional</h2>
In this section, you can find optional addons.<br><br>
You can change the state of 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}}">
<input type="hidden" name="options-form" value="options-form">
{% if is_clamav_enabled == true %}
<input type="checkbox" id="clamav" name="clamav" checked="checked"><label for="clamav">ClamAV (only supported on x64, needs ~2GB additional RAM)</label>
{% else %}
<input type="checkbox" id="clamav" name="clamav"><label for="clamav">ClamAV (only supported on x64, needs ~2GB additional RAM)</label>
{% endif %}
<input id="options-form-submit" class="button" type="submit" value="Save changes" />
</form>
{% if isAnyRunning == true or is_x64_platform == false %}
<script type="text/javascript" src="disable-clamav.js"></script>
{% endif %}
{% endif %}
{% endif %}
{% endif %}
{% if isApacheStarting == true or isBackupContainerRunning == true or isWatchtowerRunning == true %}
<script>
if (document.hasFocus()) {
// hide reload button if the site reloads automatically
var list = document.getElementsByClassName("reload button");
for (var i = 0; i < list.length; i++) {
// list[i] is a node with the desired class name
list[i].style.display = 'none';
}
// set timeout for reload
setTimeout(function(){
window.location.reload(1);
}, 5000);
}
</script>
<script type="text/javascript" src="automatic_reload.js"></script>
{% endif %}
</div>

View File

@@ -4,6 +4,7 @@
<link rel="stylesheet" href="/style.css" media="all" />
<link rel="icon" href="/img/favicon.png">
<script type="text/javascript" src="forms.js"></script>
<script type="text/javascript" src="options-form-submit.js"></script>
</head>
<body>

162
readme.md
View File

@@ -66,29 +66,29 @@ Included are:
</details>
4. After the initial startup, you should be able to open the Nextcloud AIO Interface now on port 8080 of this server.<br>
E.g. https://internal.ip.of.this.server:8080<br>
E.g. `https://internal.ip.of.this.server:8080`<br>
If your server has port 80 and 8443 open and you point a domain to your server, you can get a valid certificate automatially by opening the Nextcloud AIO Interface via:<br>
https://your-domain-that-points-to-this-server.tld:8443
`https://your-domain-that-points-to-this-server.tld:8443`
5. Please do not forget to open port `3478/TCP` and `3478/UDP` for the Talk container!
## FAQ
### How does it work?
Nextcloud AIO is inspired by projects like Portainer that allow to manage the docker daemon by talking to the docker socket directly. This concept allows to install only one container with a single command that does the heavy lifting of creating and managing all containers that are needed in order to provide a Nextcloud installation with most features included. It also makes updating a breeze and is not bound to the host system (and its slow updates) anymore as everything is in containers. Additionally, it is very easy to handle from a user perspective because a simple interface for managing your Nextcloud AIO installation is provided.
### Are reverse proxies supported?
Reverse proxies are currently because of the above mentioned architecture not supported.<br>
You might investigate yourself though how it could made work behind reverse proxies. If you open a PR with that we might consider it then :)
Yes. Please refer to the following documentation on this: [reverse-proxy.md](https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md)
### Which ports are mandatory to be open?
Only those (if you acces the Mastercontainer Interface internally via port 8080):
- `443/TCP` for the Nextcloud container
- `3478/TCP` and `3478/UPD` for the Talk container
- `443/TCP` for the Apache container
- `3478/TCP` and `3478/UDP` for the Talk container
### Explanation of used ports:
- `8080/TCP`: Mastercontainer Interface with self-signed certificate (works always, also if only access via IP-address is possible, e.g. `https://internal.ip.address:8080/`)
- `80/TCP`: redirects to Nextcloud (is used for getting the certificate via ACME http-challenge for the Mastercontainer)
- `8443/TCP`: Mastercontainer Interface with valid certificate (only works if port 80 and 8443 are open and you point a domain to your server. It generates a valid certificate then automatically and access via e.g. `https://public.domain.com:8443/` is possible.)
- `443/TCP`: will be used by the Nextcloud container later on and needs to be open
- `3478/TCP` and `3478/UPD`: will be used by the Turnserver inside the Talk container and needs to be open
- `443/TCP`: will be used by the Apache container later on and needs to be open
- `3478/TCP` and `3478/UDP`: will be used by the Turnserver inside the Talk container and needs to be open
### How to run `occ` commands?
Simply run the following: `sudo docker exec -it nextcloud-aio-nextcloud php occ your-command`. Of course `your-command` needs to be exchanged with the command that you want to run.
@@ -104,7 +104,7 @@ If a new `Mastercontainer` update was found, you'll see an additional section be
Additionally, there is a cronjob that runs once a day that checks for container and mastercontainer updates and sends a notification to all Nextcloud admins if a new update was found.
### How to easily log in to the AIO interface?
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.
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.
@@ -113,11 +113,148 @@ It is recommended to create a backup before any container update. By doing this,
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.
Backups can be created and restored in the AIO interface using the buttons `Create Backup` and `Restore last backup`. Additionally, a backup check is provided that checks the integrity of your backups but it shouldn't be needed in most situations.
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.
Note that this implementation does not provide remote backups, for this you can use the [backup app](https://apps.nextcloud.com/apps/backup).
Be aware that this solution does not back up files and folders that are mounted into Nextcloud using the external storage app.
Note that this implementation does not provide remote backups, for this you can use the [backup app](https://apps.nextcloud.com/apps/backup).
---
#### Failure of the backup container in LXC containers
If you are running AIO in a LXC container, you need to make sure that FUSE is enabled in the LXC container settings. Otherwise the backup container will not be able to start as FUSE is required for it to work.
---
#### Pro-tip: Backup archives access
You can open the BorgBackup archives on your host by following these steps:<br>
(instructions for Ubuntu Desktop)
```bash
# Install borgbackup on the host
sudo apt update && sudo apt install borgbackup
# Mount the archives to /tmp/borg (if you are using the default backup location /mnt/backup/borg)
sudo mkdir -p /tmp/borg && sudo borg mount "/mnt/backup/borg" /tmp/borg
# After entering your repository key successfully, you should be able to access all archives in /tmp/borg
# You can now do whatever you want by syncing them to a different place using rsync or doing other things
# E.g. you can open the file manager on that location by running:
xhost +si:localuser:root && sudo nautilus /tmp/borg
# When you are done, simply close the file manager and run the following command to unmount the backup archives:
sudo umount /tmp/borg
```
---
#### Delete backup archives manually
You can delete BorgBackup archives on your host manually by following these steps:<br>
(instructions for Debian based OS' like Ubuntu)
```bash
# Install borgbackup on the host
sudo apt update && sudo apt install borgbackup
# List all archives (if you are using the default backup location /mnt/backup/borg)
sudo borg list "/mnt/backup/borg"
# After entering your repository key successfully, you should now see a list of all backup archives
# An example backup archive might be called 20220223_174237-nextcloud-aio
# Then you can simply delete the archive with:
sudo borg delete --stats --progress "/mnt/backup/borg::20220223_174237-nextcloud-aio"
```
After doing so, make sure to update the backup archives list in the AIO interface!<br>
You can do so by clicking on the `Check backup integrity` button or `Create backup` button.
---
#### Sync the backup regularly to another drive
For increased backup security, you might consider syncing the backup repository regularly to another drive.
To do that, first add the drive to `/etc/fstab` so that it is able to get automatically mounted and then create a script that does all the things automatically. Here is an example for such a script:
<details>
<summary>Click here to expand</summary>
```bash
#!/bin/bash
# Please modify all variables below to your needings:
SOURCE_DIRECTORY="/mnt/backup/borg"
DRIVE_MOUNTPOINT="/mnt/backup-drive"
TARGET_DIRECTORY="/mnt/backup-drive/borg"
########################################
# Please do NOT modify anything below! #
########################################
if [ "$EUID" -ne 0 ]; then
echo "Please run as root"
exit 1
fi
if ! [ -d "$SOURCE_DIRECTORY" ]; then
echo "The source directory does not exist."
exit 1
fi
if ! [ -d "$DRIVE_MOUNTPOINT" ]; then
echo "The drive mountpoint must be an existing directory"
exit 1
fi
if ! grep -q " $DRIVE_MOUNTPOINT " /etc/fstab; then
echo "Could not find the drive mountpoint in the fstab file. Did you add it there?"
exit 1
fi
if ! mountpoint -q "$DRIVE_MOUNTPOINT"; then
mount "$DRIVE_MOUNTPOINT"
if ! mountpoint -q "$DRIVE_MOUNTPOINT"; then
echo "Could not mount the drive. Is it connected?"
exit 1
fi
fi
if [ -f "$SOURCE_DIRECTORY/lock.roster" ]; then
echo "Cannot run the script as the backup archive is currently changed. Please try again later."
exit 1
fi
mkdir -p "$TARGET_DIRECTORY"
if ! [ -d "$TARGET_DIRECTORY" ]; then
echo "Could not create target directory"
exit 1
fi
if ! rsync --stats --archive --human-readable --delete "$SOURCE_DIRECTORY/" "$TARGET_DIRECTORY"; then
echo "Failed to sync the backup repository to the target directory."
exit 1
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
fi
echo "Synced the backup repository successfully and unmounted the target drive."
exit 0
```
</details>
You can simply copy and past the script into a file e.g. named `backup-script.sh` e.g. here: `/root/backup-script.sh`. Do not forget to modify the variables to your needings though!
Afterwards apply the correct permissions with `sudo chown root:root /root/backup-script.sh` and `sudo chmod 700 /root/backup-script.sh`. Then you can create a cronjob that runs e.g. at `20:00` each week on sundays like this: `crontab -u root -l | { cat; echo "0 20 * * 7 /root/backup-script.sh"; } | crontab -u root -`. Make sure that it does not collidate with the daily backups from AIO (if configured) since the target backup repository might get into an inconsistent state. (There is no check in place that checks this.)
### How to change the default location of Nextcloud's Datadir?
You can configure the Nextcloud container to use a specific directory on your host as data directory. You can do so by adding the environmental variable `NEXTCLOUD_DATADIR` to the initial startup of the mastercontainer. Allowed values for that variable are strings that start with `/mnt/` or `/media/`. An example for this is `-e NEXTCLOUD_DATADIR="/mnt/ncdata"`. Please make sure to apply the correct permissions to the chosen directory before starting Nextcloud the first time. In this example would the command for this be: `sudo chown -R 33:0 /mnt/ncdata`. **Attention:** It is very important to change the datadir **before** Nextcloud is installed/started the first time and not to change it afterwards!
### How to allow the Nextcloud container to access directories on the host?
By default, the Nextcloud container is confined and cannot access directories on the host OS. You might want to change this when you are planning to use local external storage in Nextcloud to store some files outside the data directory and can do so by adding the environmental variable `NEXTCLOUD_MOUNT` to the initial startup of the mastercontainer. Allowed values for that variable are strings that are equal to or start with `/mnt/` or `/media/` or are equal to `/var/backups` and unequal to `/mnt/ncdata`. Two examples for this are: `-e NEXTCLOUD_MOUNT="/mnt/"` or `-e NEXTCLOUD_MOUNT="/media/"`. After doing so, please make sure to apply the correct permissions to the directories that you want to use in Nextcloud. E.g. `sudo chown -R 33:0 /mnt/your-drive-mountpoint` should make it work. You can then navigate to the apps management page, activate the external storage app, navigate to `https://your-nc-domain.com/settings/admin/externalstorages` and add a local external storage directory that will be accessible inside the container at the same place that you've entered. E.g. `/mnt/your-drive-mountpoint` will be mounted to `/mnt/your-drive-mountpoint` inside the container, etc. Be aware though that these locations will not be covered by the built-in backup solution!
### Huge docker logs
When your containers run for a few days without a restart, the container logs that you can view from the AIO interface can get really huge. You can limit the loge sizes by enabling logrotate for docker container logs. Feel free to enable this by following those instructions: https://sandro-keil.de/blog/logrotate-for-docker-container/
@@ -134,6 +271,9 @@ You can move the whole docker library and all its files including all Nextcloud
### How to edit Nextclouds config.php file with a texteditor?
You can edit Nextclouds config.php file directly from the host with your favorite text editor. E.g. like this: `sudo nano /var/lib/docker/volumes/nextcloud_aio_nextcloud/_data/config/config.php`. Make sure to not break the file though which might corrupt your Nextcloud instance otherwise. In best case, create a backup using the built-in backup solution before editing the file.
### Custom skeleton directory
If you want to define a custom skeleton directory, you can do so by putting your skeleton files into `/var/lib/docker/volumes/nextcloud_aio_nextcloud_data/_data/skeleton/`, applying the correct permissions with `sudo chown -R 33:0 /var/lib/docker/volumes/nextcloud_aio_nextcloud_data/_data/skeleton` and setting the skeleton directory option with `sudo docker exec -it nextcloud-aio-nextcloud php occ config:system:set skeletondirectory --value="/mnt/ncdata/skeleton"`. You can read further on this option here: [click here](https://docs.nextcloud.com/server/stable/admin_manual/configuration_server/config_sample_php_parameters.html?highlight=skeletondir#:~:text=adding%20%3Fdirect%3D1-,'skeletondirectory',-%3D%3E%20'%2Fpath%2Fto%2Fnextcloud)
### LDAP
It is possible to connect to an existing LDAP server. You need to make sure that the LDAP server is reachable from the Nextcloud container. Then you can enable the LDAP app and configure LDAP in Nextcloud manually. If you don't have a LDAP server yet, recommended is to use this docker container: https://hub.docker.com/r/osixia/openldap/. Make sure here as well that Nextcloud can talk to the LDAP server. The easiest way is by adding the LDAP docker container to the docker network `nextcloud-aio`. Then you can connect to the LDAP container by its name from the Nextcloud container. **Pro-tip**: You will probably find this app useful: https://apps.nextcloud.com/apps/ldap_write_support

68
reverse-proxy.md Normal file
View File

@@ -0,0 +1,68 @@
## Reverse Proxy Config
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
Add this to your Caddyfile:
```
https://<your-nc-domain>:443 {
header Strict-Transport-Security max-age=31536000;
reverse_proxy localhost:11000
}
```
Of course you need to modify `<your-nc-domain>` to the domain on which you want to run Nextcloud.
### Startup command
```
# For x64 CPUs:
sudo docker run -it \
--name nextcloud-aio-mastercontainer \
--restart always \
-p 8080:8080 \
-e APACHE_PORT=11000 \
--volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
--volume /var/run/docker.sock:/var/run/docker.sock:ro \
nextcloud/all-in-one:latest
```
<details>
<summary>Command for arm64 CPUs like the Raspberry Pi 4</summary>
```
# For arm64 CPUs:
sudo docker run -it \
--name nextcloud-aio-mastercontainer \
--restart always \
-p 8080:8080 \
-e APACHE_PORT=11000 \
--volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
--volume /var/run/docker.sock:/var/run/docker.sock:ro \
nextcloud/all-in-one:latest-arm64
```
</details>
After doing so, you should be able to access the AIO Interface via `https://internal.ip.of.this.server:8080`. Enter your domain that you've entered in the reverse proxy config and you should be done. Please do not forget to open port `3478/TCP` and `3478/UDP` for the Talk container!
### Optional
If you want to also access your AIO interface publicly with a valid certificate, you can add e.g. the following config to your Caddyfile:
```
https://<your-nc-domain>:8443 {
reverse_proxy https://localhost:8080 {
transport http {
tls_insecure_skip_verify
}
}
}
```
Of course you also need to modify `<your-nc-domain>` to the domain that you want to use. Afterwards should the AIO interface be accessible via `https://<your-nc-domain>:8443`.