Compare commits

...

45 Commits

Author SHA1 Message Date
Pablo Zmdl
624601b1d4 Use WORKDIR instead of cd
To fulfill DL3003

Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-03-24 20:17:06 +01:00
Pablo Zmdl
a9c3daedb1 Fix wrong spelling
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-03-24 20:15:06 +01:00
Pablo Zmdl
1039363de6 Allow arbitrary characters in passwords
This converts some shell scripted commands to small golang tools
("aio-container-tools") in order to ensure proper string handling.

In effect database passwords now can contain all characters, even emojis
and quotes.

AI-assistant: Copilot v1.0.7 (Claude Sonnet 4.6)

Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-03-24 20:11:34 +01:00
Simon L.
c777cbaf45 Merge pull request #7809 from nextcloud/dependabot/github_actions/dot-github/workflows/astral-sh/setup-uv-7.6.0
build(deps): bump astral-sh/setup-uv from 7.3.1 to 7.6.0 in /.github/workflows
2026-03-24 15:39:35 +01:00
dependabot[bot]
1739ab0a7b build(deps): bump astral-sh/setup-uv in /.github/workflows
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 7.3.1 to 7.6.0.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](5a095e7a20...37802adc94)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: 7.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-24 12:06:03 +00:00
Simon L.
7c8cabdb2d Merge pull request #7802 from nextcloud/dependabot/docker/Containers/collabora/collabora/code-25.04.9.4.1
build(deps): bump collabora/code from 25.04.9.3.1 to 25.04.9.4.1 in /Containers/collabora
2026-03-23 08:43:13 +01:00
dependabot[bot]
7049448541 build(deps): bump collabora/code in /Containers/collabora
Bumps collabora/code from 25.04.9.3.1 to 25.04.9.4.1.

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-23 04:08:55 +00:00
Simon L.
35dd0a2c00 Merge pull request #7762 from nextcloud/alan/fix-wopi
fix collabora not working anymore
2026-03-20 16:06:04 +01:00
Simon L.
fbe60b852c Merge pull request #7763 from nextcloud/alan/fix-bypass
aio-interface: Fix bypass_container_update when not detected as available
2026-03-20 16:05:44 +01:00
Alan Savage
5782a01b7f Fix bypass_container_update when not detected as available
isAnyUpdateAvailable is not necessarily synced with the PullImage
logic from DockerActionManager. This ensures no images are pulled
regardless of detection.

There's also a minor code improvement to avoid unnecessary interpolation.

Signed-off-by: Alan Savage <3028205+asavageiv@users.noreply.github.com>
2026-03-20 15:42:54 +01:00
Alan Savage
46b325f2bd Workaround #7757 with nextcloud-aio-apache FQDN
CollaboraOnline/online/pull/13869 prevents http://nextcloud-aio-apache:23973 from
being correctly recognized as a valid URI and thus breaks matching as an
authorized WOPI host.

This uses http://nextcloud-aio-apache.nextcloud-aio:23973 which is correctly
recognized as a valid URI.

