Compare commits

...

44 Commits

Author SHA1 Message Date
Simon L.
80e7f45748 Merge pull request #5428 from nextcloud/aio-helm-update
Helm Chart updates
2024-10-17 11:46:32 +02:00
szaimen
fb3c8ec4de Helm Chart updates
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-10-17 09:39:05 +00:00
Simon L.
6e26dfccaf Merge pull request #5423 from nextcloud/dependabot/docker/Containers/whiteboard/nextcloud-releases/whiteboard-v1.0.4
build(deps): bump nextcloud-releases/whiteboard from v1.0.3 to v1.0.4 in /Containers/whiteboard
2024-10-17 10:56:51 +02:00
Simon L.
45317e3304 Merge pull request #5417 from nextcloud/dependabot/docker/Containers/collabora/collabora/code-24.04.8.2.1
build(deps): bump collabora/code from 24.04.8.1.1 to 24.04.8.2.1 in /Containers/collabora
2024-10-17 10:56:09 +02:00
Simon L.
d9f8bfebfa Merge pull request #5416 from nextcloud/dependabot/docker/Containers/clamav/clamav/clamav-1.4.1-8
build(deps): bump clamav/clamav from 1.4.1-7 to 1.4.1-8 in /Containers/clamav
2024-10-17 10:55:04 +02:00
Simon L.
908ebe0b97 Merge pull request #5412 from nextcloud/aio-dependency-update
PHP dependency updates
2024-10-17 10:54:50 +02:00
Simon L.
e6c6b170e5 Merge pull request #5397 from nextcloud/ernolf/ui_dark-mode
feat(ui): introducing dark-mode and refactor some templates and css
2024-10-17 10:54:19 +02:00
szaimen
3ffc511c10 php dependency updates
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-10-16 12:03:01 +00:00
Simon L.
266526557d Update local-instance.md
Signed-off-by: Simon L. <szaimen@e.mail.de>
2024-10-15 16:13:52 +02:00
dependabot[bot]
6e0c76a23b build(deps): bump nextcloud-releases/whiteboard
Bumps nextcloud-releases/whiteboard from v1.0.3 to v1.0.4.

---
updated-dependencies:
- dependency-name: nextcloud-releases/whiteboard
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-15 05:05:32 +00:00
Simon L.
9130cff804 remove the schedule foor update-copyright for now
Signed-off-by: Simon L. <szaimen@e.mail.de>
2024-10-14 14:20:25 +02:00
Simon L.
e2f76b8685 add copyright update workflow
Signed-off-by: Simon L. <szaimen@e.mail.de>
2024-10-14 11:08:29 +02:00
dependabot[bot]
2c81cb0a0a build(deps): bump collabora/code in /Containers/collabora
Bumps collabora/code from 24.04.8.1.1 to 24.04.8.2.1.

---
updated-dependencies:
- dependency-name: collabora/code
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-14 04:32:47 +00:00
dependabot[bot]
83ac2a0c99 build(deps): bump clamav/clamav in /Containers/clamav
Bumps clamav/clamav from 1.4.1-7 to 1.4.1-8.

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-14 04:32:45 +00:00
ernolf
1f144b9ee7 feat(ui): introducing dark-mode and refactor some template details and css
- chore: increase to 9.7.0 - reconcile with main after rebase
- chore: reconcile fixes to containers.twig from main after rebase
- refactor(layout): increment CSS version from v2 to v3

Signed-off-by: ernolf <raphael.gradenwitz@googlemail.com>
2024-10-10 17:08:21 +02:00
Simon L.
10495fd56e Merge pull request #5241 from punkyard/patch-1
Update reverse-proxy.md
2024-10-10 15:41:18 +02:00
Simon L.
9b25f8b061 make wording consistant
Signed-off-by: Simon L. <szaimen@e.mail.de>

Co-authored-by: Jean-Yves <7360784+docjyJ@users.noreply.github.com>
Signed-off-by: Simon L. <szaimen@e.mail.de>
2024-10-10 15:34:31 +02:00
Simon L.
e45bd1ef2d address review
Signed-off-by: Simon L. <szaimen@e.mail.de>

Co-authored-by: Jean-Yves <7360784+docjyJ@users.noreply.github.com>
Signed-off-by: Simon L. <szaimen@e.mail.de>
2024-10-10 15:34:15 +02:00
Simon L.
e4528678b1 adjust description of reverse proxy
Signed-off-by: Simon L. <szaimen@e.mail.de>

Co-authored-by: Jean-Yves <7360784+docjyJ@users.noreply.github.com>
Signed-off-by: Simon L. <szaimen@e.mail.de>
2024-10-10 15:33:29 +02:00
Simon L.
a647d10bf0 Merge pull request #5401 from nextcloud/nextcloud-container-update
Nextcloud dependency update
2024-10-10 12:56:28 +02:00
szaimen
ce29c17ca4 nextcloud-update automated change
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-10-10 10:52:10 +00:00
Simon L.
6b30744fc3 revert headings so that old links still work and adjust some details
Signed-off-by: Simon L. <szaimen@e.mail.de>
2024-10-10 12:43:46 +02:00
pun kyard
0051b04683 Update reverse-proxy.md
59349105+punkyard@users.noreply.github.com>
Signed-off-by: Simon L. <szaimen@e.mail.de>
Co-Authored-By: Jean-Yves <7360784+docjyJ@users.noreply.github.com>
2024-10-10 12:37:56 +02:00
Simon L.
1050095d89 Merge pull request #5398 from nextcloud/enn/noid/adjust-config
nginx: adjust configs
2024-10-09 15:42:14 +02:00
Simon L.
0250098a71 Merge pull request #5399 from nextcloud/imaginary-container-update
Imaginary update
2024-10-09 15:29:54 +02:00
szaimen
1ea728bd2a imaginary-update automated change
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-10-09 12:10:45 +00:00
Simon L.
bf8395c62e nginx: radjust configs
Signed-off-by: Simon L. <szaimen@e.mail.de>
2024-10-09 13:51:29 +02:00
Simon L.
531104db66 increase to 9.7.0
Signed-off-by: Simon L. <szaimen@e.mail.de>
2024-10-08 11:08:23 +02:00
Simon L.
32f8c6587c Merge pull request #5372 from nextcloud/enh/noid/enum
Use enum instead of interface for state
2024-10-08 10:57:01 +02:00
Simon L.
b375f61a70 Merge pull request #5395 from nextcloud/dependabot/docker/Containers/talk-recording/python-3.13.0-alpine3.20
build(deps): bump python from 3.12.7-alpine3.20 to 3.13.0-alpine3.20 in /Containers/talk-recording
2024-10-08 09:47:44 +02:00
Simon L.
519b5114d7 Merge pull request #5394 from nextcloud/dependabot/docker/Containers/redis/redis-7.2.6-alpine
build(deps): bump redis from 7.2.5-alpine to 7.2.6-alpine in /Containers/redis
2024-10-08 09:47:25 +02:00
dependabot[bot]
bd9070ec6a build(deps): bump python in /Containers/talk-recording
Bumps python from 3.12.7-alpine3.20 to 3.13.0-alpine3.20.

---
updated-dependencies:
- dependency-name: python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-08 05:04:23 +00:00
dependabot[bot]
966e0175ab build(deps): bump redis in /Containers/redis
Bumps redis from 7.2.5-alpine to 7.2.6-alpine.

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-08 05:04:09 +00:00
Simon L.
433a7c81fe Merge pull request #5392 from nextcloud/dependabot/docker/Containers/whiteboard/nextcloud-releases/whiteboard-v1.0.3
build(deps): bump nextcloud-releases/whiteboard from v1.0.2 to v1.0.3 in /Containers/whiteboard
2024-10-07 18:08:50 +02:00
dependabot[bot]
386bab0958 build(deps): bump nextcloud-releases/whiteboard
Bumps nextcloud-releases/whiteboard from v1.0.2 to v1.0.3.

---
updated-dependencies:
- dependency-name: nextcloud-releases/whiteboard
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-07 16:08:00 +00:00
Jean-Yves
dc209adb84 Update php/src/Container/WorkingState.php
Co-authored-by: Simon L. <szaimen@e.mail.de>
Signed-off-by: Jean-Yves <7360784+docjyJ@users.noreply.github.com>
2024-10-07 13:24:21 +02:00
Jean-Yves
edeb5ca40a Fix containers.twig
Signed-off-by: Jean-Yves <7360784+docjyJ@users.noreply.github.com>
2024-10-07 13:22:38 +02:00
Jean-Yves
a0ec043c49 Add Enum
Signed-off-by: Jean-Yves <7360784+docjyJ@users.noreply.github.com>
2024-10-07 13:22:37 +02:00
Simon L.
a54cfed53d Merge pull request #5389 from nextcloud/enh/noid/constructor
Inprove constructor
2024-10-07 12:49:08 +02:00
Simon L.
a5e8c82e59 Merge pull request #5382 from nextcloud/nextcloud-container-update
Nextcloud dependency update
2024-10-07 11:27:37 +02:00
Simon L.
43e60cb76f Merge pull request #5388 from nextcloud/dependabot/docker/Containers/clamav/clamav/clamav-1.4.1-7
build(deps): bump clamav/clamav from 1.4.1-5 to 1.4.1-7 in /Containers/clamav
2024-10-07 11:27:23 +02:00
Jean-Yves
496ec9ba17 update constructor
Signed-off-by: Jean-Yves <7360784+docjyJ@users.noreply.github.com>
2024-10-07 10:12:43 +02:00
dependabot[bot]
505e2dc2ab build(deps): bump clamav/clamav in /Containers/clamav
Bumps clamav/clamav from 1.4.1-5 to 1.4.1-7.

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-07 04:34:27 +00:00
szaimen
4aaf8e9067 nextcloud-update automated change
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-10-05 12:09:56 +00:00
62 changed files with 1217 additions and 1091 deletions

11
.github/workflows/update-copyright.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
name: Update Copyright
on:
workflow_dispatch:
jobs:
update-copyright:
name: update copyright
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:latest
# Probably from this file: https://github.com/Cisco-Talos/clamav-docker/blob/main/clamav/1.3/alpine/Dockerfile
FROM clamav/clamav:1.4.1-5
FROM clamav/clamav:1.4.1-8
COPY clamav.conf /clamav.conf
COPY --chmod=775 start.script /start.script

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:latest
# From a file located probably somewhere here: https://github.com/CollaboraOnline/online/tree/master/docker
FROM collabora/code:24.04.8.1.1
FROM collabora/code:24.04.8.2.1
USER root
ARG DEBIAN_FRONTEND=noninteractive

