diff --git a/Dockerfile b/Dockerfile index 0fbc589..b3ff846 100644 --- a/Dockerfile +++ b/Dockerfile @@ -45,42 +45,55 @@ RUN \ php82-sqlite3 \ php82-sysvsem \ php82-xmlreader \ + rsync \ samba-client \ sudo && \ apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing \ php82-pecl-mcrypt && \ - echo "**** configure php and nginx for nextcloud ****" && \ - echo 'apc.enable_cli=1' >> /etc/php82/conf.d/apcu.ini && \ - sed -i \ - -e 's/;opcache.enable.*=.*/opcache.enable=1/g' \ - -e 's/;opcache.interned_strings_buffer.*=.*/opcache.interned_strings_buffer=16/g' \ - -e 's/;opcache.max_accelerated_files.*=.*/opcache.max_accelerated_files=10000/g' \ - -e 's/;opcache.memory_consumption.*=.*/opcache.memory_consumption=128/g' \ - -e 's/;opcache.save_comments.*=.*/opcache.save_comments=1/g' \ - -e 's/;opcache.revalidate_freq.*=.*/opcache.revalidate_freq=1/g' \ - -e 's/;always_populate_raw_post_data.*=.*/always_populate_raw_post_data=-1/g' \ - -e 's/memory_limit.*=.*128M/memory_limit=512M/g' \ - -e 's/max_execution_time.*=.*30/max_execution_time=120/g' \ - -e 's/upload_max_filesize.*=.*2M/upload_max_filesize=1024M/g' \ - -e 's/post_max_size.*=.*8M/post_max_size=1024M/g' \ - -e 's/output_buffering.*=.*/output_buffering=0/g' \ - /etc/php82/php.ini && \ - sed -i \ - '/opcache.enable=1/a opcache.enable_cli=1' \ - /etc/php82/php.ini && \ + echo "**** configure php-fpm to pass env vars ****" && \ + sed -E -i 's/^;?clear_env ?=.*$/clear_env = no/g' /etc/php82/php-fpm.d/www.conf && \ + grep -qxF 'clear_env = no' /etc/php82/php-fpm.d/www.conf || echo 'clear_env = no' >> /etc/php82/php-fpm.d/www.conf && \ echo "env[PATH] = /usr/local/bin:/usr/bin:/bin" >> /etc/php82/php-fpm.conf && \ - echo "**** set version tag ****" && \ + echo "**** configure php for nextcloud ****" && \ + { \ + echo 'apc.enable_cli=1' \ + } >> /etc/php82/conf.d/apcu.ini && \ + { \ + echo 'opcache.enable=1' \ + echo 'opcache.interned_strings_buffer=32' \ + echo 'opcache.max_accelerated_files=10000' \ + echo 'opcache.memory_consumption=128' \ + echo 'opcache.save_comments=1' \ + echo 'opcache.revalidate_freq=60' \ + echo 'opcache.jit=1255' \ + echo 'opcache.jit_buffer_size=128M' \ + } >> "/etc/php82/conf.d/00_opcache.ini" && \ + { \ + echo 'memory_limit=512M' \ + echo 'upload_max_filesize=16G' \ + echo 'post_max_size=16G' \ + echo 'max_input_time=3600' \ + echo 'max_execution_time=3600' \ + echo 'output_buffering=0' \ + echo 'always_populate_raw_post_data=-1' \ + } >> "/etc/php82/conf.d/nextcloud.ini" && \ + echo "**** install nextcloud ****" && \ + mkdir -p \ + /app/www/src/ && \ if [ -z ${NEXTCLOUD_RELEASE+x} ]; then \ NEXTCLOUD_RELEASE=$(curl -sX GET https://api.github.com/repos/nextcloud/server/releases \ | jq -r '.[] | select(.prerelease != true) | .tag_name' \ | sed 's|^v||g' | sort -rV | head -1); \ fi && \ - echo "**** download nextcloud ****" && \ - curl -o /app/nextcloud.tar.bz2 -L \ + curl -o \ + /tmp/nextcloud.tar.bz2 -L \ https://download.nextcloud.com/server/releases/nextcloud-${NEXTCLOUD_RELEASE}.tar.bz2 && \ - echo "**** test tarball ****" && \ - tar xvf /app/nextcloud.tar.bz2 -C \ - /tmp && \ + tar xf /tmp/nextcloud.tar.bz2 -C \ + /app/www/src --strip-components=1 \ + rm -rf /app/www/src/updater; \ + mkdir -p /app/www/src/data; \ + mkdir -p /app/www/src/custom_apps; \ + chmod +x /app/www/src/occ; \ echo "**** cleanup ****" && \ rm -rf \ /tmp/* diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 index db3ecbb..e461c54 100644 --- a/Dockerfile.aarch64 +++ b/Dockerfile.aarch64 @@ -45,42 +45,55 @@ RUN \ php82-sqlite3 \ php82-sysvsem \ php82-xmlreader \ + rsync \ samba-client \ sudo && \ apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing \ php82-pecl-mcrypt && \ - echo "**** configure php and nginx for nextcloud ****" && \ - echo 'apc.enable_cli=1' >> /etc/php82/conf.d/apcu.ini && \ - sed -i \ - -e 's/;opcache.enable.*=.*/opcache.enable=1/g' \ - -e 's/;opcache.interned_strings_buffer.*=.*/opcache.interned_strings_buffer=16/g' \ - -e 's/;opcache.max_accelerated_files.*=.*/opcache.max_accelerated_files=10000/g' \ - -e 's/;opcache.memory_consumption.*=.*/opcache.memory_consumption=128/g' \ - -e 's/;opcache.save_comments.*=.*/opcache.save_comments=1/g' \ - -e 's/;opcache.revalidate_freq.*=.*/opcache.revalidate_freq=1/g' \ - -e 's/;always_populate_raw_post_data.*=.*/always_populate_raw_post_data=-1/g' \ - -e 's/memory_limit.*=.*128M/memory_limit=512M/g' \ - -e 's/max_execution_time.*=.*30/max_execution_time=120/g' \ - -e 's/upload_max_filesize.*=.*2M/upload_max_filesize=1024M/g' \ - -e 's/post_max_size.*=.*8M/post_max_size=1024M/g' \ - -e 's/output_buffering.*=.*/output_buffering=0/g' \ - /etc/php82/php.ini && \ - sed -i \ - '/opcache.enable=1/a opcache.enable_cli=1' \ - /etc/php82/php.ini && \ + echo "**** configure php-fpm to pass env vars ****" && \ + sed -E -i 's/^;?clear_env ?=.*$/clear_env = no/g' /etc/php82/php-fpm.d/www.conf && \ + grep -qxF 'clear_env = no' /etc/php82/php-fpm.d/www.conf || echo 'clear_env = no' >> /etc/php82/php-fpm.d/www.conf && \ echo "env[PATH] = /usr/local/bin:/usr/bin:/bin" >> /etc/php82/php-fpm.conf && \ - echo "**** set version tag ****" && \ + echo "**** configure php for nextcloud ****" && \ + { \ + echo 'apc.enable_cli=1' \ + } >> /etc/php82/conf.d/apcu.ini && \ + { \ + echo 'opcache.enable=1' \ + echo 'opcache.interned_strings_buffer=32' \ + echo 'opcache.max_accelerated_files=10000' \ + echo 'opcache.memory_consumption=128' \ + echo 'opcache.save_comments=1' \ + echo 'opcache.revalidate_freq=60' \ + echo 'opcache.jit=1255' \ + echo 'opcache.jit_buffer_size=128M' \ + } >> "/etc/php82/conf.d/00_opcache.ini" && \ + { \ + echo 'memory_limit=512M' \ + echo 'upload_max_filesize=16G' \ + echo 'post_max_size=16G' \ + echo 'max_input_time=3600' \ + echo 'max_execution_time=3600' \ + echo 'output_buffering=0' \ + echo 'always_populate_raw_post_data=-1' \ + } >> "/etc/php82/conf.d/nextcloud.ini" && \ + echo "**** install nextcloud ****" && \ + mkdir -p \ + /app/www/src/ && \ if [ -z ${NEXTCLOUD_RELEASE+x} ]; then \ NEXTCLOUD_RELEASE=$(curl -sX GET https://api.github.com/repos/nextcloud/server/releases \ | jq -r '.[] | select(.prerelease != true) | .tag_name' \ | sed 's|^v||g' | sort -rV | head -1); \ fi && \ - echo "**** download nextcloud ****" && \ - curl -o /app/nextcloud.tar.bz2 -L \ + curl -o \ + /tmp/nextcloud.tar.bz2 -L \ https://download.nextcloud.com/server/releases/nextcloud-${NEXTCLOUD_RELEASE}.tar.bz2 && \ - echo "**** test tarball ****" && \ - tar xvf /app/nextcloud.tar.bz2 -C \ - /tmp && \ + tar xf /tmp/nextcloud.tar.bz2 -C \ + /app/www/src --strip-components=1 \ + rm -rf /app/www/src/updater; \ + mkdir -p /app/www/src/data; \ + mkdir -p /app/www/src/custom_apps; \ + chmod +x /app/www/src/occ; \ echo "**** cleanup ****" && \ rm -rf \ /tmp/* diff --git a/README.md b/README.md index 4b5e915..d3d3db8 100644 --- a/README.md +++ b/README.md @@ -64,21 +64,13 @@ The architectures supported by this image are: Access the webui at `https://:443`, for more information check out [Nextcloud](https://nextcloud.com/). -Docker image update and recreation of container alone won't update nextcloud version. +### Updating Nextcloud -In order to update nextcloud version, you have two options, firstly make sure you are using the latest docker image,then either +Updating the Nextcloud container is done by pulling the new image, throwing away the old container and starting the new one. -1. Perform the in app gui update. -2. Use the CLI version by running `docker exec -it nextcloud updater.phar` - (Both of these are described [here](https://docs.nextcloud.com/server/latest/admin_manual/maintenance/update.html)) +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. -Note: Both `occ` and `updater.phar` can be run without prepending with `sudo -u abc php` or `sudo -u www-data php` - -If you are not customizing our default nginx configuration you will need to remove the file: -``` -/config/nginx/site-confs/default.conf -``` -Then restart the container to replace it with the latest one. +Since all data is stored in the `/config` and `/data` volumes, nothing gets lost. The startup script will check for the version in your volume and the installed docker version. If it finds a mismatch, it automatically starts the upgrade process. ### Collaborative Editing @@ -254,6 +246,7 @@ Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64 ## Versions +* **06.06.23:** - Move Nextcloud installation inside container. * **25.05.23:** - Rebase to Alpine 3.18, deprecate armhf. * **13.04.23:** - Move ssl.conf include to default.conf. * **21.03.23:** - Add php81-sysvsem as new dep for v26. Update default X-Robots-Tag to `noindex, nofollow``. diff --git a/readme-vars.yml b/readme-vars.yml index 68d10cb..a454c2a 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -51,22 +51,14 @@ app_setup_block_enabled: true app_setup_block: | Access the webui at `https://:443`, for more information check out [Nextcloud]({{ project_url }}). - Docker image update and recreation of container alone won't update nextcloud version. + ### Updating Nextcloud - In order to update nextcloud version, you have two options, firstly make sure you are using the latest docker image,then either + Updating the Nextcloud container is done by pulling the new image, throwing away the old container and starting the new one. + + 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. + + Since all data is stored in the `/config` and `/data` volumes, nothing gets lost. The startup script will check for the version in your volume and the installed docker version. If it finds a mismatch, it automatically starts the upgrade process. - 1. Perform the in app gui update. - 2. Use the CLI version by running `docker exec -it nextcloud updater.phar` - (Both of these are described [here](https://docs.nextcloud.com/server/latest/admin_manual/maintenance/update.html)) - - Note: Both `occ` and `updater.phar` can be run without prepending with `sudo -u abc php` or `sudo -u www-data php` - - If you are not customizing our default nginx configuration you will need to remove the file: - ``` - /config/nginx/site-confs/default.conf - ``` - Then restart the container to replace it with the latest one. - ### Collaborative Editing Nextcloud's built-in collaborative editing packages (Collabora/CODE and OnlyOffice) only work on x86_64 systems with glibc, and therefore they are not compatible with our images. You should create separate containers for them and set them up in Nextcloud with their respective connector addons. @@ -76,6 +68,7 @@ app_setup_block: | # changelog changelogs: + - { date: "06.06.23:", desc: "Move Nextcloud installation inside container." } - { date: "25.05.23:", desc: "Rebase to Alpine 3.18, deprecate armhf." } - { date: "13.04.23:", desc: "Move ssl.conf include to default.conf." } - { date: "21.03.23:", desc: "Add php81-sysvsem as new dep for v26. Update default X-Robots-Tag to `noindex, nofollow``." } diff --git a/root/app/upgrade.exclude b/root/app/upgrade.exclude new file mode 100644 index 0000000..354864d --- /dev/null +++ b/root/app/upgrade.exclude @@ -0,0 +1,5 @@ +/config/ +/data/ +/custom_apps/ +/themes/ +/version.php diff --git a/root/defaults/nginx/site-confs/default.conf.sample b/root/defaults/nginx/site-confs/default.conf.sample index 812b413..fcb937c 100644 --- a/root/defaults/nginx/site-confs/default.conf.sample +++ b/root/defaults/nginx/site-confs/default.conf.sample @@ -1,4 +1,4 @@ -## Version 2023/04/13 - Changelog: https://github.com/linuxserver/docker-nextcloud/commits/master/root/defaults/nginx/site-confs/default.conf.sample +## Version 2023/06/06 - Changelog: https://github.com/linuxserver/docker-nextcloud/commits/master/root/defaults/nginx/site-confs/default.conf.sample # Set the `immutable` cache control options only for assets with a cache busting `v` argument map $arg_v $asset_immutable { @@ -17,7 +17,7 @@ server { include /config/nginx/ssl.conf; - root /config/www/nextcloud/; + root /app/www/public; # display real ip in nginx logs when connected through reverse proxy via docker network set_real_ip_from 172.0.0.0/8; diff --git a/root/etc/crontabs/root b/root/etc/crontabs/root index 85227e4..804eb03 100644 --- a/root/etc/crontabs/root +++ b/root/etc/crontabs/root @@ -6,4 +6,4 @@ 0 3 * * 6 run-parts /etc/periodic/weekly 0 5 1 * * run-parts /etc/periodic/monthly # nextcloud cron -*/5 * * * * s6-setuidgid abc php -f /config/www/nextcloud/cron.php +*/5 * * * * s6-setuidgid abc php -f /app/www/public/cron.php diff --git a/root/etc/s6-overlay/s6-rc.d/init-crontabs-config/run b/root/etc/s6-overlay/s6-rc.d/init-crontabs-config/run index da3a7b4..45f3844 100755 --- a/root/etc/s6-overlay/s6-rc.d/init-crontabs-config/run +++ b/root/etc/s6-overlay/s6-rc.d/init-crontabs-config/run @@ -17,7 +17,7 @@ if [[ ! -f /config/crontabs/root ]]; then # copy crontab from included defaults (using -n, do not overwrite an existing file) cp -n /etc/crontabs/root /config/crontabs/ fi -sed -i "s|s6-setuidgid abc php[78] -f /config/www/nextcloud/cron.php|s6-setuidgid abc php -f /config/www/nextcloud/cron.php|" /config/crontabs/root +sed -i "s|s6-setuidgid abc php[0-9]* -f /config/www/nextcloud/cron.php|s6-setuidgid abc php -f /app/www/public/cron.php|" /config/crontabs/root # set permissions and import user crontabs lsiown root:root /config/crontabs/root crontab -u root /config/crontabs/root diff --git a/root/etc/s6-overlay/s6-rc.d/init-nextcloud-config/run b/root/etc/s6-overlay/s6-rc.d/init-nextcloud-config/run index 546ea61..e48741f 100755 --- a/root/etc/s6-overlay/s6-rc.d/init-nextcloud-config/run +++ b/root/etc/s6-overlay/s6-rc.d/init-nextcloud-config/run @@ -3,26 +3,106 @@ # create folders mkdir -p \ - /config/www/nextcloud \ + /app/www/public \ + /config/www/nextcloud/config \ + /config/www/nextcloud/custom_apps \ + /config/www/nextcloud/themes \ /data +# migrate legacy install (copy inside container) +if [ -f /config/www/nextcloud/version.php ]; then + echo "Migrating legacy install" + rsync -rlD --delete --exclude-from=/app/upgrade.exclude /config/www/nextcloud/ /app/www/public/ + for dir in config custom_apps themes; do + if [ -z "$(ls -A /app/www/public/${dir}/)" ]; then + rsync -rlD --include "/${dir}/" --exclude '/*' /config/www/nextcloud/ /app/www/public/ + fi + done + rsync -rlD --include '/version.php' --exclude '/*' /config/www/nextcloud/ /app/www/public/ + rm -f /config/www/nextcloud/version.php + touch /tmp/full_chown +fi + +# copy defaults +if [[ ! -f /app/www/public/config/config.php ]]; then + cp /defaults/config.php /app/www/public/config/config.php +fi +datadirectory=$(php -r "require '/app/www/public/version.php'; echo \$CONFIG['datadirectory'];") + +# symlink folders +for dir in config data custom_apps themes; do + if [ "${dir}" = "data" ]; then + if [ "$(readlink /app/www/public/${dir})" != "${datadirectory}" ]; then + rm -rf "/app/www/public/${dir}" + ln -s "${datadirectory}" "/app/www/public/${dir}" + fi + continue + fi + if [ "$(readlink /app/www/public/${dir})" != "/config/www/nextcloud/${dir}" ]; then + rm -rf "/app/www/public/${dir}" + ln -s "/config/www/nextcloud/${dir}" "/app/www/public/${dir}" + fi +done + # install app -if [ ! -e /config/www/nextcloud/index.php ]; then - tar xf /app/nextcloud.tar.bz2 -C \ - /config/www/nextcloud --strip-components=1 +vergte() { printf '%s\n%s' "${2}" "${1}" | sort -C -V; } +vergt() { ! vergte "${2}" "${1}"; } +verlte() { printf '%s\n%s' "${1}" "${2}" | sort -C -V; } +verlt() { ! verlte "${2}" "${1}"; } + +installed_version="0.0.0.0" +if [ -f /app/www/public/version.php ]; then + installed_version=$(php -r "require '/app/www/public/version.php'; echo implode('.', \$OC_Version);") +fi +image_version=$(php -r "require '/app/www/src/version.php'; echo implode('.', \$OC_Version);") + +if vergt "${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?" + sleep infinity +fi + +if vergt "${image_version}" "${installed_version}"; then + echo "Initializing nextcloud ${image_version} ..." + if [ "${installed_version}" != "0.0.0.0" ]; then + echo "Upgrading nextcloud from ${installed_version} ..." + occ app:list | sed -n "/Enabled:/,/Disabled:/p" >/tmp/list_before + fi + + rsync -rlD --delete --exclude-from=/app/upgrade.exclude /app/www/src/ /app/www/public/ + for dir in config data custom_apps themes; do + if [ -z "$(ls -A /app/www/public/${dir}/)" ]; then + rsync -rlD --include "/${dir}/" --exclude '/*' /app/www/src/ /app/www/public/ + fi + done + rsync -rlD --include '/version.php' --exclude '/*' /app/www/src/ /app/www/public/ + + touch /tmp/full_chown + + if [ "${installed_version}" = "0.0.0.0" ]; then + # Install + echo "New nextcloud instance" + echo "Please run the web-based installer on first connect!" + else + # Upgrade + occ upgrade + + 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 + fi + + rm -f /tmp/list_before /tmp/list_after + echo "Initializing finished" +fi + +echo "Setting permissions" +if [ -f /tmp/full_chown ]; then lsiown abc:abc -R \ - /config/www/nextcloud - chmod +x /config/www/nextcloud/occ + /app/www/public + rm -f /tmp/full_chown fi - -# copy config -if [[ ! -f /config/www/nextcloud/config/config.php ]]; then - cp /defaults/config.php /config/www/nextcloud/config/config.php -fi - -# permissions lsiown abc:abc \ - /config/www/nextcloud/config/config.php \ + /app/www/public \ /data if (occ app:list --no-interaction | grep -q richdocumentscode) 2>/dev/null; then diff --git a/root/migrations/02-default-location b/root/migrations/02-default-location new file mode 100644 index 0000000..a3727ec --- /dev/null +++ b/root/migrations/02-default-location @@ -0,0 +1,11 @@ +#!/usr/bin/with-contenv bash +# shellcheck shell=bash + +DEFAULT_CONF="/config/nginx/site-confs/default.conf" +OLD_ROOT="root /config/www/nextcloud/;" +NEW_ROOT="root /app/www/public;" + +if grep -q "${OLD_ROOT}" "${DEFAULT_CONF}"; then + echo "updating root in ${DEFAULT_CONF}" + sed -i "s|${OLD_ROOT}|${NEW_ROOT}|" "${DEFAULT_CONF}" +fi diff --git a/root/usr/bin/occ b/root/usr/bin/occ index d1370d8..a08d55e 100755 --- a/root/usr/bin/occ +++ b/root/usr/bin/occ @@ -1,4 +1,4 @@ #!/usr/bin/with-contenv bash # shellcheck shell=bash -sudo -u abc -s /bin/bash -c "php /config/www/nextcloud/occ $*" +sudo -u abc -s /bin/bash -c "php /app/www/public/occ $*" diff --git a/root/usr/bin/updater.phar b/root/usr/bin/updater.phar deleted file mode 100755 index 5839f5d..0000000 --- a/root/usr/bin/updater.phar +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/with-contenv bash -# shellcheck shell=bash - -sudo -u abc -s /bin/bash -c "php /config/www/nextcloud/updater/updater.phar $*"