Signed-off-by: Alan Savage <3028205+asavageiv@users.noreply.github.com>
2026-03-20 15:42:49 +01:00
Copilot
05f9fa0e25 Fix playwright CI tests broken by Apache→Caddy switch (#7795)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: szaimen <42591237+szaimen@users.noreply.github.com>
2026-03-20 15:27:54 +01:00
Simon L.
443f3a4bee Merge pull request #6168 from nextcloud/enh/noid/update-qa-tests
QA-tests: update some sections and details
2026-03-20 13:35:00 +01:00
Simon L.
d280786934 QA-tests: update some details
Signed-off-by: Simon L. <szaimen@e.mail.de>
Co-Authored-By: szaimen <42591237+szaimen@users.noreply.github.com>
2026-03-20 13:34:16 +01:00
Simon L.
253df4ee0c Merge pull request #7789 from nextcloud/automated/noid/psalm-baseline-update
[Automated] Update psalm-baseline.xml
2026-03-20 09:41:01 +01:00
Simon L.
8073f3c562 Merge pull request #7788 from nextcloud/dependabot/docker/Containers/fulltextsearch/elasticsearch-8.19.13
build(deps): bump elasticsearch from 8.19.12 to 8.19.13 in /Containers/fulltextsearch
2026-03-20 09:40:44 +01:00
Simon L.
a3dac35edb Merge pull request #7787 from nextcloud/dependabot/docker/Containers/docker-socket-proxy/haproxy-3.3.6-alpine
build(deps): bump haproxy from 3.3.5-alpine to 3.3.6-alpine in /Containers/docker-socket-proxy
2026-03-20 09:40:26 +01:00
nextcloud-command
b222639bbd Update psalm baseline
Signed-off-by: GitHub <noreply@github.com>
2026-03-20 04:40:46 +00:00
dependabot[bot]
a5d4f2dd88 build(deps): bump elasticsearch in /Containers/fulltextsearch
Bumps elasticsearch from 8.19.12 to 8.19.13.

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-20 04:06:40 +00:00
dependabot[bot]
51c7b270b4 build(deps): bump haproxy in /Containers/docker-socket-proxy
Bumps haproxy from 3.3.5-alpine to 3.3.6-alpine.

---
updated-dependencies:
- dependency-name: haproxy
  dependency-version: 3.3.6-alpine
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-20 04:06:36 +00:00
Simon L.
754a317fea Merge pull request #7783 from nextcloud/revert-7769-enh/7765/refactor-network-creation
Revert "mastercontainer: create the nextcloud-aio network during start.sh and attach mastercontainer to it"
2026-03-19 14:24:30 +01:00
Simon L.
7f35ee5fbb Revert "mastercontainer: create the nextcloud-aio network during start.sh and attach mastercontainer to it" 2026-03-19 14:22:13 +01:00
Simon L.
b7b6cc8a16 Merge pull request #7781 from nextcloud/dependabot/composer/php/vimeo/psalm-6.16.1
build(deps-dev): bump vimeo/psalm from 6.16.0 to 6.16.1 in /php
2026-03-19 13:52:28 +01:00
Simon L.
7dc489168a psalm: revert changes
Signed-off-by: Simon L. <szaimen@e.mail.de>
2026-03-19 13:51:12 +01:00
dependabot[bot]
d71683ff38 build(deps-dev): bump vimeo/psalm from 6.16.0 to 6.16.1 in /php
Bumps [vimeo/psalm](https://github.com/vimeo/psalm) from 6.16.0 to 6.16.1.
- [Release notes](https://github.com/vimeo/psalm/releases)
- [Commits](https://github.com/vimeo/psalm/compare/6.16.0...6.16.1)

---
updated-dependencies:
- dependency-name: vimeo/psalm
  dependency-version: 6.16.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-19 12:03:55 +00:00
Simon L.
d4743d9800 Merge pull request #7769 from nextcloud/enh/7765/refactor-network-creation
mastercontainer: create the nextcloud-aio network during start.sh and attach mastercontainer to it
2026-03-19 12:54:43 +01:00
Simon L.
f1b635c196 Merge pull request #7777 from nextcloud/enh/noid/fix-health-check
mastercontainer: fix health-check
2026-03-19 12:54:13 +01:00
Simon L.
ecd85281cc Merge pull request #7779 from nextcloud/enh/7778/remote-host-login-endpoints
mastercontainer: use remote-host caddy plugin only for login endpoints
2026-03-19 12:53:28 +01:00
Simon L.
558e8735b5 mastercontainer: create the nextcloud-aio network during start.sh and attach mastercontainer to it
Signed-off-by: Simon L. <szaimen@e.mail.de>
2026-03-19 12:49:33 +01:00
Simon L.
e0ff3acb3d mastercontainer: use remote-host caddy plugin only for login endpoints
Signed-off-by: Simon L. <szaimen@e.mail.de>
2026-03-19 12:21:36 +01:00
Simon L.
4963558691 mastercontainer: fix health-check
Signed-off-by: Simon L. <szaimen@e.mail.de>
2026-03-19 11:39:14 +01:00
Simon L.
90d5d6bcf1 Merge pull request #7756 from nextcloud/aio-dependency-update
PHP dependency updates
2026-03-19 11:28:15 +01:00
Simon L.
b19c6dfddb Merge pull request #7731 from nextcloud/enh/noid/move-appdata-dir
readme: add section how to move the appdata folder from the datadir to an ssd to improve the performance
2026-03-19 11:27:04 +01:00
szaimen
904921c815 php dependency updates
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-19 09:14:59 +00:00
Simon L.
7d63b13a40 Merge pull request #7775 from nextcloud/automated/noid/psalm-baseline-update
[Automated] Update psalm-baseline.xml
2026-03-19 10:13:03 +01:00
nextcloud-command
83102e46b2 Update psalm baseline
Signed-off-by: GitHub <noreply@github.com>
2026-03-19 04:46:16 +00:00
Simon L.
9e49f81c43 Merge pull request #7772 from nextcloud/enh/noid/suppress-psalm
ignore psalm error
2026-03-18 20:02:13 +01:00
Pi-Farm
25a63abbc8 Merge pull request #7472 from pi-farm/cc_glances
New Community-Container: Glances
2026-03-18 20:01:24 +01:00
Simon L.
f1eeea9337 ignore psalm error
Signed-off-by: Simon L. <szaimen@e.mail.de>
2026-03-18 19:58:53 +01:00
Simon L.
156e55d0ad Merge pull request #7755 from nextcloud/dependabot/composer/php/vimeo/psalm-6.16.0
build(deps-dev): bump vimeo/psalm from 6.15.1 to 6.16.0 in /php
2026-03-18 18:25:08 +01:00
dependabot[bot]
c5501c885d build(deps-dev): bump vimeo/psalm from 6.15.1 to 6.16.0 in /php
Bumps [vimeo/psalm](https://github.com/vimeo/psalm) from 6.15.1 to 6.16.0.
- [Release notes](https://github.com/vimeo/psalm/releases)
- [Commits](https://github.com/vimeo/psalm/compare/6.15.1...6.16.0)

---
updated-dependencies:
- dependency-name: vimeo/psalm
  dependency-version: 6.16.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Simon L. <szaimen@e.mail.de>
2026-03-18 18:10:41 +01:00
Simon L.
de7b5cd8e4 Merge pull request #7767 from nextcloud/watchtower-container-update
watchtower container update
2026-03-18 18:03:56 +01:00
szaimen
1e76d39742 watchtower-update automated change
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-18 12:23:46 +00:00
Simon L.
d761f22fa1 address review
Signed-off-by: Simon L. <szaimen@e.mail.de>
2026-03-17 11:53:35 +01:00
Simon L.
1b69fb88ae readme: add section how to move the appdata folder from the datadir to an ssd to improve the performance
Signed-off-by: Simon L. <szaimen@e.mail.de>
2026-03-16 14:04:03 +01:00
42 changed files with 520 additions and 101 deletions

View File

@@ -36,7 +36,7 @@ jobs:
line-length: warning
- name: Install the latest version of uv
uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098 # v7.3.1
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
- name: Check GitHub actions
run: uvx zizmor --min-severity medium .github/workflows/*.yml

View File

@@ -19,10 +19,6 @@ jobs:
extensions: apcu
coverage: none
ini-file: development
jit: false
ini_values: |
opcache.jit=0
opcache.jit_buffer_size=0
- name: Run script
run: |

View File

@@ -43,10 +43,6 @@ jobs:
extensions: apcu
coverage: none
ini-file: development
jit: false
ini_values: |
opcache.jit=0
opcache.jit_buffer_size=0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -15,7 +15,7 @@
}
https://{$ADDITIONAL_TRUSTED_DOMAIN}:443,
http://{$APACHE_HOST}:23973, # For Collabora callback and WOPI requests, see containers.json
http://{$APACHE_HOST}.nextcloud-aio:23973, # For Collabora callback and WOPI requests, see containers.json
{$PROTOCOL}://{$NC_DOMAIN}:{$APACHE_PORT} {
header -Server
header -X-Powered-By

View File

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

View File

@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:latest
FROM haproxy:3.3.5-alpine
FROM haproxy:3.3.6-alpine
# hadolint ignore=DL3002
USER root

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:latest
# Probably from here https://github.com/elastic/elasticsearch/blob/main/distribution/docker/src/docker/Dockerfile
FROM elasticsearch:8.19.12
FROM elasticsearch:8.19.13
USER root

View File

@@ -17,7 +17,8 @@
}
servers {
protocols h1 h2 h2c
# Only h1 is allowed as we prevent `ERR_NETWORK_CHANGED` from happening
protocols h1
}
on_demand_tls {
@@ -32,11 +33,13 @@ http://:80 {
}
https://:8443 {
@denied remote_host nextcloud-aio-nextcloud
@denied {
path /api/auth/login /api/auth/getlogin
remote_host nextcloud-aio-nextcloud
}
abort @denied
root * /var/www/docker-aio/php/public
encode
php_fastcgi unix//run/php.sock
file_server

View File

@@ -4,6 +4,6 @@ if [ -f "/mnt/docker-aio-config/data/configuration.json" ]; then
nc -z 127.0.0.1 80 || exit 1
nc -z 127.0.0.1 8080 || exit 1
nc -z 127.0.0.1 8443 || exit 1
[ -f /run/php.sock ] || exit 1
test -S /run/php.sock || exit 1
nc -z 127.0.0.1 9876 || exit 1
fi

View File

@@ -13,18 +13,21 @@
}
servers {
protocols h1 h2
# Only h1 is allowed as we prevent `ERR_NETWORK_CHANGED` from happening
protocols h1
}
skip_install_trust
}
https://:8080 {
@denied remote_host nextcloud-aio-nextcloud
@denied {
path /api/auth/login /api/auth/getlogin
remote_host nextcloud-aio-nextcloud
}
abort @denied
root * /var/www/docker-aio/php/public
encode
php_fastcgi unix//run/php.sock
file_server

View File

@@ -1,4 +1,11 @@
# syntax=docker/dockerfile:latest
FROM docker.io/library/golang:alpine AS aio-container-tools-builder
# hadolint ignore=DL3022
COPY --from=aio-container-tools . /tmp/aio-container-tools/
WORKDIR /tmp/aio-container-tools
RUN go build -o /usr/local/bin/aio-pg-healthcheck ./cmd/aio-pg-healthcheck
FROM php:8.3.30-fpm-alpine3.23
ENV PHP_MEMORY_LIMIT=512M
@@ -17,6 +24,7 @@ COPY --chmod=775 Containers/nextcloud/*.sh /
COPY --chmod=774 Containers/nextcloud/upgrade.exclude /upgrade.exclude
COPY Containers/nextcloud/config/*.php /
COPY Containers/nextcloud/supervisord.conf /supervisord.conf
COPY --from=aio-container-tools-builder /usr/local/bin/aio-pg-healthcheck /usr/local/bin/aio-pg-healthcheck
# AIO cloning start # Do not remove or change this line!
COPY app /usr/src/nextcloud/apps/nextcloud-aio
@@ -226,7 +234,6 @@ RUN set -ex; \
openssl \
gnupg \
git \
postgresql-client \
tzdata \
sudo \
grep \

View File

@@ -25,7 +25,7 @@ fi
# Fix false database connection on old instances
if [ -f "/var/www/html/config/config.php" ]; then
sleep 2
while ! sudo -E -u www-data psql -d "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST:$POSTGRES_PORT/$POSTGRES_DB" -c "select now()"; do
while ! sudo -E -u www-data /usr/local/bin/aio-pg-healthcheck; do
echo "Waiting for the database to start..."
sleep 5
done

View File

@@ -1,8 +1,18 @@
# syntax=docker/dockerfile:latest
FROM docker.io/library/golang:alpine AS aio-container-tools-builder
# hadolint ignore=DL3022
COPY --from=aio-container-tools . /tmp/aio-container-tools/
WORKDIR /tmp/aio-container-tools
RUN go build -o /usr/local/bin/aio-pg-init ./cmd/aio-pg-init \
&& go build -o /usr/local/bin/aio-pg-healthcheck ./cmd/aio-pg-healthcheck
# From https://github.com/docker-library/postgres/blob/master/17/alpine3.23/Dockerfile
FROM postgres:17.9-alpine
COPY --chmod=775 start.sh /start.sh
COPY --from=aio-container-tools-builder /usr/local/bin/aio-pg-init /usr/local/bin/aio-pg-init
COPY --from=aio-container-tools-builder /usr/local/bin/aio-pg-healthcheck /usr/local/bin/aio-pg-healthcheck
COPY --chmod=775 healthcheck.sh /healthcheck.sh
COPY --chmod=775 init-user-db.sh /docker-entrypoint-initdb.d/init-user-db.sh

View File

@@ -2,6 +2,4 @@
test -f "/mnt/data/backup-is-running" && exit 0
psql -d "postgresql://oc_$POSTGRES_USER:$POSTGRES_PASSWORD@127.0.0.1:11000/$POSTGRES_DB" -c "select now()" && exit 0
psql -d "postgresql://oc_$POSTGRES_USER:$POSTGRES_PASSWORD@127.0.0.1:5432/$POSTGRES_DB" -c "select now()" || exit 1
POSTGRES_PORT=11000 /usr/local/bin/aio-pg-healthcheck debug || exec /usr/local/bin/aio-pg-healthcheck

View File

@@ -3,12 +3,7 @@ set -ex
touch "$DUMP_DIR/initialization.failed"
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";
GRANT ALL PRIVILEGES ON DATABASE "$POSTGRES_DB" TO "oc_$POSTGRES_USER";
GRANT ALL PRIVILEGES ON SCHEMA public TO "oc_$POSTGRES_USER";
EOSQL
POSTGRES_DB_OWNER="oc_$POSTGRES_USER" /usr/local/bin/aio-pg-init
rm "$DUMP_DIR/initialization.failed"

View File

@@ -4,6 +4,7 @@
DATADIR="/var/lib/postgresql/data"
export DUMP_DIR="/mnt/data"
DUMP_FILE="$DUMP_DIR/database-dump.sql"
# TODO: Do we need this? It's not used anywhere visible
export PGPASSWORD="$POSTGRES_PASSWORD"
# Don't start database as long as backup is running
@@ -85,7 +86,7 @@ if ( [ -f "$DATADIR/PG_VERSION" ] && [ "$PG_MAJOR" != "$(cat "$DATADIR/PG_VERSIO
exec docker-entrypoint.sh postgres &
# Wait for creation
while ! psql -d "postgresql://oc_$POSTGRES_USER:$POSTGRES_PASSWORD@127.0.0.1:11000/$POSTGRES_DB" -c "select now()"; do
while ! env POSTGRES_PORT=11000 POSTGRES_USER="oc_$POSTGRES_USER" /usr/local/bin/aio-pg-healthcheck; do
echo "Waiting for the database to start."
sleep 5
done
@@ -107,12 +108,7 @@ if ( [ -f "$DATADIR/PG_VERSION" ] && [ "$PG_MAJOR" != "$(cat "$DATADIR/PG_VERSIO
exit 1
elif [ "$DB_OWNER" != "oc_$POSTGRES_USER" ]; then
DIFFERENT_DB_OWNER=1
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE USER "$DB_OWNER" WITH PASSWORD '$POSTGRES_PASSWORD' CREATEDB;
ALTER DATABASE "$POSTGRES_DB" OWNER TO "$DB_OWNER";
GRANT ALL PRIVILEGES ON DATABASE "$POSTGRES_DB" TO "$DB_OWNER";
GRANT ALL PRIVILEGES ON SCHEMA public TO "$DB_OWNER";
EOSQL
POSTGRES_DB_OWNER="$DB_OWNER" /usr/local/bin/aio-pg-init
fi
# Restore database

View File

@@ -1,13 +1,13 @@
# syntax=docker/dockerfile:latest
FROM golang:1.26.1-alpine3.23 AS go
ENV WATCHTOWER_COMMIT_HASH=2a3fe10ad86f36a7f208105bbe1fb29e51caac5b
ENV WATCHTOWER_COMMIT_HASH=5a33e3c0aa3b2770c648a114b4a9d32e0a5b55ba
RUN set -ex; \
apk upgrade --no-cache -a; \
apk add --no-cache \
build-base; \
go install github.com/nicholas-fedor/watchtower@$WATCHTOWER_COMMIT_HASH # v1.14.3
go install github.com/nicholas-fedor/watchtower@$WATCHTOWER_COMMIT_HASH # v1.14.4
FROM alpine:3.23.3

View File

@@ -0,0 +1,42 @@
# aio-container-tools
Standalone tools for Nextcloud AIO containers, for tasks that shouldn't be executed in a shell environment
(e.g. due to string handling issues).
Golang was chosen because it doesn't require additional runtimes in the containers, and has a pretty easy
syntax that is comprehensible even for people without much experience with the language.
The tools should be built in the container image build process, so they are built for the correct target
platform in multi-arch builds. See below for an example.
## Build process
To include the binary of `aio-pg-healhcheck` into your container image, include such a snippet into your Containerfile:
```dockerfile
FROM docker.io/library/golang:alpine AS golang-builder
# hadolint ignore=DL3022
COPY --from=aio-container-tools . /tmp/aio-container-tools/
RUN cd /tmp/aio-container-tools \
&& go build -o /usr/local/bin/aio-pg-healthcheck ./cmd/aio-pg-healthcheck
FROM your-base-image
COPY --from=golang-builder /usr/local/bin/aio-pg-healthcheck /usr/local/bin/
```
To build it you now have to pass the aio-container-tools directory as additional, named build-context like this:
```bash
docker build \
--build-context aio-container-tools=/path/to/all-in-one/aio-container-tools \
.
```
#### Remote git variant (without local clone of this repo)
```bash
docker build \
--build-context aio-container-tools="https://github.com/nextcloud-releases/all-in-one.git#main:aio-container-tools" \
.
```

View File

@@ -0,0 +1,92 @@
package main
import (
"context"
"flag"
"fmt"
"os"
"strconv"
"github.com/jackc/pgx/v5"
"github.com/nextcloud/aio-container-tools/internal/util"
)
// tryConnect opens a TCP connection to the given database host:port and runs SELECT 1.
// Returns nil on success, an error otherwise.
func tryConnect(ctx context.Context, host string, port uint16, user, password, database string) error {
util.Debugf("attempting connection: host=%s port=%d user=%s database=%s", host, port, user, database)
cfg, err := pgx.ParseConfig("")
if err != nil {
return err
}
cfg.Host = host
cfg.Port = port
cfg.User = user
cfg.Password = password
cfg.Database = database
conn, err := pgx.ConnectConfig(ctx, cfg)
if err != nil {
util.Debugf("connection failed: %v", err)
return err
}
defer conn.Close(ctx)
util.Debugf("connection established, running SELECT 1")
var result string
if err := conn.QueryRow(ctx, "SELECT 1").Scan(&result); err != nil {
util.Debugf("SELECT 1 failed: %v", err)
return err
}
util.Debugf("SELECT 1 returned %q", result)
return nil
}
// envOrDefault returns the value of the named environment variable,
// or the provided default if the variable is unset or empty.
func envOrDefault(key, defaultVal string) string {
if v := os.Getenv(key); v != "" {
util.Debugf("env %s = %q", key, v)
return v
}
util.Debugf("env %s not set, using default %q", key, defaultVal)
return defaultVal
}
func main() {
debug := flag.Bool("debug", false, "enable debug output")
flag.Parse()
util.SetDebug(*debug)
util.Debugf("reading required environment variables")
pgUser := util.RequireEnv("POSTGRES_USER")
pgPassword := util.RequireEnv("POSTGRES_PASSWORD")
pgDB := util.RequireEnv("POSTGRES_DB")
ctx := context.Background()
pgHost := envOrDefault("POSTGRES_HOST", "127.0.0.1")
var pgPort uint16 = 5432
if portStr := os.Getenv("POSTGRES_PORT"); portStr != "" {
util.Debugf("env POSTGRES_PORT = %q", portStr)
p, err := strconv.ParseUint(portStr, 10, 16)
if err != nil {
fmt.Fprintf(os.Stderr, "invalid POSTGRES_PORT %q: %v\n", portStr, err)
os.Exit(1)
}
pgPort = uint16(p)
} else {
util.Debugf("env POSTGRES_PORT not set, using default port %d", pgPort)
}
util.Debugf("connecting to: host=%s port=%d user=%s", pgHost, pgPort, pgUser)
if err := tryConnect(ctx, pgHost, pgPort, pgUser, pgPassword, pgDB); err == nil {
util.Debugf("connection succeeded, exiting 0")
os.Exit(0)
}
util.Debugf("connection failed, exiting 1")
os.Exit(1)
}

View File

@@ -0,0 +1,78 @@
package main
import (
"context"
"flag"
"fmt"
"strings"
"github.com/jackc/pgx/v5"
"github.com/nextcloud/aio-container-tools/internal/util"
)
// quoteLiteral safely quotes a string as a PostgreSQL string literal.
// Single quotes are escaped by doubling them. This is safe with
// standard_conforming_strings=on (default since PostgreSQL 9.1).
func quoteLiteral(s string) string {
return "'" + strings.ReplaceAll(s, "'", "''") + "'"
}
// main reimplements init-user-db.sh:
// - Creates $POSTGRES_DB_OWNER (falling back to $POSTGRES_USER) with $POSTGRES_PASSWORD and CREATEDB
// - Transfers ownership of $POSTGRES_DB to that user
// - Grants all privileges on the database and public schema
// - Connects using $POSTGRES_USER in all cases
func main() {
debug := flag.Bool("debug", false, "enable debug output")
flag.Parse()
util.SetDebug(*debug)
util.Debugf("reading required environment variables")
pgUser := util.RequireEnv("POSTGRES_USER")
pgPassword := util.RequireEnv("POSTGRES_PASSWORD")
pgDB := util.RequireEnv("POSTGRES_DB")
pgDBOwner := util.OptionalEnv("POSTGRES_DB_OWNER", pgUser)
util.Debugf("building connection config: host=/var/run/postgresql port=5432 user=%s database=%s", pgUser, pgDB)
cfg, err := pgx.ParseConfig("")
if err != nil {
util.ErrorOut(fmt.Errorf("building connection config: %w", err))
}
cfg.Host = "/var/run/postgresql"
cfg.Port = 5432
cfg.User = pgUser
cfg.Password = pgPassword
cfg.Database = pgDB
ctx := context.Background()
util.Debugf("connecting to postgres via unix socket")
conn, err := pgx.ConnectConfig(ctx, cfg)
if err != nil {
util.ErrorOut(fmt.Errorf("connecting to postgres: %w", err))
}
defer conn.Close(ctx)
util.Debugf("connected successfully")
dbOwner := pgDBOwner
util.Debugf("dbOwner = %q (from POSTGRES_DB_OWNER=%q, POSTGRES_USER=%q)", dbOwner, pgDBOwner, pgUser)
// pgx.Identifier.Sanitize() double-quotes and escapes the identifier safely.
dbOwnerIdent := pgx.Identifier{dbOwner}.Sanitize()
dbIdent := pgx.Identifier{pgDB}.Sanitize()
util.Debugf("quoted dbOwnerIdent = %s, dbIdent = %s", dbOwnerIdent, dbIdent)
statements := []string{
fmt.Sprintf("CREATE USER %s WITH PASSWORD %s CREATEDB", dbOwnerIdent, quoteLiteral(pgPassword)),
fmt.Sprintf("ALTER DATABASE %s OWNER TO %s", dbIdent, dbOwnerIdent),
fmt.Sprintf("GRANT ALL PRIVILEGES ON DATABASE %s TO %s", dbIdent, dbOwnerIdent),
fmt.Sprintf("GRANT ALL PRIVILEGES ON SCHEMA public TO %s", dbOwnerIdent),
}
for i, stmt := range statements {
util.Debugf("executing statement %d/%d: %s", i+1, len(statements), stmt)
if _, err := conn.Exec(ctx, stmt); err != nil {
util.ErrorOut(fmt.Errorf("executing statement: %w", err))
}
util.Debugf("statement %d/%d succeeded", i+1, len(statements))
}
util.Debugf("all statements executed successfully")
}

View File

@@ -0,0 +1,10 @@
module github.com/nextcloud/aio-container-tools
go 1.25.1
require (
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.8.0 // indirect
golang.org/x/text v0.29.0 // indirect
)

View File

@@ -0,0 +1,15 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.8.0 h1:TYPDoleBBme0xGSAX3/+NujXXtpZn9HBONkQC7IEZSo=
github.com/jackc/pgx/v5 v5.8.0/go.mod h1:QVeDInX2m9VyzvNeiCJVjCkNFqzsNb43204HshNSZKw=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -0,0 +1,49 @@
package util
import (
"fmt"
"log"
"os"
)
var debugEnabled bool
// SetDebug enables or disables debug output.
func SetDebug(enabled bool) {
debugEnabled = enabled
}
// Debugf prints a formatted debug message to stdout when debug mode is enabled.
func Debugf(format string, args ...any) {
if debugEnabled {
fmt.Printf("[debug] "+format+"\n", args...)
}
}
// RequireEnv returns the value of the named environment variable.
// It writes an error to stderr and exits with code 1 if the variable is unset or empty.
func RequireEnv(key string) string {
v := os.Getenv(key)
if v == "" {
fmt.Fprintf(os.Stderr, "required environment variable %q is not set\n", key)
os.Exit(1)
}
Debugf("env %s = %q", key, v)
return v
}
// OptionalEnv returns the value of the named environment variable, or fallback if it is unset or empty.
func OptionalEnv(key, fallback string) string {
v := os.Getenv(key)
if v == "" {
Debugf("env %s unset, using fallback %q", key, fallback)
return fallback
}
Debugf("env %s = %q", key, v)
return v
}
// ErrorOut logs the error with a standard prefix and exits with code 1.
func ErrorOut(err error) {
log.Fatalf("error: %v", err)
}

View File

@@ -0,0 +1,38 @@
{
"aio_services_v1": [
{
"container_name": "nextcloud-aio-glances",
"display_name": "Glances",
"documentation": "https://github.com/nextcloud/all-in-one/tree/main/community-containers/glances",
"image": "nicolargo/glances",
"image_tag": "latest-full",
"internal_port": "61208",
"restart": "unless-stopped",
"ports": [
{
"ip_binding": "",
"port_number": "61208",
"protocol": "tcp"
}
],
"volumes": [
{
"source": "nextcloud_aio_glances",
"destination": "/etc/glances",
"writeable": true
},
{
"source": "%WATCHTOWER_DOCKER_SOCKET_PATH%",
"destination": "/var/run/docker.sock",
"writeable": false
}
],
"environment": [
"GLANCES_OPT=-w"
],
"backup_volumes": [
"nextcloud_aio_glances"
]
}
]
}

View File

@@ -0,0 +1,18 @@
## Glances
This container starts Glances, a web-based info-board, and auto-configures it for you.
> [!CAUTION]
> This container mounts the docker-socket from the host-system.
### Notes
- After adding and starting the container, you can directly visit http://ip.address.of.server:61208/ and access your new Glances instance!
- It is recommended to start this container only in home networks, because there is no built-in authentication. But you can do a http-auth with your proxy.
- In order to access your Glances outside the local network, you have to set up your own reverse proxy. You can set up a reverse proxy following [these instructions](https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md).
- The data of Glances will be automatically included in AIO's backup solution!
- See [here](https://github.com/nextcloud/all-in-one/tree/main/community-containers#community-containers) how to add it to the AIO stack.
### Repository
https://github.com/nicolargo/glances
### Maintainer
https://github.com/pi-farm

37
php/composer.lock generated
View File

@@ -1780,16 +1780,16 @@
},
{
"name": "twig/twig",
"version": "v3.23.0",
"version": "v3.24.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9"
"reference": "a6769aefb305efef849dc25c9fd1653358c148f0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9",
"reference": "a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/a6769aefb305efef849dc25c9fd1653358c148f0",
"reference": "a6769aefb305efef849dc25c9fd1653358c148f0",
"shasum": ""
},
"require": {
@@ -1799,7 +1799,8 @@
"symfony/polyfill-mbstring": "^1.3"
},
"require-dev": {
"phpstan/phpstan": "^2.0",
"php-cs-fixer/shim": "^3.0@stable",
"phpstan/phpstan": "^2.0@stable",
"psr/container": "^1.0|^2.0",
"symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0"
},
@@ -1843,7 +1844,7 @@
],
"support": {
"issues": "https://github.com/twigphp/Twig/issues",
"source": "https://github.com/twigphp/Twig/tree/v3.23.0"
"source": "https://github.com/twigphp/Twig/tree/v3.24.0"
},
"funding": [
{
@@ -1855,7 +1856,7 @@
"type": "tidelift"
}
],
"time": "2026-01-23T21:00:41+00:00"
"time": "2026-03-17T21:31:11+00:00"
}
],
"packages-dev": [
@@ -3591,16 +3592,16 @@
},
{
"name": "phpdocumentor/reflection-docblock",
"version": "6.0.2",
"version": "6.0.3",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
"reference": "897b5986ece6b4f9d8413fea345c7d49c757d6bf"
"reference": "7bae67520aa9f5ecc506d646810bd40d9da54582"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/897b5986ece6b4f9d8413fea345c7d49c757d6bf",
"reference": "897b5986ece6b4f9d8413fea345c7d49c757d6bf",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/7bae67520aa9f5ecc506d646810bd40d9da54582",
"reference": "7bae67520aa9f5ecc506d646810bd40d9da54582",
"shasum": ""
},
"require": {
@@ -3650,9 +3651,9 @@
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
"source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/6.0.2"
"source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/6.0.3"
},
"time": "2026-03-01T18:43:49+00:00"
"time": "2026-03-18T20:49:53+00:00"
},
{
"name": "phpdocumentor/type-resolver",
@@ -4699,16 +4700,16 @@
},
{
"name": "vimeo/psalm",
"version": "6.15.1",
"version": "6.16.1",
"source": {
"type": "git",
"url": "https://github.com/vimeo/psalm.git",
"reference": "28dc127af1b5aecd52314f6f645bafc10d0e11f9"
"reference": "f1f5de594dc76faf8784e02d3dc4716c91c6f6ac"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/vimeo/psalm/zipball/28dc127af1b5aecd52314f6f645bafc10d0e11f9",
"reference": "28dc127af1b5aecd52314f6f645bafc10d0e11f9",
"url": "https://api.github.com/repos/vimeo/psalm/zipball/f1f5de594dc76faf8784e02d3dc4716c91c6f6ac",
"reference": "f1f5de594dc76faf8784e02d3dc4716c91c6f6ac",
"shasum": ""
},
"require": {
@@ -4813,7 +4814,7 @@
"issues": "https://github.com/vimeo/psalm/issues",
"source": "https://github.com/vimeo/psalm"
},
"time": "2026-02-07T19:27:16+00:00"
"time": "2026-03-19T10:56:09+00:00"
},
{
"name": "wapmorgan/php-deprecation-detector",

View File

@@ -379,7 +379,7 @@
],
"internal_port": "9980",
"environment": [
"aliasgroup1=https://%NC_DOMAIN%:443,http://nextcloud-aio-apache:23973",
"aliasgroup1=https://%NC_DOMAIN%:443,http://nextcloud-aio-apache.nextcloud-aio:23973",
"extra_params=--o:ssl.enable=false --o:ssl.termination=true --o:logging.disable_server_audit=true --o:logging.level=warning --o:logging.level_startup=warning --o:welcome.enable=false --o:fetch_update_check=0 --o:allow_update_popup=false %COLLABORA_SECCOMP_POLICY% --o:remote_font_config.url=https://%NC_DOMAIN%/apps/richdocuments/settings/fonts.json --o:net.post_allow.host[0]=.+",
"dictionaries=%COLLABORA_DICTIONARIES%",
"TZ=%TIMEZONE%",
@@ -389,7 +389,7 @@
"restart": "unless-stopped",
"nextcloud_exec_commands": [
"echo 'Activating Collabora config...'",
"php /var/www/html/occ richdocuments:activate-config --wopi-url='http://nextcloud-aio-apache:23973' --callback-url='http://nextcloud-aio-apache:23973'"
"php /var/www/html/occ richdocuments:activate-config --wopi-url='http://nextcloud-aio-apache.nextcloud-aio:23973' --callback-url='http://nextcloud-aio-apache.nextcloud-aio:23973'"
],
"profiles": [
"collabora"

View File

@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="6.15.1@28dc127af1b5aecd52314f6f645bafc10d0e11f9"/>
<files psalm-version="6.16.1@f1f5de594dc76faf8784e02d3dc4716c91c6f6ac"/>

View File

@@ -353,6 +353,9 @@
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
<input id="base_path" type="hidden" name="base_path" value="">
{% if bypass_container_update == true %}
<input type="hidden" name="bypass_container_update" value="true">
{% endif %}
<input type="submit" value="Start containers" />
</form>
{% else %}
@@ -361,7 +364,7 @@
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
<input id="base_path" type="hidden" name="base_path" value="">
{% if bypass_container_update == true %}
<input type="hidden" name="bypass_container_update" value="{{bypass_container_update}}">
<input type="hidden" name="bypass_container_update" value="true">
{% endif %}
<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>

0
php/tests/tests/initial-setup.spec.js Normal file → Executable file
View File

0
php/tests/tests/restore-instance.spec.js Normal file → Executable file
View File

View File

@@ -221,6 +221,7 @@ https://your-domain-that-points-to-this-server.tld:8443
- [How to adjust the internally used docker api version?](#how-to-adjust-the-internally-used-docker-api-version)
- [How to change the default location of Nextcloud's Datadir?](#how-to-change-the-default-location-of-nextclouds-datadir)
- [How to configure custom UID/GID?](#how-to-configure-custom-uidgid)
- [How to move the appdata folder from the datadir to an ssd to improve the performance?](#how-to-move-the-appdata-folder-from-the-datadir-to-an-ssd-to-improve-the-performance)
- [How to store the files/installation on a separate drive?](#how-to-store-the-filesinstallation-on-a-separate-drive)
- [How to limit the resource usage of AIO?](#how-to-limit-the-resource-usage-of-aio)
- [How to allow the Nextcloud container to access directories on the host?](#how-to-allow-the-nextcloud-container-to-access-directories-on-the-host)
@@ -475,7 +476,26 @@ Another solution if you really need to use host mounts is to use a bind mount to
/source/path /target/path/where/the/source/directory/will/be/mounted/on/the/server fuse.bindfs force-user=33,force-group=33,allow_other 0 0
```
You can then use `--env NEXTCLOUD_DATADIR="/target/path/where/the/source/directory/will/be/mounted/on/the/server"` as described in the section above.
Then use `sudo mount /target/path/where/the/source/directory/will/be/mounted/on/the/server` to mount it directly.
You can afterwards use `--env NEXTCLOUD_DATADIR="/target/path/where/the/source/directory/will/be/mounted/on/the/server"` as described in the section above.
### How to move the appdata folder from the datadir to an ssd to improve the performance?
If the datadir in your setup is configured to be placed on an HDD or network FS like SMB or NFS, you can follow the steps below to change the location of the appdata folder to be located on an SSD in order to improve the performance of the setup.
> [!NOTE]
> The following steps only work if you already configured and used NEXTCLOUD_DATADIR as mentioned [two sections above](#how-to-change-the-default-location-of-nextclouds-datadir).
> In this example here, we assume that you used `NEXTCLOUD_DATADIR="/target/path/`.
After the initial installation is done and all datadir files of Nextcloud are stored inside the configured `/target/path` directory, you will also see an `appdata_*` folder in there that stores app-related data. You can now move that folder to a faster SSD if the target dir is not already positioned on an SSD by first using `rsync` to sync the files a location on an SSD. Afterwards rename the appdata folder in the datadir to something like `appdata_*-backup`. Afterwards add the following line to `/etc/fstab`:
```
/source/path/on/ssd /target/path/<appdata-path> fuse.bindfs force-user=33,force-group=33,allow_other 0 0
```
Do not forget to adjust `<appdata-path>` to the correct `appdata_*` name that your installation initially created automatically.
Then use `sudo mount /target/path/<appdata-path>` to mount it directly.
Afterwards things should be speed up.
### How to store the files/installation on a separate drive?
You can move the whole docker library and all its files including all Nextcloud AIO files and folders to a separate drive by first mounting the drive in the host OS (NTFS is not supported and ext4 is recommended as FS) and then following this tutorial: https://www.guguweb.com/2019/02/07/how-to-move-docker-data-directory-to-another-location-on-ubuntu/<br>
@@ -748,7 +768,10 @@ password=<password>
```
(Of course you need to modify `<smb/cifs username>` and `<password>` for your specific case.)
Now you can use `/mnt/storagebox` as Nextcloud's datadir like described in the section above this one.
Now you can use `/mnt/storagebox` as Nextcloud's datadir like described in the section [here](#how-to-change-the-default-location-of-nextclouds-datadir).
> [!NOTE]
> You also might want to move the appdata dir after the initial installation is done to improve the performance. See [this section](#how-to-move-the-appdata-folder-from-the-datadir-to-an-ssd-to-improve-the-performance)
### Can I run this with Docker swarm?
Yes. For that to work, you need to use and follow the [manual-install documentation](./manual-install/).

View File

@@ -169,8 +169,8 @@ The process to run Nextcloud AIO behind a reverse proxy has three required steps
The reverse-proxy container needs to be connected to the nextcloud containers. This can be achieved one of these 3 ways:
1. Utilize host networking instead of docker bridge networking: Specify `--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. With this setup, the default sample configurations with reverse-proxy pointing to `localhost:$APACHE_PORT` should work directly.
1. Connect nextcloud's external-facing containers to the reverse-proxy's docker network by specifying env variable APACHE_ADDITIONAL_NETWORK. With this setup, the reverse proxy can utilize Docker bridge network's DNS name resolution to access nextcloud at `http://nextcloud-aio-apache:$APACHE_PORT`. ⚠️⚠️⚠️ Note, the specified network must already exist before Nextcloud AIO is started. Otherwise it will fail to start the container because the network is not existing.
1. Connect the reverse-proxy container to the `nextcloud-aio` network by specifying it as a secondary (external) network for the reverse proxy container. With this setup also, the reverse proxy can utilize Docker bridge network's DNS name resolution to access nextcloud at `http://nextcloud-aio-apache:$APACHE_PORT` .
1. Connect nextcloud's external-facing containers to the reverse-proxy's docker network by specifying env variable APACHE_ADDITIONAL_NETWORK. With this setup, the reverse proxy can utilize Docker bridge network's DNS name resolution to access nextcloud at `http://nextcloud-aio-apache.nextcloud-aio:$APACHE_PORT`. ⚠️⚠️⚠️ Note, the specified network must already exist before Nextcloud AIO is started. Otherwise it will fail to start the container because the network is not existing.
1. Connect the reverse-proxy container to the `nextcloud-aio` network by specifying it as a secondary (external) network for the reverse proxy container. With this setup also, the reverse proxy can utilize Docker bridge network's DNS name resolution to access nextcloud at `http://nextcloud-aio-apache.nextcloud-aio:$APACHE_PORT` .
</details>

View File

@@ -1,10 +1,10 @@
# Initial setup
- [ ] Verify that after starting the test container, you can access the AIO interface using https://internal.ip.address:8080
- [ ] After clicking the self-signed-certificate warning away, it should show the setup page with an explanation what AIO is and the initial password and a button that contains a link to the AIO login page
- [ ] After copying the password and clicking on this button, it should open a new tab with the login page
- [ ] The login page should show an input field that allows to enter the AIO password and a `Log in` button
- [ ] After pasting the new password into the input field and clicking on this button button, you should be logged in
- [ ] After clicking the self-signed-certificate warning away, it should show the setup page with an explanation what AIO is and the initial passphrase and a button that contains a link to the AIO login page
- [ ] After copying the passphrase and clicking on this button, it should open a new tab with the login page
- [ ] The login page should show an input field that allows to enter the AIO passphrase and a `Log in` button
- [ ] After pasting the passphrase into the input field and clicking on this button, you should be logged in
- [ ] You should now see the containers page and you should see three sections: one general section which explains what AIO is, one `New AIO instance` section and one section that allows to restore the whole AIO instance from backup.
You can now continue with [002-new-instance.md](./002-new-instance.md) or [010-restore-instance.md](./010-restore-instance.md).

View File

@@ -11,7 +11,7 @@ For the below to work, it is important that you have a domain that you point ont
- [ ] Entering the domain that does point to your server e.g. `yourdomain.com` should finally redirect you to the next screen (if you did not configure your domain yet or did not open port 443, it should report that to you)
- [ ] Now you should see a button `Start containers` and an explanation which points out that clicking on the button will start the containers and that this can take a long time.
- [ ] Below that you should see a section `Optional addons` which shows a checkbox list with addons that can be enabled or disabled.
- [ ] Collabora and Nextcloud Talk should be enabled, the rest disabled
- [ ] Collabora, Imaginary, Talk and Whiteboard should be enabled, the rest disabled
- [ ] Unchecking/Checking any of these should insert a button that allows to save the set config
- [ ] Checking OnlyOffice and Collabora at the same time should show a warning that this is not supported and should not saving the new config
- [ ] Recommended is to uncheck all options now

View File

@@ -1,18 +1,32 @@
# Initial backup
- [ ] In the Backup and restore section, you should now see and input box where you should type in the path where the backup should get created and some explanation below
- [ ] In the Backup and restore section, you should now see two input boxes where for one you should type in the path where the backup should get created and some explanation below or the other type in a remote ssh location
- [ ] First, check a local backup:
- [ ] Enter `/` which should send an error
- [ ] Enter `/mnt/` or `/media/` or `/host_mnt/` or `/var/backups/` should send an error as well
- [ ] Accepted should be `/mnt/backup`, `/media/backup`, `/host_mnt/c/backup` and `/var/backups`.
- [ ] The side should now reload
- [ ] In the Backup restore section you should now see a Backup information section with important info like the encryption password, the backup location and more.
- [ ] Also you should see a Backup creation section that contains a `Create backup` button.
- [ ] Clicking on the `Create backup` button should open a window prompt that allows to cancel the operation.
- [ ] Canceling should return to the website, confirming should reveal the big spinner again which should block the website again.
- [ ] After a while you should see the information that Backup container is currently running
- [ ] another option are remote backups via SSH using borgbackup. The remote borg repo URL must contain both `@` and `:`. The process works as follows:
1. You enter a remote borg repo URL (e.g. `ssh://user@host:port/path/to/repo` or `user@host:/path/to/repo`).
2. On the first connection attempt, a SSH key pair is generated automatically and the public key is displayed.
3. You add the public key to the `~/.ssh/authorized_keys` file on the remote server so that AIO can connect to it.
4. Once authorized, AIO can create and restore backups on the remote server.
- [ ] Enter `user` (no `@` and no `:`) which should send an error
- [ ] Enter `user@host` (no `:`) which should send an error
- [ ] Enter `userhost:/path` (no `@`) which should send an error
- [ ] Accepted should be `ssh://user@host:22/path/to/repo` or `user@host:/path/to/repo`
- [ ] Both a local backup location and a remote repo URL should not be accepted at the same time
- [ ] The page should now reload
- [ ] Now click on `Create backup`
- [ ] After the first failed backup attempt with a remote repo, the SSH public key for borg should be shown so it can be authorized on the remote server
- [ ] After authorizing the server on the remote, scroll down and click on `Create backup` again to create another backup. This time it should succeed.
- [ ] The initial Nextcloud credentials on top of the page that are visible when the containers are running should now be hidden in a details tag
- [ ] In the Backup restore section you should now see a Backup information section with important info like the encryption password, the backup location and more.
- [ ] Also you should see a Backup cretion section that contains a `Create backup` button.
- [ ] Clicking on the `Create backup` button should open a window prompt that allows to cancel the operation.
- [ ] Canceling should return to the website, confirming should reveal the big spinner again which should block the website again.
- [ ] After a while you should see the information that Backup container is currently running
- [ ] Below the Containers section you should see the option to `Start containers` again.
- [ ] After a while and a few automatic reloads (as long as the side is focused), you should be redirected to the usual page and seen in the Backup and restore section that the last backup was successful.
- [ ] Below thhat you should see a details tag that allows to reveal all backup options
- [ ] Below that you should see a details tag that allows to reveal all backup options
You can now continue with [020-backup-and-restore.md](.//020-backup-and-restore.md)

View File

@@ -2,17 +2,34 @@
For the below to work, you need a backup archive of an AIO instance and the location on the test machine and the password for the backup archive. You can get one here: [backup-archive](./assets/backup-archive/)
- [ ] The section that allows to restore the whole AIO instance from backup should show two input fields: one that allows to enter a location where the backup archive is located and one that allows to enter password of the archive. It should also show a short explanation regarding the path requirements
- [ ] Entering an incorrect path and/or password should let you continue and test your settings in the next step
- [ ] Clicking on the test button should after a reload bring you back to the initial screen where it should say that the test was unsuccessful. Also you should be able to have a look at the backup container logs for investigation what exactly failed.
- [ ] You should also now see the input boxes again where you can change the path and password, confirm it and bring you again to the screen where you can test your settings.
- [ ] Entering the correct path to the backup archive and the correct password here should:
- [ ] Should reload and should hide all options except the option to test the path and password
- [ ] After the test you should see the options to check the integrity of the backup and a list of backup archives that you can choose from to restore your instance
- [ ] Clicking on either option should show a window prompt that lets you cancel the operation
- [ ] Clicking on the integrity check option should check the integrity and report that the backup integrity is good after a while which should then only show the option to choose the backup archive that should be restored
- [ ] Choosing the restore option should finally restore your files.
- [ ] After waiting a while it should reload the page and should show the usual container interface again with the state of your containers (stopped) and the option to start and update the containers again.
- [ ] The section that allows to restore the whole AIO instance from backup should show three input fields: one that allows to enter a location where the backup archive is located and one that allows to enter a remote ssh path and one that allows to enter password of the archive. It should also show a short explanation regarding the path requirements
- [ ] First, check restoring from a local backup location:
- [ ] Entering an incorrect path and/or password should let you continue and test your settings in the next step
- [ ] Clicking on the test button should after a reload bring you back to the initial screen where it should say that the test was unsuccessful. Also you should be able to have a look at the backup container logs for investigation what exactly failed.
- [ ] You should also now see the input boxes again where you can change the path and password, confirm it and bring you again to the screen where you can test your settings.
- [ ] Entering the correct path to the backup archive and the correct password here should:
- [ ] Should reload and should hide all options except the option to test the path and password
- [ ] After the test you should see the options to check the integrity of the backup and a list of backup archives that you can choose from to restore your instance
- [ ] Clicking on either option should show a window prompt that lets you cancel the operation
- [ ] Clicking on the integrity check option should check the integrity and report that the backup integrity is good after a while which should then only show the option to choose the backup archive that should be restored
- [ ] Choosing the restore option should finally restore your files.
- [ ] After waiting a while it should reload the page and should show the usual container interface again with the state of your containers (stopped) and the option to start and update the containers again.
- [ ] Next, check restoring from a remote backup location via SSH. The remote borg repo URL must contain both `@` and `:`. The restore process works as follows:
1. You enter a remote borg repo URL (e.g. `ssh://user@host:port/path/to/repo` or `user@host:/path/to/repo`) and the backup password.
2. On the first connection attempt, a SSH key pair is generated automatically and the public key is displayed.
3. You add the public key to the `~/.ssh/authorized_keys` file on the remote server so that AIO can connect to it.
4. Once authorized, AIO can list and restore backups from the remote server.
- [ ] Enter an invalid remote repo URL (e.g. `user` without `@` and `:`) which should send an error
- [ ] Enter a valid remote borg repo URL and the correct backup password:
- [ ] Should reload and should hide all options except the option to test the path and password
- [ ] After the first failed connection attempt, the SSH public key for borg should be shown so it can be authorized on the remote server
- [ ] After authorizing the key on the remote server, scroll down and click on the test button again. This time it should succeed and show the options to check the integrity and list backup archives
- [ ] After the test you should see the options to check the integrity of the backup and a list of backup archives that you can choose from to restore your instance
- [ ] Clicking on either option should show a window prompt that lets you cancel the operation
- [ ] Clicking on the integrity check option should check the integrity and report that the backup integrity is good after a while which should then only show the option to choose the backup archive that should be restored
- [ ] Choosing the restore option should finally restore your files.
- [ ] After waiting a while it should reload the page and should show the usual container interface again with the state of your containers (stopped) and the option to start and update the containers again.
- [ ] Clicking on `Start and update containers` should show a window prompt that you should create a backup. Canceling should cancel the operation, confirming should reveal the big spinner again.
- [ ] After waiting a bit, all containers should be green and your instance should be fully functional again

View File

@@ -1,6 +1,6 @@
# Backup and restore
- [ ] Expanding all backup options in the Backup and restore sectioin should reveal a Backup information section, Backup creation section, Backup check section, Backup restore section and a Daily backup section.
- [ ] Expanding all backup options in the Backup and restore sectioin should reveal a Backup information section, Backup creation section, Backup check section, Backup restore section and a Daily backup section as well as a additional backup location section
- [ ] The backup restore section should list all available backup archives and list them from most recent to least recent.
- [ ] Clicking on either option of Create backup, Check backup integrity or Restore selected backup should run the corresponding action and report after a while in the last check, backup or restore was successful.
- [ ] Daily backup creatio should allow to enter a time in 24h format e.g. `04:00` should be accepted, `24:00` or `dfjlk` not.

View File

@@ -1,12 +1,12 @@
# AIO password change
# AIO passphrase change
- [ ] In the AIO password change section you should see two input fields. And below the requirements for a new password
- [ ] When entering nothing it should report that you need to enter your current aio password
- [ ] When entering a false password, it should report that to you
- [ ] After entering your current password and leaving the new password empty it should report that you need to enter a new password
- [ ] After entering a new passwort shorter than 24 characters or not allowed characters, it should report that the password requirements are not met.
- [ ] In the AIO passphrase change section you should see two input fields. And below the requirements for a new passphrase
- [ ] When entering nothing it should report that you need to enter your current AIO passphrase
- [ ] When entering a false passphrase, it should report that to you
- [ ] After entering your current passphrase and leaving the new passphrase empty it should report that you need to enter a new passphrase
- [ ] After entering a new passphrase shorter than 24 characters or not allowed characters, it should report that the passphrase requirements are not met.
- [ ] `sdfjlksj` should not be accepted
- [ ] `jdsfklöjiroewoäsadjkfölk` should not be accepted
- [ ] `sdjlfj SDJFLK 32489 sdjklf` should which should reload the page
- [ ] `sdjlfj SDJFLK 32489 sdjklf` should be accepted, which should reload the page
You can now continue with [040-login-behavior.md](./040-login-behavior.md)

View File

@@ -1,7 +1,7 @@
# Login behavior
- [ ] When opening the AIO interface in a new tab while the apache container is running, it should report on the login page that Nextcloud is running and you should use the automatic login
- [ ] When the apache container is stopped, you should see here an input field that allows you to enter the AIO password which should log you in
- [ ] When the apache container is stopped, you should see here an input field that allows you to enter the AIO passphrase which should log you in
- [ ] Starting and stopping the containers multiple times should every time produce a new token that is used in the admin overview in Nextcloud as link in the button to log you into the AIO interface. (see [003-automatic-login.md](./003-automatic-login.md))
You can now continue with [050-optional-addons.md](./050-optional-addons.md)

View File

@@ -10,6 +10,8 @@
- [ ] Imaginary by having a look if when uploading a new picture in Nextcloud, it adds some log entries to the container
- [ ] Fulltextsearch by trying to search for a heading inside a file in Nextcloud
- [ ] Talk-recording by starting a call and trying to record something
- [ ] When Collabora is enabled, it should show below the Optional Addons section a section where you can change the dictionaries for collabora. `de_DE en_GB en_US es_ES fr_FR it nl pt_BR pt_PT ru` should be a valid setting. E.g. `de.De` not. If already set, it should show a button that allows to remove the setting again.
- [ ] When Collabora is enabled
- [ ] It should show below the Optional Addons section a section where you can change the dictionaries for collabora. `de_DE en_GB en_US es_ES fr_FR it nl pt_BR pt_PT ru` should be a valid setting. E.g. `de.De` not. If already set, it should show a button that allows to remove the setting again.
- [ ] Also, you should see an input field that allows to enter additional collabora options. E.g. `net.content_security_policy=false` should not be accepted, but `--o:net.content_security_policy="frame-ancestors *.example.com:*;"` should.
You can now continue with [060-environmental-variables.md](./060-environmental-variables.md)
You can now continue with [055-community-containers.md](./055-community-containers.md)

View File

@@ -0,0 +1,13 @@
# Community Containers
- [ ] At the very bottom of the page, there should be a Community Containers section
- [ ] The section should show a details element that allows to reveal the list of available community containers
- [ ] When containers are running, the checkboxes should be disabled and a notice should inform the user that changes can only be made when containers are stopped
- [ ] When containers are stopped, checkboxes should be enabled
- [ ] Enabling a community container and clicking `Save changes` should show a confirmation dialog
- [ ] Canceling the confirmation dialog should not save the changes
- [ ] Confirming should save the changes and reload the page
- [ ] After saving, the enabled community container should appear in the containers section and start along with the other containers when `Start containers` is clicked
- [ ] Disabling a previously enabled community container and saving should remove it from the containers section after stopping and starting containers
You can now continue with [060-environmental-variables.md](./060-environmental-variables.md)