View File

@@ -1,7 +1,7 @@
# syntax=docker/dockerfile:latest
FROM golang:1.23.2-alpine3.20 AS go
ENV IMAGINARY_HASH=6cd9edd1d3fb151eb773c14552886e4fc8e50138
ENV IMAGINARY_HASH=8f36a26c448be8c151a3878404b75fcd1cd3cf0c
RUN set -ex; \
apk add --no-cache \

View File

@@ -8,7 +8,7 @@ ENV SOURCE_LOCATION=/usr/src/nextcloud
ENV REDIS_DB_INDEX=0
# AIO settings start # Do not remove or change this line!
ENV NEXTCLOUD_VERSION=29.0.7
ENV NEXTCLOUD_VERSION=29.0.8
ENV AIO_TOKEN=123456
ENV AIO_URL=localhost
# AIO settings end # Do not remove or change this line!
@@ -81,7 +81,7 @@ RUN set -ex; \
pecl install igbinary-3.2.16; \
pecl install APCu-5.1.24; \
pecl install -D 'enable-memcached-igbinary="yes"' memcached-3.2.0; \
pecl install -D 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"' redis-6.0.2; \
pecl install -D 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"' redis-6.1.0; \
pecl install imagick-3.7.0; \
\
docker-php-ext-enable \

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:latest
# From https://github.com/docker-library/redis/blob/master/7.2/alpine/Dockerfile
FROM redis:7.2.5-alpine
FROM redis:7.2.6-alpine
COPY --chmod=775 start.sh /start.sh

View File

@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:latest
FROM python:3.12.7-alpine3.20
FROM python:3.13.0-alpine3.20
COPY --chmod=775 start.sh /start.sh

View File

@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:latest
FROM ghcr.io/nextcloud-releases/whiteboard:v1.0.2
FROM ghcr.io/nextcloud-releases/whiteboard:v1.0.4
USER root
RUN set -ex; \

View File

@@ -9,6 +9,8 @@ The recommended way is the following:
1. Enter the ip-address of your local dns-server in the daemon.json file for docker so that you are sure that all docker containers use the correct local dns-server.
1. Now, entering the domain in the AIO-interface should work as expected and should allow you to continue with the setup
Here is a video that does shows this a bit more in detail: https://youtu.be/zk-y2wVkY4c
## 2. Use the ACME DNS-challenge
You can alternatively use the ACME DNS-challenge to get a valid certificate for Nextcloud. Here is described how to set it up: https://github.com/nextcloud/all-in-one#how-to-get-nextcloud-running-using-the-acme-dns-challenge

View File

@@ -1,6 +1,6 @@
name: nextcloud-aio-helm-chart
description: A generated Helm Chart for Nextcloud AIO from Skippbox Kompose
version: 9.6.0
version: 9.7.0
apiVersion: v2
keywords:
- latest

View File

@@ -64,7 +64,7 @@ spec:
value: "{{ .Values.TIMEZONE }}"
- name: WHITEBOARD_HOST
value: nextcloud-aio-whiteboard
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-apache:20240925_080419"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-apache:20241017_085101"
name: nextcloud-aio-apache
ports:
- containerPort: {{ .Values.APACHE_PORT }}

View File

@@ -53,7 +53,7 @@ spec:
value: "{{ .Values.NEXTCLOUD_UPLOAD_LIMIT }}"
- name: TZ
value: "{{ .Values.TIMEZONE }}"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-clamav:20240925_080419"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-clamav:20241017_085101"
name: nextcloud-aio-clamav
ports:
- containerPort: 3310

View File

@@ -36,7 +36,7 @@ spec:
value: --o:ssl.enable=false --o:ssl.termination=true --o:mount_jail_tree=false --o:logging.level=warning --o:home_mode.enable=true {{ .Values.COLLABORA_SECCOMP_POLICY }} --o:remote_font_config.url=https://{{ .Values.NC_DOMAIN }}/apps/richdocuments/settings/fonts.json
- name: server_name
value: "{{ .Values.NC_DOMAIN }}"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-collabora:20240925_080419"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-collabora:20241017_085101"
name: nextcloud-aio-collabora
ports:
- containerPort: 9980

View File

@@ -62,7 +62,7 @@ spec:
value: nextcloud
- name: TZ
value: "{{ .Values.TIMEZONE }}"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-postgresql:20240925_080419"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-postgresql:20241017_085101"
name: nextcloud-aio-database
ports:
- containerPort: 5432

View File

@@ -56,7 +56,7 @@ spec:
value: basic
- name: xpack.security.enabled
value: "false"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-fulltextsearch:20240925_080419"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-fulltextsearch:20241017_085101"
name: nextcloud-aio-fulltextsearch
ports:
- containerPort: 9200

View File

@@ -28,7 +28,7 @@ spec:
value: "{{ .Values.IMAGINARY_SECRET }}"
- name: TZ
value: "{{ .Values.TIMEZONE }}"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-imaginary:20240925_080419"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-imaginary:20241017_085101"
name: nextcloud-aio-imaginary
ports:
- containerPort: 9000

View File

@@ -173,7 +173,7 @@ spec:
value: "{{ .Values.WHITEBOARD_ENABLED }}"
- name: WHITEBOARD_SECRET
value: "{{ .Values.WHITEBOARD_SECRET }}"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-nextcloud:20240925_080419"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-nextcloud:20241017_085101"
name: nextcloud-aio-nextcloud
ports:
- containerPort: 9000

View File

@@ -53,7 +53,7 @@ spec:
value: nextcloud-aio-redis
- name: REDIS_HOST_PASSWORD
value: "{{ .Values.REDIS_PASSWORD }}"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-notify-push:20240925_080419"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-notify-push:20241017_085101"
name: nextcloud-aio-notify-push
ports:
- containerPort: 7867

View File

@@ -44,7 +44,7 @@ spec:
value: "{{ .Values.ONLYOFFICE_SECRET }}"
- name: TZ
value: "{{ .Values.TIMEZONE }}"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-onlyoffice:20240925_080419"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-onlyoffice:20241017_085101"
name: nextcloud-aio-onlyoffice
ports:
- containerPort: 80

View File

@@ -39,7 +39,7 @@ spec:
value: "{{ .Values.REDIS_PASSWORD }}"
- name: TZ
value: "{{ .Values.TIMEZONE }}"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-redis:20240925_080419"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-redis:20241017_085101"
name: nextcloud-aio-redis
ports:
- containerPort: 6379

View File

@@ -42,7 +42,7 @@ spec:
value: "{{ .Values.TURN_SECRET }}"
- name: TZ
value: "{{ .Values.TIMEZONE }}"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-talk:20240925_080419"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-talk:20241017_085101"
name: nextcloud-aio-talk
ports:
- containerPort: {{ .Values.TALK_PORT }}

View File

@@ -32,7 +32,7 @@ spec:
value: "{{ .Values.RECORDING_SECRET }}"
- name: TZ
value: "{{ .Values.TIMEZONE }}"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-talk-recording:20240925_080419"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-talk-recording:20241017_085101"
name: nextcloud-aio-talk-recording
ports:
- containerPort: 1234

View File

@@ -36,7 +36,7 @@ spec:
value: redis
- name: TZ
value: "{{ .Values.TIMEZONE }}"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-whiteboard:20240925_080419"
image: "{{ .Values.IMAGE_MIRROR_PREFIX }}{{ .Values.NEXTCLOUD_IMAGE_ORG }}/aio-whiteboard:20241017_085101"
name: nextcloud-aio-whiteboard
ports:
- containerPort: 3002

12
php/composer.lock generated
View File

