From c1962656d5de3f0692b97cdf3893b2e47947c6ee Mon Sep 17 00:00:00 2001 From: Alexander Olofsson Date: Thu, 14 Oct 2021 14:48:26 +0200 Subject: [PATCH 01/13] Add nginx-unit server support Signed-off-by: Alexander Olofsson --- Dockerfile-unit.template | 164 +++++++++++++++++++++++++++++++++++++++ docker-entrypoint.sh | 6 +- nextcloud-unit.json | 162 ++++++++++++++++++++++++++++++++++++++ update.sh | 29 ++++++- 4 files changed, 359 insertions(+), 2 deletions(-) create mode 100644 Dockerfile-unit.template create mode 100644 nextcloud-unit.json diff --git a/Dockerfile-unit.template b/Dockerfile-unit.template new file mode 100644 index 00000000..0095b351 --- /dev/null +++ b/Dockerfile-unit.template @@ -0,0 +1,164 @@ +FROM unit:%%UNIT_VERSION%%-php%%PHP_VERSION%% + +# make nginx-unit co-operate with the nextcloud entrypoint +RUN set -ex; \ + \ + mv /docker-entrypoint.d /unit-entrypoint.d; \ + mv /usr/local/bin/docker-entrypoint.sh /usr/local/bin/unit-entrypoint.sh; \ + sed -e 's/docker-entrypoint.d/unit-entrypoint.d/' -i /usr/local/bin/unit-entrypoint.sh + +# entrypoint.sh and cron.sh dependencies +RUN set -ex; \ + \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + busybox-static \ + bzip2 \ + libldap-common \ + libmagickcore-6.q16-6-extra \ + rsync \ + ; \ + rm -rf /var/lib/apt/lists/*; \ + \ + mkdir -p /var/spool/cron/crontabs; \ + echo '*/%%CRONTAB_INT%% * * * * php -f /var/www/html/cron.php' > /var/spool/cron/crontabs/www-data + +# install the PHP extensions we need +# see https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html +ENV PHP_MEMORY_LIMIT 512M +ENV PHP_UPLOAD_LIMIT 512M +RUN set -ex; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + libcurl4-openssl-dev \ + libevent-dev \ + libfreetype6-dev \ + libgmp-dev \ + libicu-dev \ + libjpeg-dev \ + libldap2-dev \ + libmagickwand-dev \ + libmcrypt-dev \ + libmemcached-dev \ + libpng-dev \ + libpq-dev \ + libwebp-dev \ + libxml2-dev \ + libzip-dev \ + ; \ + \ + debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \ + docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp; \ + docker-php-ext-configure ldap --with-libdir="lib/$debMultiarch"; \ + docker-php-ext-install -j "$(nproc)" \ + bcmath \ + exif \ + gd \ + gmp \ + intl \ + ldap \ + opcache \ + pcntl \ + pdo_mysql \ + pdo_pgsql \ + sysvsem \ + zip \ + ; \ + \ +# pecl will claim success even if one install fails, so we need to perform each install separately + pecl install APCu-%%APCU_VERSION%%; \ + pecl install imagick-%%IMAGICK_VERSION%%; \ + pecl install memcached-%%MEMCACHED_VERSION%%; \ + pecl install redis-%%REDIS_VERSION%%; \ + \ + docker-php-ext-enable \ + apcu \ + imagick \ + memcached \ + redis \ + ; \ + rm -r /tmp/pear; \ + \ +# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark; \ + ldd "$(php -r 'echo ini_get("extension_dir");')"/*.so \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); print so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ + | cut -d: -f1 \ + | sort -u \ + | xargs -rt apt-mark manual; \ + \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + rm -rf /var/lib/apt/lists/* + +# set recommended PHP.ini settings +# see https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#enable-php-opcache +RUN { \ + echo 'opcache.enable=1'; \ + echo 'opcache.interned_strings_buffer=32'; \ + echo 'opcache.max_accelerated_files=10000'; \ + echo 'opcache.memory_consumption=128'; \ + echo 'opcache.save_comments=1'; \ + echo 'opcache.revalidate_freq=60'; \ + echo 'opcache.jit=1255'; \ + echo 'opcache.jit_buffer_size=128M'; \ + } > "${PHP_INI_DIR}/conf.d/opcache-recommended.ini"; \ + \ + echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \ + \ + { \ + echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \ + echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \ + echo 'post_max_size=${PHP_UPLOAD_LIMIT}'; \ + } > "${PHP_INI_DIR}/conf.d/nextcloud.ini"; \ + \ + mkdir /var/www/data; \ + mkdir -p /docker-entrypoint-hooks.d/pre-installation \ + /docker-entrypoint-hooks.d/post-installation \ + /docker-entrypoint-hooks.d/pre-upgrade \ + /docker-entrypoint-hooks.d/post-upgrade \ + /docker-entrypoint-hooks.d/before-starting; \ + chown -R www-data:root /var/www; \ + chmod -R g=u /var/www + +VOLUME /var/www/html +%%VARIANT_EXTRAS%% + +ENV NEXTCLOUD_VERSION %%VERSION%% + +RUN set -ex; \ + fetchDeps=" \ + gnupg \ + dirmngr \ + "; \ + apt-get update; \ + apt-get install -y --no-install-recommends $fetchDeps; \ + \ + curl -fsSL -o nextcloud.tar.bz2 "%%DOWNLOAD_URL%%"; \ + curl -fsSL -o nextcloud.tar.bz2.asc "%%DOWNLOAD_URL_ASC%%"; \ + export GNUPGHOME="$(mktemp -d)"; \ +# gpg key from https://nextcloud.com/nextcloud.asc + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \ + gpg --batch --verify nextcloud.tar.bz2.asc nextcloud.tar.bz2; \ + tar -xjf nextcloud.tar.bz2 -C /usr/src/; \ + gpgconf --kill all; \ + rm nextcloud.tar.bz2.asc nextcloud.tar.bz2; \ + rm -rf "$GNUPGHOME" /usr/src/nextcloud/updater; \ + mkdir -p /usr/src/nextcloud/data; \ + mkdir -p /usr/src/nextcloud/custom_apps; \ + chmod +x /usr/src/nextcloud/occ; \ + \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $fetchDeps; \ + rm -rf /var/lib/apt/lists/* + +COPY *.sh upgrade.exclude / +COPY config/* /usr/src/nextcloud/config/ +COPY nextcloud-unit.json /unit-entrypoint.d/ + +ENTRYPOINT ["/entrypoint.sh"] +CMD ["%%CMD%%"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 5b627f07..a91a116a 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -82,7 +82,7 @@ if expr "$1" : "apache" 1>/dev/null; then fi fi -if expr "$1" : "apache" 1>/dev/null || [ "$1" = "php-fpm" ] || [ "${NEXTCLOUD_UPDATE:-0}" -eq 1 ]; then +if expr "$1" : "apache" 1>/dev/null || [ "$1" = "php-fpm" ] || expr "$1" : "unitd" 1>/dev/null || [ "${NEXTCLOUD_UPDATE:-0}" -eq 1 ]; then uid="$(id -u)" gid="$(id -g)" if [ "$uid" = '0' ]; then @@ -276,4 +276,8 @@ if expr "$1" : "apache" 1>/dev/null || [ "$1" = "php-fpm" ] || [ "${NEXTCLOUD_UP run_path before-starting fi +if expr "$1" : "unitd" 1>/dev/null; then + exec /usr/local/bin/unit-entrypoint.sh "$@" +fi + exec "$@" diff --git a/nextcloud-unit.json b/nextcloud-unit.json new file mode 100644 index 00000000..12b8ac00 --- /dev/null +++ b/nextcloud-unit.json @@ -0,0 +1,162 @@ +{ + "listeners": { + "*:80": { + "pass": "routes", + "forwarded": { + "client_ip": "X-Forwarded-For", + "source": [ + "10.0.0.0/8", + "172.16.0.0/12", + "192.168.0.0/16", + "fc00::/7" + ] + } + } + }, + + "routes": [ + { + "match": { + "uri": [ + "/.well-known/carddav", + "/.well-known/caldav" + ] + }, + + "action": { + "return": 301, + "location": "/remote.php/dav" + } + }, + { + "match": { + "uri": [ + "/.well-known/*" + ] + }, + + "action": { + "pass": "applications/nextcloud/index" + } + }, + { + "match": { + "uri": [ + "/build/*", + "/tests/*", + "/config/*", + "/lib/*", + "/3rdparty/*", + "/templates/*", + "/data/*", + "/.*", + "/autotest*", + "/occ*", + "/issue*", + "/indie*", + "/db_*", + "/console*" + ] + }, + + "action": { + "return": 404 + } + }, + { + "match": { + "uri": [ + "/core/ajax/update.php*", + "/cron.php*", + "/ocs-provider*.php*", + "/ocs/v1.php*", + "/ocs/v2.php*", + "/public.php*", + "/remote.php*", + "/status.php*", + "/updater*.php*" + ] + }, + + "action": { + "pass": "applications/nextcloud/direct" + } + }, + { + "match": { + "uri": "/ocs-provider*" + }, + + "action": { + "pass": "applications/nextcloud/ocs" + } + }, + { + "match": { + "uri": [ + "/index.php", + "index.php/*" + ] + }, + "action": { + "pass": "applications/nextcloud/index" + } + }, + { + "match": { + "uri": [ + "~\\.(?:css|js|mjs|svg|gif|png|jpg|ico|wasm|tflite|map|ogg|flac|woff2?)$" + ] + }, + "action": { + "share": "/var/www/html$uri", + "fallback": { + "pass": "applications/nextcloud/index" + }, + "response_headers": { + "Cache-Control": "public, max-age=15778463" + } + } + }, + { + "action": { + "share": "/var/www/html$uri", + "fallback": { + "pass": "applications/nextcloud/index" + } + } + } + ], + + "applications": { + "nextcloud": { + "type": "php", + "user": "www-data", + "processes": {}, + "targets": { + "direct": { + "root": "/var/www/html/" + }, + + "index": { + "root": "/var/www/html/", + "script": "index.php" + }, + + "ocs": { + "root": "/var/www/html/ocs-provider/", + "script": "index.php" + } + }, + "environment": { + "front_controller_active": "true" + } + } + }, + + "settings": { + "http": { + "max_body_size": 1073741824 + } + } +} diff --git a/update.sh b/update.sh index 015cf9ae..458352b6 100755 --- a/update.sh +++ b/update.sh @@ -17,24 +17,37 @@ declare -A cmd=( [apache]='apache2-foreground' [fpm]='php-fpm' [fpm-alpine]='php-fpm' + [unit]='unitd --no-daemon' ) declare -A base=( [apache]='debian' [fpm]='debian' [fpm-alpine]='alpine' + [unit]='unit' ) declare -A extras=( [apache]='\nRUN a2enmod headers rewrite remoteip ; \\\n { \\\n echo '\''RemoteIPHeader X-Real-IP'\''; \\\n echo '\''RemoteIPInternalProxy 10.0.0.0/8'\''; \\\n echo '\''RemoteIPInternalProxy 172.16.0.0/12'\''; \\\n echo '\''RemoteIPInternalProxy 192.168.0.0/16'\''; \\\n } > /etc/apache2/conf-available/remoteip.conf; \\\n a2enconf remoteip\n\n# set apache config LimitRequestBody\nENV APACHE_BODY_LIMIT 1073741824\nRUN { \\\n echo '\''LimitRequestBody ${APACHE_BODY_LIMIT}'\''; \\\n } > /etc/apache2/conf-available/apache-limits.conf; \\\n a2enconf apache-limits' [fpm]='' [fpm-alpine]='' + [unit]='' ) declare -A crontab_int=( [default]='5' ) +unit_version="$( + git ls-remote --tags https://github.com/nginx/unit.git \ + | cut -d/ -f3 \ + | grep -v -- '-1' \ + | grep -v '\^' \ + | sed -E 's/^v//' \ + | sort -V \ + | tail -1 +)" + apcu_version="$( git ls-remote --tags https://github.com/krakjoe/apcu.git \ | cut -d/ -f3 \ @@ -82,6 +95,7 @@ variants=( apache fpm fpm-alpine + unit ) min_version='27' @@ -91,6 +105,13 @@ function version_greater_or_equal() { [[ "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1" || "$1" == "$2" ]]; } +# joins a list of strings together with a delimiter +# join_by delim first rest... +function join_by() { + local delim=${1-} first=${2-} + shift 2 && printf %s "${first}" "${@/#/$delim}" +} + function create_variant() { dir="$1/$variant" alpineVersion=${alpine_version[$version]-${alpine_version[default]}} @@ -118,12 +139,13 @@ function create_variant() { s/%%VERSION%%/'"$fullversion"'/g; s/%%DOWNLOAD_URL%%/'"$(sed -e 's/[\/&]/\\&/g' <<< "$url")"'/g; s/%%DOWNLOAD_URL_ASC%%/'"$(sed -e 's/[\/&]/\\&/g' <<< "$ascUrl")"'/g; - s/%%CMD%%/'"${cmd[$variant]}"'/g; + s/%%CMD%%/'"$(join_by '", "' ${cmd[$variant]})"'/g; s|%%VARIANT_EXTRAS%%|'"${extras[$variant]}"'|g; s/%%APCU_VERSION%%/'"${pecl_versions[APCu]}"'/g; s/%%MEMCACHED_VERSION%%/'"${pecl_versions[memcached]}"'/g; s/%%REDIS_VERSION%%/'"${pecl_versions[redis]}"'/g; s/%%IMAGICK_VERSION%%/'"${pecl_versions[imagick]}"'/g; + s/%%UNIT_VERSION%%/'"${unit_version}"'/g; s/%%CRONTAB_INT%%/'"$crontabInt"'/g; ' "$dir/Dockerfile" @@ -132,6 +154,11 @@ function create_variant() { cp "docker-$name.sh" "$dir/$name.sh" done + # Copy the nginx-unit configuration if unit variant. + if [ "$variant" == "unit" ]; then + cp nextcloud-unit.json "$dir/nextcloud-unit.json" + fi + # Copy the upgrade.exclude cp upgrade.exclude "$dir/" From abd813f5fb0e5bba961f2029ad2eec06f73869a6 Mon Sep 17 00:00:00 2001 From: J0WI Date: Mon, 21 Oct 2024 16:44:25 +0000 Subject: [PATCH 02/13] Bump stable to 30.0.1 Signed-off-by: J0WI --- generate-stackbrew-library.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generate-stackbrew-library.sh b/generate-stackbrew-library.sh index a7718bc0..43c9aab0 100755 --- a/generate-stackbrew-library.sh +++ b/generate-stackbrew-library.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -Eeuo pipefail -stable_channel='29.0.7' +stable_channel='30.0.1' self="$(basename "$BASH_SOURCE")" cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" From 9b63f3e4dccf071b5ffaf7b7d228d3a829e135da Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 21 Oct 2024 17:38:50 -0400 Subject: [PATCH 03/13] fix(examples): volumes must match (insecure-mariadb-apache) Signed-off-by: Josh --- .examples/docker-compose/insecure/mariadb/apache/compose.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.examples/docker-compose/insecure/mariadb/apache/compose.yaml b/.examples/docker-compose/insecure/mariadb/apache/compose.yaml index 4d0fd8fd..daa51590 100644 --- a/.examples/docker-compose/insecure/mariadb/apache/compose.yaml +++ b/.examples/docker-compose/insecure/mariadb/apache/compose.yaml @@ -23,6 +23,7 @@ services: - 127.0.0.1:8080:80 volumes: - nextcloud:/var/www/html:z + # NOTE: The `volumes` config of the `cron` and `app` containers must match environment: - MYSQL_HOST=db - REDIS_HOST=redis @@ -37,6 +38,7 @@ services: restart: always volumes: - nextcloud:/var/www/html:z + # NOTE: The `volumes` config of the `cron` and `app` containers must match entrypoint: /cron.sh depends_on: - db From abf51f1cd76ba2d4f4c9598882e67bf03e2739a9 Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 21 Oct 2024 17:43:54 -0400 Subject: [PATCH 04/13] fix(examples): volumes must match (insecure-mariadb-fpm) Signed-off-by: Josh --- .examples/docker-compose/insecure/mariadb/fpm/compose.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.examples/docker-compose/insecure/mariadb/fpm/compose.yaml b/.examples/docker-compose/insecure/mariadb/fpm/compose.yaml index 06b12afb..25e5b717 100644 --- a/.examples/docker-compose/insecure/mariadb/fpm/compose.yaml +++ b/.examples/docker-compose/insecure/mariadb/fpm/compose.yaml @@ -21,6 +21,7 @@ services: restart: always volumes: - nextcloud:/var/www/html:z + # NOTE: The `volumes` config of the `cron` and `app` containers must match environment: - MYSQL_HOST=db - REDIS_HOST=redis @@ -37,6 +38,7 @@ services: - 127.0.0.1:8080:80 volumes: - nextcloud:/var/www/html:z,ro + # NOTE: The `volumes` included here should match those of the `app` container (unless you know what you're doing) depends_on: - app @@ -45,6 +47,7 @@ services: restart: always volumes: - nextcloud:/var/www/html:z + # NOTE: The `volumes` config of the `cron` and `app` containers must match entrypoint: /cron.sh depends_on: - db From 9395077d115d88817618652603519b5f53bdd6aa Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 21 Oct 2024 17:45:19 -0400 Subject: [PATCH 05/13] fix(examples): volumes must match (insecure-postgres-apache) Signed-off-by: Josh --- .../docker-compose/insecure/postgres/apache/compose.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.examples/docker-compose/insecure/postgres/apache/compose.yaml b/.examples/docker-compose/insecure/postgres/apache/compose.yaml index 646261d0..19c75ba4 100644 --- a/.examples/docker-compose/insecure/postgres/apache/compose.yaml +++ b/.examples/docker-compose/insecure/postgres/apache/compose.yaml @@ -18,6 +18,7 @@ services: - 127.0.0.1:8080:80 volumes: - nextcloud:/var/www/html:z + # NOTE: The `volumes` config of the `cron` and `app` containers must match environment: - POSTGRES_HOST=db - REDIS_HOST=redis @@ -32,6 +33,7 @@ services: restart: always volumes: - nextcloud:/var/www/html:z + # NOTE: The `volumes` config of the `cron` and `app` containers must match entrypoint: /cron.sh depends_on: - db @@ -39,4 +41,4 @@ services: volumes: db: - nextcloud: \ No newline at end of file + nextcloud: From e3dc1f3d62fcda80f35ae38a8748e75f3b50692e Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 21 Oct 2024 17:47:11 -0400 Subject: [PATCH 06/13] fix(examples): volumes must match (insecure-postgres-fpm) Signed-off-by: Josh --- .examples/docker-compose/insecure/postgres/fpm/compose.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.examples/docker-compose/insecure/postgres/fpm/compose.yaml b/.examples/docker-compose/insecure/postgres/fpm/compose.yaml index b5071d5c..4e268cab 100644 --- a/.examples/docker-compose/insecure/postgres/fpm/compose.yaml +++ b/.examples/docker-compose/insecure/postgres/fpm/compose.yaml @@ -16,6 +16,7 @@ services: restart: always volumes: - nextcloud:/var/www/html:z + # NOTE: The `volumes` config of the `cron` and `app` containers must match environment: - POSTGRES_HOST=db - REDIS_HOST=redis @@ -32,6 +33,7 @@ services: - 127.0.0.1:8080:80 volumes: - nextcloud:/var/www/html:z,ro + # NOTE: The `volumes` included here should match those of the `app` container (unless you know what you're doing) depends_on: - app @@ -40,6 +42,7 @@ services: restart: always volumes: - nextcloud:/var/www/html:z + # NOTE: The `volumes` config of the `cron` and `app` containers must match entrypoint: /cron.sh depends_on: - db From 60f205abeab9ad60df5d9a44cf8bdc8fa5536a73 Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 21 Oct 2024 17:49:39 -0400 Subject: [PATCH 07/13] fix(examples): volumes must match (with-nginx-proxy-mariadb-apache) Signed-off-by: Josh --- .../docker-compose/with-nginx-proxy/mariadb/apache/compose.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.examples/docker-compose/with-nginx-proxy/mariadb/apache/compose.yaml b/.examples/docker-compose/with-nginx-proxy/mariadb/apache/compose.yaml index 7a221407..2a0d57a5 100644 --- a/.examples/docker-compose/with-nginx-proxy/mariadb/apache/compose.yaml +++ b/.examples/docker-compose/with-nginx-proxy/mariadb/apache/compose.yaml @@ -21,6 +21,7 @@ services: restart: always volumes: - nextcloud:/var/www/html:z + # NOTE: The `volumes` config of the `cron` and `app` containers must match environment: - VIRTUAL_HOST= - LETSENCRYPT_HOST= @@ -45,6 +46,7 @@ services: restart: always volumes: - nextcloud:/var/www/html:z + # NOTE: The `volumes` config of the `cron` and `app` containers must match entrypoint: /cron.sh depends_on: - db From 7e188da4fa2f24edf41dd0efee49a2cdf3105eff Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 21 Oct 2024 17:51:06 -0400 Subject: [PATCH 08/13] fix(examples): volumes must match (with-nginx-proxy-mariadb-fpm) Signed-off-by: Josh --- .../docker-compose/with-nginx-proxy/mariadb/fpm/compose.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/compose.yaml b/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/compose.yaml index ff7a5388..20db19a9 100644 --- a/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/compose.yaml +++ b/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/compose.yaml @@ -21,6 +21,7 @@ services: restart: always volumes: - nextcloud:/var/www/html:z + # NOTE: The `volumes` config of the `cron` and `app` containers must match environment: - MYSQL_HOST=db - REDIS_HOST=redis @@ -36,6 +37,7 @@ services: restart: always volumes: - nextcloud:/var/www/html:z,ro + # NOTE: The `volumes` included here should match those of the `app` container (unless you know what you're doing) environment: - VIRTUAL_HOST= - LETSENCRYPT_HOST= @@ -51,6 +53,7 @@ services: restart: always volumes: - nextcloud:/var/www/html:z + # NOTE: The `volumes` config of the `cron` and `app` containers must match entrypoint: /cron.sh depends_on: - db From 24b67696829f015a2d7a03b4be9b190aeb274ca6 Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 21 Oct 2024 17:52:21 -0400 Subject: [PATCH 09/13] fix(examples): volumes must match (with-nginx-proxy-postgres-apache) Signed-off-by: Josh --- .../with-nginx-proxy/postgres/apache/compose.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.examples/docker-compose/with-nginx-proxy/postgres/apache/compose.yaml b/.examples/docker-compose/with-nginx-proxy/postgres/apache/compose.yaml index a3dece4b..2eb4f638 100644 --- a/.examples/docker-compose/with-nginx-proxy/postgres/apache/compose.yaml +++ b/.examples/docker-compose/with-nginx-proxy/postgres/apache/compose.yaml @@ -16,6 +16,7 @@ services: restart: always volumes: - nextcloud:/var/www/html:z + # NOTE: The `volumes` config of the `cron` and `app` containers must match environment: - VIRTUAL_HOST= - LETSENCRYPT_HOST= @@ -37,6 +38,7 @@ services: restart: always volumes: - nextcloud:/var/www/html:z + # NOTE: The `volumes` config of the `cron` and `app` containers must match entrypoint: /cron.sh depends_on: - db From 9b245ac4a1c401a9890bd8ffa903058d2c83cf20 Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 21 Oct 2024 17:53:55 -0400 Subject: [PATCH 10/13] fix(examples): volumes must match (with-nginx-proxy-postgres-fpm) Signed-off-by: Josh --- .../docker-compose/with-nginx-proxy/postgres/fpm/compose.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.examples/docker-compose/with-nginx-proxy/postgres/fpm/compose.yaml b/.examples/docker-compose/with-nginx-proxy/postgres/fpm/compose.yaml index 09a80e7d..80be65a6 100644 --- a/.examples/docker-compose/with-nginx-proxy/postgres/fpm/compose.yaml +++ b/.examples/docker-compose/with-nginx-proxy/postgres/fpm/compose.yaml @@ -18,6 +18,7 @@ services: restart: always volumes: - nextcloud:/var/www/html:z + # NOTE: The `volumes` config of the `cron` and `app` containers must match environment: - POSTGRES_HOST=db - REDIS_HOST=redis @@ -33,6 +34,7 @@ services: restart: always volumes: - nextcloud:/var/www/html:z,ro + # NOTE: The `volumes` included here should match those of the `app` container (unless you know what you're doing) environment: - VIRTUAL_HOST= - LETSENCRYPT_HOST= @@ -48,6 +50,7 @@ services: restart: always volumes: - nextcloud:/var/www/html:z + # NOTE: The `volumes` config of the `cron` and `app` containers must match entrypoint: /cron.sh depends_on: - db From 090934d9b0e1eec99479f84ab0e0b0bf8ff74857 Mon Sep 17 00:00:00 2001 From: Josh Date: Tue, 22 Oct 2024 09:15:05 -0400 Subject: [PATCH 11/13] feat(readme): Viewing merged config via `occ config:list system` Signed-off-by: Josh --- README.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d8f41dcb..ab6608ad 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,8 @@ If mounting additional volumes under `/var/www/html`, you should consider: You should note that data inside the main folder (`/var/www/html`) will be overridden/removed during installation and upgrades, unless listed in [upgrade.exclude](https://github.com/nextcloud/docker/blob/master/upgrade.exclude). The additional volumes officially supported are already in that list, but custom volumes will need to be added by you. We suggest mounting custom storage volumes outside of `/var/www/html` and if possible read-only so that making this adjustment is unnecessary. If you must do so, however, you may build a custom image with a modified `/upgrade.exclude` file that incorporates your custom volume(s). -## Using the Nextcloud command-line interface +## Using the Nextcloud command-line interface (`occ`) + To use the [Nextcloud command-line interface](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/occ_command.html) (aka. `occ` command): ```console $ docker exec --user www-data CONTAINER_ID php occ @@ -112,6 +113,23 @@ or for docker compose: ```console $ docker compose exec --user www-data app php occ ``` +or even shorter: +```console +$ docker compose exec -u33 app ./occ +``` +Note: substitute `82` for `33` if using the Alpine-based images. + +## Viewing the Nextcloud configuration (`config.php`) + +The image takes advantage of Nextcloud's [Multiple config.php support](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/config_sample_php_parameters.html#multiple-config-php-file) to inject auto configuration environment variables and set image specific config values. + +This means that merely viewing your `config.php` will not give you an accurate view of your running config. Instead, you should use Nextcloud's [`occ config:list system` command](https://docs.nextcloud.com/server/latest/admin_manual/occ_command.html#config-commands-label) to get get a complete view of your merged configuration. This has the added benefit of automatically omitting sensitive values such as passwords and secrets from the output by default (e.g. useful for shared publicly or assisting others when troubleshooting or reporting a bug). + +```console +$ docker compose exec -u33 app ./occ config:list system +``` + +The `--private` flag can also be specified, in order to output all configuration values including passwords and secrets. ## Auto configuration via environment variables The Nextcloud image supports auto configuration via environment variables. You can preconfigure everything that is asked on the install page on first run. To enable auto configuration, set your database connection via the following environment variables. You must specify all of the environment variables for a given database or the database environment variables defaults to SQLITE. ONLY use one database type! From d3341b61c1d41ac7fa98a34b8a3c6bc14c534efe Mon Sep 17 00:00:00 2001 From: Valentin Brandl Date: Thu, 24 Oct 2024 21:52:36 +0200 Subject: [PATCH 12/13] Fix initialization of `autocreate` and `use_ssl` (#2309) According to the documentation, both `OBJECTSTORE_S3_SSL` and `OBJECTSTORE_S3_AUTOCREATE` should default to `true`. Currently, when these environment variables are not set, they default to `false`. (See https://github.com/nextcloud/docker/issues/2308). This fix works, because `strtolower(false)` returns the empty string. So when `OBJECTSTORE_S3_SSL` is not set and `getenv('OBJECTSTORE_S3_SSL')` returns `false`, the check `strtolower($use_ssl) !== 'false'` will evaluate to `true`. With this fix, both values will be `true` if they are * not set * the empty string * any string that is not equal to `false` when converted to lowercase This should now match the documented behavior. Signed-off-by: Valentin Brandl --- .config/s3.config.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.config/s3.config.php b/.config/s3.config.php index 9941c562..a17e4037 100644 --- a/.config/s3.config.php +++ b/.config/s3.config.php @@ -14,8 +14,8 @@ if (getenv('OBJECTSTORE_S3_BUCKET')) { 'port' => getenv('OBJECTSTORE_S3_PORT') ?: '', 'storageClass' => getenv('OBJECTSTORE_S3_STORAGE_CLASS') ?: '', 'objectPrefix' => getenv("OBJECTSTORE_S3_OBJECT_PREFIX") ? getenv("OBJECTSTORE_S3_OBJECT_PREFIX") : "urn:oid:", - 'autocreate' => (strtolower($autocreate) === 'false' || $autocreate == false) ? false : true, - 'use_ssl' => (strtolower($use_ssl) === 'false' || $use_ssl == false) ? false : true, + 'autocreate' => strtolower($autocreate) !== 'false', + 'use_ssl' => strtolower($use_ssl) !== 'false', // required for some non Amazon S3 implementations 'use_path_style' => $use_path == true && strtolower($use_path) !== 'false', // required for older protocol versions From 29d959acfdeccbc3603a37cc4201b6ad916290bd Mon Sep 17 00:00:00 2001 From: GitHub Workflow Date: Thu, 24 Oct 2024 19:52:51 +0000 Subject: [PATCH 13/13] Runs update.sh --- 28/apache/config/s3.config.php | 4 ++-- 28/fpm-alpine/config/s3.config.php | 4 ++-- 28/fpm/config/s3.config.php | 4 ++-- 29/apache/config/s3.config.php | 4 ++-- 29/fpm-alpine/config/s3.config.php | 4 ++-- 29/fpm/config/s3.config.php | 4 ++-- 30/apache/config/s3.config.php | 4 ++-- 30/fpm-alpine/config/s3.config.php | 4 ++-- 30/fpm/config/s3.config.php | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/28/apache/config/s3.config.php b/28/apache/config/s3.config.php index 9941c562..a17e4037 100644 --- a/28/apache/config/s3.config.php +++ b/28/apache/config/s3.config.php @@ -14,8 +14,8 @@ if (getenv('OBJECTSTORE_S3_BUCKET')) { 'port' => getenv('OBJECTSTORE_S3_PORT') ?: '', 'storageClass' => getenv('OBJECTSTORE_S3_STORAGE_CLASS') ?: '', 'objectPrefix' => getenv("OBJECTSTORE_S3_OBJECT_PREFIX") ? getenv("OBJECTSTORE_S3_OBJECT_PREFIX") : "urn:oid:", - 'autocreate' => (strtolower($autocreate) === 'false' || $autocreate == false) ? false : true, - 'use_ssl' => (strtolower($use_ssl) === 'false' || $use_ssl == false) ? false : true, + 'autocreate' => strtolower($autocreate) !== 'false', + 'use_ssl' => strtolower($use_ssl) !== 'false', // required for some non Amazon S3 implementations 'use_path_style' => $use_path == true && strtolower($use_path) !== 'false', // required for older protocol versions diff --git a/28/fpm-alpine/config/s3.config.php b/28/fpm-alpine/config/s3.config.php index 9941c562..a17e4037 100644 --- a/28/fpm-alpine/config/s3.config.php +++ b/28/fpm-alpine/config/s3.config.php @@ -14,8 +14,8 @@ if (getenv('OBJECTSTORE_S3_BUCKET')) { 'port' => getenv('OBJECTSTORE_S3_PORT') ?: '', 'storageClass' => getenv('OBJECTSTORE_S3_STORAGE_CLASS') ?: '', 'objectPrefix' => getenv("OBJECTSTORE_S3_OBJECT_PREFIX") ? getenv("OBJECTSTORE_S3_OBJECT_PREFIX") : "urn:oid:", - 'autocreate' => (strtolower($autocreate) === 'false' || $autocreate == false) ? false : true, - 'use_ssl' => (strtolower($use_ssl) === 'false' || $use_ssl == false) ? false : true, + 'autocreate' => strtolower($autocreate) !== 'false', + 'use_ssl' => strtolower($use_ssl) !== 'false', // required for some non Amazon S3 implementations 'use_path_style' => $use_path == true && strtolower($use_path) !== 'false', // required for older protocol versions diff --git a/28/fpm/config/s3.config.php b/28/fpm/config/s3.config.php index 9941c562..a17e4037 100644 --- a/28/fpm/config/s3.config.php +++ b/28/fpm/config/s3.config.php @@ -14,8 +14,8 @@ if (getenv('OBJECTSTORE_S3_BUCKET')) { 'port' => getenv('OBJECTSTORE_S3_PORT') ?: '', 'storageClass' => getenv('OBJECTSTORE_S3_STORAGE_CLASS') ?: '', 'objectPrefix' => getenv("OBJECTSTORE_S3_OBJECT_PREFIX") ? getenv("OBJECTSTORE_S3_OBJECT_PREFIX") : "urn:oid:", - 'autocreate' => (strtolower($autocreate) === 'false' || $autocreate == false) ? false : true, - 'use_ssl' => (strtolower($use_ssl) === 'false' || $use_ssl == false) ? false : true, + 'autocreate' => strtolower($autocreate) !== 'false', + 'use_ssl' => strtolower($use_ssl) !== 'false', // required for some non Amazon S3 implementations 'use_path_style' => $use_path == true && strtolower($use_path) !== 'false', // required for older protocol versions diff --git a/29/apache/config/s3.config.php b/29/apache/config/s3.config.php index 9941c562..a17e4037 100644 --- a/29/apache/config/s3.config.php +++ b/29/apache/config/s3.config.php @@ -14,8 +14,8 @@ if (getenv('OBJECTSTORE_S3_BUCKET')) { 'port' => getenv('OBJECTSTORE_S3_PORT') ?: '', 'storageClass' => getenv('OBJECTSTORE_S3_STORAGE_CLASS') ?: '', 'objectPrefix' => getenv("OBJECTSTORE_S3_OBJECT_PREFIX") ? getenv("OBJECTSTORE_S3_OBJECT_PREFIX") : "urn:oid:", - 'autocreate' => (strtolower($autocreate) === 'false' || $autocreate == false) ? false : true, - 'use_ssl' => (strtolower($use_ssl) === 'false' || $use_ssl == false) ? false : true, + 'autocreate' => strtolower($autocreate) !== 'false', + 'use_ssl' => strtolower($use_ssl) !== 'false', // required for some non Amazon S3 implementations 'use_path_style' => $use_path == true && strtolower($use_path) !== 'false', // required for older protocol versions diff --git a/29/fpm-alpine/config/s3.config.php b/29/fpm-alpine/config/s3.config.php index 9941c562..a17e4037 100644 --- a/29/fpm-alpine/config/s3.config.php +++ b/29/fpm-alpine/config/s3.config.php @@ -14,8 +14,8 @@ if (getenv('OBJECTSTORE_S3_BUCKET')) { 'port' => getenv('OBJECTSTORE_S3_PORT') ?: '', 'storageClass' => getenv('OBJECTSTORE_S3_STORAGE_CLASS') ?: '', 'objectPrefix' => getenv("OBJECTSTORE_S3_OBJECT_PREFIX") ? getenv("OBJECTSTORE_S3_OBJECT_PREFIX") : "urn:oid:", - 'autocreate' => (strtolower($autocreate) === 'false' || $autocreate == false) ? false : true, - 'use_ssl' => (strtolower($use_ssl) === 'false' || $use_ssl == false) ? false : true, + 'autocreate' => strtolower($autocreate) !== 'false', + 'use_ssl' => strtolower($use_ssl) !== 'false', // required for some non Amazon S3 implementations 'use_path_style' => $use_path == true && strtolower($use_path) !== 'false', // required for older protocol versions diff --git a/29/fpm/config/s3.config.php b/29/fpm/config/s3.config.php index 9941c562..a17e4037 100644 --- a/29/fpm/config/s3.config.php +++ b/29/fpm/config/s3.config.php @@ -14,8 +14,8 @@ if (getenv('OBJECTSTORE_S3_BUCKET')) { 'port' => getenv('OBJECTSTORE_S3_PORT') ?: '', 'storageClass' => getenv('OBJECTSTORE_S3_STORAGE_CLASS') ?: '', 'objectPrefix' => getenv("OBJECTSTORE_S3_OBJECT_PREFIX") ? getenv("OBJECTSTORE_S3_OBJECT_PREFIX") : "urn:oid:", - 'autocreate' => (strtolower($autocreate) === 'false' || $autocreate == false) ? false : true, - 'use_ssl' => (strtolower($use_ssl) === 'false' || $use_ssl == false) ? false : true, + 'autocreate' => strtolower($autocreate) !== 'false', + 'use_ssl' => strtolower($use_ssl) !== 'false', // required for some non Amazon S3 implementations 'use_path_style' => $use_path == true && strtolower($use_path) !== 'false', // required for older protocol versions diff --git a/30/apache/config/s3.config.php b/30/apache/config/s3.config.php index 9941c562..a17e4037 100644 --- a/30/apache/config/s3.config.php +++ b/30/apache/config/s3.config.php @@ -14,8 +14,8 @@ if (getenv('OBJECTSTORE_S3_BUCKET')) { 'port' => getenv('OBJECTSTORE_S3_PORT') ?: '', 'storageClass' => getenv('OBJECTSTORE_S3_STORAGE_CLASS') ?: '', 'objectPrefix' => getenv("OBJECTSTORE_S3_OBJECT_PREFIX") ? getenv("OBJECTSTORE_S3_OBJECT_PREFIX") : "urn:oid:", - 'autocreate' => (strtolower($autocreate) === 'false' || $autocreate == false) ? false : true, - 'use_ssl' => (strtolower($use_ssl) === 'false' || $use_ssl == false) ? false : true, + 'autocreate' => strtolower($autocreate) !== 'false', + 'use_ssl' => strtolower($use_ssl) !== 'false', // required for some non Amazon S3 implementations 'use_path_style' => $use_path == true && strtolower($use_path) !== 'false', // required for older protocol versions diff --git a/30/fpm-alpine/config/s3.config.php b/30/fpm-alpine/config/s3.config.php index 9941c562..a17e4037 100644 --- a/30/fpm-alpine/config/s3.config.php +++ b/30/fpm-alpine/config/s3.config.php @@ -14,8 +14,8 @@ if (getenv('OBJECTSTORE_S3_BUCKET')) { 'port' => getenv('OBJECTSTORE_S3_PORT') ?: '', 'storageClass' => getenv('OBJECTSTORE_S3_STORAGE_CLASS') ?: '', 'objectPrefix' => getenv("OBJECTSTORE_S3_OBJECT_PREFIX") ? getenv("OBJECTSTORE_S3_OBJECT_PREFIX") : "urn:oid:", - 'autocreate' => (strtolower($autocreate) === 'false' || $autocreate == false) ? false : true, - 'use_ssl' => (strtolower($use_ssl) === 'false' || $use_ssl == false) ? false : true, + 'autocreate' => strtolower($autocreate) !== 'false', + 'use_ssl' => strtolower($use_ssl) !== 'false', // required for some non Amazon S3 implementations 'use_path_style' => $use_path == true && strtolower($use_path) !== 'false', // required for older protocol versions diff --git a/30/fpm/config/s3.config.php b/30/fpm/config/s3.config.php index 9941c562..a17e4037 100644 --- a/30/fpm/config/s3.config.php +++ b/30/fpm/config/s3.config.php @@ -14,8 +14,8 @@ if (getenv('OBJECTSTORE_S3_BUCKET')) { 'port' => getenv('OBJECTSTORE_S3_PORT') ?: '', 'storageClass' => getenv('OBJECTSTORE_S3_STORAGE_CLASS') ?: '', 'objectPrefix' => getenv("OBJECTSTORE_S3_OBJECT_PREFIX") ? getenv("OBJECTSTORE_S3_OBJECT_PREFIX") : "urn:oid:", - 'autocreate' => (strtolower($autocreate) === 'false' || $autocreate == false) ? false : true, - 'use_ssl' => (strtolower($use_ssl) === 'false' || $use_ssl == false) ? false : true, + 'autocreate' => strtolower($autocreate) !== 'false', + 'use_ssl' => strtolower($use_ssl) !== 'false', // required for some non Amazon S3 implementations 'use_path_style' => $use_path == true && strtolower($use_path) !== 'false', // required for older protocol versions