From 52650497660678ef31476ade50375b833c7eae8d Mon Sep 17 00:00:00 2001 From: Aaron Skarlupka Date: Wed, 30 Jan 2019 12:06:05 -0600 Subject: [PATCH 1/6] Create docker-compose.yml This docker-compose.yml file will create a nextcloud instance with signed certs using the lets encrypt companion and the nginx reverse proxy. Collabora office will also be deployed using signed certs. To use collabora the app must be installed within nextcloud and configured to use office.DOMAIN.TLD. There is no need to specify a port, simply the pubilc domain used to create your certs for the office instance. Ports, 443 and 80 should be forwarded to the server. Signed-off-by: aarskar --- .../docker-compose.yml | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 .examples/docker-compose/with-nginx-proxy-self-signed-ssl-collabora-office-mariadb/docker-compose.yml diff --git a/.examples/docker-compose/with-nginx-proxy-self-signed-ssl-collabora-office-mariadb/docker-compose.yml b/.examples/docker-compose/with-nginx-proxy-self-signed-ssl-collabora-office-mariadb/docker-compose.yml new file mode 100644 index 00000000..b6091b0b --- /dev/null +++ b/.examples/docker-compose/with-nginx-proxy-self-signed-ssl-collabora-office-mariadb/docker-compose.yml @@ -0,0 +1,109 @@ +version: '3' + +services: + + proxy: + image: jwilder/nginx-proxy:alpine + labels: + - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true" + container_name: nextcloud-proxy + networks: + - nextcloud_network + ports: + - 80:80 + - 443:443 + volumes: + - ./proxy/conf.d:/etc/nginx/conf.d:rw + - ./proxy/vhost.d:/etc/nginx/vhost.d:rw + - ./proxy/html:/usr/share/nginx/html:rw + - ./proxy/certs:/etc/nginx/certs:ro + - /etc/localtime:/etc/localtime:ro + - /var/run/docker.sock:/tmp/docker.sock:ro + restart: unless-stopped + + letsencrypt: + image: jrcs/letsencrypt-nginx-proxy-companion + container_name: nextcloud-letsencrypt + depends_on: + - proxy + networks: + - nextcloud_network + volumes: + - ./proxy/certs:/etc/nginx/certs:rw + - ./proxy/vhost.d:/etc/nginx/vhost.d:rw + - ./proxy/html:/usr/share/nginx/html:rw + - /etc/localtime:/etc/localtime:ro + - /var/run/docker.sock:/var/run/docker.sock:ro + restart: unless-stopped + db: + image: mariadb + container_name: nextcloud-mariadb + networks: + - nextcloud_network + volumes: + - db:/var/lib/mysql + - /etc/localtime:/etc/localtime:ro + environment: + # Create a root password for the maraiadb instance. + - MYSQL_ROOT_PASSWORD=CREATE-A-SECURE-ROOT-PASSWORD-HERE + # Create a password for the nextcloud users. If you have to manually connect your database you would use the nextcloud user and this password. + - MYSQL_PASSWORD=CREATE-A-SECURE-NEXTCLOUD-USER-PASSWORD-HERE + - MYSQL_DATABASE=nextcloud + - MYSQL_USER=nextcloud + restart: unless-stopped + + app: + image: nextcloud:latest + container_name: nextcloud-app + networks: + - nextcloud_network + depends_on: + - letsencrypt + - proxy + - db + volumes: + - nextcloud:/var/www/html + - ./app/config:/var/www/html/config + - ./app/custom_apps:/var/www/html/custom_apps + - ./app/data:/var/www/html/data + - ./app/themes:/var/www/html/themes + - /etc/localtime:/etc/localtime:ro + environment: + # The VIRTUAL_HOST and LETSENCRYPT_HOST should use the same publically reachable domain for your nextlcloud instance. + - VIRTUAL_HOST=cloud.DOMAIN.TLD + - LETSENCRYPT_HOST=cloud.DOMAIN.TLD + # This needs to be a real email as it will be used by let's encrypt for your cert and is used to warn you about renewals. + - LETSENCRYPT_EMAIL=YOUR-EMAIL@DOMAIN.TDL + restart: unless-stopped + collab: + image: collabora/code + container_name: nextcloud-collab + networks: + - nextcloud_network + depends_on: + - proxy + - letsencrypt + cap_add: + - MKNOD + ports: + - 9980:9980 + environment: + # This nees to be the same as what you set your app domain too (ex: cloud.domain.tld). + - domain=cloud\\.DOMAIN\\.TDL + - username=admin + # Create a passoword for the collabora office admin page. + - password=CREATE-A-SECURE-PASSWORD-HERE + - VIRTUAL_PROTO=https + - VIRTUAL_PORT=443 + # The VIRTUAL_HOST and LETSENCRYPT_HOST should use the same publically reachable domain for your collabora instance (ex: office.domain.tld). + - VIRTUAL_HOST=office.DOMAIN.TLD + - LETSENCRYPT_HOST=office.DOMAIN.TLD + # This needs to be a real email as it will be used by let's encrypt for your cert and is used to warn you about renewals. + - LETSENCRYPT_EMAIL=YOUR-EMAIL@DOMAIN.TDL + restart: unless-stopped +volumes: + nextcloud: + db: + +networks: + nextcloud_network: From e6054a4909ee1779a0506181d6750dfb1f4a955a Mon Sep 17 00:00:00 2001 From: Aaron Skarlupka Date: Wed, 30 Jan 2019 12:06:22 -0600 Subject: [PATCH 2/6] Create README.MD Signed-off-by: aarskar --- .../README.MD | 1 + 1 file changed, 1 insertion(+) create mode 100644 .examples/docker-compose/with-nginx-proxy-self-signed-ssl-collabora-office-mariadb/README.MD diff --git a/.examples/docker-compose/with-nginx-proxy-self-signed-ssl-collabora-office-mariadb/README.MD b/.examples/docker-compose/with-nginx-proxy-self-signed-ssl-collabora-office-mariadb/README.MD new file mode 100644 index 00000000..716256e5 --- /dev/null +++ b/.examples/docker-compose/with-nginx-proxy-self-signed-ssl-collabora-office-mariadb/README.MD @@ -0,0 +1 @@ +This docker-compose.yml file will create a nextcloud instance with signed certs using the lets encrypt companion and the nginx reverse proxy. Collabora office will also be deployed using signed certs. To use collabora the app must be installed within nextcloud and configured to use office.DOMAIN.TLD. There is no need to specify a port, simply the pubilc domain used to create your certs for the office instance. Ports, 443 and 80 should be forwarded to the server. From 02e6f4339c0eb74831eca1b946936278fcfeee22 Mon Sep 17 00:00:00 2001 From: Aaron Skarlupka Date: Wed, 30 Jan 2019 12:11:22 -0600 Subject: [PATCH 3/6] Add files via upload Signed-off-by: aarskar --- .../collaboraOnlineNCSettings.png | Bin 0 -> 24868 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .examples/docker-compose/with-nginx-proxy-self-signed-ssl-collabora-office-mariadb/collaboraOnlineNCSettings.png diff --git a/.examples/docker-compose/with-nginx-proxy-self-signed-ssl-collabora-office-mariadb/collaboraOnlineNCSettings.png b/.examples/docker-compose/with-nginx-proxy-self-signed-ssl-collabora-office-mariadb/collaboraOnlineNCSettings.png new file mode 100644 index 0000000000000000000000000000000000000000..1922a88732ee6a3bd56eeecc4610f963f4bb22e8 GIT binary patch literal 24868 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 r+&2PnkNp=v|NnZ+|Bu@oUE$xZdRBLydhi Date: Wed, 30 Jan 2019 12:17:13 -0600 Subject: [PATCH 4/6] Update README.MD Signed-off-by: aarskar --- .../README.MD | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.examples/docker-compose/with-nginx-proxy-self-signed-ssl-collabora-office-mariadb/README.MD b/.examples/docker-compose/with-nginx-proxy-self-signed-ssl-collabora-office-mariadb/README.MD index 716256e5..26dc0b4f 100644 --- a/.examples/docker-compose/with-nginx-proxy-self-signed-ssl-collabora-office-mariadb/README.MD +++ b/.examples/docker-compose/with-nginx-proxy-self-signed-ssl-collabora-office-mariadb/README.MD @@ -1 +1,5 @@ -This docker-compose.yml file will create a nextcloud instance with signed certs using the lets encrypt companion and the nginx reverse proxy. Collabora office will also be deployed using signed certs. To use collabora the app must be installed within nextcloud and configured to use office.DOMAIN.TLD. There is no need to specify a port, simply the pubilc domain used to create your certs for the office instance. Ports, 443 and 80 should be forwarded to the server. +This docker-compose.yml file will create a nextcloud instance with signed certs using the lets encrypt companion and the nginx reverse proxy. Collabora office will also be deployed using signed certs. To use collabora the app must be installed within nextcloud and configured to use office.DOMAIN.TLD. + +There is no need to specify a port, simply the pubilc domain used to create your certs for the office instance. Ports, 443 and 80 should be forwarded to the server. + +![Callabora Settings](collaboraOnlineNCSettings.png) From 71235584cd7c01cdf3dcec27f3241685006eac49 Mon Sep 17 00:00:00 2001 From: GitHub Workflow Date: Tue, 25 Feb 2025 19:50:02 +0000 Subject: [PATCH 5/6] Runs update.sh --- 31/apache/Dockerfile | 184 +++++++++++ .../config/apache-pretty-urls.config.php | 4 + 31/apache/config/apcu.config.php | 4 + 31/apache/config/apps.config.php | 15 + 31/apache/config/autoconfig.php | 41 +++ 31/apache/config/redis.config.php | 21 ++ 31/apache/config/reverse-proxy.config.php | 35 +++ 31/apache/config/s3.config.php | 48 +++ 31/apache/config/smtp.config.php | 22 ++ 31/apache/config/swift.config.php | 31 ++ .../config/upgrade-disable-web.config.php | 4 + 31/apache/cron.sh | 4 + 31/apache/entrypoint.sh | 293 ++++++++++++++++++ 31/apache/upgrade.exclude | 6 + 31/fpm-alpine/Dockerfile | 160 ++++++++++ 31/fpm-alpine/config/apcu.config.php | 4 + 31/fpm-alpine/config/apps.config.php | 15 + 31/fpm-alpine/config/autoconfig.php | 41 +++ 31/fpm-alpine/config/redis.config.php | 21 ++ 31/fpm-alpine/config/reverse-proxy.config.php | 35 +++ 31/fpm-alpine/config/s3.config.php | 48 +++ 31/fpm-alpine/config/smtp.config.php | 22 ++ 31/fpm-alpine/config/swift.config.php | 31 ++ .../config/upgrade-disable-web.config.php | 4 + 31/fpm-alpine/cron.sh | 4 + 31/fpm-alpine/entrypoint.sh | 293 ++++++++++++++++++ 31/fpm-alpine/upgrade.exclude | 6 + 31/fpm/Dockerfile | 169 ++++++++++ 31/fpm/config/apcu.config.php | 4 + 31/fpm/config/apps.config.php | 15 + 31/fpm/config/autoconfig.php | 41 +++ 31/fpm/config/redis.config.php | 21 ++ 31/fpm/config/reverse-proxy.config.php | 35 +++ 31/fpm/config/s3.config.php | 48 +++ 31/fpm/config/smtp.config.php | 22 ++ 31/fpm/config/swift.config.php | 31 ++ 31/fpm/config/upgrade-disable-web.config.php | 4 + 31/fpm/cron.sh | 4 + 31/fpm/entrypoint.sh | 293 ++++++++++++++++++ 31/fpm/upgrade.exclude | 6 + latest.txt | 2 +- versions.json | 26 ++ 42 files changed, 2116 insertions(+), 1 deletion(-) create mode 100644 31/apache/Dockerfile create mode 100644 31/apache/config/apache-pretty-urls.config.php create mode 100644 31/apache/config/apcu.config.php create mode 100644 31/apache/config/apps.config.php create mode 100644 31/apache/config/autoconfig.php create mode 100644 31/apache/config/redis.config.php create mode 100644 31/apache/config/reverse-proxy.config.php create mode 100644 31/apache/config/s3.config.php create mode 100644 31/apache/config/smtp.config.php create mode 100644 31/apache/config/swift.config.php create mode 100644 31/apache/config/upgrade-disable-web.config.php create mode 100755 31/apache/cron.sh create mode 100755 31/apache/entrypoint.sh create mode 100644 31/apache/upgrade.exclude create mode 100644 31/fpm-alpine/Dockerfile create mode 100644 31/fpm-alpine/config/apcu.config.php create mode 100644 31/fpm-alpine/config/apps.config.php create mode 100644 31/fpm-alpine/config/autoconfig.php create mode 100644 31/fpm-alpine/config/redis.config.php create mode 100644 31/fpm-alpine/config/reverse-proxy.config.php create mode 100644 31/fpm-alpine/config/s3.config.php create mode 100644 31/fpm-alpine/config/smtp.config.php create mode 100644 31/fpm-alpine/config/swift.config.php create mode 100644 31/fpm-alpine/config/upgrade-disable-web.config.php create mode 100755 31/fpm-alpine/cron.sh create mode 100755 31/fpm-alpine/entrypoint.sh create mode 100644 31/fpm-alpine/upgrade.exclude create mode 100644 31/fpm/Dockerfile create mode 100644 31/fpm/config/apcu.config.php create mode 100644 31/fpm/config/apps.config.php create mode 100644 31/fpm/config/autoconfig.php create mode 100644 31/fpm/config/redis.config.php create mode 100644 31/fpm/config/reverse-proxy.config.php create mode 100644 31/fpm/config/s3.config.php create mode 100644 31/fpm/config/smtp.config.php create mode 100644 31/fpm/config/swift.config.php create mode 100644 31/fpm/config/upgrade-disable-web.config.php create mode 100755 31/fpm/cron.sh create mode 100755 31/fpm/entrypoint.sh create mode 100644 31/fpm/upgrade.exclude diff --git a/31/apache/Dockerfile b/31/apache/Dockerfile new file mode 100644 index 00000000..aeab9d9b --- /dev/null +++ b/31/apache/Dockerfile @@ -0,0 +1,184 @@ +# DO NOT EDIT: created by update.sh from Dockerfile-debian.template +FROM php:8.2-apache-bookworm + +# 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 '*/5 * * * * 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 +ENV PHP_OPCACHE_MEMORY_CONSUMPTION 128 +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 ftp --with-openssl-dir=/usr; \ + 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 \ + ftp \ + 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-5.1.24; \ + pecl install igbinary-3.2.16; \ + pecl install imagick-3.7.0; \ + pecl install memcached-3.3.0 \ + --configureoptions 'enable-memcached-igbinary="yes"'; \ + pecl install redis-6.1.0 \ + --configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"'; \ + \ + docker-php-ext-enable \ + apcu \ + igbinary \ + 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=${PHP_OPCACHE_MEMORY_CONSUMPTION}'; \ + echo 'opcache.save_comments=1'; \ + echo 'opcache.revalidate_freq=60'; \ + echo 'opcache.jit=1255'; \ + echo 'opcache.jit_buffer_size=8M'; \ + } > "${PHP_INI_DIR}/conf.d/opcache-recommended.ini"; \ + \ + echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \ + \ + { \ + echo 'apc.serializer=igbinary'; \ + echo 'session.serialize_handler=igbinary'; \ + } >> "${PHP_INI_DIR}/conf.d/docker-php-ext-igbinary.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 + +RUN a2enmod headers rewrite remoteip ; \ + { \ + echo 'RemoteIPHeader X-Real-IP'; \ + echo 'RemoteIPInternalProxy 10.0.0.0/8'; \ + echo 'RemoteIPInternalProxy 172.16.0.0/12'; \ + echo 'RemoteIPInternalProxy 192.168.0.0/16'; \ + } > /etc/apache2/conf-available/remoteip.conf; \ + a2enconf remoteip + +# set apache config LimitRequestBody +ENV APACHE_BODY_LIMIT 1073741824 +RUN { \ + echo 'LimitRequestBody ${APACHE_BODY_LIMIT}'; \ + } > /etc/apache2/conf-available/apache-limits.conf; \ + a2enconf apache-limits + +ENV NEXTCLOUD_VERSION 31.0.0 + +RUN set -ex; \ + fetchDeps=" \ + gnupg \ + dirmngr \ + "; \ + apt-get update; \ + apt-get install -y --no-install-recommends $fetchDeps; \ + \ + curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-31.0.0.tar.bz2"; \ + curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-31.0.0.tar.bz2.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/ + +ENTRYPOINT ["/entrypoint.sh"] +CMD ["apache2-foreground"] diff --git a/31/apache/config/apache-pretty-urls.config.php b/31/apache/config/apache-pretty-urls.config.php new file mode 100644 index 00000000..72da1d8c --- /dev/null +++ b/31/apache/config/apache-pretty-urls.config.php @@ -0,0 +1,4 @@ + '/', +); diff --git a/31/apache/config/apcu.config.php b/31/apache/config/apcu.config.php new file mode 100644 index 00000000..69fed876 --- /dev/null +++ b/31/apache/config/apcu.config.php @@ -0,0 +1,4 @@ + '\OC\Memcache\APCu', +); diff --git a/31/apache/config/apps.config.php b/31/apache/config/apps.config.php new file mode 100644 index 00000000..4c37f72a --- /dev/null +++ b/31/apache/config/apps.config.php @@ -0,0 +1,15 @@ + array ( + 0 => array ( + 'path' => OC::$SERVERROOT.'/apps', + 'url' => '/apps', + 'writable' => false, + ), + 1 => array ( + 'path' => OC::$SERVERROOT.'/custom_apps', + 'url' => '/custom_apps', + 'writable' => true, + ), + ), +); diff --git a/31/apache/config/autoconfig.php b/31/apache/config/autoconfig.php new file mode 100644 index 00000000..92ad2a1c --- /dev/null +++ b/31/apache/config/autoconfig.php @@ -0,0 +1,41 @@ + '\OC\Memcache\Redis', + 'memcache.locking' => '\OC\Memcache\Redis', + 'redis' => array( + 'host' => getenv('REDIS_HOST'), + 'password' => getenv('REDIS_HOST_PASSWORD_FILE') ? trim(file_get_contents(getenv('REDIS_HOST_PASSWORD_FILE'))) : (string) getenv('REDIS_HOST_PASSWORD'), + ), + ); + + if (getenv('REDIS_HOST_PORT') !== false) { + $CONFIG['redis']['port'] = (int) getenv('REDIS_HOST_PORT'); + } elseif (getenv('REDIS_HOST')[0] != '/') { + $CONFIG['redis']['port'] = 6379; + } + + if (getenv('REDIS_HOST_USER') !== false) { + $CONFIG['redis']['user'] = (string) getenv('REDIS_HOST_USER'); + } +} diff --git a/31/apache/config/reverse-proxy.config.php b/31/apache/config/reverse-proxy.config.php new file mode 100644 index 00000000..30c660ff --- /dev/null +++ b/31/apache/config/reverse-proxy.config.php @@ -0,0 +1,35 @@ + array( + 'class' => '\OC\Files\ObjectStore\S3', + 'arguments' => array( + 'bucket' => getenv('OBJECTSTORE_S3_BUCKET'), + 'region' => getenv('OBJECTSTORE_S3_REGION') ?: '', + 'hostname' => getenv('OBJECTSTORE_S3_HOST') ?: '', + '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', + '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 + 'legacy_auth' => $use_legacyauth == true && strtolower($use_legacyauth) !== 'false' + ) + ) + ); + + if (getenv('OBJECTSTORE_S3_KEY_FILE')) { + $CONFIG['objectstore']['arguments']['key'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_KEY_FILE'))); + } elseif (getenv('OBJECTSTORE_S3_KEY')) { + $CONFIG['objectstore']['arguments']['key'] = getenv('OBJECTSTORE_S3_KEY'); + } else { + $CONFIG['objectstore']['arguments']['key'] = ''; + } + + if (getenv('OBJECTSTORE_S3_SECRET_FILE')) { + $CONFIG['objectstore']['arguments']['secret'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_SECRET_FILE'))); + } elseif (getenv('OBJECTSTORE_S3_SECRET')) { + $CONFIG['objectstore']['arguments']['secret'] = getenv('OBJECTSTORE_S3_SECRET'); + } else { + $CONFIG['objectstore']['arguments']['secret'] = ''; + } + + if (getenv('OBJECTSTORE_S3_SSE_C_KEY_FILE')) { + $CONFIG['objectstore']['arguments']['sse_c_key'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_SSE_C_KEY_FILE'))); + } elseif (getenv('OBJECTSTORE_S3_SSE_C_KEY')) { + $CONFIG['objectstore']['arguments']['sse_c_key'] = getenv('OBJECTSTORE_S3_SSE_C_KEY'); + } +} diff --git a/31/apache/config/smtp.config.php b/31/apache/config/smtp.config.php new file mode 100644 index 00000000..66a2ef7e --- /dev/null +++ b/31/apache/config/smtp.config.php @@ -0,0 +1,22 @@ + 'smtp', + 'mail_smtphost' => getenv('SMTP_HOST'), + 'mail_smtpport' => getenv('SMTP_PORT') ?: (getenv('SMTP_SECURE') ? 465 : 25), + 'mail_smtpsecure' => getenv('SMTP_SECURE') ?: '', + 'mail_smtpauth' => getenv('SMTP_NAME') && (getenv('SMTP_PASSWORD') || getenv('SMTP_PASSWORD_FILE')), + 'mail_smtpauthtype' => getenv('SMTP_AUTHTYPE') ?: 'LOGIN', + 'mail_smtpname' => getenv('SMTP_NAME') ?: '', + 'mail_from_address' => getenv('MAIL_FROM_ADDRESS'), + 'mail_domain' => getenv('MAIL_DOMAIN'), + ); + + if (getenv('SMTP_PASSWORD_FILE')) { + $CONFIG['mail_smtppassword'] = trim(file_get_contents(getenv('SMTP_PASSWORD_FILE'))); + } elseif (getenv('SMTP_PASSWORD')) { + $CONFIG['mail_smtppassword'] = getenv('SMTP_PASSWORD'); + } else { + $CONFIG['mail_smtppassword'] = ''; + } +} diff --git a/31/apache/config/swift.config.php b/31/apache/config/swift.config.php new file mode 100644 index 00000000..47ada566 --- /dev/null +++ b/31/apache/config/swift.config.php @@ -0,0 +1,31 @@ + [ + 'class' => 'OC\\Files\\ObjectStore\\Swift', + 'arguments' => [ + 'autocreate' => $autocreate == true && strtolower($autocreate) !== 'false', + 'user' => [ + 'name' => getenv('OBJECTSTORE_SWIFT_USER_NAME'), + 'password' => getenv('OBJECTSTORE_SWIFT_USER_PASSWORD'), + 'domain' => [ + 'name' => (getenv('OBJECTSTORE_SWIFT_USER_DOMAIN')) ?: 'Default', + ], + ], + 'scope' => [ + 'project' => [ + 'name' => getenv('OBJECTSTORE_SWIFT_PROJECT_NAME'), + 'domain' => [ + 'name' => (getenv('OBJECTSTORE_SWIFT_PROJECT_DOMAIN')) ?: 'Default', + ], + ], + ], + 'serviceName' => (getenv('OBJECTSTORE_SWIFT_SERVICE_NAME')) ?: 'swift', + 'region' => getenv('OBJECTSTORE_SWIFT_REGION'), + 'url' => getenv('OBJECTSTORE_SWIFT_URL'), + 'bucket' => getenv('OBJECTSTORE_SWIFT_CONTAINER_NAME'), + ] + ] + ); +} diff --git a/31/apache/config/upgrade-disable-web.config.php b/31/apache/config/upgrade-disable-web.config.php new file mode 100644 index 00000000..cb00b436 --- /dev/null +++ b/31/apache/config/upgrade-disable-web.config.php @@ -0,0 +1,4 @@ + true, +); diff --git a/31/apache/cron.sh b/31/apache/cron.sh new file mode 100755 index 00000000..b4cd9af6 --- /dev/null +++ b/31/apache/cron.sh @@ -0,0 +1,4 @@ +#!/bin/sh +set -eu + +exec busybox crond -f -L /dev/stdout diff --git a/31/apache/entrypoint.sh b/31/apache/entrypoint.sh new file mode 100755 index 00000000..8e178f2e --- /dev/null +++ b/31/apache/entrypoint.sh @@ -0,0 +1,293 @@ +#!/bin/sh +set -eu + +# version_greater A B returns whether A > B +version_greater() { + [ "$(printf '%s\n' "$@" | sort -t '.' -n -k1,1 -k2,2 -k3,3 -k4,4 | head -n 1)" != "$1" ] +} + +# return true if specified directory is empty +directory_empty() { + [ -z "$(ls -A "$1/")" ] +} + +run_as() { + if [ "$(id -u)" = 0 ]; then + su -p "$user" -s /bin/sh -c "$1" + else + sh -c "$1" + fi +} + +# Execute all executable files in a given directory in alphanumeric order +run_path() { + local hook_folder_path="/docker-entrypoint-hooks.d/$1" + local return_code=0 + + if ! [ -d "${hook_folder_path}" ]; then + echo "=> Skipping the folder \"${hook_folder_path}\", because it doesn't exist" + return 0 + fi + + echo "=> Searching for scripts (*.sh) to run, located in the folder: ${hook_folder_path}" + + ( + find "${hook_folder_path}" -maxdepth 1 -iname '*.sh' '(' -type f -o -type l ')' -print | sort | while read -r script_file_path; do + if ! [ -x "${script_file_path}" ]; then + echo "==> The script \"${script_file_path}\" was skipped, because it didn't have the executable flag" + continue + fi + + echo "==> Running the script (cwd: $(pwd)): \"${script_file_path}\"" + + run_as "${script_file_path}" || return_code="$?" + + if [ "${return_code}" -ne "0" ]; then + echo "==> Failed at executing \"${script_file_path}\". Exit code: ${return_code}" + exit 1 + fi + + echo "==> Finished the script: \"${script_file_path}\"" + done + ) +} + +# usage: file_env VAR [DEFAULT] +# ie: file_env 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + local varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//") + local fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//") + if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + if [ -n "${varValue}" ]; then + export "$var"="${varValue}" + elif [ -n "${fileVarValue}" ]; then + export "$var"="$(cat "${fileVarValue}")" + elif [ -n "${def}" ]; then + export "$var"="$def" + fi + unset "$fileVar" +} + +if expr "$1" : "apache" 1>/dev/null; then + if [ -n "${APACHE_DISABLE_REWRITE_IP+x}" ]; then + a2disconf remoteip + fi +fi + +if expr "$1" : "apache" 1>/dev/null || [ "$1" = "php-fpm" ] || [ "${NEXTCLOUD_UPDATE:-0}" -eq 1 ]; then + uid="$(id -u)" + gid="$(id -g)" + if [ "$uid" = '0' ]; then + case "$1" in + apache2*) + user="${APACHE_RUN_USER:-www-data}" + group="${APACHE_RUN_GROUP:-www-data}" + + # strip off any '#' symbol ('#1000' is valid syntax for Apache) + user="${user#'#'}" + group="${group#'#'}" + ;; + *) # php-fpm + user='www-data' + group='www-data' + ;; + esac + else + user="$uid" + group="$gid" + fi + + if [ -n "${REDIS_HOST+x}" ]; then + + echo "Configuring Redis as session handler" + { + file_env REDIS_HOST_PASSWORD + echo 'session.save_handler = redis' + # check if redis host is an unix socket path + if [ "$(echo "$REDIS_HOST" | cut -c1-1)" = "/" ]; then + if [ -n "${REDIS_HOST_PASSWORD+x}" ]; then + echo "session.save_path = \"unix://${REDIS_HOST}?auth=${REDIS_HOST_PASSWORD}\"" + else + echo "session.save_path = \"unix://${REDIS_HOST}\"" + fi + # check if redis password has been set + elif [ -n "${REDIS_HOST_PASSWORD+x}" ]; then + echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}?auth=${REDIS_HOST_PASSWORD}\"" + else + echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}\"" + fi + echo "redis.session.locking_enabled = 1" + echo "redis.session.lock_retries = -1" + # redis.session.lock_wait_time is specified in microseconds. + # Wait 10ms before retrying the lock rather than the default 2ms. + echo "redis.session.lock_wait_time = 10000" + } > /usr/local/etc/php/conf.d/redis-session.ini + fi + + # If another process is syncing the html folder, wait for + # it to be done, then escape initalization. + ( + if ! flock -n 9; then + # If we couldn't get it immediately, show a message, then wait for real + echo "Another process is initializing Nextcloud. Waiting..." + flock 9 + fi + + installed_version="0.0.0.0" + if [ -f /var/www/html/version.php ]; then + # shellcheck disable=SC2016 + installed_version="$(php -r 'require "/var/www/html/version.php"; echo implode(".", $OC_Version);')" + fi + # shellcheck disable=SC2016 + image_version="$(php -r 'require "/usr/src/nextcloud/version.php"; echo implode(".", $OC_Version);')" + + if version_greater "$installed_version" "$image_version"; then + echo "Can't start Nextcloud because the version of the data ($installed_version) is higher than the docker image version ($image_version) and downgrading is not supported. Are you sure you have pulled the newest image version?" + exit 1 + fi + + if version_greater "$image_version" "$installed_version"; then + echo "Initializing nextcloud $image_version ..." + if [ "$installed_version" != "0.0.0.0" ]; then + if [ "${image_version%%.*}" -gt "$((${installed_version%%.*} + 1))" ]; then + echo "Can't start Nextcloud because upgrading from $installed_version to $image_version is not supported." + echo "It is only possible to upgrade one major version at a time. For example, if you want to upgrade from version 14 to 16, you will have to upgrade from version 14 to 15, then from 15 to 16." + exit 1 + fi + echo "Upgrading nextcloud from $installed_version ..." + run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_before + fi + if [ "$(id -u)" = 0 ]; then + rsync_options="-rlDog --chown $user:$group" + else + rsync_options="-rlD" + fi + + rsync $rsync_options --delete --exclude-from=/upgrade.exclude /usr/src/nextcloud/ /var/www/html/ + for dir in config data custom_apps themes; do + if [ ! -d "/var/www/html/$dir" ] || directory_empty "/var/www/html/$dir"; then + rsync $rsync_options --include "/$dir/" --exclude '/*' /usr/src/nextcloud/ /var/www/html/ + fi + done + rsync $rsync_options --include '/version.php' --exclude '/*' /usr/src/nextcloud/ /var/www/html/ + + # Install + if [ "$installed_version" = "0.0.0.0" ]; then + echo "New nextcloud instance" + + file_env NEXTCLOUD_ADMIN_PASSWORD + file_env NEXTCLOUD_ADMIN_USER + + install=false + if [ -n "${NEXTCLOUD_ADMIN_USER+x}" ] && [ -n "${NEXTCLOUD_ADMIN_PASSWORD+x}" ]; then + # shellcheck disable=SC2016 + install_options='-n --admin-user "$NEXTCLOUD_ADMIN_USER" --admin-pass "$NEXTCLOUD_ADMIN_PASSWORD"' + if [ -n "${NEXTCLOUD_DATA_DIR+x}" ]; then + # shellcheck disable=SC2016 + install_options=$install_options' --data-dir "$NEXTCLOUD_DATA_DIR"' + fi + + file_env MYSQL_DATABASE + file_env MYSQL_PASSWORD + file_env MYSQL_USER + file_env POSTGRES_DB + file_env POSTGRES_PASSWORD + file_env POSTGRES_USER + + if [ -n "${SQLITE_DATABASE+x}" ]; then + echo "Installing with SQLite database" + # shellcheck disable=SC2016 + install_options=$install_options' --database-name "$SQLITE_DATABASE"' + install=true + elif [ -n "${MYSQL_DATABASE+x}" ] && [ -n "${MYSQL_USER+x}" ] && [ -n "${MYSQL_PASSWORD+x}" ] && [ -n "${MYSQL_HOST+x}" ]; then + echo "Installing with MySQL database" + # shellcheck disable=SC2016 + install_options=$install_options' --database mysql --database-name "$MYSQL_DATABASE" --database-user "$MYSQL_USER" --database-pass "$MYSQL_PASSWORD" --database-host "$MYSQL_HOST"' + install=true + elif [ -n "${POSTGRES_DB+x}" ] && [ -n "${POSTGRES_USER+x}" ] && [ -n "${POSTGRES_PASSWORD+x}" ] && [ -n "${POSTGRES_HOST+x}" ]; then + echo "Installing with PostgreSQL database" + # shellcheck disable=SC2016 + install_options=$install_options' --database pgsql --database-name "$POSTGRES_DB" --database-user "$POSTGRES_USER" --database-pass "$POSTGRES_PASSWORD" --database-host "$POSTGRES_HOST"' + install=true + fi + + if [ "$install" = true ]; then + run_path pre-installation + + echo "Starting nextcloud installation" + max_retries=10 + try=0 + until [ "$try" -gt "$max_retries" ] || run_as "php /var/www/html/occ maintenance:install $install_options" + do + echo "Retrying install..." + try=$((try+1)) + sleep 10s + done + if [ "$try" -gt "$max_retries" ]; then + echo "Installing of nextcloud failed!" + exit 1 + fi + if [ -n "${NEXTCLOUD_TRUSTED_DOMAINS+x}" ]; then + echo "Setting trusted domains…" + NC_TRUSTED_DOMAIN_IDX=1 + for DOMAIN in $NEXTCLOUD_TRUSTED_DOMAINS ; do + DOMAIN=$(echo "$DOMAIN" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + run_as "php /var/www/html/occ config:system:set trusted_domains $NC_TRUSTED_DOMAIN_IDX --value=$DOMAIN" + NC_TRUSTED_DOMAIN_IDX=$((NC_TRUSTED_DOMAIN_IDX+1)) + done + fi + + run_path post-installation + fi + fi + # not enough specified to do a fully automated installation + if [ "$install" = false ]; then + echo "Next step: Access your instance to finish the web-based installation!" + echo "Hint: You can specify NEXTCLOUD_ADMIN_USER and NEXTCLOUD_ADMIN_PASSWORD and the database variables _prior to first launch_ to fully automate initial installation." + fi + # Upgrade + else + run_path pre-upgrade + + run_as 'php /var/www/html/occ upgrade' + + run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_after + echo "The following apps have been disabled:" + diff /tmp/list_before /tmp/list_after | grep '<' | cut -d- -f2 | cut -d: -f1 + rm -f /tmp/list_before /tmp/list_after + + run_path post-upgrade + fi + + echo "Initializing finished" + fi + + # Update htaccess after init if requested + if [ -n "${NEXTCLOUD_INIT_HTACCESS+x}" ] && [ "$installed_version" != "0.0.0.0" ]; then + run_as 'php /var/www/html/occ maintenance:update:htaccess' + fi + ) 9> /var/www/html/nextcloud-init-sync.lock + + # warn if config files on persistent storage differ from the latest version of this image + for cfgPath in /usr/src/nextcloud/config/*.php; do + cfgFile=$(basename "$cfgPath") + + if [ "$cfgFile" != "config.sample.php" ] && [ "$cfgFile" != "autoconfig.php" ]; then + if ! cmp -s "/usr/src/nextcloud/config/$cfgFile" "/var/www/html/config/$cfgFile"; then + echo "Warning: /var/www/html/config/$cfgFile differs from the latest version of this image at /usr/src/nextcloud/config/$cfgFile" + fi + fi + done + + run_path before-starting +fi + +exec "$@" diff --git a/31/apache/upgrade.exclude b/31/apache/upgrade.exclude new file mode 100644 index 00000000..31ce39a8 --- /dev/null +++ b/31/apache/upgrade.exclude @@ -0,0 +1,6 @@ +/config/ +/data/ +/custom_apps/ +/themes/ +/version.php +/nextcloud-init-sync.lock diff --git a/31/fpm-alpine/Dockerfile b/31/fpm-alpine/Dockerfile new file mode 100644 index 00000000..9972b489 --- /dev/null +++ b/31/fpm-alpine/Dockerfile @@ -0,0 +1,160 @@ +# DO NOT EDIT: created by update.sh from Dockerfile-alpine.template +FROM php:8.2-fpm-alpine3.21 + +# entrypoint.sh and cron.sh dependencies +RUN set -ex; \ + \ + apk add --no-cache \ + imagemagick \ + imagemagick-pdf \ + imagemagick-jpeg \ + imagemagick-raw \ + imagemagick-tiff \ + imagemagick-heic \ + imagemagick-webp \ + imagemagick-svg \ + rsync \ + ; \ + \ + rm /var/spool/cron/crontabs/root; \ + echo '*/5 * * * * 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 +RUN set -ex; \ + \ + apk add --no-cache --virtual .build-deps \ + $PHPIZE_DEPS \ + autoconf \ + freetype-dev \ + gmp-dev \ + icu-dev \ + imagemagick-dev \ + libevent-dev \ + libjpeg-turbo-dev \ + libmcrypt-dev \ + libmemcached-dev \ + libpng-dev \ + libwebp-dev \ + libxml2-dev \ + libzip-dev \ + openldap-dev \ + pcre-dev \ + postgresql-dev \ + ; \ + \ + docker-php-ext-configure ftp --with-openssl-dir=/usr; \ + docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp; \ + docker-php-ext-configure ldap; \ + docker-php-ext-install -j "$(nproc)" \ + bcmath \ + exif \ + ftp \ + 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-5.1.24; \ + pecl install igbinary-3.2.16; \ + pecl install imagick-3.7.0; \ + pecl install memcached-3.3.0 \ + --configureoptions 'enable-memcached-igbinary="yes"'; \ + pecl install redis-6.1.0 \ + --configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"'; \ + \ + docker-php-ext-enable \ + apcu \ + igbinary \ + imagick \ + memcached \ + redis \ + ; \ + rm -r /tmp/pear; \ + \ + runDeps="$( \ + scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \ + | tr ',' '\n' \ + | sort -u \ + | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ + )"; \ + apk add --no-network --virtual .nextcloud-phpext-rundeps $runDeps; \ + apk del --no-network .build-deps + +# set recommended PHP.ini settings +# see https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#enable-php-opcache +ENV PHP_MEMORY_LIMIT 512M +ENV PHP_UPLOAD_LIMIT 512M +ENV PHP_OPCACHE_MEMORY_CONSUMPTION 128 +RUN { \ + echo 'opcache.enable=1'; \ + echo 'opcache.interned_strings_buffer=32'; \ + echo 'opcache.max_accelerated_files=10000'; \ + echo 'opcache.memory_consumption=${PHP_OPCACHE_MEMORY_CONSUMPTION}'; \ + echo 'opcache.save_comments=1'; \ + echo 'opcache.revalidate_freq=60'; \ + echo 'opcache.jit=1255'; \ + echo 'opcache.jit_buffer_size=8M'; \ + } > "${PHP_INI_DIR}/conf.d/opcache-recommended.ini"; \ + \ + echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \ + \ + { \ + echo 'apc.serializer=igbinary'; \ + echo 'session.serialize_handler=igbinary'; \ + } >> "${PHP_INI_DIR}/conf.d/docker-php-ext-igbinary.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 + + +ENV NEXTCLOUD_VERSION 31.0.0 + +RUN set -ex; \ + apk add --no-cache --virtual .fetch-deps \ + bzip2 \ + gnupg \ + ; \ + \ + curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-31.0.0.tar.bz2"; \ + curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-31.0.0.tar.bz2.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; \ + apk del --no-network .fetch-deps + +COPY *.sh upgrade.exclude / +COPY config/* /usr/src/nextcloud/config/ + +ENTRYPOINT ["/entrypoint.sh"] +CMD ["php-fpm"] diff --git a/31/fpm-alpine/config/apcu.config.php b/31/fpm-alpine/config/apcu.config.php new file mode 100644 index 00000000..69fed876 --- /dev/null +++ b/31/fpm-alpine/config/apcu.config.php @@ -0,0 +1,4 @@ + '\OC\Memcache\APCu', +); diff --git a/31/fpm-alpine/config/apps.config.php b/31/fpm-alpine/config/apps.config.php new file mode 100644 index 00000000..4c37f72a --- /dev/null +++ b/31/fpm-alpine/config/apps.config.php @@ -0,0 +1,15 @@ + array ( + 0 => array ( + 'path' => OC::$SERVERROOT.'/apps', + 'url' => '/apps', + 'writable' => false, + ), + 1 => array ( + 'path' => OC::$SERVERROOT.'/custom_apps', + 'url' => '/custom_apps', + 'writable' => true, + ), + ), +); diff --git a/31/fpm-alpine/config/autoconfig.php b/31/fpm-alpine/config/autoconfig.php new file mode 100644 index 00000000..92ad2a1c --- /dev/null +++ b/31/fpm-alpine/config/autoconfig.php @@ -0,0 +1,41 @@ + '\OC\Memcache\Redis', + 'memcache.locking' => '\OC\Memcache\Redis', + 'redis' => array( + 'host' => getenv('REDIS_HOST'), + 'password' => getenv('REDIS_HOST_PASSWORD_FILE') ? trim(file_get_contents(getenv('REDIS_HOST_PASSWORD_FILE'))) : (string) getenv('REDIS_HOST_PASSWORD'), + ), + ); + + if (getenv('REDIS_HOST_PORT') !== false) { + $CONFIG['redis']['port'] = (int) getenv('REDIS_HOST_PORT'); + } elseif (getenv('REDIS_HOST')[0] != '/') { + $CONFIG['redis']['port'] = 6379; + } + + if (getenv('REDIS_HOST_USER') !== false) { + $CONFIG['redis']['user'] = (string) getenv('REDIS_HOST_USER'); + } +} diff --git a/31/fpm-alpine/config/reverse-proxy.config.php b/31/fpm-alpine/config/reverse-proxy.config.php new file mode 100644 index 00000000..30c660ff --- /dev/null +++ b/31/fpm-alpine/config/reverse-proxy.config.php @@ -0,0 +1,35 @@ + array( + 'class' => '\OC\Files\ObjectStore\S3', + 'arguments' => array( + 'bucket' => getenv('OBJECTSTORE_S3_BUCKET'), + 'region' => getenv('OBJECTSTORE_S3_REGION') ?: '', + 'hostname' => getenv('OBJECTSTORE_S3_HOST') ?: '', + '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', + '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 + 'legacy_auth' => $use_legacyauth == true && strtolower($use_legacyauth) !== 'false' + ) + ) + ); + + if (getenv('OBJECTSTORE_S3_KEY_FILE')) { + $CONFIG['objectstore']['arguments']['key'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_KEY_FILE'))); + } elseif (getenv('OBJECTSTORE_S3_KEY')) { + $CONFIG['objectstore']['arguments']['key'] = getenv('OBJECTSTORE_S3_KEY'); + } else { + $CONFIG['objectstore']['arguments']['key'] = ''; + } + + if (getenv('OBJECTSTORE_S3_SECRET_FILE')) { + $CONFIG['objectstore']['arguments']['secret'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_SECRET_FILE'))); + } elseif (getenv('OBJECTSTORE_S3_SECRET')) { + $CONFIG['objectstore']['arguments']['secret'] = getenv('OBJECTSTORE_S3_SECRET'); + } else { + $CONFIG['objectstore']['arguments']['secret'] = ''; + } + + if (getenv('OBJECTSTORE_S3_SSE_C_KEY_FILE')) { + $CONFIG['objectstore']['arguments']['sse_c_key'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_SSE_C_KEY_FILE'))); + } elseif (getenv('OBJECTSTORE_S3_SSE_C_KEY')) { + $CONFIG['objectstore']['arguments']['sse_c_key'] = getenv('OBJECTSTORE_S3_SSE_C_KEY'); + } +} diff --git a/31/fpm-alpine/config/smtp.config.php b/31/fpm-alpine/config/smtp.config.php new file mode 100644 index 00000000..66a2ef7e --- /dev/null +++ b/31/fpm-alpine/config/smtp.config.php @@ -0,0 +1,22 @@ + 'smtp', + 'mail_smtphost' => getenv('SMTP_HOST'), + 'mail_smtpport' => getenv('SMTP_PORT') ?: (getenv('SMTP_SECURE') ? 465 : 25), + 'mail_smtpsecure' => getenv('SMTP_SECURE') ?: '', + 'mail_smtpauth' => getenv('SMTP_NAME') && (getenv('SMTP_PASSWORD') || getenv('SMTP_PASSWORD_FILE')), + 'mail_smtpauthtype' => getenv('SMTP_AUTHTYPE') ?: 'LOGIN', + 'mail_smtpname' => getenv('SMTP_NAME') ?: '', + 'mail_from_address' => getenv('MAIL_FROM_ADDRESS'), + 'mail_domain' => getenv('MAIL_DOMAIN'), + ); + + if (getenv('SMTP_PASSWORD_FILE')) { + $CONFIG['mail_smtppassword'] = trim(file_get_contents(getenv('SMTP_PASSWORD_FILE'))); + } elseif (getenv('SMTP_PASSWORD')) { + $CONFIG['mail_smtppassword'] = getenv('SMTP_PASSWORD'); + } else { + $CONFIG['mail_smtppassword'] = ''; + } +} diff --git a/31/fpm-alpine/config/swift.config.php b/31/fpm-alpine/config/swift.config.php new file mode 100644 index 00000000..47ada566 --- /dev/null +++ b/31/fpm-alpine/config/swift.config.php @@ -0,0 +1,31 @@ + [ + 'class' => 'OC\\Files\\ObjectStore\\Swift', + 'arguments' => [ + 'autocreate' => $autocreate == true && strtolower($autocreate) !== 'false', + 'user' => [ + 'name' => getenv('OBJECTSTORE_SWIFT_USER_NAME'), + 'password' => getenv('OBJECTSTORE_SWIFT_USER_PASSWORD'), + 'domain' => [ + 'name' => (getenv('OBJECTSTORE_SWIFT_USER_DOMAIN')) ?: 'Default', + ], + ], + 'scope' => [ + 'project' => [ + 'name' => getenv('OBJECTSTORE_SWIFT_PROJECT_NAME'), + 'domain' => [ + 'name' => (getenv('OBJECTSTORE_SWIFT_PROJECT_DOMAIN')) ?: 'Default', + ], + ], + ], + 'serviceName' => (getenv('OBJECTSTORE_SWIFT_SERVICE_NAME')) ?: 'swift', + 'region' => getenv('OBJECTSTORE_SWIFT_REGION'), + 'url' => getenv('OBJECTSTORE_SWIFT_URL'), + 'bucket' => getenv('OBJECTSTORE_SWIFT_CONTAINER_NAME'), + ] + ] + ); +} diff --git a/31/fpm-alpine/config/upgrade-disable-web.config.php b/31/fpm-alpine/config/upgrade-disable-web.config.php new file mode 100644 index 00000000..cb00b436 --- /dev/null +++ b/31/fpm-alpine/config/upgrade-disable-web.config.php @@ -0,0 +1,4 @@ + true, +); diff --git a/31/fpm-alpine/cron.sh b/31/fpm-alpine/cron.sh new file mode 100755 index 00000000..b4cd9af6 --- /dev/null +++ b/31/fpm-alpine/cron.sh @@ -0,0 +1,4 @@ +#!/bin/sh +set -eu + +exec busybox crond -f -L /dev/stdout diff --git a/31/fpm-alpine/entrypoint.sh b/31/fpm-alpine/entrypoint.sh new file mode 100755 index 00000000..8e178f2e --- /dev/null +++ b/31/fpm-alpine/entrypoint.sh @@ -0,0 +1,293 @@ +#!/bin/sh +set -eu + +# version_greater A B returns whether A > B +version_greater() { + [ "$(printf '%s\n' "$@" | sort -t '.' -n -k1,1 -k2,2 -k3,3 -k4,4 | head -n 1)" != "$1" ] +} + +# return true if specified directory is empty +directory_empty() { + [ -z "$(ls -A "$1/")" ] +} + +run_as() { + if [ "$(id -u)" = 0 ]; then + su -p "$user" -s /bin/sh -c "$1" + else + sh -c "$1" + fi +} + +# Execute all executable files in a given directory in alphanumeric order +run_path() { + local hook_folder_path="/docker-entrypoint-hooks.d/$1" + local return_code=0 + + if ! [ -d "${hook_folder_path}" ]; then + echo "=> Skipping the folder \"${hook_folder_path}\", because it doesn't exist" + return 0 + fi + + echo "=> Searching for scripts (*.sh) to run, located in the folder: ${hook_folder_path}" + + ( + find "${hook_folder_path}" -maxdepth 1 -iname '*.sh' '(' -type f -o -type l ')' -print | sort | while read -r script_file_path; do + if ! [ -x "${script_file_path}" ]; then + echo "==> The script \"${script_file_path}\" was skipped, because it didn't have the executable flag" + continue + fi + + echo "==> Running the script (cwd: $(pwd)): \"${script_file_path}\"" + + run_as "${script_file_path}" || return_code="$?" + + if [ "${return_code}" -ne "0" ]; then + echo "==> Failed at executing \"${script_file_path}\". Exit code: ${return_code}" + exit 1 + fi + + echo "==> Finished the script: \"${script_file_path}\"" + done + ) +} + +# usage: file_env VAR [DEFAULT] +# ie: file_env 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + local varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//") + local fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//") + if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + if [ -n "${varValue}" ]; then + export "$var"="${varValue}" + elif [ -n "${fileVarValue}" ]; then + export "$var"="$(cat "${fileVarValue}")" + elif [ -n "${def}" ]; then + export "$var"="$def" + fi + unset "$fileVar" +} + +if expr "$1" : "apache" 1>/dev/null; then + if [ -n "${APACHE_DISABLE_REWRITE_IP+x}" ]; then + a2disconf remoteip + fi +fi + +if expr "$1" : "apache" 1>/dev/null || [ "$1" = "php-fpm" ] || [ "${NEXTCLOUD_UPDATE:-0}" -eq 1 ]; then + uid="$(id -u)" + gid="$(id -g)" + if [ "$uid" = '0' ]; then + case "$1" in + apache2*) + user="${APACHE_RUN_USER:-www-data}" + group="${APACHE_RUN_GROUP:-www-data}" + + # strip off any '#' symbol ('#1000' is valid syntax for Apache) + user="${user#'#'}" + group="${group#'#'}" + ;; + *) # php-fpm + user='www-data' + group='www-data' + ;; + esac + else + user="$uid" + group="$gid" + fi + + if [ -n "${REDIS_HOST+x}" ]; then + + echo "Configuring Redis as session handler" + { + file_env REDIS_HOST_PASSWORD + echo 'session.save_handler = redis' + # check if redis host is an unix socket path + if [ "$(echo "$REDIS_HOST" | cut -c1-1)" = "/" ]; then + if [ -n "${REDIS_HOST_PASSWORD+x}" ]; then + echo "session.save_path = \"unix://${REDIS_HOST}?auth=${REDIS_HOST_PASSWORD}\"" + else + echo "session.save_path = \"unix://${REDIS_HOST}\"" + fi + # check if redis password has been set + elif [ -n "${REDIS_HOST_PASSWORD+x}" ]; then + echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}?auth=${REDIS_HOST_PASSWORD}\"" + else + echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}\"" + fi + echo "redis.session.locking_enabled = 1" + echo "redis.session.lock_retries = -1" + # redis.session.lock_wait_time is specified in microseconds. + # Wait 10ms before retrying the lock rather than the default 2ms. + echo "redis.session.lock_wait_time = 10000" + } > /usr/local/etc/php/conf.d/redis-session.ini + fi + + # If another process is syncing the html folder, wait for + # it to be done, then escape initalization. + ( + if ! flock -n 9; then + # If we couldn't get it immediately, show a message, then wait for real + echo "Another process is initializing Nextcloud. Waiting..." + flock 9 + fi + + installed_version="0.0.0.0" + if [ -f /var/www/html/version.php ]; then + # shellcheck disable=SC2016 + installed_version="$(php -r 'require "/var/www/html/version.php"; echo implode(".", $OC_Version);')" + fi + # shellcheck disable=SC2016 + image_version="$(php -r 'require "/usr/src/nextcloud/version.php"; echo implode(".", $OC_Version);')" + + if version_greater "$installed_version" "$image_version"; then + echo "Can't start Nextcloud because the version of the data ($installed_version) is higher than the docker image version ($image_version) and downgrading is not supported. Are you sure you have pulled the newest image version?" + exit 1 + fi + + if version_greater "$image_version" "$installed_version"; then + echo "Initializing nextcloud $image_version ..." + if [ "$installed_version" != "0.0.0.0" ]; then + if [ "${image_version%%.*}" -gt "$((${installed_version%%.*} + 1))" ]; then + echo "Can't start Nextcloud because upgrading from $installed_version to $image_version is not supported." + echo "It is only possible to upgrade one major version at a time. For example, if you want to upgrade from version 14 to 16, you will have to upgrade from version 14 to 15, then from 15 to 16." + exit 1 + fi + echo "Upgrading nextcloud from $installed_version ..." + run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_before + fi + if [ "$(id -u)" = 0 ]; then + rsync_options="-rlDog --chown $user:$group" + else + rsync_options="-rlD" + fi + + rsync $rsync_options --delete --exclude-from=/upgrade.exclude /usr/src/nextcloud/ /var/www/html/ + for dir in config data custom_apps themes; do + if [ ! -d "/var/www/html/$dir" ] || directory_empty "/var/www/html/$dir"; then + rsync $rsync_options --include "/$dir/" --exclude '/*' /usr/src/nextcloud/ /var/www/html/ + fi + done + rsync $rsync_options --include '/version.php' --exclude '/*' /usr/src/nextcloud/ /var/www/html/ + + # Install + if [ "$installed_version" = "0.0.0.0" ]; then + echo "New nextcloud instance" + + file_env NEXTCLOUD_ADMIN_PASSWORD + file_env NEXTCLOUD_ADMIN_USER + + install=false + if [ -n "${NEXTCLOUD_ADMIN_USER+x}" ] && [ -n "${NEXTCLOUD_ADMIN_PASSWORD+x}" ]; then + # shellcheck disable=SC2016 + install_options='-n --admin-user "$NEXTCLOUD_ADMIN_USER" --admin-pass "$NEXTCLOUD_ADMIN_PASSWORD"' + if [ -n "${NEXTCLOUD_DATA_DIR+x}" ]; then + # shellcheck disable=SC2016 + install_options=$install_options' --data-dir "$NEXTCLOUD_DATA_DIR"' + fi + + file_env MYSQL_DATABASE + file_env MYSQL_PASSWORD + file_env MYSQL_USER + file_env POSTGRES_DB + file_env POSTGRES_PASSWORD + file_env POSTGRES_USER + + if [ -n "${SQLITE_DATABASE+x}" ]; then + echo "Installing with SQLite database" + # shellcheck disable=SC2016 + install_options=$install_options' --database-name "$SQLITE_DATABASE"' + install=true + elif [ -n "${MYSQL_DATABASE+x}" ] && [ -n "${MYSQL_USER+x}" ] && [ -n "${MYSQL_PASSWORD+x}" ] && [ -n "${MYSQL_HOST+x}" ]; then + echo "Installing with MySQL database" + # shellcheck disable=SC2016 + install_options=$install_options' --database mysql --database-name "$MYSQL_DATABASE" --database-user "$MYSQL_USER" --database-pass "$MYSQL_PASSWORD" --database-host "$MYSQL_HOST"' + install=true + elif [ -n "${POSTGRES_DB+x}" ] && [ -n "${POSTGRES_USER+x}" ] && [ -n "${POSTGRES_PASSWORD+x}" ] && [ -n "${POSTGRES_HOST+x}" ]; then + echo "Installing with PostgreSQL database" + # shellcheck disable=SC2016 + install_options=$install_options' --database pgsql --database-name "$POSTGRES_DB" --database-user "$POSTGRES_USER" --database-pass "$POSTGRES_PASSWORD" --database-host "$POSTGRES_HOST"' + install=true + fi + + if [ "$install" = true ]; then + run_path pre-installation + + echo "Starting nextcloud installation" + max_retries=10 + try=0 + until [ "$try" -gt "$max_retries" ] || run_as "php /var/www/html/occ maintenance:install $install_options" + do + echo "Retrying install..." + try=$((try+1)) + sleep 10s + done + if [ "$try" -gt "$max_retries" ]; then + echo "Installing of nextcloud failed!" + exit 1 + fi + if [ -n "${NEXTCLOUD_TRUSTED_DOMAINS+x}" ]; then + echo "Setting trusted domains…" + NC_TRUSTED_DOMAIN_IDX=1 + for DOMAIN in $NEXTCLOUD_TRUSTED_DOMAINS ; do + DOMAIN=$(echo "$DOMAIN" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + run_as "php /var/www/html/occ config:system:set trusted_domains $NC_TRUSTED_DOMAIN_IDX --value=$DOMAIN" + NC_TRUSTED_DOMAIN_IDX=$((NC_TRUSTED_DOMAIN_IDX+1)) + done + fi + + run_path post-installation + fi + fi + # not enough specified to do a fully automated installation + if [ "$install" = false ]; then + echo "Next step: Access your instance to finish the web-based installation!" + echo "Hint: You can specify NEXTCLOUD_ADMIN_USER and NEXTCLOUD_ADMIN_PASSWORD and the database variables _prior to first launch_ to fully automate initial installation." + fi + # Upgrade + else + run_path pre-upgrade + + run_as 'php /var/www/html/occ upgrade' + + run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_after + echo "The following apps have been disabled:" + diff /tmp/list_before /tmp/list_after | grep '<' | cut -d- -f2 | cut -d: -f1 + rm -f /tmp/list_before /tmp/list_after + + run_path post-upgrade + fi + + echo "Initializing finished" + fi + + # Update htaccess after init if requested + if [ -n "${NEXTCLOUD_INIT_HTACCESS+x}" ] && [ "$installed_version" != "0.0.0.0" ]; then + run_as 'php /var/www/html/occ maintenance:update:htaccess' + fi + ) 9> /var/www/html/nextcloud-init-sync.lock + + # warn if config files on persistent storage differ from the latest version of this image + for cfgPath in /usr/src/nextcloud/config/*.php; do + cfgFile=$(basename "$cfgPath") + + if [ "$cfgFile" != "config.sample.php" ] && [ "$cfgFile" != "autoconfig.php" ]; then + if ! cmp -s "/usr/src/nextcloud/config/$cfgFile" "/var/www/html/config/$cfgFile"; then + echo "Warning: /var/www/html/config/$cfgFile differs from the latest version of this image at /usr/src/nextcloud/config/$cfgFile" + fi + fi + done + + run_path before-starting +fi + +exec "$@" diff --git a/31/fpm-alpine/upgrade.exclude b/31/fpm-alpine/upgrade.exclude new file mode 100644 index 00000000..31ce39a8 --- /dev/null +++ b/31/fpm-alpine/upgrade.exclude @@ -0,0 +1,6 @@ +/config/ +/data/ +/custom_apps/ +/themes/ +/version.php +/nextcloud-init-sync.lock diff --git a/31/fpm/Dockerfile b/31/fpm/Dockerfile new file mode 100644 index 00000000..29a53311 --- /dev/null +++ b/31/fpm/Dockerfile @@ -0,0 +1,169 @@ +# DO NOT EDIT: created by update.sh from Dockerfile-debian.template +FROM php:8.2-fpm-bookworm + +# 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 '*/5 * * * * 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 +ENV PHP_OPCACHE_MEMORY_CONSUMPTION 128 +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 ftp --with-openssl-dir=/usr; \ + 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 \ + ftp \ + 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-5.1.24; \ + pecl install igbinary-3.2.16; \ + pecl install imagick-3.7.0; \ + pecl install memcached-3.3.0 \ + --configureoptions 'enable-memcached-igbinary="yes"'; \ + pecl install redis-6.1.0 \ + --configureoptions 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"'; \ + \ + docker-php-ext-enable \ + apcu \ + igbinary \ + 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=${PHP_OPCACHE_MEMORY_CONSUMPTION}'; \ + echo 'opcache.save_comments=1'; \ + echo 'opcache.revalidate_freq=60'; \ + echo 'opcache.jit=1255'; \ + echo 'opcache.jit_buffer_size=8M'; \ + } > "${PHP_INI_DIR}/conf.d/opcache-recommended.ini"; \ + \ + echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \ + \ + { \ + echo 'apc.serializer=igbinary'; \ + echo 'session.serialize_handler=igbinary'; \ + } >> "${PHP_INI_DIR}/conf.d/docker-php-ext-igbinary.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 + + +ENV NEXTCLOUD_VERSION 31.0.0 + +RUN set -ex; \ + fetchDeps=" \ + gnupg \ + dirmngr \ + "; \ + apt-get update; \ + apt-get install -y --no-install-recommends $fetchDeps; \ + \ + curl -fsSL -o nextcloud.tar.bz2 "https://download.nextcloud.com/server/releases/nextcloud-31.0.0.tar.bz2"; \ + curl -fsSL -o nextcloud.tar.bz2.asc "https://download.nextcloud.com/server/releases/nextcloud-31.0.0.tar.bz2.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/ + +ENTRYPOINT ["/entrypoint.sh"] +CMD ["php-fpm"] diff --git a/31/fpm/config/apcu.config.php b/31/fpm/config/apcu.config.php new file mode 100644 index 00000000..69fed876 --- /dev/null +++ b/31/fpm/config/apcu.config.php @@ -0,0 +1,4 @@ + '\OC\Memcache\APCu', +); diff --git a/31/fpm/config/apps.config.php b/31/fpm/config/apps.config.php new file mode 100644 index 00000000..4c37f72a --- /dev/null +++ b/31/fpm/config/apps.config.php @@ -0,0 +1,15 @@ + array ( + 0 => array ( + 'path' => OC::$SERVERROOT.'/apps', + 'url' => '/apps', + 'writable' => false, + ), + 1 => array ( + 'path' => OC::$SERVERROOT.'/custom_apps', + 'url' => '/custom_apps', + 'writable' => true, + ), + ), +); diff --git a/31/fpm/config/autoconfig.php b/31/fpm/config/autoconfig.php new file mode 100644 index 00000000..92ad2a1c --- /dev/null +++ b/31/fpm/config/autoconfig.php @@ -0,0 +1,41 @@ + '\OC\Memcache\Redis', + 'memcache.locking' => '\OC\Memcache\Redis', + 'redis' => array( + 'host' => getenv('REDIS_HOST'), + 'password' => getenv('REDIS_HOST_PASSWORD_FILE') ? trim(file_get_contents(getenv('REDIS_HOST_PASSWORD_FILE'))) : (string) getenv('REDIS_HOST_PASSWORD'), + ), + ); + + if (getenv('REDIS_HOST_PORT') !== false) { + $CONFIG['redis']['port'] = (int) getenv('REDIS_HOST_PORT'); + } elseif (getenv('REDIS_HOST')[0] != '/') { + $CONFIG['redis']['port'] = 6379; + } + + if (getenv('REDIS_HOST_USER') !== false) { + $CONFIG['redis']['user'] = (string) getenv('REDIS_HOST_USER'); + } +} diff --git a/31/fpm/config/reverse-proxy.config.php b/31/fpm/config/reverse-proxy.config.php new file mode 100644 index 00000000..30c660ff --- /dev/null +++ b/31/fpm/config/reverse-proxy.config.php @@ -0,0 +1,35 @@ + array( + 'class' => '\OC\Files\ObjectStore\S3', + 'arguments' => array( + 'bucket' => getenv('OBJECTSTORE_S3_BUCKET'), + 'region' => getenv('OBJECTSTORE_S3_REGION') ?: '', + 'hostname' => getenv('OBJECTSTORE_S3_HOST') ?: '', + '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', + '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 + 'legacy_auth' => $use_legacyauth == true && strtolower($use_legacyauth) !== 'false' + ) + ) + ); + + if (getenv('OBJECTSTORE_S3_KEY_FILE')) { + $CONFIG['objectstore']['arguments']['key'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_KEY_FILE'))); + } elseif (getenv('OBJECTSTORE_S3_KEY')) { + $CONFIG['objectstore']['arguments']['key'] = getenv('OBJECTSTORE_S3_KEY'); + } else { + $CONFIG['objectstore']['arguments']['key'] = ''; + } + + if (getenv('OBJECTSTORE_S3_SECRET_FILE')) { + $CONFIG['objectstore']['arguments']['secret'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_SECRET_FILE'))); + } elseif (getenv('OBJECTSTORE_S3_SECRET')) { + $CONFIG['objectstore']['arguments']['secret'] = getenv('OBJECTSTORE_S3_SECRET'); + } else { + $CONFIG['objectstore']['arguments']['secret'] = ''; + } + + if (getenv('OBJECTSTORE_S3_SSE_C_KEY_FILE')) { + $CONFIG['objectstore']['arguments']['sse_c_key'] = trim(file_get_contents(getenv('OBJECTSTORE_S3_SSE_C_KEY_FILE'))); + } elseif (getenv('OBJECTSTORE_S3_SSE_C_KEY')) { + $CONFIG['objectstore']['arguments']['sse_c_key'] = getenv('OBJECTSTORE_S3_SSE_C_KEY'); + } +} diff --git a/31/fpm/config/smtp.config.php b/31/fpm/config/smtp.config.php new file mode 100644 index 00000000..66a2ef7e --- /dev/null +++ b/31/fpm/config/smtp.config.php @@ -0,0 +1,22 @@ + 'smtp', + 'mail_smtphost' => getenv('SMTP_HOST'), + 'mail_smtpport' => getenv('SMTP_PORT') ?: (getenv('SMTP_SECURE') ? 465 : 25), + 'mail_smtpsecure' => getenv('SMTP_SECURE') ?: '', + 'mail_smtpauth' => getenv('SMTP_NAME') && (getenv('SMTP_PASSWORD') || getenv('SMTP_PASSWORD_FILE')), + 'mail_smtpauthtype' => getenv('SMTP_AUTHTYPE') ?: 'LOGIN', + 'mail_smtpname' => getenv('SMTP_NAME') ?: '', + 'mail_from_address' => getenv('MAIL_FROM_ADDRESS'), + 'mail_domain' => getenv('MAIL_DOMAIN'), + ); + + if (getenv('SMTP_PASSWORD_FILE')) { + $CONFIG['mail_smtppassword'] = trim(file_get_contents(getenv('SMTP_PASSWORD_FILE'))); + } elseif (getenv('SMTP_PASSWORD')) { + $CONFIG['mail_smtppassword'] = getenv('SMTP_PASSWORD'); + } else { + $CONFIG['mail_smtppassword'] = ''; + } +} diff --git a/31/fpm/config/swift.config.php b/31/fpm/config/swift.config.php new file mode 100644 index 00000000..47ada566 --- /dev/null +++ b/31/fpm/config/swift.config.php @@ -0,0 +1,31 @@ + [ + 'class' => 'OC\\Files\\ObjectStore\\Swift', + 'arguments' => [ + 'autocreate' => $autocreate == true && strtolower($autocreate) !== 'false', + 'user' => [ + 'name' => getenv('OBJECTSTORE_SWIFT_USER_NAME'), + 'password' => getenv('OBJECTSTORE_SWIFT_USER_PASSWORD'), + 'domain' => [ + 'name' => (getenv('OBJECTSTORE_SWIFT_USER_DOMAIN')) ?: 'Default', + ], + ], + 'scope' => [ + 'project' => [ + 'name' => getenv('OBJECTSTORE_SWIFT_PROJECT_NAME'), + 'domain' => [ + 'name' => (getenv('OBJECTSTORE_SWIFT_PROJECT_DOMAIN')) ?: 'Default', + ], + ], + ], + 'serviceName' => (getenv('OBJECTSTORE_SWIFT_SERVICE_NAME')) ?: 'swift', + 'region' => getenv('OBJECTSTORE_SWIFT_REGION'), + 'url' => getenv('OBJECTSTORE_SWIFT_URL'), + 'bucket' => getenv('OBJECTSTORE_SWIFT_CONTAINER_NAME'), + ] + ] + ); +} diff --git a/31/fpm/config/upgrade-disable-web.config.php b/31/fpm/config/upgrade-disable-web.config.php new file mode 100644 index 00000000..cb00b436 --- /dev/null +++ b/31/fpm/config/upgrade-disable-web.config.php @@ -0,0 +1,4 @@ + true, +); diff --git a/31/fpm/cron.sh b/31/fpm/cron.sh new file mode 100755 index 00000000..b4cd9af6 --- /dev/null +++ b/31/fpm/cron.sh @@ -0,0 +1,4 @@ +#!/bin/sh +set -eu + +exec busybox crond -f -L /dev/stdout diff --git a/31/fpm/entrypoint.sh b/31/fpm/entrypoint.sh new file mode 100755 index 00000000..8e178f2e --- /dev/null +++ b/31/fpm/entrypoint.sh @@ -0,0 +1,293 @@ +#!/bin/sh +set -eu + +# version_greater A B returns whether A > B +version_greater() { + [ "$(printf '%s\n' "$@" | sort -t '.' -n -k1,1 -k2,2 -k3,3 -k4,4 | head -n 1)" != "$1" ] +} + +# return true if specified directory is empty +directory_empty() { + [ -z "$(ls -A "$1/")" ] +} + +run_as() { + if [ "$(id -u)" = 0 ]; then + su -p "$user" -s /bin/sh -c "$1" + else + sh -c "$1" + fi +} + +# Execute all executable files in a given directory in alphanumeric order +run_path() { + local hook_folder_path="/docker-entrypoint-hooks.d/$1" + local return_code=0 + + if ! [ -d "${hook_folder_path}" ]; then + echo "=> Skipping the folder \"${hook_folder_path}\", because it doesn't exist" + return 0 + fi + + echo "=> Searching for scripts (*.sh) to run, located in the folder: ${hook_folder_path}" + + ( + find "${hook_folder_path}" -maxdepth 1 -iname '*.sh' '(' -type f -o -type l ')' -print | sort | while read -r script_file_path; do + if ! [ -x "${script_file_path}" ]; then + echo "==> The script \"${script_file_path}\" was skipped, because it didn't have the executable flag" + continue + fi + + echo "==> Running the script (cwd: $(pwd)): \"${script_file_path}\"" + + run_as "${script_file_path}" || return_code="$?" + + if [ "${return_code}" -ne "0" ]; then + echo "==> Failed at executing \"${script_file_path}\". Exit code: ${return_code}" + exit 1 + fi + + echo "==> Finished the script: \"${script_file_path}\"" + done + ) +} + +# usage: file_env VAR [DEFAULT] +# ie: file_env 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + local varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//") + local fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//") + if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + if [ -n "${varValue}" ]; then + export "$var"="${varValue}" + elif [ -n "${fileVarValue}" ]; then + export "$var"="$(cat "${fileVarValue}")" + elif [ -n "${def}" ]; then + export "$var"="$def" + fi + unset "$fileVar" +} + +if expr "$1" : "apache" 1>/dev/null; then + if [ -n "${APACHE_DISABLE_REWRITE_IP+x}" ]; then + a2disconf remoteip + fi +fi + +if expr "$1" : "apache" 1>/dev/null || [ "$1" = "php-fpm" ] || [ "${NEXTCLOUD_UPDATE:-0}" -eq 1 ]; then + uid="$(id -u)" + gid="$(id -g)" + if [ "$uid" = '0' ]; then + case "$1" in + apache2*) + user="${APACHE_RUN_USER:-www-data}" + group="${APACHE_RUN_GROUP:-www-data}" + + # strip off any '#' symbol ('#1000' is valid syntax for Apache) + user="${user#'#'}" + group="${group#'#'}" + ;; + *) # php-fpm + user='www-data' + group='www-data' + ;; + esac + else + user="$uid" + group="$gid" + fi + + if [ -n "${REDIS_HOST+x}" ]; then + + echo "Configuring Redis as session handler" + { + file_env REDIS_HOST_PASSWORD + echo 'session.save_handler = redis' + # check if redis host is an unix socket path + if [ "$(echo "$REDIS_HOST" | cut -c1-1)" = "/" ]; then + if [ -n "${REDIS_HOST_PASSWORD+x}" ]; then + echo "session.save_path = \"unix://${REDIS_HOST}?auth=${REDIS_HOST_PASSWORD}\"" + else + echo "session.save_path = \"unix://${REDIS_HOST}\"" + fi + # check if redis password has been set + elif [ -n "${REDIS_HOST_PASSWORD+x}" ]; then + echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}?auth=${REDIS_HOST_PASSWORD}\"" + else + echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}\"" + fi + echo "redis.session.locking_enabled = 1" + echo "redis.session.lock_retries = -1" + # redis.session.lock_wait_time is specified in microseconds. + # Wait 10ms before retrying the lock rather than the default 2ms. + echo "redis.session.lock_wait_time = 10000" + } > /usr/local/etc/php/conf.d/redis-session.ini + fi + + # If another process is syncing the html folder, wait for + # it to be done, then escape initalization. + ( + if ! flock -n 9; then + # If we couldn't get it immediately, show a message, then wait for real + echo "Another process is initializing Nextcloud. Waiting..." + flock 9 + fi + + installed_version="0.0.0.0" + if [ -f /var/www/html/version.php ]; then + # shellcheck disable=SC2016 + installed_version="$(php -r 'require "/var/www/html/version.php"; echo implode(".", $OC_Version);')" + fi + # shellcheck disable=SC2016 + image_version="$(php -r 'require "/usr/src/nextcloud/version.php"; echo implode(".", $OC_Version);')" + + if version_greater "$installed_version" "$image_version"; then + echo "Can't start Nextcloud because the version of the data ($installed_version) is higher than the docker image version ($image_version) and downgrading is not supported. Are you sure you have pulled the newest image version?" + exit 1 + fi + + if version_greater "$image_version" "$installed_version"; then + echo "Initializing nextcloud $image_version ..." + if [ "$installed_version" != "0.0.0.0" ]; then + if [ "${image_version%%.*}" -gt "$((${installed_version%%.*} + 1))" ]; then + echo "Can't start Nextcloud because upgrading from $installed_version to $image_version is not supported." + echo "It is only possible to upgrade one major version at a time. For example, if you want to upgrade from version 14 to 16, you will have to upgrade from version 14 to 15, then from 15 to 16." + exit 1 + fi + echo "Upgrading nextcloud from $installed_version ..." + run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_before + fi + if [ "$(id -u)" = 0 ]; then + rsync_options="-rlDog --chown $user:$group" + else + rsync_options="-rlD" + fi + + rsync $rsync_options --delete --exclude-from=/upgrade.exclude /usr/src/nextcloud/ /var/www/html/ + for dir in config data custom_apps themes; do + if [ ! -d "/var/www/html/$dir" ] || directory_empty "/var/www/html/$dir"; then + rsync $rsync_options --include "/$dir/" --exclude '/*' /usr/src/nextcloud/ /var/www/html/ + fi + done + rsync $rsync_options --include '/version.php' --exclude '/*' /usr/src/nextcloud/ /var/www/html/ + + # Install + if [ "$installed_version" = "0.0.0.0" ]; then + echo "New nextcloud instance" + + file_env NEXTCLOUD_ADMIN_PASSWORD + file_env NEXTCLOUD_ADMIN_USER + + install=false + if [ -n "${NEXTCLOUD_ADMIN_USER+x}" ] && [ -n "${NEXTCLOUD_ADMIN_PASSWORD+x}" ]; then + # shellcheck disable=SC2016 + install_options='-n --admin-user "$NEXTCLOUD_ADMIN_USER" --admin-pass "$NEXTCLOUD_ADMIN_PASSWORD"' + if [ -n "${NEXTCLOUD_DATA_DIR+x}" ]; then + # shellcheck disable=SC2016 + install_options=$install_options' --data-dir "$NEXTCLOUD_DATA_DIR"' + fi + + file_env MYSQL_DATABASE + file_env MYSQL_PASSWORD + file_env MYSQL_USER + file_env POSTGRES_DB + file_env POSTGRES_PASSWORD + file_env POSTGRES_USER + + if [ -n "${SQLITE_DATABASE+x}" ]; then + echo "Installing with SQLite database" + # shellcheck disable=SC2016 + install_options=$install_options' --database-name "$SQLITE_DATABASE"' + install=true + elif [ -n "${MYSQL_DATABASE+x}" ] && [ -n "${MYSQL_USER+x}" ] && [ -n "${MYSQL_PASSWORD+x}" ] && [ -n "${MYSQL_HOST+x}" ]; then + echo "Installing with MySQL database" + # shellcheck disable=SC2016 + install_options=$install_options' --database mysql --database-name "$MYSQL_DATABASE" --database-user "$MYSQL_USER" --database-pass "$MYSQL_PASSWORD" --database-host "$MYSQL_HOST"' + install=true + elif [ -n "${POSTGRES_DB+x}" ] && [ -n "${POSTGRES_USER+x}" ] && [ -n "${POSTGRES_PASSWORD+x}" ] && [ -n "${POSTGRES_HOST+x}" ]; then + echo "Installing with PostgreSQL database" + # shellcheck disable=SC2016 + install_options=$install_options' --database pgsql --database-name "$POSTGRES_DB" --database-user "$POSTGRES_USER" --database-pass "$POSTGRES_PASSWORD" --database-host "$POSTGRES_HOST"' + install=true + fi + + if [ "$install" = true ]; then + run_path pre-installation + + echo "Starting nextcloud installation" + max_retries=10 + try=0 + until [ "$try" -gt "$max_retries" ] || run_as "php /var/www/html/occ maintenance:install $install_options" + do + echo "Retrying install..." + try=$((try+1)) + sleep 10s + done + if [ "$try" -gt "$max_retries" ]; then + echo "Installing of nextcloud failed!" + exit 1 + fi + if [ -n "${NEXTCLOUD_TRUSTED_DOMAINS+x}" ]; then + echo "Setting trusted domains…" + NC_TRUSTED_DOMAIN_IDX=1 + for DOMAIN in $NEXTCLOUD_TRUSTED_DOMAINS ; do + DOMAIN=$(echo "$DOMAIN" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + run_as "php /var/www/html/occ config:system:set trusted_domains $NC_TRUSTED_DOMAIN_IDX --value=$DOMAIN" + NC_TRUSTED_DOMAIN_IDX=$((NC_TRUSTED_DOMAIN_IDX+1)) + done + fi + + run_path post-installation + fi + fi + # not enough specified to do a fully automated installation + if [ "$install" = false ]; then + echo "Next step: Access your instance to finish the web-based installation!" + echo "Hint: You can specify NEXTCLOUD_ADMIN_USER and NEXTCLOUD_ADMIN_PASSWORD and the database variables _prior to first launch_ to fully automate initial installation." + fi + # Upgrade + else + run_path pre-upgrade + + run_as 'php /var/www/html/occ upgrade' + + run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_after + echo "The following apps have been disabled:" + diff /tmp/list_before /tmp/list_after | grep '<' | cut -d- -f2 | cut -d: -f1 + rm -f /tmp/list_before /tmp/list_after + + run_path post-upgrade + fi + + echo "Initializing finished" + fi + + # Update htaccess after init if requested + if [ -n "${NEXTCLOUD_INIT_HTACCESS+x}" ] && [ "$installed_version" != "0.0.0.0" ]; then + run_as 'php /var/www/html/occ maintenance:update:htaccess' + fi + ) 9> /var/www/html/nextcloud-init-sync.lock + + # warn if config files on persistent storage differ from the latest version of this image + for cfgPath in /usr/src/nextcloud/config/*.php; do + cfgFile=$(basename "$cfgPath") + + if [ "$cfgFile" != "config.sample.php" ] && [ "$cfgFile" != "autoconfig.php" ]; then + if ! cmp -s "/usr/src/nextcloud/config/$cfgFile" "/var/www/html/config/$cfgFile"; then + echo "Warning: /var/www/html/config/$cfgFile differs from the latest version of this image at /usr/src/nextcloud/config/$cfgFile" + fi + fi + done + + run_path before-starting +fi + +exec "$@" diff --git a/31/fpm/upgrade.exclude b/31/fpm/upgrade.exclude new file mode 100644 index 00000000..31ce39a8 --- /dev/null +++ b/31/fpm/upgrade.exclude @@ -0,0 +1,6 @@ +/config/ +/data/ +/custom_apps/ +/themes/ +/version.php +/nextcloud-init-sync.lock diff --git a/latest.txt b/latest.txt index 1c07a42c..221a8da0 100644 --- a/latest.txt +++ b/latest.txt @@ -1 +1 @@ -30.0.6 +31.0.0 diff --git a/versions.json b/versions.json index 6a9ce73a..2616bc41 100644 --- a/versions.json +++ b/versions.json @@ -1,4 +1,30 @@ { + "31": { + "branch": "31", + "version": "31.0.0", + "url": "https://download.nextcloud.com/server/releases/nextcloud-31.0.0.tar.bz2", + "ascUrl": "https://download.nextcloud.com/server/releases/nextcloud-31.0.0.tar.bz2.asc", + "variants": { + "apache": { + "variant": "apache", + "base": "debian", + "baseVersion": "bookworm", + "phpVersion": "8.2" + }, + "fpm": { + "variant": "fpm", + "base": "debian", + "baseVersion": "bookworm", + "phpVersion": "8.2" + }, + "fpm-alpine": { + "variant": "fpm-alpine", + "base": "alpine", + "baseVersion": "3.21", + "phpVersion": "8.2" + } + } + }, "30": { "branch": "30", "version": "30.0.6", From af005991484e03918488bb6cdb75750598a121f5 Mon Sep 17 00:00:00 2001 From: J0WI Date: Tue, 25 Feb 2025 22:37:43 +0000 Subject: [PATCH 6/6] Build imagick for PHP 8.3 (#2394) Signed-off-by: J0WI --- 29/apache/Dockerfile | 18 +++++++++++++++++- 29/fpm-alpine/Dockerfile | 18 +++++++++++++++++- 29/fpm/Dockerfile | 18 +++++++++++++++++- 30/apache/Dockerfile | 18 +++++++++++++++++- 30/fpm-alpine/Dockerfile | 18 +++++++++++++++++- 30/fpm/Dockerfile | 18 +++++++++++++++++- 31/apache/Dockerfile | 20 ++++++++++++++++++-- 31/fpm-alpine/Dockerfile | 20 ++++++++++++++++++-- 31/fpm/Dockerfile | 20 ++++++++++++++++++-- Dockerfile-alpine.template | 18 +++++++++++++++++- Dockerfile-debian.template | 18 +++++++++++++++++- update.sh | 1 + versions.json | 6 +++--- 13 files changed, 194 insertions(+), 17 deletions(-) diff --git a/29/apache/Dockerfile b/29/apache/Dockerfile index 4aec7fe7..3ca9ab54 100644 --- a/29/apache/Dockerfile +++ b/29/apache/Dockerfile @@ -1,6 +1,9 @@ # DO NOT EDIT: created by update.sh from Dockerfile-debian.template FROM php:8.2-apache-bookworm +# Define the commit hash for imagick as a variable +ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b + # entrypoint.sh and cron.sh dependencies RUN set -ex; \ \ @@ -65,10 +68,23 @@ RUN set -ex; \ zip \ ; \ \ +# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet. +# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround. + curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \ + tar -xzf imagick.tar.gz -C /tmp; \ + rm imagick.tar.gz; \ + cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \ + phpize; \ + ./configure; \ + make; \ + make install; \ + cd; \ + rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + \ # pecl will claim success even if one install fails, so we need to perform each install separately pecl install APCu-5.1.24; \ pecl install igbinary-3.2.16; \ - pecl install imagick-3.7.0; \ pecl install memcached-3.3.0 \ --configureoptions 'enable-memcached-igbinary="yes"'; \ pecl install redis-6.1.0 \ diff --git a/29/fpm-alpine/Dockerfile b/29/fpm-alpine/Dockerfile index 7eec3144..47179e44 100644 --- a/29/fpm-alpine/Dockerfile +++ b/29/fpm-alpine/Dockerfile @@ -1,6 +1,9 @@ # DO NOT EDIT: created by update.sh from Dockerfile-alpine.template FROM php:8.2-fpm-alpine3.21 +# Define the commit hash for imagick as a variable +ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b + # entrypoint.sh and cron.sh dependencies RUN set -ex; \ \ @@ -62,10 +65,23 @@ RUN set -ex; \ zip \ ; \ \ +# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet. +# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround. + curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \ + tar -xzf imagick.tar.gz -C /tmp; \ + rm imagick.tar.gz; \ + cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \ + phpize; \ + ./configure; \ + make; \ + make install; \ + cd; \ + rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + \ # pecl will claim success even if one install fails, so we need to perform each install separately pecl install APCu-5.1.24; \ pecl install igbinary-3.2.16; \ - pecl install imagick-3.7.0; \ pecl install memcached-3.3.0 \ --configureoptions 'enable-memcached-igbinary="yes"'; \ pecl install redis-6.1.0 \ diff --git a/29/fpm/Dockerfile b/29/fpm/Dockerfile index 819fd601..3a984575 100644 --- a/29/fpm/Dockerfile +++ b/29/fpm/Dockerfile @@ -1,6 +1,9 @@ # DO NOT EDIT: created by update.sh from Dockerfile-debian.template FROM php:8.2-fpm-bookworm +# Define the commit hash for imagick as a variable +ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b + # entrypoint.sh and cron.sh dependencies RUN set -ex; \ \ @@ -65,10 +68,23 @@ RUN set -ex; \ zip \ ; \ \ +# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet. +# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround. + curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \ + tar -xzf imagick.tar.gz -C /tmp; \ + rm imagick.tar.gz; \ + cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \ + phpize; \ + ./configure; \ + make; \ + make install; \ + cd; \ + rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + \ # pecl will claim success even if one install fails, so we need to perform each install separately pecl install APCu-5.1.24; \ pecl install igbinary-3.2.16; \ - pecl install imagick-3.7.0; \ pecl install memcached-3.3.0 \ --configureoptions 'enable-memcached-igbinary="yes"'; \ pecl install redis-6.1.0 \ diff --git a/30/apache/Dockerfile b/30/apache/Dockerfile index 3bb31915..472e005d 100644 --- a/30/apache/Dockerfile +++ b/30/apache/Dockerfile @@ -1,6 +1,9 @@ # DO NOT EDIT: created by update.sh from Dockerfile-debian.template FROM php:8.2-apache-bookworm +# Define the commit hash for imagick as a variable +ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b + # entrypoint.sh and cron.sh dependencies RUN set -ex; \ \ @@ -65,10 +68,23 @@ RUN set -ex; \ zip \ ; \ \ +# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet. +# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround. + curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \ + tar -xzf imagick.tar.gz -C /tmp; \ + rm imagick.tar.gz; \ + cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \ + phpize; \ + ./configure; \ + make; \ + make install; \ + cd; \ + rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + \ # pecl will claim success even if one install fails, so we need to perform each install separately pecl install APCu-5.1.24; \ pecl install igbinary-3.2.16; \ - pecl install imagick-3.7.0; \ pecl install memcached-3.3.0 \ --configureoptions 'enable-memcached-igbinary="yes"'; \ pecl install redis-6.1.0 \ diff --git a/30/fpm-alpine/Dockerfile b/30/fpm-alpine/Dockerfile index 7ad94ea2..b060e713 100644 --- a/30/fpm-alpine/Dockerfile +++ b/30/fpm-alpine/Dockerfile @@ -1,6 +1,9 @@ # DO NOT EDIT: created by update.sh from Dockerfile-alpine.template FROM php:8.2-fpm-alpine3.21 +# Define the commit hash for imagick as a variable +ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b + # entrypoint.sh and cron.sh dependencies RUN set -ex; \ \ @@ -62,10 +65,23 @@ RUN set -ex; \ zip \ ; \ \ +# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet. +# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround. + curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \ + tar -xzf imagick.tar.gz -C /tmp; \ + rm imagick.tar.gz; \ + cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \ + phpize; \ + ./configure; \ + make; \ + make install; \ + cd; \ + rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + \ # pecl will claim success even if one install fails, so we need to perform each install separately pecl install APCu-5.1.24; \ pecl install igbinary-3.2.16; \ - pecl install imagick-3.7.0; \ pecl install memcached-3.3.0 \ --configureoptions 'enable-memcached-igbinary="yes"'; \ pecl install redis-6.1.0 \ diff --git a/30/fpm/Dockerfile b/30/fpm/Dockerfile index c904d52e..85d0f477 100644 --- a/30/fpm/Dockerfile +++ b/30/fpm/Dockerfile @@ -1,6 +1,9 @@ # DO NOT EDIT: created by update.sh from Dockerfile-debian.template FROM php:8.2-fpm-bookworm +# Define the commit hash for imagick as a variable +ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b + # entrypoint.sh and cron.sh dependencies RUN set -ex; \ \ @@ -65,10 +68,23 @@ RUN set -ex; \ zip \ ; \ \ +# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet. +# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround. + curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \ + tar -xzf imagick.tar.gz -C /tmp; \ + rm imagick.tar.gz; \ + cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \ + phpize; \ + ./configure; \ + make; \ + make install; \ + cd; \ + rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + \ # pecl will claim success even if one install fails, so we need to perform each install separately pecl install APCu-5.1.24; \ pecl install igbinary-3.2.16; \ - pecl install imagick-3.7.0; \ pecl install memcached-3.3.0 \ --configureoptions 'enable-memcached-igbinary="yes"'; \ pecl install redis-6.1.0 \ diff --git a/31/apache/Dockerfile b/31/apache/Dockerfile index aeab9d9b..96b8511c 100644 --- a/31/apache/Dockerfile +++ b/31/apache/Dockerfile @@ -1,5 +1,8 @@ # DO NOT EDIT: created by update.sh from Dockerfile-debian.template -FROM php:8.2-apache-bookworm +FROM php:8.3-apache-bookworm + +# Define the commit hash for imagick as a variable +ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b # entrypoint.sh and cron.sh dependencies RUN set -ex; \ @@ -65,10 +68,23 @@ RUN set -ex; \ zip \ ; \ \ +# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet. +# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround. + curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \ + tar -xzf imagick.tar.gz -C /tmp; \ + rm imagick.tar.gz; \ + cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \ + phpize; \ + ./configure; \ + make; \ + make install; \ + cd; \ + rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + \ # pecl will claim success even if one install fails, so we need to perform each install separately pecl install APCu-5.1.24; \ pecl install igbinary-3.2.16; \ - pecl install imagick-3.7.0; \ pecl install memcached-3.3.0 \ --configureoptions 'enable-memcached-igbinary="yes"'; \ pecl install redis-6.1.0 \ diff --git a/31/fpm-alpine/Dockerfile b/31/fpm-alpine/Dockerfile index 9972b489..ca69007f 100644 --- a/31/fpm-alpine/Dockerfile +++ b/31/fpm-alpine/Dockerfile @@ -1,5 +1,8 @@ # DO NOT EDIT: created by update.sh from Dockerfile-alpine.template -FROM php:8.2-fpm-alpine3.21 +FROM php:8.3-fpm-alpine3.21 + +# Define the commit hash for imagick as a variable +ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b # entrypoint.sh and cron.sh dependencies RUN set -ex; \ @@ -62,10 +65,23 @@ RUN set -ex; \ zip \ ; \ \ +# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet. +# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround. + curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \ + tar -xzf imagick.tar.gz -C /tmp; \ + rm imagick.tar.gz; \ + cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \ + phpize; \ + ./configure; \ + make; \ + make install; \ + cd; \ + rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + \ # pecl will claim success even if one install fails, so we need to perform each install separately pecl install APCu-5.1.24; \ pecl install igbinary-3.2.16; \ - pecl install imagick-3.7.0; \ pecl install memcached-3.3.0 \ --configureoptions 'enable-memcached-igbinary="yes"'; \ pecl install redis-6.1.0 \ diff --git a/31/fpm/Dockerfile b/31/fpm/Dockerfile index 29a53311..68c7b75f 100644 --- a/31/fpm/Dockerfile +++ b/31/fpm/Dockerfile @@ -1,5 +1,8 @@ # DO NOT EDIT: created by update.sh from Dockerfile-debian.template -FROM php:8.2-fpm-bookworm +FROM php:8.3-fpm-bookworm + +# Define the commit hash for imagick as a variable +ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b # entrypoint.sh and cron.sh dependencies RUN set -ex; \ @@ -65,10 +68,23 @@ RUN set -ex; \ zip \ ; \ \ +# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet. +# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround. + curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \ + tar -xzf imagick.tar.gz -C /tmp; \ + rm imagick.tar.gz; \ + cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \ + phpize; \ + ./configure; \ + make; \ + make install; \ + cd; \ + rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + \ # pecl will claim success even if one install fails, so we need to perform each install separately pecl install APCu-5.1.24; \ pecl install igbinary-3.2.16; \ - pecl install imagick-3.7.0; \ pecl install memcached-3.3.0 \ --configureoptions 'enable-memcached-igbinary="yes"'; \ pecl install redis-6.1.0 \ diff --git a/Dockerfile-alpine.template b/Dockerfile-alpine.template index cf6af0ff..2295bddf 100644 --- a/Dockerfile-alpine.template +++ b/Dockerfile-alpine.template @@ -1,5 +1,8 @@ FROM php:%%PHP_VERSION%%-%%VARIANT%%%%ALPINE_VERSION%% +# Define the commit hash for imagick as a variable +ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b + # entrypoint.sh and cron.sh dependencies RUN set -ex; \ \ @@ -61,10 +64,23 @@ RUN set -ex; \ zip \ ; \ \ +# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet. +# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround. + curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \ + tar -xzf imagick.tar.gz -C /tmp; \ + rm imagick.tar.gz; \ + cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \ + phpize; \ + ./configure; \ + make; \ + make install; \ + cd; \ + rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + \ # pecl will claim success even if one install fails, so we need to perform each install separately pecl install APCu-%%APCU_VERSION%%; \ pecl install igbinary-%%IGBINARY_VERSION%%; \ - pecl install imagick-%%IMAGICK_VERSION%%; \ pecl install memcached-%%MEMCACHED_VERSION%% \ --configureoptions 'enable-memcached-igbinary="yes"'; \ pecl install redis-%%REDIS_VERSION%% \ diff --git a/Dockerfile-debian.template b/Dockerfile-debian.template index cadae18a..8734caa9 100644 --- a/Dockerfile-debian.template +++ b/Dockerfile-debian.template @@ -1,5 +1,8 @@ FROM php:%%PHP_VERSION%%-%%VARIANT%%-%%DEBIAN_VERSION%% +# Define the commit hash for imagick as a variable +ENV IMAGICK_COMMIT_HASH d7d3c24af1b4f599897408f1714600b69a56473b + # entrypoint.sh and cron.sh dependencies RUN set -ex; \ \ @@ -64,10 +67,23 @@ RUN set -ex; \ zip \ ; \ \ +# The master version on the imagick repository is compatible with PHP 8.3. However, the PECL version is not updated yet. +# As soon as it will get updated, we can switch back to the PECL version, instead of having this workaround. + curl -fsSL -o imagick.tar.gz "https://github.com/Imagick/imagick/archive/$IMAGICK_COMMIT_HASH.tar.gz"; \ + tar -xzf imagick.tar.gz -C /tmp; \ + rm imagick.tar.gz; \ + cd "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + sed -i "s/@PACKAGE_VERSION@/git-$(echo ${IMAGICK_COMMIT_HASH} | cut -c 1-7)/" php_imagick.h; \ + phpize; \ + ./configure; \ + make; \ + make install; \ + cd; \ + rm -r "/tmp/imagick-$IMAGICK_COMMIT_HASH"; \ + \ # pecl will claim success even if one install fails, so we need to perform each install separately pecl install APCu-%%APCU_VERSION%%; \ pecl install igbinary-%%IGBINARY_VERSION%%; \ - pecl install imagick-%%IMAGICK_VERSION%%; \ pecl install memcached-%%MEMCACHED_VERSION%% \ --configureoptions 'enable-memcached-igbinary="yes"'; \ pecl install redis-%%REDIS_VERSION%% \ diff --git a/update.sh b/update.sh index f55da259..0f224b06 100755 --- a/update.sh +++ b/update.sh @@ -11,6 +11,7 @@ declare -A debian_version=( declare -A php_version=( [default]='8.2' + [31]='8.3' ) declare -A cmd=( diff --git a/versions.json b/versions.json index 2616bc41..1d54bae2 100644 --- a/versions.json +++ b/versions.json @@ -9,19 +9,19 @@ "variant": "apache", "base": "debian", "baseVersion": "bookworm", - "phpVersion": "8.2" + "phpVersion": "8.3" }, "fpm": { "variant": "fpm", "base": "debian", "baseVersion": "bookworm", - "phpVersion": "8.2" + "phpVersion": "8.3" }, "fpm-alpine": { "variant": "fpm-alpine", "base": "alpine", "baseVersion": "3.21", - "phpVersion": "8.2" + "phpVersion": "8.3" } } },