@@ -2700,16 +2700,16 @@
},
{
"name": "phpstan/phpdoc-parser",
"version": "1.32.0",
"version": "1.33.0",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpdoc-parser.git",
"reference": "6ca22b154efdd9e3c68c56f5d94670920a1c19a4"
"reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6ca22b154efdd9e3c68c56f5d94670920a1c19a4",
"reference": "6ca22b154efdd9e3c68c56f5d94670920a1c19a4",
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/82a311fd3690fb2bf7b64d5c98f912b3dd746140",
"reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140",
"shasum": ""
},
"require": {
@@ -2741,9 +2741,9 @@
"description": "PHPDoc parser with support for nullable, intersection and generic types",
"support": {
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.32.0"
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.33.0"
},
"time": "2024-09-26T07:23:32+00:00"
"time": "2024-10-13T11:25:22+00:00"
},
{
"name": "sebastian/diff",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 661 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -1 +0,0 @@
<svg width="256" height="128" version="1.1" viewBox="0 0 256 128" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke-width="22"><circle cx="40" cy="64" r="26" stroke="#ffffff" fill="none"/><circle cx="216" cy="64" r="26" stroke="#ffffff" fill="none"/><circle cx="128" cy="64" r="46" stroke="#ffffff" fill="none"/></g></svg>

Before

Width:  |  Height:  |  Size: 330 B

View File

@@ -0,0 +1,4 @@
<svg id="nextcloud-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 142 100" width="142" height="100">
<g id="logo" stroke="currentColor" fill="none" stroke-width="11" transform="scale(1.109)"><circle cx="20" cy="32" r="13"/><circle cx="64" cy="32" r="23"/><circle cx="108" cy="32" r="13"/></g>
<g id="Nextcloud" fill="currentColor" transform="translate(-3.4, -3.4) scale(1.17)"><path d="M15.4,67.4c-0.4,0-0.5,0.2-0.5,0.6v14.6c0,0.4,0.2,0.5,0.5,0.5h0.4c0.4,0,0.5-0.2,0.5-0.5V70.4 l7.9,12.3c0,0.1,0.1,0.1,0.1,0.1c0,0,0,0,0,0c0,0,0.1,0,0.1,0.1c0,0,0,0,0.1,0c0,0,0,0,0,0c0.1,0,0.1,0,0.2,0h0.4 c0.4,0,0.5-0.2,0.5-0.5V68c0-0.4-0.2-0.6-0.5-0.6h-0.4c-0.4,0-0.6,0.2-0.6,0.6v12.1l-7.9-12.3c0,0-0.1-0.1-0.1-0.1 c-0.1-0.1-0.2-0.2-0.4-0.2L15.4,67.4z M110.8,67.6c-0.4,0-0.2,0.2-0.2,0.6v5c0,0.5,0,0.9,0,0.9h0c0,0-1-2.2-3.6-2.2 c-2.9,0-5,2.3-4.9,5.7c0,3.4,1.9,5.8,4.8,5.8c2.9,0,3.8-2.3,3.8-2.3h0.1c0,0-0.1,0.3-0.1,0.7v0.9c0,0.4,0.2,0.5,0.6,0.5h0.4 c0.4,0,0.5-0.2,0.5-0.6V68.2c0-0.4-0.6-0.6-0.9-0.6H110.8z M71.8,67.7c-0.4,0-0.1,0.2-0.1,0.6v12.3c0,2.4,1.6,2.7,2.5,2.7 c0.4,0,0.6-0.2,0.6-0.6v-0.4c0-0.4-0.2-0.5-0.5-0.5c-0.5-0.1-1.2-0.2-1.2-1.6v-12c0-0.4-0.6-0.6-0.9-0.6L71.8,67.7z M53.8,69 c-0.4,0-0.6,0.2-0.6,0.6v2.6v1.3v5.7c0,2.6,1.5,4.1,3.9,4.1c0.5,0,0.6-0.1,0.6-0.5v-0.3c0-0.4-0.1-0.5-0.6-0.6 c-0.9-0.1-2.4-0.4-2.4-2.9v-5.5h2.3c0.4,0,0.6-0.1,0.6-0.5v-0.2c0-0.4-0.2-0.6-0.6-0.6h-2.3v-2.6c0-0.4-0.1-0.6-0.5-0.6L53.8,69z M33.8,71.8c-3,0-5.4,2.2-5.5,5.8c0,3.4,2.5,5.8,5.8,5.8c1.8,0,3.1-0.8,3.7-1.2c0.3-0.2,0.3-0.5,0.2-0.7l-0.2-0.2 c-0.2-0.3-0.4-0.4-0.7-0.2c-0.5,0.4-1.5,1-2.9,1c-2.3,0-4.2-1.6-4.3-4.4h8c0.3,0,0.6-0.3,0.6-0.6C38.4,73.9,36.8,71.8,33.8,71.8z M65,71.8c-3.3,0-5.8,2.4-5.8,5.8c0,3.4,2.5,5.8,5.8,5.8c2,0,3.4-1,3.9-1.4c0.3-0.3,0.3-0.5,0.1-0.8L68.8,81 c-0.2-0.3-0.4-0.4-0.7-0.2C67.6,81.3,66.6,82,65,82c-2.4,0-4.3-1.8-4.3-4.4c0-2.7,1.9-4.5,4.3-4.5c1.3,0,2.3,0.7,2.8,1 c0.3,0.2,0.6,0.2,0.8-0.1l0.2-0.3c0.3-0.3,0.2-0.6-0.1-0.8C68.1,72.6,66.9,71.8,65,71.8L65,71.8z M81.9,71.8 c-3.2,0-5.8,2.5-5.8,5.7c0,3.3,2.6,5.8,5.8,5.8c3.2,0,5.8-2.5,5.8-5.8C87.8,74.3,85.1,71.8,81.9,71.8z M49.5,72 c-0.1,0-0.2,0.1-0.4,0.2l-2,2.4l-1.5,1.8l-2.3-2.7L42,72.2c-0.1-0.1-0.2-0.2-0.4-0.2c-0.1,0-0.3,0-0.4,0.2l-0.3,0.3 c-0.3,0.2-0.3,0.5,0,0.7l2,2.4l1.7,2l-2.5,2.9c0,0,0,0,0,0L40.9,82c-0.2,0.3-0.2,0.6,0.1,0.8l0.3,0.3c0.3,0.2,0.5,0.2,0.7-0.1 l2-2.4l1.5-1.8l2.3,2.7c0,0,0,0,0,0l1.2,1.5c0.2,0.3,0.5,0.3,0.8,0.1l0.3-0.3c0.3-0.2,0.3-0.5,0-0.7l-2-2.4l-1.7-2l2.5-2.9 c0,0,0,0,0,0l1.2-1.5c0.2-0.3,0.2-0.6-0.1-0.8l-0.3-0.3C49.7,72,49.6,71.9,49.5,72L49.5,72z M90.7,72c-0.4,0-0.5,0.2-0.5,0.6v6.5 c0,2.9,2.1,4.3,4.7,4.3c2.6,0,4.7-1.4,4.7-4.3v-6.5c0.1-0.4-0.1-0.6-0.5-0.6h-0.4c-0.4,0-0.6,0.2-0.6,0.6v6.1 c0,1.7-1.1,3.3-3.3,3.3c-2.1,0-3.3-1.6-3.3-3.3v-6.1c0-0.4-0.2-0.6-0.6-0.6L90.7,72z M33.8,73c1.6,0,3,1.2,3.1,3.5h-6.9 C30.3,74.3,31.9,73,33.8,73z M81.9,73.1c2.4,0,4.3,1.9,4.3,4.4c0,2.6-1.9,4.5-4.3,4.5c-2.4,0-4.3-2-4.3-4.5 C77.6,75.1,79.6,73.1,81.9,73.1z M107.1,73.1c2.4,0,3.5,2.2,3.5,4.4c0,3.2-1.7,4.5-3.6,4.5c-2.1,0-3.5-1.8-3.5-4.5 C103.5,74.8,105.1,73.1,107.1,73.1z"/></g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -1,12 +1,58 @@
:root {
--color-nextcloud-blue: #0082c9;
--color-nextcloud-logo: var(--color-nextcloud-blue);
--color-main-background: white;
--color-input-background: white;
--color-main-text: black;
--color-main-border: black;
--color-main-border-hover: var(--color-main-border);
--color-error: #db0606;
--color-error-hover: #df2525;
--color-error-text: #c20505;
--color-success: #46ba61;
--color-running: #ffd000;
--color-info: #0071ad;
--color-info-hover: #00aaef;
--color-border-maxcontrast: #7d7d7d;
--border: .5px;
--border-hover: 2px;
--border-radius: 7px;
--border-radius-large: 12px;
--default-font-size: 13px;
--checkbox-size: 16px;
--max-width: 500px;
}
[data-theme="dark"] {
--color-main-background: #171717;
--color-input-background: #ebebeb;
--color-main-text: #ebebeb;
--color-nextcloud-logo: var(--color-main-text);
--color-main-border: var(--color-border-maxcontrast);
--color-main-border-hover: var(--color-main-text);
--color-error: #ff3333;
--color-error-hover: #ff6666;
--color-error-text: #ff8080;
--color-info: #00aeff;
--color-info-hover: #33beff;
--border-hover: var(--border);
}
html, body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen-Sans, Cantarell, Ubuntu, Helvetica Neue, Arial, Noto Color Emoji, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;;
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Oxygen-Sans, Cantarell, Ubuntu, 'Helvetica Neue', 'Noto Sans', 'Liberation Sans', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
background-color: var(--color-main-background);
color: var(--color-main-text);
}
a {
text-decoration: none;
color: #0082c9;
color: var(--color-info);
}
a:hover {
color: var(--color-info-hover);
}
a.button,
@@ -15,19 +61,24 @@ input[type="submit"] {
width: auto;
height: 34px;
cursor: pointer;
background-color: #0082c9;
background-color: var(--color-nextcloud-blue);
font-weight: bold;
border-radius: 8px;
border-radius: var(--border-radius);
margin: 3px 3px 3px 0;
font-size: 14px;
font-size: var(--default-font-size);
color: white;
border: .5px solid black;
border: .5px solid var(--color-main-border);
outline: none;
}
a.button:focus,
input[type="submit"]:focus {
border: 1px solid black;
border: 1px solid var(--color-main-border);
}
a.button:hover,
input[type="submit"]:hover {
background-color: var(--color-info-hover);
}
summary {
@@ -41,38 +92,36 @@ ul {
li {
padding-bottom: 5px;
text-indent: 0;
padding-left: 0;
}
span.error {
background-color: #e9322d;
background-color: var(--color-error);
}
div.toast.error {
border-left-color: #e9322d;
border-left-color: var(--color-error);
}
.status {
display: inline-block;
height: 16px;
width: 16px;
vertical-align: text-bottom
}
.status {
height: var(--checkbox-size);
width: var(--checkbox-size);
vertical-align: text-bottom;
border-radius: 50%
}
span.success {
background-color: #46ba61;
background-color: var(--color-success);
}
span.running {
background-color: rgb(255, 208, 0);
background-color: var(--color-running);
}
div.toast.success {
border-left-color: #46ba61;
border-left-color: var(--color-success);
}
div.toast {
@@ -84,19 +133,36 @@ div.toast {
margin-top: 45px;
position: fixed;
z-index: 1000;
border-radius: 3px;
background: white none;
border-radius: var(--border-radius);
background: var(--color-main-background) none;
color: var(--color-main-text);
}
.nextcloud-logo {
margin-left: auto;
margin-right: auto;
display: block;
color: var(--color-nextcloud-logo);
}
.fallback-text {
display: none;
}
svg:not(:has(use)) .fallback-text {
display: block;
}
.login {
padding: 50px;
background-color: white;
background-color: var(--color-main-background);
color: var(--color-main-text);
width: 500px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 12px;
border-radius: var(--border-radius-large);
}
.login > .monospace {
@@ -104,33 +170,6 @@ div.toast {
font-size: 17px;
}
form {
margin: 0;
}
input[type="text"],
input[type="password"],
select {
padding-left: 8px;
padding-right: 8px;
height: 34px;
margin-bottom: 15px;
border-radius: 8px;
border: .5px solid black;
}
textarea {
border-radius: 8px;
border: .5px solid black;
}
input[type="text"]:focus,
input[type="password"]:focus,
textarea:focus,
select:focus {
border: 1px solid black;
}
.login > form > input[type="password"],
.login > form > input[type="text"],
.login > form > input[type="submit"] {
@@ -153,34 +192,113 @@ select:focus {
align-content: center;
}
.login-wrapper {
.wrapper {
min-height: 100dvh;
min-width: 100vw;
position: fixed;
width: 100vw;
height: auto;
background-image: url("img/Background_Light.jpg");
background-image: url("img/jenna-kim-the-globe.webp");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
box-sizing: border-box;
overflow: hidden;
}
html[data-theme="dark"] .wrapper {
background-image: url("img/jenna-kim-the-globe-dark.webp");
}
form {
margin: 0;
}
input[type="text"],
input[type="password"],
select {
padding-left: 8px;
padding-right: 8px;
height: 34px;
margin-bottom: 15px;
border-radius: var(--border-radius);
border: var(--border) solid var(--color-border-maxcontrast);
background: var(--color-main-background);
color: var(--color-main-text);
}
input[type="text"]:hover,
input[type="password"]:hover,
select:hover {
border: var(--border-hover) solid var(--color-main-border-hover);
}
textarea {
border-radius: var(--border-radius);
border: .5px solid var(--color-main-border);
}
input[type="text"]:focus,
input[type="password"]:focus,
textarea:focus,
select:focus {
border: 1px solid var(--color-main-border);
}
/* Scroll bar for dark mode */
html[data-theme="dark"] ::-webkit-scrollbar {
width: 8px; /* Width of the scroll bar */
}
html[data-theme="dark"] ::-webkit-scrollbar-thumb {
background-color: #444; /* Dark mode scrollbar thumb color */
border-radius: 4px; /* Rounded corners for the thumb */
}
html[data-theme="dark"] ::-webkit-scrollbar-track {
background-color: #333; /* Dark mode scrollbar track color */
}
/* Scroll bar for light mode */
::-webkit-scrollbar {
width: 8px; /* Width of the scroll bar */
}
::-webkit-scrollbar-thumb {
background-color: #888; /* Light mode scrollbar thumb color */
border-radius: 4px; /* Rounded corners for the thumb */
}
::-webkit-scrollbar-track {
background-color: #f0f0f0; /* Light mode scrollbar track color */
}
.container {
margin: 20px auto;
padding: 2px;
max-width: calc(var(--max-width) + 108px);
background-color: var(--color-main-background);
border-radius: var(--border-radius-large);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
max-height: calc(100dvh - 40px);
overflow: hidden;
}
main {
padding: 20px;
max-width: 100%;
padding-left: 50px;
padding-right: 50px;
background-color: transparent; /* transparent, since color comes from outer container */
color: var(--color-main-text);
max-height: calc(100dvh - 44px);
overflow-y: auto;
box-sizing: border-box;
word-break: break-word;
max-width: 500px;
max-width: calc(var(--max-width) + 100px);
margin: 0 auto;
}
.logo {
background-image: url('/img/logo.svg');
color: white;
height: 50px;
background-repeat: no-repeat;
display: inline-flex;
background-size: contain;
background-position: center center;
width: 62px;
position: absolute;
left: 12px;
@@ -189,16 +307,62 @@ main {
}
header {
background-color: #0082c9;
background-image: linear-gradient(40deg, #0082c9 0%, #30b6ff 100%);
position: fixed;
top: 0;
width: 100%;
background-color: transparent;
height: 50px;
justify-content: space-between;
align-items: center;
display: flex;
padding: 0 20px;
z-index: 1000;
}
header > form {
margin: 0 8px;
margin-left: auto;
margin-right: 30px;
}
input[type="checkbox"] {
width: var(--checkbox-size);
height: var(--checkbox-size);
-webkit-appearance: none; /* remove default styling */
-moz-appearance: none;
appearance: none;
border: 1px solid var(--color-nextcloud-blue);
border-radius: 2px;
cursor: pointer;
position: relative;
vertical-align: middle; /* align checkbox vertically with text */
margin-top: -1px; /* adjust for better alignment */
}
input[type="checkbox"]:checked {
background-color: var(--color-nextcloud-blue);
border-color: var(--color-border-maxcontrast);
}
input[type="checkbox"]:checked::after {
content: ''; /* Create a pseudo-element for the checkmark */
position: absolute; /* Position it absolutely */
left: 4px; /* Positioning of the checkmark */
top: 0; /* Positioning of the checkmark */
width: 4px; /* Width of the checkmark */
height: 9px; /* Height of the checkmark */
border: solid white; /* Color of the checkmark */
border-width: 0 2px 3px 0; /* Create the checkmark shape */
transform: rotate(45deg); /* Rotate to form a checkmark */
}
input[type="checkbox"]:hover {
border-color: var(--color-info-hover);
}
label {
cursor: pointer;
margin-left: 4px;
line-height: var(--checkbox-size);
}
.loading {
@@ -223,7 +387,7 @@ header > form {
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #0082c9;
border-top: 16px solid var(--color-nextcloud-blue);
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite; /* Safari */
@@ -243,3 +407,58 @@ header > form {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* General theme button styling */
#theme-toggle {
position: fixed; /* Keep the button in the same position */
right: 30px; /* Adjust the distance from the right */
bottom: 30px; /* Adjust the distance from the bottom */
background-color: transparent; /* Make the background transparent */
border: none; /* Remove border */
font-size: 36px; /* Adjust font size */
cursor: pointer; /* Change cursor to pointer */
outline: none;
}
/* Icon styling: default state */
#theme-icon {
display: inline-block;
border-radius: 50%; /* Round shape */
position: relative; /* For the pseudo-element positioning */
transition: box-shadow 0.3s, background-color 0.3s; /* Smooth transition for hover effect */
opacity: 0.6; /* Slightly transparent by default */
filter: grayscale(100%); /* Make the icon black and white */
}
/* Create the inner glow effect with ::after */
#theme-icon::after {
content: ''; /* Empty content for the pseudo-element */
position: absolute;
top: 50%;
left: 50%;
width: 0px; /* Invisible dot */
height: 0px; /* Invisible dot */
background-color: transparent; /* Invisible by default */
border-radius: 50%; /* Circle shape */
transform: translate(-50%, -50%); /* Center the dot */
transition: box-shadow 0.3s, background-color 0.3s; /* Smooth transition for hover */
}
/* Hover effect for both light and dark modes */
#theme-toggle:hover #theme-icon {
position: relative; /* Ensures stacking order */
filter: grayscale(0%); /* Restore full color */
opacity: 1; /* Fully visible on hover */
z-index: 1; /* Ensures the icon is on top of the shadow */
}
/* Inner glow when hovered */
#theme-toggle:hover #theme-icon::after {
box-shadow: 0 0 40px 40px rgba(128, 128, 128, 0.4); /* Blur effect from inside */
background-color: rgba(128, 128, 128, 0.2); /* Light glow inside */
}
/* Remove hover effects when not hovering */
#theme-toggle:not(:hover) #theme-icon {
opacity: 0.6; /* Slightly transparent */
}

View File

@@ -0,0 +1,26 @@
// Function to toggle theme
function toggleTheme() {
const currentTheme = document.documentElement.getAttribute('data-theme');
const newTheme = (currentTheme === 'dark') ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', newTheme);
localStorage.setItem('theme', newTheme);
// Change the icon based on the current theme
const themeIcon = document.getElementById('theme-icon');
themeIcon.textContent = newTheme === 'dark' ? '☀️' : '🌙'; // Switch between moon and sun icons
}
// Function to apply saved theme from localStorage
function applySavedTheme() {
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
document.documentElement.setAttribute('data-theme', savedTheme);
// Ensure the icon is set correctly based on the saved theme
const themeIcon = document.getElementById('theme-icon');
themeIcon.textContent = savedTheme === 'dark' ? '☀️' : '🌙';
}
}
// Apply theme when the page loads
document.addEventListener('DOMContentLoaded', applySavedTheme);

View File

@@ -6,12 +6,12 @@ use AIO\Data\ConfigurationManager;
use AIO\Data\DataConst;
use \DateTime;
class AuthManager {
readonly class AuthManager {
private const string SESSION_KEY = 'aio_authenticated';
private ConfigurationManager $configurationManager;
public function __construct(ConfigurationManager $configurationManager) {
$this->configurationManager = $configurationManager;
public function __construct(
private ConfigurationManager $configurationManager
) {
}
public function CheckCredentials(string $password) : bool {

View File

@@ -2,92 +2,42 @@
namespace AIO\Container;
use AIO\Container\State\IContainerState;
use AIO\Data\ConfigurationManager;
use AIO\Docker\DockerActionManager;
use AIO\ContainerDefinitionFetcher;
class Container {
private string $identifier;
private string $displayName;
private string $containerName;
private string $restartPolicy;
private int $maxShutdownTime;
private ContainerPorts $ports;
private string $internalPorts;
private ContainerVolumes $volumes;
private ContainerEnvironmentVariables $containerEnvironmentVariables;
/** @var string[] */
private array $dependsOn;
/** @var string[] */
private array $secrets;
/** @var string[] */
private array $devices;
/** @var string[] */
private array $capAdd;
private int $shmSize;
private bool $apparmorUnconfined;
/** @var string[] */
private array $backupVolumes;
private array $nextcloudExecCommands;
private bool $readOnlyRootFs;
private array $tmpfs;
private bool $init;
private string $imageTag;
private AioVariables $aioVariables;
private string $documentation;
private DockerActionManager $dockerActionManager;
readonly class Container {
public function __construct(
string $identifier,
string $displayName,
string $containerName,
string $restartPolicy,
int $maxShutdownTime,
ContainerPorts $ports,
string $internalPorts,
ContainerVolumes $volumes,
ContainerEnvironmentVariables $containerEnvironmentVariables,
array $dependsOn,
array $secrets,
array $devices,
array $capAdd,
int $shmSize,
bool $apparmorUnconfined,
array $backupVolumes,
array $nextcloudExecCommands,
bool $readOnlyRootFs,
array $tmpfs,
bool $init,
string $imageTag,
AioVariables $aioVariables,
string $documentation,
DockerActionManager $dockerActionManager
private string $identifier,
private string $displayName,
private string $containerName,
private string $restartPolicy,
private int $maxShutdownTime,
private ContainerPorts $ports,
private string $internalPorts,
private ContainerVolumes $volumes,
private ContainerEnvironmentVariables $containerEnvironmentVariables,
/** @var string[] */
private array $dependsOn,
/** @var string[] */
private array $secrets,
/** @var string[] */
private array $devices,
/** @var string[] */
private array $capAdd,
private int $shmSize,
private bool $apparmorUnconfined,
/** @var string[] */
private array $backupVolumes,
private array $nextcloudExecCommands,
private bool $readOnlyRootFs,
private array $tmpfs,
private bool $init,
private string $imageTag,
private AioVariables $aioVariables,
private string $documentation,
private DockerActionManager $dockerActionManager
) {
$this->identifier = $identifier;
$this->displayName = $displayName;
$this->containerName = $containerName;
$this->restartPolicy = $restartPolicy;
$this->maxShutdownTime = $maxShutdownTime;
$this->ports = $ports;
$this->internalPorts = $internalPorts;
$this->volumes = $volumes;
$this->containerEnvironmentVariables = $containerEnvironmentVariables;
$this->dependsOn = $dependsOn;
$this->secrets = $secrets;
$this->devices = $devices;
$this->capAdd = $capAdd;
$this->shmSize = $shmSize;
$this->apparmorUnconfined = $apparmorUnconfined;
$this->backupVolumes = $backupVolumes;
$this->nextcloudExecCommands = $nextcloudExecCommands;
$this->readOnlyRootFs = $readOnlyRootFs;
$this->tmpfs = $tmpfs;
$this->init = $init;
$this->imageTag = $imageTag;
$this->aioVariables = $aioVariables;
$this->documentation = $documentation;
$this->dockerActionManager = $dockerActionManager;
}
public function GetIdentifier() : string {
@@ -162,19 +112,19 @@ class Container {
return $this->volumes;
}
public function GetRunningState() : IContainerState {
public function GetRunningState() : ContainerState {
return $this->dockerActionManager->GetContainerRunningState($this);
}
public function GetRestartingState() : IContainerState {
public function GetRestartingState() : ContainerState {
return $this->dockerActionManager->GetContainerRestartingState($this);
}
public function GetUpdateState() : IContainerState {
public function GetUpdateState() : VersionState {
return $this->dockerActionManager->GetContainerUpdateState($this);
}
public function GetStartingState() : IContainerState {
public function GetStartingState() : ContainerState {
return $this->dockerActionManager->GetContainerStartingState($this);
}

View File

@@ -3,17 +3,10 @@
namespace AIO\Container;
class ContainerPort {
public string $port;
public string $ipBinding;
public string $protocol;
public function __construct(
string $port,
string $ipBinding,
string $protocol
public string $port,
public string $ipBinding,
public string $protocol
) {
$this->port = $port;
$this->ipBinding = $ipBinding;
$this->protocol = $protocol;
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace AIO\Container;
enum ContainerState: string {
case ImageDoesNotExist = 'image_does_not_exist';
case NotRestarting = 'not_restarting';
case Restarting = 'restarting';
case Running = 'running';
case Starting = 'starting';
case Stopped = 'stopped';
}

View File

@@ -3,17 +3,10 @@
namespace AIO\Container;
class ContainerVolume {
public string $name;
public string $mountPoint;
public bool $isWritable;
public function __construct(
string $name,
string $mountPoint,
bool $isWritable
public string $name,
public string $mountPoint,
public bool $isWritable
) {
$this->name = $name;
$this->mountPoint = $mountPoint;
$this->isWritable = $isWritable;
}
}

View File

@@ -1,5 +0,0 @@
<?php
namespace AIO\Container\State;
interface IContainerState {}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,8 @@
<?php
namespace AIO\Container;
enum VersionState: string {
case Different = 'different';
case Equal = 'equal';
}

View File

@@ -9,23 +9,15 @@ use AIO\Container\ContainerPort;
use AIO\Container\ContainerPorts;
use AIO\Container\ContainerVolume;
use AIO\Container\ContainerVolumes;
use AIO\Container\State\RunningState;
use AIO\Data\ConfigurationManager;
use AIO\Data\DataConst;
use AIO\Docker\DockerActionManager;
class ContainerDefinitionFetcher
{
private ConfigurationManager $configurationManager;
private \DI\Container $container;
readonly class ContainerDefinitionFetcher {
public function __construct(
ConfigurationManager $configurationManager,
\DI\Container $container
)
{
$this->configurationManager = $configurationManager;
$this->container = $container;
private ConfigurationManager $configurationManager,
private \DI\Container $container
) {
}
public function GetContainerById(string $id): Container
@@ -103,7 +95,7 @@ class ContainerDefinitionFetcher
$ports = new ContainerPorts();
if (isset($entry['ports'])) {
foreach ($entry['ports'] as $value) {
foreach ($entry['ports'] as $value) {
$ports->AddPort(
new ContainerPort(
$value['port_number'],
@@ -212,7 +204,7 @@ class ContainerDefinitionFetcher
$dependsOn[] = $value;
}
}
$variables = new ContainerEnvironmentVariables();
if (isset($entry['environment'])) {
foreach ($entry['environment'] as $value) {

View File

@@ -9,14 +9,10 @@ use AIO\Docker\DockerActionManager;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
class ConfigurationController
{
private ConfigurationManager $configurationManager;
readonly class ConfigurationController {
public function __construct(
ConfigurationManager $configurationManager
private ConfigurationManager $configurationManager
) {
$this->configurationManager = $configurationManager;
}
public function SetConfig(Request $request, Response $response, array $args) : Response {

View File

@@ -2,28 +2,21 @@
namespace AIO\Controller;
use AIO\Container\State\RunningState;
use AIO\Container\ContainerState;
use AIO\ContainerDefinitionFetcher;
use AIO\Docker\DockerActionManager;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use AIO\Data\ConfigurationManager;
class DockerController
{
private DockerActionManager $dockerActionManager;
private ContainerDefinitionFetcher $containerDefinitionFetcher;
readonly class DockerController {
private const string TOP_CONTAINER = 'nextcloud-aio-apache';
private ConfigurationManager $configurationManager;
public function __construct(
DockerActionManager $dockerActionManager,
ContainerDefinitionFetcher $containerDefinitionFetcher,
ConfigurationManager $configurationManager
private DockerActionManager $dockerActionManager,
private ContainerDefinitionFetcher $containerDefinitionFetcher,
private ConfigurationManager $configurationManager
) {
$this->dockerActionManager = $dockerActionManager;
$this->containerDefinitionFetcher = $containerDefinitionFetcher;
$this->configurationManager = $configurationManager;
}
private function PerformRecursiveContainerStart(string $id, bool $pullImage = true) : void {
@@ -35,7 +28,7 @@ class DockerController
// Don't start if container is already running
// This is expected to happen if a container is defined in depends_on of multiple containers
if ($container->GetRunningState() instanceof RunningState) {
if ($container->GetRunningState() === ContainerState::Running) {
error_log('Not starting ' . $id . ' because it was already started.');
return;
}
@@ -48,7 +41,7 @@ class DockerController
}
}
// Check if docker hub is reachable in order to make sure that we do not try to pull an image if it is down
// Check if docker hub is reachable in order to make sure that we do not try to pull an image if it is down
// and try to mitigate issues that are arising due to that
if ($pullImage) {
if (!$this->dockerActionManager->isDockerHubReachable($container)) {
@@ -261,10 +254,10 @@ class DockerController
$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) {
if ($apacheContainer->GetRunningState() === ContainerState::Running) {
return;
// Don't start if domaincheck is already running
} elseif ($domaincheckContainer->GetRunningState() instanceof RunningState) {
} elseif ($domaincheckContainer->GetRunningState() === ContainerState::Running) {
$domaincheckWasStarted = apcu_fetch($cacheKey);
// Start domaincheck again when 10 minutes are over by not returning here
if($domaincheckWasStarted !== false && is_string($domaincheckWasStarted)) {

View File

@@ -9,14 +9,11 @@ use AIO\Docker\DockerActionManager;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
class LoginController
{
private AuthManager $authManager;
private DockerActionManager $dockerActionManager;
public function __construct(AuthManager $authManager, DockerActionManager $dockerActionManager) {
$this->authManager = $authManager;
$this->dockerActionManager = $dockerActionManager;
readonly class LoginController {
public function __construct(
private AuthManager $authManager,
private DockerActionManager $dockerActionManager,
) {
}
public function TryLogin(Request $request, Response $response, array $args) : Response {

View File

@@ -4,16 +4,11 @@ namespace AIO\Data;
use AIO\Auth\PasswordGenerator;
class Setup
{
private PasswordGenerator $passwordGenerator;
private ConfigurationManager $configurationManager;
readonly class Setup {
public function __construct(
PasswordGenerator $passwordGenerator,
ConfigurationManager $configurationManager) {
$this->passwordGenerator = $passwordGenerator;
$this->configurationManager = $configurationManager;
private PasswordGenerator $passwordGenerator,
private ConfigurationManager $configurationManager,
) {
}
public function Setup() : string {

View File

@@ -3,44 +3,24 @@
namespace AIO\Docker;
use AIO\Container\Container;
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;
use AIO\Container\VersionState;
use AIO\Container\ContainerState;
use AIO\Data\ConfigurationManager;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use AIO\ContainerDefinitionFetcher;
use http\Env\Response;
class DockerActionManager
{
readonly class DockerActionManager {
private const string API_VERSION = 'v1.41';
private \GuzzleHttp\Client $guzzleClient;
private ConfigurationManager $configurationManager;
private ContainerDefinitionFetcher $containerDefinitionFetcher;
private DockerHubManager $dockerHubManager;
private Client $guzzleClient;
public function __construct(
ConfigurationManager $configurationManager,
ContainerDefinitionFetcher $containerDefinitionFetcher,
DockerHubManager $dockerHubManager
private ConfigurationManager $configurationManager,
private ContainerDefinitionFetcher $containerDefinitionFetcher,
private DockerHubManager $dockerHubManager
) {
$this->configurationManager = $configurationManager;
$this->containerDefinitionFetcher = $containerDefinitionFetcher;
$this->dockerHubManager = $dockerHubManager;
$this->guzzleClient = new \GuzzleHttp\Client(
[
'curl' => [
CURLOPT_UNIX_SOCKET_PATH => '/var/run/docker.sock',
],
]
);
$this->guzzleClient = new Client(['curl' => [CURLOPT_UNIX_SOCKET_PATH => '/var/run/docker.sock']]);
}
private function BuildApiUrl(string $url) : string {
@@ -55,14 +35,14 @@ class DockerActionManager
return $container->GetContainerName() . ':' . $tag;
}
public function GetContainerRunningState(Container $container) : IContainerState
public function GetContainerRunningState(Container $container) : ContainerState
{
$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();
return ContainerState::ImageDoesNotExist;
}
throw $e;
}
@@ -70,20 +50,20 @@ class DockerActionManager
$responseBody = json_decode((string)$response->getBody(), true);
if ($responseBody['State']['Running'] === true) {
return new RunningState();
return ContainerState::Running;
} else {
return new StoppedState();
return ContainerState::Stopped;
}
}
public function GetContainerRestartingState(Container $container) : IContainerState
public function GetContainerRestartingState(Container $container) : ContainerState
{
$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();
return ContainerState::ImageDoesNotExist;
}
throw $e;
}
@@ -91,13 +71,13 @@ class DockerActionManager
$responseBody = json_decode((string)$response->getBody(), true);
if ($responseBody['State']['Restarting'] === true) {
return new RestartingState();
return ContainerState::Restarting;
} else {
return new NotRestartingState();
return ContainerState::NotRestarting;
}
}
public function GetContainerUpdateState(Container $container) : IContainerState
public function GetContainerUpdateState(Container $container) : VersionState
{
$tag = $container->GetImageTag();
if ($tag === '%AIO_CHANNEL%') {
@@ -106,28 +86,26 @@ class DockerActionManager
$runningDigests = $this->GetRepoDigestsOfContainer($container->GetIdentifier());
if ($runningDigests === null) {
return new VersionDifferentState();
return VersionState::Different;
}
$remoteDigest = $this->dockerHubManager->GetLatestDigestOfTag($container->GetContainerName(), $tag);
if ($remoteDigest === null) {
return new VersionEqualstate();
return VersionState::Equal;
}
foreach($runningDigests as $runningDigest) {
if ($runningDigest === $remoteDigest) {
return new VersionEqualState();
return VersionState::Equal;
}
}
return new VersionDifferentState();
return VersionState::Different;
}
public function GetContainerStartingState(Container $container) : IContainerState
public function GetContainerStartingState(Container $container) : ContainerState
{
$runningState = $this->GetContainerRunningState($container);
if ($runningState instanceof StoppedState) {
return new StoppedState();
} elseif ($runningState instanceof ImageDoesNotExistState) {
return new ImageDoesNotExistState();
if ($runningState === ContainerState::Stopped || $runningState === ContainerState::ImageDoesNotExist) {
return $runningState;
}
$containerName = $container->GetIdentifier();
@@ -142,12 +120,12 @@ class DockerActionManager
$connection = @fsockopen($containerName, (int)$internalPort, $errno, $errstr, 0.2);
if ($connection) {
fclose($connection);
return new RunningState();
return ContainerState::Running;
} else {
return new StartingState();
return ContainerState::Starting;
}
} else {
return new RunningState();
return ContainerState::Running;
}
}
@@ -641,7 +619,7 @@ class DockerActionManager
$container = $this->containerDefinitionFetcher->GetContainerById($id);
$updateAvailable = "";
if ($container->GetUpdateState() instanceof VersionDifferentState) {
if ($container->GetUpdateState() === VersionState::Different) {
$updateAvailable = '1';
}
foreach ($container->GetDependsOn() as $dependency) {
@@ -802,7 +780,7 @@ class DockerActionManager
public function sendNotification(Container $container, string $subject, string $message, string $file = '/notify.sh') : void
{
if ($this->GetContainerStartingState($container) instanceof RunningState) {
if ($this->GetContainerStartingState($container) === ContainerState::Running) {
$containerName = $container->GetIdentifier();
@@ -986,7 +964,7 @@ class DockerActionManager
public function isLoginAllowed() : bool {
$id = 'nextcloud-aio-apache';
$apacheContainer = $this->containerDefinitionFetcher->GetContainerById($id);
if ($this->GetContainerStartingState($apacheContainer) instanceof RunningState) {
if ($this->GetContainerStartingState($apacheContainer) === ContainerState::Running) {
return false;
}
return true;
@@ -995,7 +973,7 @@ class DockerActionManager
public function isBackupContainerRunning() : bool {
$id = 'nextcloud-aio-borgbackup';
$backupContainer = $this->containerDefinitionFetcher->GetContainerById($id);
if ($this->GetContainerRunningState($backupContainer) instanceof RunningState) {
if ($this->GetContainerRunningState($backupContainer) === ContainerState::Running) {
return true;
}
return false;

View File

@@ -6,12 +6,11 @@ use AIO\ContainerDefinitionFetcher;
use AIO\Data\ConfigurationManager;
use GuzzleHttp\Client;
class DockerHubManager
{
readonly class DockerHubManager {
private Client $guzzleClient;
public function __construct()
{
public function __construct(
) {
$this->guzzleClient = new Client();
}
@@ -59,4 +58,4 @@ class DockerHubManager
return null;
}
}
}
}

View File

@@ -8,12 +8,10 @@ use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class AuthMiddleware
{
private AuthManager $authManager;
public function __construct(AuthManager $authManager) {
$this->authManager = $authManager;
readonly class AuthMiddleware {
public function __construct(
private AuthManager $authManager
) {
}
public function __invoke(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface

View File

@@ -3,17 +3,13 @@
namespace AIO\Twig;
use Slim\Csrf\Guard;
use Twig\Extension\AbstractExtension;
use Twig\Extension\GlobalsInterface;
class CsrfExtension extends \Twig\Extension\AbstractExtension implements \Twig\Extension\GlobalsInterface
{
/**
* @var Guard
*/
protected Guard $csrf;
public function __construct(Guard $csrf)
{
$this->csrf = $csrf;
class CsrfExtension extends AbstractExtension implements GlobalsInterface {
public function __construct(
protected Guard $csrf
) {
}
public function getGlobals() : array
@@ -35,4 +31,4 @@ class CsrfExtension extends \Twig\Extension\AbstractExtension implements \Twig\E
]
];
}
}
}

View File

@@ -1,5 +1,13 @@
{% extends "layout.twig" %}
{% block body %}
Already installed.
{% endblock %}
<div class="login">
<svg class="nextcloud-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 142 100" width="142" height="100"">
<use href="/img/nextcloud-logo.svg#logo"></use>
<use href="/img/nextcloud-logo.svg#Nextcloud"></use>
<text x="10" y="50" fill="var(--color-nextcloud-logo)" class="fallback-text">Nextcloud Logo</text>
</svg>
<h2>Nextcloud All-In-One is already installed</h2>
<a href="/" class="button">Open Nextcloud AIO</a>
</div>
{% endblock %}

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,16 @@
<html>
<head>
<title>AIO</title>
<link rel="stylesheet" href="/style.css?v2" media="all" />
<link rel="stylesheet" href="/style.css?v3" media="all" />
<link rel="icon" href="/img/favicon.png">
<script type="text/javascript" src="forms.js"></script>
</head>
<body>
<div class="wrapper">
{% block body %}{% endblock %}
</div>
<button id="theme-toggle" onclick="toggleTheme()"><span id="theme-icon"/></button>
<script type="text/javascript" src="toggle-dark-mode.js"></script>
</body>
</html>
</html>

View File

@@ -1,28 +1,28 @@
{% extends "layout.twig" %}
{% block body %}
<div class="login-wrapper">
<div class="login">
<img alt="Nextcloud logo" src="/img/logo-blue.svg" style="margin-left: auto;margin-right: auto;display: block;">
<h1>Nextcloud AIO Login</h1>
{% if is_login_allowed == true %}
<p>Log in using your Nextcloud AIO passphrase:</p>
<form method="POST" action="/api/auth/login" class="xhr">
<input type="password" autocomplete="current-password" name="password" placeholder="Password" id="master-password" oninput="showPassword('master-password')">
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
<input type="submit" class="button" value="Log in" />
</form>
{% else %}
<p>The login is blocked since Nextcloud is running.<br>Please use the <a href="https://github.com/nextcloud/all-in-one#how-to-easily-log-in-to-the-aio-interface"><strong>automatic login</strong></a> from your Nextcloud.<br><br>
If that is not possible, you can unblock the login by running<br><strong>sudo docker stop nextcloud-aio-apache</strong></p>
{% endif %}
</div>
</div>
<script type="text/javascript" src="before-unload.js"></script>
<div id="overlay">
<div class="loader"></div>
</div>
{% endblock %}
{% extends "layout.twig" %}
{% block body %}
<div class="login">
<svg class="nextcloud-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 142 100" width="142" height="100"">
<use href="/img/nextcloud-logo.svg#logo"></use>
<use href="/img/nextcloud-logo.svg#Nextcloud"></use>
<text x="10" y="50" fill="var(--color-nextcloud-logo)" class="fallback-text">Nextcloud Logo</text>
</svg>
<h1>Nextcloud AIO Login</h1>
{% if is_login_allowed == true %}
<p>Log in using your Nextcloud AIO passphrase:</p>
<form method="POST" action="/api/auth/login" class="xhr">
<input type="password" autocomplete="current-password" name="password" placeholder="Password" id="master-password" oninput="showPassword('master-password')">
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
<input type="submit" class="button" value="Log in" />
</form>
{% else %}
<p>The login is blocked since Nextcloud is running.<br>Please use the <a href="https://github.com/nextcloud/all-in-one#how-to-easily-log-in-to-the-aio-interface"><strong>automatic login</strong></a> from your Nextcloud.<br><br>
If that is not possible, you can unblock the login by running<br><strong>sudo docker stop nextcloud-aio-apache</strong></p>
{% endif %}
</div>
<script type="text/javascript" src="before-unload.js"></script>
<div id="overlay">
<div class="loader"></div>
</div>
{% endblock %}

View File

@@ -1,14 +1,16 @@
{% extends "layout.twig" %}
{% block body %}
<div class="login-wrapper">
<div class="login">
<img alt="Nextcloud logo" src="/img/logo-blue.svg" style="margin-left: auto;margin-right: auto;display: block;">
<h1>All-in-One setup</h1>
<p>The official Nextcloud installation method. Nextcloud All-in-One provides easy deployment and maintenance with most features included in this one Nextcloud instance.</p>
<p>⚠️ <strong>Please note down the passphrase to access the AIO interface and don't lose it!</strong></p>
<strong>Passphrase</strong><br/><span class="monospace">{{ password }}</span><br>
<a href="/" class="button" target="_blank" rel="noopener">Open Nextcloud AIO login ↗</a>
</div>
<div class="login">
<svg class="nextcloud-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 142 100" width="142" height="100"">
<use href="/img/nextcloud-logo.svg#logo"></use>
<use href="/img/nextcloud-logo.svg#Nextcloud"></use>
<text x="10" y="50" fill="var(--color-nextcloud-logo)" class="fallback-text">Nextcloud Logo</text>
</svg>
<h1>All-in-One setup</h1>
<p>The official Nextcloud installation method. Nextcloud All-in-One provides easy deployment and maintenance with most features included in this one Nextcloud instance.</p>
<p>⚠️ <strong>Please note down the passphrase to access the AIO interface and don't lose it!</strong></p>
<strong>Passphrase</strong><br/><span class="monospace">{{ password }}</span><br>
<a href="/" class="button" target="_blank" rel="noopener">Open Nextcloud AIO login ↗</a>
</div>
{% endblock %}
{% endblock %}

View File

@@ -1,22 +1,29 @@
# Reverse Proxy Documentation
**Note:** The maintainers of AIO noticed that this documentation could be improved to make it easier to follow. All contributions that improve this are very welcome!
> [!NOTE]
> The maintainers of AIO noticed that this documentation could be improved to make it easier to follow. All contributions that improve this are very welcome!
A [reverse proxy](https://en.wikipedia.org/wiki/Reverse_proxy) is basically a web server that enables computers on the internet to access a service in a [private subnet](https://en.wikipedia.org/wiki/Private_network).
A [reverse proxy](https://en.wikipedia.org/wiki/Reverse_proxy) is a software service that acts as a gateway between services and a client. It is commonly used to allow a client connected to the Internet to access a website located in the [private subnet](https://en.wikipedia.org/wiki/Private_network) of that web server.
**Please note:** Publishing the AIO interface with a valid certificate to the public internet is **not** the goal of this documentation! Instead, the main goal is to publish Nextcloud with a valid certificate to the public internet which is **not** running inside the mastercontainer but in a different container! If you need a valid certificate for the AIO interface, see [point 5](#5-optional-get-a-valid-certificate-for-the-aio-interface).
**Please note:** Publishing the AIO interface with a valid certificate to the public internet is **not** the goal of this documentation! If you need a valid certificate for the AIO interface, see [point 5](#5-optional-get-a-valid-certificate-for-the-aio-interface).
In order to run Nextcloud behind a web server or reverse proxy (like Apache, Nginx, Caddy, Cloudflare Tunnel and else), you need to specify the port that AIO's Apache container shall use, add a specific config to your web server or reverse proxy and modify the startup command a bit. All examples below will use port `11000` as example `APACHE_PORT` which will be exposed on the host to receive unencrypted HTTP traffic from the reverse proxy. **Advice:** If you need https between Nextcloud and the reverse proxy because it is running on a different server in the same network, simply add another reverse proxy to the chain that runs on the same server like AIO and takes care of https proxying (most likely via self-signed cert). Another option is to create a VPN between the server that runs AIO and the server that runs the reverse proxy which takes care of encrypting the connection.
In order to run Nextcloud behind a web server or reverse proxy (like Apache, Nginx, Caddy, Cloudflare Tunnel and else), you need to:
1. specify the port that AIO's integrated Apache container shall use
2. add a specific config to your web server or reverse proxy
3. modify the startup command a bit.
All examples below will use port `11000` as `APACHE_PORT`. This port will be exposed in the private network to receive unencrypted HTTP traffic from the reverse proxy.
> [!IMPORTANT]
> If you need HTTPS between Nextcloud and the reverse proxy because it is running on a different server in the same network, simply add another reverse proxy to the chain that runs on the same server like AIO and takes care of HTTPS proxying (most likely via self-signed certificates). Another option would be to create a VPN between the server that runs AIO and the server that runs the reverse proxy which takes care of encrypting the connection.
**Attention:** The process to run Nextcloud behind a reverse proxy consists of at least steps 1, 2 and 4:
1. **Configure the reverse proxy! See [point 1](#1-configure-the-reverse-proxy)**
1. **Use this startup command! See [point 2](#2-use-this-startup-command)**
1. Optional: If the reverse proxy is installed on the same host and in the host network, you should limit the apache container to only listen on localhost. See [point 3](#3-limit-the-access-to-the-apache-container)
1. Optional: if the reverse proxy is installed on the same host and in the host network, you should limit the apache container to only listen on localhost. See [point 3](#3-limit-the-access-to-the-apache-container)
1. **Open the AIO interface. See [point 4](#4-open-the-aio-interface)**
1. Optional: Get a valid certificate for the AIO interface! See [point 5](#5-optional-get-a-valid-certificate-for-the-aio-interface)
1. Optional: How to debug things? See [point 6](#6-how-to-debug-things)
1. Optional: get a valid certificate for the AIO interface! See [point 5](#5-optional-get-a-valid-certificate-for-the-aio-interface)
1. Optional: how to debug things? See [point 6](#6-how-to-debug-things)
**Please note:** Since the Apache container gets created by the mastercontainer, there is **NO** way to provide custom docker labels or custom environmental variables for the Apache container. So please do not attempt to do this because you will fail! Only the documented way will work!
**Please note:** Since the Apache container gets created by the mastercontainer, there is **NO** way to provide custom docker labels or custom environmental variables for the Apache container. So please do not attempt to do this because it will fail!
## 1. Configure the reverse proxy
@@ -39,7 +46,7 @@ In order to run Nextcloud behind a web server or reverse proxy (like Apache, Ngi
For this setup, you can use as target `host.docker.internal:$APACHE_PORT` instead of `localhost:$APACHE_PORT`. **⚠️ Important:** In order to make this work on Docker for Linux, you need to add `--add-host=host.docker.internal:host-gateway` to the docker run command of your reverse proxy container or `extra_hosts: ["host.docker.internal:host-gateway"]` in docker compose (it works on Docker Desktop by default).
Another option and actually the recommended way in this case is to use `--network host` option (or `network_mode: host` for docker-compose) as setting for the reverse proxy container to connect it to the host network. If you are using a firewall on the server, you need to open ports 80 and 443 for the reverse proxy manually. By doing so, the default sample configurations that point at `localhost:$APACHE_PORT` should work without having to modify them.
Another option (actually the recommended way) in this case is to use `--network host` option (or `network_mode: host` for docker-compose) as setting for the reverse proxy container to connect it to the host network. If you are using a firewall on the server, you need to open ports 80 and 443 for the reverse proxy manually. By doing so, the default sample configurations that point at `localhost:$APACHE_PORT` should work without having to modify them.
</details>
@@ -132,7 +139,7 @@ To make the config work you can run the following command:
</details>
### Caddy (Recommended)
### Caddy (recommended)
<details>
@@ -147,7 +154,7 @@ https://<your-nc-domain>:443 {
```
The Caddyfile is a text file called `Caddyfile` (no extension) which if you should be running Caddy inside a container should usually be created in the same location as your `compose.yaml` file prior to starting the container.
⚠️ **Please note:** Look into [this](#adapting-the-sample-web-server-configurations-below) to adapt the above example configuration.
⚠️ **Please note:** look into [this](#adapting-the-sample-web-server-configurations-below) to adapt the above example configuration.
**Advice:** You may have a look at [this](https://github.com/nextcloud/all-in-one/discussions/575#discussion-4055615) for a more complete example.
@@ -181,7 +188,7 @@ You can get AIO running using the ACME DNS-challenge. Here is how to do it.
</details>
### Citrix ADC VPX / Citrix Netscaler
### Citrix ADC VPX / Citrix Netscaler
<details>
@@ -200,8 +207,8 @@ For a reverse proxy example guide for Citrix ADC VPX / Citrix Netscaler, see thi
Although it does not seem like it is the case but from AIO perspective a Cloudflare Tunnel works like a reverse proxy. Please see the [caveats](https://github.com/nextcloud/all-in-one#notes-on-cloudflare-proxytunnel) before proceeding. Here is then how to make it work:
1. Install the Cloudflare Tunnel on the same machine where AIO will be running on and point the Tunnel with the domain that you want to use for AIO to `http://localhost:11000`.<br>
⚠️ **Please note:** Look into [this](#adapting-the-sample-web-server-configurations-below) to adapt the above example configuration.
1. Now continue with [point 2](#2-use-this-startup-command) but additionally, add `--env SKIP_DOMAIN_VALIDATION=true` to the docker run command which will disable the domain validation (because it is known that the domain validation will not work behind a Cloudflare Tunnel). So you need to ensure yourself that you've configured everything correctly.
⚠️ **Please note:** look into [this](#adapting-the-sample-web-server-configurations-below) to adapt the above example configuration.
1. Now continue with [point 2](#2-use-this-startup-command) but add `--env SKIP_DOMAIN_VALIDATION=true` to the docker run command - which will disable the domain validation (because it is known that the domain validation will not work behind a Cloudflare Tunnel).
**Advice:** Make sure to [disable Cloudflares Rocket Loader feature](https://help.nextcloud.com/t/login-page-not-working-solved/149417/8) as otherwise Nextcloud's login prompt will not be shown.
@@ -310,11 +317,11 @@ backend Nextcloud
<summary>click here to expand</summary>
**Disclaimer:** This config was tested and should normally work on all modern nginx version if you configure it correctly. Improvements to the config are very welcome!
**Disclaimer:** This config was tested and should normally work on all modern Nginx versions. Improvements to the config are very welcome!
Add the below template to your nginx config.
Add the below template to your Nginx config.
**Note:** please check your nginx version by running: `nginx -v` and adjust it the lines marked with version notes, so that they fit your nginx version.
**Note:** please check your Nginx version by running: `nginx -v` and adjust the lines marked with version notes to fit your version.
```
map $http_upgrade $connection_upgrade {
@@ -353,10 +360,9 @@ server {
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Accept-Encoding "";
proxy_set_header Host $host;
client_body_buffer_size 512k;
proxy_request_buffering off;
proxy_read_timeout 86400s;
client_max_body_size 0;
@@ -393,19 +399,19 @@ server {
```
⚠️ **Please note:** Look into [this](#adapting-the-sample-web-server-configurations-below) to adapt the above example configuration.
⚠️ **Please note:** look into [this](#adapting-the-sample-web-server-configurations-below) to adapt the above example configuration.
**Advice:** You may have a look at [this](https://github.com/nextcloud/all-in-one/discussions/588#discussioncomment-2811152) for a more complete example.
</details>
### Nginx-Proxy-Manager
### Nginx-Proxy-Manager - NPM
<details>
<summary>click here to expand</summary>
First, please make sure that the environmental variables `PUID` and `PGID` in the compose.yaml file for NPM are either unset or set to `0`.
First, make sure the environmental variables `PUID` and `PGID` in the `compose.yaml` file for NPM are either unset or set to `0`.
If you need to change the GID/PID then please add `net.ipv4.ip_unprivileged_port_start=0` at the end of `/etc/sysctl.conf`. Note: this will cause that non root users can bind privileged ports.
Second, see these screenshots for a working config:
@@ -424,8 +430,7 @@ proxy_read_timeout 86400s;
client_max_body_size 0;
```
⚠️ **Please note:** Look into [this](#adapting-the-sample-web-server-configurations-below) to adapt the above example configuration.
⚠️ **Please note:** look into [this](#adapting-the-sample-web-server-configurations-below) to adapt the above example configuration.
Also change `<you>@<your-mail-provider-domain>` to a mail address of yours.
</details>
@@ -436,12 +441,11 @@ Also change `<you>@<your-mail-provider-domain>` to a mail address of yours.
<summary>click here to expand</summary>
Unfortunately it is not possible to configure nginx-proxy in a way that works because it completely relies on environmental variables of the docker containers itself. Providing these variables does not work as stated above.
Unfortunately, it is not possible to configure Nginx-proxy in a way that works because it completely relies on environmental variables of the docker containers itself. Providing these variables does not work as stated above.
If you really want to use AIO, we recommend you to switch to caddy. It is simply amazing!<br>
Of course understandable if that is not possible for you.
Apart from that, there is this: [manual-install](https://github.com/nextcloud/all-in-one/tree/main/manual-install)
Apart from that, there is a [manual-install](https://github.com/nextcloud/all-in-one/tree/main/manual-install).
</details>
@@ -451,7 +455,7 @@ Apart from that, there is this: [manual-install](https://github.com/nextcloud/al
<summary>click here to expand</summary>
**Disclaimer:** It might be possible that the config below is not working 100% correctly, yet. Improvements to it are very welcome!
**Disclaimer:** it might be possible that the config below is not working 100% correctly, yet. Improvements to it are very welcome!
For Node.js, we will use the npm package `http-proxy`. WebSockets must be handled separately.
@@ -528,7 +532,7 @@ httpServer.on('upgrade', (req, socket, head) => {
});
```
⚠️ **Please note:** Look into [this](#adapting-the-sample-web-server-configurations-below) to adapt the above example configuration.
⚠️ **Please note:** look into [this](#adapting-the-sample-web-server-configurations-below) to adapt the above example configuration.
</details>
@@ -538,7 +542,7 @@ httpServer.on('upgrade', (req, socket, head) => {
<summary>click here to expand</summary>
**Disclaimer:** It might be possible that the config below is not working 100% correctly, yet. Improvements to it are very welcome!
**Disclaimer:** it might be possible that the config below is not working 100% correctly, yet. Improvements to it are very welcome!
See these screenshots for a working config:
@@ -546,7 +550,7 @@ See these screenshots for a working config:
![image](https://user-images.githubusercontent.com/70434961/213193789-fa936edc-e307-4e6a-9a53-ae26d1bf2f42.jpg)
⚠️ **Please note:** Look into [this](#adapting-the-sample-web-server-configurations-below) to adapt the above example configuration.
⚠️ **Please note:** look into [this](#adapting-the-sample-web-server-configurations-below) to adapt the above example configuration.
</details>
@@ -556,7 +560,7 @@ See these screenshots for a working config:
<summary>click here to expand</summary>
**Disclaimer:** It might be possible that the config below is not working 100% correctly, yet. Improvements to it are very welcome!
**Disclaimer:** it might be possible that the config below is not working 100% correctly, yet. Improvements to it are very welcome!
Traefik's building blocks (router, service, middlewares) need to be defined using dynamic configuration similar to [this](https://doc.traefik.io/traefik/providers/file/#configuration-examples) official Traefik configuration example. Using **docker labels _won't work_** because of the nature of the project.
@@ -633,8 +637,7 @@ The examples below define the dynamic configuration in YAML files. If you rather
---
⚠️ **Please note:** Look into [this](#adapting-the-sample-web-server-configurations-below) to adapt the above example configuration.
⚠️ **Please note:** look into [this](#adapting-the-sample-web-server-configurations-below) to adapt the above example configuration.
**Hint**: see https://www.youtube.com/watch?v=VLPSRrLMDmA for a video on configuring Traefik.
</details>
@@ -721,7 +724,7 @@ Config examples for other reverse proxies are currently not documented. Pull req
After adjusting your reverse proxy config, use the following command to start AIO:<br>
(For a docker-compose example, see the example further [below](#inspiration-for-a-docker-compose-file).)
(For a `compose.yaml` example, see the example further [below](#inspiration-for-a-docker-compose-file).)
```
# For Linux:
@@ -738,9 +741,9 @@ sudo docker run \
nextcloud/all-in-one:latest
```
Note: You may be interested in adjusting Nextclouds datadir to store the files in a different location than the default docker volume. See [this documentation](https://github.com/nextcloud/all-in-one#how-to-change-the-default-location-of-nextclouds-datadir) on how to do it.
Note: you may be interested in adjusting Nextclouds datadir to store the files in a different location than the default docker volume. See [this documentation](https://github.com/nextcloud/all-in-one#how-to-change-the-default-location-of-nextclouds-datadir) on how to do it.
You should also think about limiting the apache container to listen only on localhost in case the reverse proxy is running on the same host and in the host network, by providing an additional environmental variable to this docker run command. See [point 3](#3-limit-the-access-to-the-apache-container).
You should also think about limiting the Apache container to listen only on localhost in case the reverse proxy is running on the same host and in the host network, by providing an additional environmental variable to this docker run command. See [point 3](#3-limit-the-access-to-the-apache-container).
On macOS see https://github.com/nextcloud/all-in-one#how-to-run-aio-on-macos.
@@ -774,11 +777,12 @@ On Synology DSM see https://github.com/nextcloud/all-in-one#how-to-run-aio-on-sy
Simply translate the docker run command into a docker-compose file. You can have a look at [this file](https://github.com/nextcloud/all-in-one/blob/main/compose.yaml) for some inspiration but you will need to modify it either way. You can find further examples here: https://github.com/nextcloud/all-in-one/discussions/588
## 3. Limit the access to the apache container
## 3. Limit the access to the Apache container
Use this environment variable during the initial startup of the mastercontainer to make the apache container only listen on localhost: `--env APACHE_IP_BINDING=127.0.0.1`. **Attention:** This is only recommended to be set if you use `localhost` in your reverse proxy config to connect to your AIO instance. If you use an ip-address instead of localhost, you should set it to `0.0.0.0`.
## 4. Open the AIO interface.
## 4. Open the AIO interface
After starting AIO, you should be able to access the AIO Interface via `https://ip.address.of.the.host:8080`.<br>
⚠️ **Important:** do always use an ip-address if you access this port and not a domain as HSTS might block access to it later! (It is also expected that this port uses a self-signed certificate due to security concerns which you need to accept in your browser)<br>
Enter your domain in the AIO interface that you've used in the reverse proxy config and you should be done. Please do not forget to open/forward port `3478/TCP` and `3478/UDP` in your firewall/router for the Talk container!
@@ -801,17 +805,18 @@ https://<your-nc-domain>:8443 {
Afterwards should the AIO interface be accessible via `https://ip.address.of.the.host:8443`. You can alternatively change the domain to a different subdomain by using `https://<your-alternative-domain>:443` instead of `https://<your-nc-domain>:8443` in the Caddyfile and use that to access the AIO interface.
## 6. How to debug things?
If something does not work, follow the steps below:
1. Make sure to exactly follow the whole reverse proxy documentation step-for-step from top to bottom!
1. Make sure that you used the docker run command that is described in this reverse proxy documentation. **Hint:** make sure that you have set the `APACHE_PORT` via e.g. `--env APACHE_PORT=11000` during the docker run command!
1. Make sure that you used the `docker run` command that is described in this reverse proxy documentation. **Hint:** make sure that you have set the `APACHE_PORT` via e.g. `--env APACHE_PORT=11000` during the docker run command!
1. Make sure to set the `APACHE_IP_BINDING` variable correctly. If in doubt, set it to `--env APACHE_IP_BINDING=0.0.0.0`
1. Make sure that all ports to which your reverse proxy is pointing match the chosen `APACHE_PORT`.
1. Make sure to follow [this](#adapting-the-sample-web-server-configurations-below) to adapt the example configurations to your specific setup
1. Make sure to follow [this](#adapting-the-sample-web-server-configurations-below) to adapt the example configurations to your specific setup!
1. Make sure that the mastercontainer is able to spawn other containers. You can do so by checking that the mastercontainer indeed has access to the Docker socket which might not be positioned in one of the suggested directories like `/var/run/docker.sock` but in a different directory, based on your OS and the way how you installed Docker. The mastercontainer logs should help figuring this out. You can have a look at them by running `sudo docker logs nextcloud-aio-mastercontainer` after the container is started the first time.
1. Check if after the mastercontainer was started, the reverse proxy if running inside a container, can reach the provided apache port. You can test this by running `nc -z localhost 11000; echo $?` from inside the reverse proxy container. If the output is `0`, everything works. Alternatively you can of course use instead of `localhost` the ip-address of the host here for the test.
1. Make sure that you are not behind CGNAT. If that is the case, you will not be able to open ports properly. In that case you might use a Cloudflare Tunnel.
1. If you use Cloudflare, you might need to skip the domain validation anyways since it is known that Cloudflare might block the validation attempts. In that case, see the last option below.
1. If your reverse proxy is configured to use the host network (as recommended in the above docs) or running on the host, make sure that you've configured your firewall to open port 443 and 80.
1. Check if you have a public IPv4- and public IPv6-address. If you only have a public IPv6-address (e.g. due to DS-Lite), make sure to enable IPv6 in Docker and your whole networking infrastructure (e.g. also by adding an AAAA DNS-entry to your domain).
1. Try to configure everything from scratch if it still does not work by following https://github.com/nextcloud/all-in-one#how-to-properly-reset-the-instance.
1. Make sure that you are not behind CGNAT. If that is the case, you will not be able to open ports properly. In that case you might use a Cloudflare Tunnel!
1. If you use Cloudflare, you might need to skip the domain validation anyways since it is known that Cloudflare might block the validation attempts. In that case, see the last option below!
1. If your reverse proxy is configured to use the host network (as recommended in the above docs) or running on the host, make sure that you've configured your firewall to open port 443 (and 80)!
1. Check if you have a public IPv4- and public IPv6-address. If you only have a public IPv6-address (e.g. due to DS-Lite), make sure to enable IPv6 in Docker and your whole networking infrastructure (e.g. also by adding an AAAA DNS-entry to your domain)!
1. Try to configure everything from scratch - if it still does not work by following https://github.com/nextcloud/all-in-one#how-to-properly-reset-the-instance.
1. As last resort, you may disable the domain validation by adding `--env SKIP_DOMAIN_VALIDATION=true` to the docker run command. But only use this if you are completely sure that you've correctly configured everything!