#!/bin/bash # T&M Hansson IT AB © - 2026, https://www.hanssonit.se/ # GNU General Public License v3.0 # https://github.com/nextcloud/vm/blob/main/LICENSE # Fix fancy progress bar for apt-get # https://askubuntu.com/a/754653 if [ -d /etc/apt/apt.conf.d ] then if ! [ -f /etc/apt/apt.conf.d/99progressbar ] then echo 'Dpkg::Progress-Fancy "1";' > /etc/apt/apt.conf.d/99progressbar echo 'APT::Color "1";' >> /etc/apt/apt.conf.d/99progressbar chmod 644 /etc/apt/apt.conf.d/99progressbar fi fi # Install curl if not existing if dpkg-query -W -f='${Status}' "curl" 2>/dev/null | grep -q "ok installed" then echo "curl OK" else apt-get update -q4 apt-get install curl -y fi # Install whiptail if not existing if dpkg-query -W -f='${Status}' "whiptail" 2>/dev/null | grep -q "ok installed" then echo "whiptail OK" else apt-get update -q4 apt-get install whiptail -y fi true SCRIPT_NAME="Nextcloud Install Script" SCRIPT_EXPLAINER="This script is installing all requirements that are needed for Nextcloud to run. It's the first of two parts that are necessary to finish your customized Nextcloud installation." # shellcheck source=lib.sh if ! source <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/main/static/fetch_lib.sh) then source <(curl -sL https://cdn.statically.io/gh/nextcloud/vm/main/static/fetch_lib.sh) fi # Check for errors + debug code and abort if something isn't right # 1 = ON # 0 = OFF DEBUG=0 debug_mode # Check if root root_check # Test RAM size (2GB min) + CPUs (min 1) ram_check 2 Nextcloud cpu_check 1 Nextcloud # Check if dpkg or apt is running is_process_running apt is_process_running dpkg # Check distribution and version if ! version "$LATEST_VERSION" "$DISTRO" "$SUPPORTED_VERSION_MAX" then msg_box "This script can only be run on Ubuntu $LATEST_VERSION (server)." exit 1 fi # Automatically restart services # Restart mode: (l)ist only, (i)nteractive or (a)utomatically. sed -i "s|#\$nrconf{restart} = .*|\$nrconf{restart} = 'a';|g" /etc/needrestart/needrestart.conf # Check for flags if [ "$1" = "" ] then print_text_in_color "$ICyan" "Running in normal mode..." sleep 1 elif [ "$1" = "--provisioning" ] || [ "$1" = "-p" ] then print_text_in_color "$ICyan" "Running in provisioning mode..." export PROVISIONING=1 sleep 1 elif [ "$1" = "--not-latest" ] then NOT_LATEST=1 print_text_in_color "$ICyan" "Running in not-latest mode..." sleep 1 else msg_box "Failed to get the correct flag. Did you enter it correctly?" exit 1 fi # Show explainer if [ -z "$PROVISIONING" ] then msg_box "$SCRIPT_EXPLAINER" fi # Create a placeholder volume before modifying anything # Ask about snapshots first export SNAPSHOTS_ENABLED="" if [ -z "$PROVISIONING" ] then if ! does_snapshot_exist "NcVM-installation" && yesno_box_no "Do you want to use LVM snapshots to be able to restore your root partition during upgrades and such? Please note: this feature will not be used by this script but by other scripts later on. For now we will only create a placeholder volume that will be used to let some space for snapshot volumes. Be aware that you will not be able to use the built-in backup solution if you choose 'No'! Enabling this will also force an automatic reboot after running the update script!" then check_free_space if [ "$FREE_SPACE" -ge 50 ] then print_text_in_color "$ICyan" "Creating volume..." sleep 1 # Create a placeholder snapshot check_command lvcreate --size 5G --name "NcVM-installation" ubuntu-vg export SNAPSHOTS_ENABLED="yes" else print_text_in_color "$IRed" "Could not create volume because of insufficient space..." sleep 2 fi fi fi # Fix LVM on BASE image # Ask about disk space - now snapshots have been reserved, we can use remaining space export USE_ALL_DISK_SPACE="" if grep -q "LVM" /etc/fstab then # In provisioning mode, always extend # In normal mode, ask the user if [ -n "$PROVISIONING" ] || yesno_box_yes "Do you want to make all free space available to your root partition?" then export USE_ALL_DISK_SPACE="yes" fi fi # Extend LVM if requested if [ "$USE_ALL_DISK_SPACE" = "yes" ] then # Resize LVM (live installer is &%¤%/! # VM print_text_in_color "$ICyan" "Extending LVM, this may take a long time..." lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv # Run it again manually just to be sure it's done while : do lvdisplay | grep "Size" | awk '{print $3}' if ! lvextend -L +10G /dev/ubuntu-vg/ubuntu-lv >/dev/null 2>&1 then if ! lvextend -L +1G /dev/ubuntu-vg/ubuntu-lv >/dev/null 2>&1 then if ! lvextend -L +100M /dev/ubuntu-vg/ubuntu-lv >/dev/null 2>&1 then if ! lvextend -L +1M /dev/ubuntu-vg/ubuntu-lv >/dev/null 2>&1 then resize2fs /dev/ubuntu-vg/ubuntu-lv break fi fi fi fi done fi # Cleanup environment variables unset SNAPSHOTS_ENABLED unset USE_ALL_DISK_SPACE # Install needed dependencies install_if_not lshw install_if_not net-tools install_if_not whiptail install_if_not apt-utils install_if_not keyboard-configuration # Nice to have dependencies install_if_not bash-completion install_if_not htop install_if_not iputils-ping # Download needed libraries before execution of the first script mkdir -p "$SCRIPTS" # Create local backup (in case GitHub is rate limited during install) ensure_local_backup_repo download_script GITHUB_REPO lib download_script STATIC fetch_lib # Set locales run_script ADDONS locales # Create new current user download_script STATIC adduser bash "$SCRIPTS"/adduser.sh "nextcloud_install_production.sh" rm -f "$SCRIPTS"/adduser.sh check_universe check_multiverse # Check if key is available if ! site_200 "$NCREPO" then msg_box "Nextcloud repo is not available, exiting..." exit 1 fi # Test Home/SME function if home_sme_server then msg_box "This is the Home/SME server, function works!" else print_text_in_color "$ICyan" "Home/SME Server not detected. No worries, just testing the function." sleep 3 fi # Check if it's a clean server stop_if_installed postgresql # Stop if any versioned PostgreSQL is already installed (covers PG 9.x through 30) for PG_VER in 9.{0..9} {10..30} do stop_if_installed postgresql-"$PG_VER" done stop_if_installed apache2 stop_if_installed nginx stop_if_installed php stop_if_installed php-fpm stop_if_installed php-common # Stop if any php-fpm (current or older) is already installed — must be a clean server for PHP_MAJOR in 7 8 do for PHP_MINOR in 0 1 2 3 4 5 6 7 8 9 do stop_if_installed php"$PHP_MAJOR.$PHP_MINOR"-fpm done done stop_if_installed mysql-common stop_if_installed mariadb-server # We don't want automatic updates since they might fail (we use our own script) if is_this_installed unattended-upgrades then apt-get purge unattended-upgrades -y apt-get autoremove -y rm -rf /var/log/unattended-upgrades fi # Create $SCRIPTS dir if [ ! -d "$SCRIPTS" ] then mkdir -p "$SCRIPTS" fi # Create $VMLOGS dir if [ ! -d "$VMLOGS" ] then mkdir -p "$VMLOGS" fi # Install needed network install_if_not netplan.io # APT over HTTPS install_if_not apt-transport-https # Install build-essentials to get make install_if_not build-essential # Install a decent text editor install_if_not nano # Install package for crontab install_if_not cron # Make sure sudo exists (needed in adduser.sh) install_if_not sudo # Make sure add-apt-repository exists (needed in lib.sh) install_if_not software-properties-common # Set dual or single drive setup if [ -n "$PROVISIONING" ] then choice="2 Disks Auto" else msg_box "This server is designed to run with two disks, one for OS and one for DATA. \ This will get you the best performance since the second disk is using ZFS which is a superior filesystem. Though not recommended, you can still choose to only run on one disk, \ if for example it's your only option on the hypervisor you're running. You will now get the option to decide which disk you want to use for DATA, \ or run the automatic script that will choose the available disk automatically." choice=$(whiptail --title "$TITLE - Choose disk format" --nocancel --menu \ "How would you like to configure your disks? $MENU_GUIDE" "$WT_HEIGHT" "$WT_WIDTH" 4 \ "2 Disks Auto" "(Automatically configured)" \ "2 Disks Manual" "(Choose by yourself)" \ "1 Disk" "(Only use one disk /mnt/ncdata - NO ZFS!)" 3>&1 1>&2 2>&3) fi case "$choice" in "2 Disks Auto") run_script DISK format-sdb # Change to zfs-mount-generator run_script DISK change-to-zfs-mount-generator # Create daily zfs prune script run_script DISK create-daily-zfs-prune ;; "2 Disks Manual") run_script DISK format-chosen # Change to zfs-mount-generator run_script DISK change-to-zfs-mount-generator # Create daily zfs prune script run_script DISK create-daily-zfs-prune ;; "1 Disk") print_text_in_color "$IRed" "1 Disk setup chosen." sleep 2 ;; *) ;; esac # Set DNS resolver # https://unix.stackexchange.com/questions/442598/how-to-configure-systemd-resolved-and-systemd-networkd-to-use-local-dns-server-f while : do if [ -n "$PROVISIONING" ] then choice="Quad9" else choice=$(whiptail --title "$TITLE - Set DNS Resolver" --menu \ "Which DNS provider should this Nextcloud box use? $MENU_GUIDE" "$WT_HEIGHT" "$WT_WIDTH" 4 \ "Quad9" "(https://www.quad9.net/)" \ "Cloudflare" "(https://www.cloudflare.com/dns/)" \ "Local" "($GATEWAY) - DNS on gateway" \ "Expert" "If you really know what you're doing!" 3>&1 1>&2 2>&3) fi case "$choice" in "Quad9") sed -i "s|^#\?DNS=.*$|DNS=9.9.9.9 149.112.112.112 2620:fe::fe 2620:fe::9|g" /etc/systemd/resolved.conf ;; "Cloudflare") sed -i "s|^#\?DNS=.*$|DNS=1.1.1.1 1.0.0.1 2606:4700:4700::1111 2606:4700:4700::1001|g" /etc/systemd/resolved.conf ;; "Local") sed -i "s|^#\?DNS=.*$|DNS=$GATEWAY|g" /etc/systemd/resolved.conf systemctl restart systemd-resolved.service if network_ok then break else msg_box "Could not validate the local DNS server. Pick an Internet DNS server and try again." continue fi ;; "Expert") OWNDNS=$(input_box_flow "Please choose your own DNS server(s) with a space in between, e.g: $GATEWAY 9.9.9.9 (NS1 NS2)") sed -i "s|^#\?DNS=.*$|DNS=$OWNDNS|g" /etc/systemd/resolved.conf systemctl restart systemd-resolved.service if network_ok then break unset OWNDNS else msg_box "Could not validate the local DNS server. Pick an Internet DNS server and try again." continue fi ;; *) ;; esac if test_connection then break else msg_box "Could not validate the DNS server. Please try again." fi done # Install PostgreSQL apt-get update -q4 & spinner_loading install_if_not postgresql # Create DB with proper permissions for Nextcloud 30+ # PostgreSQL 15+ requires explicit schema permissions cd /tmp if ! sudo -u postgres psql <> /etc/apache2/apache2.conf check_command systemctl restart apache2.service fi # Install PHP "$PHPVER" install_if_not php"$PHPVER"-fpm install_if_not php"$PHPVER"-intl install_if_not php"$PHPVER"-ldap # php-imap was deprecated in PHP 8.4 and removed in PHP 8.5 (no longer in Ubuntu). # Nextcloud Mail uses bytestream/horde-imap-client (pure PHP) and does not need it. install_if_not php"$PHPVER"-gd install_if_not php"$PHPVER"-pgsql install_if_not php"$PHPVER"-curl install_if_not php"$PHPVER"-xml install_if_not php"$PHPVER"-zip install_if_not php"$PHPVER"-mbstring install_if_not php"$PHPVER"-soap install_if_not php"$PHPVER"-gmp install_if_not php"$PHPVER"-bz2 install_if_not php"$PHPVER"-bcmath install_if_not php-pear # Enable php-fpm a2enconf php"$PHPVER"-fpm # Enable HTTP/2 server wide print_text_in_color "$ICyan" "Enabling HTTP/2 server wide..." cat << HTTP2_ENABLE > "$HTTP2_CONF" Protocols h2 http/1.1 HTTP2_ENABLE print_text_in_color "$IGreen" "$HTTP2_CONF was successfully created" a2enmod http2 restart_webserver # Set up a php-fpm pool with a unixsocket cat << POOL_CONF > "$PHP_POOL_DIR"/nextcloud.conf [Nextcloud] user = www-data group = www-data listen = /run/php/php"$PHPVER"-fpm.nextcloud.sock listen.owner = www-data listen.group = www-data pm = dynamic ; max_children is set dynamically with calculate_php_fpm() pm.max_children = 8 pm.start_servers = 3 pm.min_spare_servers = 2 pm.max_spare_servers = 3 env[HOSTNAME] = $(hostname -f) env[PATH] = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin env[TMP] = /tmp env[TMPDIR] = /tmp env[TEMP] = /tmp security.limit_extensions = .php php_admin_value [cgi.fix_pathinfo] = 1 ; Optional ; pm.max_requests = 2000 POOL_CONF # Disable the idling example pool. mv "$PHP_POOL_DIR"/www.conf "$PHP_POOL_DIR"/www.conf.backup # Enable the new php-fpm config restart_webserver # Calculate the values of PHP-FPM based on the amount of RAM available (it's done in the startup script as well) calculate_php_fpm # Install VM-tools if [ "$SYSVENDOR" == "VMware, Inc." ]; then install_if_not open-vm-tools elif [[ "$SYSVENDOR" == "QEMU" || "$SYSVENDOR" == "Red Hat" ]]; then install_if_not qemu-guest-agent systemctl enable qemu-guest-agent systemctl start qemu-guest-agent fi # Get not-latest Nextcloud version if [ -n "$NOT_LATEST" ] then while [ -z "$NCVERSION" ] do print_text_in_color "$ICyan" "Fetching the not-latest Nextcloud version..." NCVERSION=$(curl -s -m 900 "$NCREPO"/ | sed --silent 's/.*href="nextcloud-\([^"]\+\).zip.asc".*/\1/p' \ | sort --version-sort | grep -v "\.0$\|\.1$\|\.2$" | tail -1) STABLEVERSION="nextcloud-$NCVERSION" print_text_in_color "$IGreen" "$NCVERSION" done fi # Download and validate Nextcloud package check_command download_verify_nextcloud_stable if [ ! -f "$HTML/$STABLEVERSION.tar.bz2" ] then msg_box "Aborting,something went wrong with the download of $STABLEVERSION.tar.bz2" exit 1 fi # Extract package tar -xjf "$HTML/$STABLEVERSION.tar.bz2" -C "$HTML" & spinner_loading rm "$HTML/$STABLEVERSION.tar.bz2" # Secure permissions download_script STATIC setup_secure_permissions_nextcloud bash "$SECURE" & spinner_loading # Ask to set a custom username if [ -z "$PROVISIONING" ] then if yesno_box_no "Nextcloud is about to be installed.\nDo you want to change the standard GUI user '$GUIUSER' to something else?" then while : do GUIUSER=$(input_box_flow "Please type in the name of the Web Admin in Nextcloud. \nThe only allowed characters for the username are: 'a-z', 'A-Z', '0-9', and '_.@-'") if [[ "$GUIUSER" == *" "* ]] then msg_box "Please don't use spaces." # - has to be escaped otherwise it won't work. # Inspired by: https://unix.stackexchange.com/a/498731/433213 elif [ "${GUIUSER//[A-Za-z0-9_.\-@]}" ] then msg_box "Allowed characters for the username are:\na-z', 'A-Z', '0-9', and '_.@-'\n\nPlease try again." else break fi done while : do GUIPASS=$(input_box_flow "Please type in the new password for the new Web Admin ($GUIUSER) in Nextcloud.") if [[ "$GUIPASS" == *" "* ]] then msg_box "Please don't use spaces." fi if [ "${GUIPASS//[A-Za-z0-9_.\-@]}" ] then msg_box "Allowed characters for the password are:\na-z', 'A-Z', '0-9', and '_.@-'\n\nPlease try again." else msg_box "The new Web Admin in Nextcloud is now: $GUIUSER\nThe password is set to: $GUIPASS This is used when you login to Nextcloud itself, i.e. on the web." break fi done fi fi # Install Nextcloud # NC 29 fix ## TODO: is this needed in coming versions? chown www-data:www-data "$NCPATH"/data # Normal install print_text_in_color "$ICyan" "Installing Nextcloud, it might take a while..." cd "$NCPATH" # Don't use nextcloud_occ here as it takes alooong time. # https://github.com/nextcloud/vm/issues/2542#issuecomment-1700406020 check_command sudo -u www-data php "$NCPATH"/occ maintenance:install \ --data-dir="$NCDATA" \ --database=pgsql \ --database-name=nextcloud_db \ --database-user="$PGDB_USER" \ --database-pass="$PGDB_PASS" \ --admin-user="$GUIUSER" \ --admin-pass="$GUIPASS" print_text_in_color "$ICyan" "Nextcloud version:" nextcloud_occ status sleep 3 # Install Redis (distributed cache) run_script ADDONS redis-server-ubuntu # Install smbclient (OS package - no longer built from PECL) install_if_not php"$PHPVER"-smbclient phpenmod -v "$PHPVER" smbclient # Install igbinary for PHP (OS package - no longer built from PECL) # https://github.com/igbinary/igbinary install_if_not php"$PHPVER"-igbinary phpenmod -v "$PHPVER" igbinary # Set igbinary as session serializer (igbinary.compact_strings is already set in the package .ini) { echo "# igbinary for PHP" echo "session.serialize_handler=igbinary" } >> "$PHP_INI" restart_webserver # Prepare cron.php to be run every 5 minutes crontab -u www-data -l | { cat; echo "*/5 * * * * php -f $NCPATH/cron.php > /dev/null 2>&1"; } | crontab -u www-data - # Run the updatenotification on a schedule nextcloud_occ config:system:set upgrade.disable-web --type=bool --value=true nextcloud_occ config:app:set updatenotification notify_groups --value="[]" print_text_in_color "$ICyan" "Configuring update notifications specific for this server..." download_script STATIC updatenotification check_command chmod +x "$SCRIPTS"/updatenotification.sh crontab -u root -l | { cat; echo "59 $AUT_UPDATES_TIME * * * $SCRIPTS/updatenotification.sh > /dev/null 2>&1"; } | crontab -u root - # Change values in php.ini (increase max file size) # max_execution_time sed -i "s|max_execution_time =.*|max_execution_time = 3500|g" "$PHP_INI" # max_input_time sed -i "s|max_input_time =.*|max_input_time = 3600|g" "$PHP_INI" # memory_limit sed -i "s|memory_limit =.*|memory_limit = 512M|g" "$PHP_INI" # post_max sed -i "s|post_max_size =.*|post_max_size = 1100M|g" "$PHP_INI" # upload_max sed -i "s|upload_max_filesize =.*|upload_max_filesize = 1000M|g" "$PHP_INI" # Set logging nextcloud_occ config:system:set log_type --value=file nextcloud_occ config:system:set logfile --value="$VMLOGS/nextcloud.log" rm -f "$NCDATA/nextcloud.log" rm -f "$NCPATH/data/nextcloud.log" nextcloud_occ config:system:set loglevel --value=2 install_and_enable_app admin_audit nextcloud_occ config:app:set admin_audit logfile --value="$VMLOGS/audit.log" nextcloud_occ config:system:set log.condition apps 0 --value admin_audit # Set maintenance window for cron # https://docs.nextcloud.com/server/29/admin_manual/configuration_server/background_jobs_configuration.html#background-jobs nextcloud_occ config:system:set maintenance_window_start --type=integer --value=2 # Set SMTP mail nextcloud_occ config:system:set mail_smtpmode --value="smtp" # Forget login/session after 30 minutes nextcloud_occ config:system:set remember_login_cookie_lifetime --value="1800" # Set logrotate (max 10 MB) nextcloud_occ config:system:set log_rotate_size --value="10485760" # Set trashbin retention obligation (save it in trashbin for 60 days or delete when space is needed) nextcloud_occ config:system:set trashbin_retention_obligation --value="auto, 60" # Set versions retention obligation (save versions for 180 days or delete when space is needed) nextcloud_occ config:system:set versions_retention_obligation --value="auto, 180" # Set activity retention obligation (save activity feed for 120 days, defaults to 365 days otherwise) nextcloud_occ config:system:set activity_expire_days --value="120" # Remove simple signup nextcloud_occ config:system:set simpleSignUpLink.shown --type=bool --value=false # Set chunk_size for files app to 100MB (defaults to 10MB) nextcloud_occ config:app:set files max_chunk_size --value="104857600" # Set product name if home_sme_server then PRODUCTNAME="Nextcloud HanssonIT Server" else PRODUCTNAME="Nextcloud HanssonIT VM" fi if is_app_installed theming then if [ "$(nextcloud_occ config:app:get theming productName)" != "$PRODUCTNAME" ] then nextcloud_occ config:app:set theming productName --value "$PRODUCTNAME" fi fi # Enable OPCache for PHP # https://docs.nextcloud.com/server/14/admin_manual/configuration_server/server_tuning.html#enable-php-opcache phpenmod opcache { echo "# OPcache settings for Nextcloud" echo "opcache.enable=1" echo "opcache.enable_cli=1" echo "opcache.interned_strings_buffer=$opcache_interned_strings_buffer_value" echo "opcache.max_accelerated_files=10000" echo "opcache.memory_consumption=256" echo "opcache.save_comments=1" echo "opcache.revalidate_freq=1" echo "opcache.validate_timestamps=1" } >> "$PHP_INI" # PHP-FPM optimization # https://geekflare.com/php-fpm-optimization/ sed -i "s|;emergency_restart_threshold.*|emergency_restart_threshold = 10|g" /etc/php/"$PHPVER"/fpm/php-fpm.conf sed -i "s|;emergency_restart_interval.*|emergency_restart_interval = 1m|g" /etc/php/"$PHPVER"/fpm/php-fpm.conf sed -i "s|;process_control_timeout.*|process_control_timeout = 10|g" /etc/php/"$PHPVER"/fpm/php-fpm.conf # PostgreSQL values for PHP (https://docs.nextcloud.com/server/latest/admin_manual/configuration_database/linux_database_configuration.html#postgresql-database) { echo "" echo "[PostgresSQL]" echo "pgsql.allow_persistent = On" echo "pgsql.auto_reset_persistent = Off" echo "pgsql.max_persistent = -1" echo "pgsql.max_links = -1" echo "pgsql.ignore_notice = 0" echo "pgsql.log_notice = 0" } >> "$PHP_FPM_DIR"/conf.d/20-pdo_pgsql.ini # Fix https://github.com/nextcloud/vm/issues/714 print_text_in_color "$ICyan" "Optimizing Nextcloud..." yes | nextcloud_occ db:convert-filecache-bigint nextcloud_occ db:add-missing-indices while [ -z "$CURRENTVERSION" ] do CURRENTVERSION=$(sudo -u www-data php "$NCPATH"/occ status | grep "versionstring" | awk '{print $3}') done if [ "${CURRENTVERSION%%.*}" -ge "19" ] then nextcloud_occ db:add-missing-columns fi if [ "${CURRENTVERSION%%.*}" -ge "20" ] then nextcloud_occ db:add-missing-primary-keys fi # Install Figlet install_if_not figlet # To be able to use snakeoil certs install_if_not ssl-cert # Generate $HTTP_CONF if [ ! -f "$SITES_AVAILABLE"/"$HTTP_CONF" ] then touch "$SITES_AVAILABLE/$HTTP_CONF" cat << HTTP_CREATE > "$SITES_AVAILABLE/$HTTP_CONF" ### YOUR SERVER ADDRESS ### # ServerAdmin admin@example.com # ServerName cloud.example.com ### SETTINGS ### SetHandler "proxy:unix:/run/php/php$PHPVER-fpm.nextcloud.sock|fcgi://localhost" # Logs LogLevel warn CustomLog \${APACHE_LOG_DIR}/access.log combined ErrorLog \${APACHE_LOG_DIR}/error.log # Document root folder DocumentRoot $NCPATH # The Nextcloud folder Options Indexes FollowSymLinks AllowOverride All Require all granted Satisfy Any # This is to include all the Nextcloud rules due to that we use PHP-FPM and .htaccess aren't read Include $NCPATH/.htaccess # Deny access to your data directory Require all denied # Deny access to the Nextcloud config folder Require all denied Dav off # The following lines prevent .htaccess and .htpasswd files from being viewed by Web clients. Require all denied SetEnv HOME $NCPATH SetEnv HTTP_HOME $NCPATH # Disable HTTP TRACE method. TraceEnable off # Disable HTTP TRACK method. RewriteEngine On RewriteCond %{REQUEST_METHOD} ^TRACK RewriteRule .* - [R=405,L] # Avoid "Sabre\DAV\Exception\BadRequest: expected filesize XXXX got XXXX" RequestReadTimeout body=0 HTTP_CREATE print_text_in_color "$IGreen" "$SITES_AVAILABLE/$HTTP_CONF was successfully created." fi # Generate $TLS_CONF if [ ! -f "$SITES_AVAILABLE"/"$TLS_CONF" ] then touch "$SITES_AVAILABLE/$TLS_CONF" cat << TLS_CREATE > "$SITES_AVAILABLE/$TLS_CONF" # # RewriteEngine On # RewriteRule ^(.*)$ https://%{HTTP_HOST}\$1 [END,NE,R=permanent] # Header add Strict-Transport-Security: "max-age=15552000;includeSubdomains" ### YOUR SERVER ADDRESS ### # ServerAdmin admin@example.com # ServerName cloud.example.com ### SETTINGS ### SetHandler "proxy:unix:/run/php/php$PHPVER-fpm.nextcloud.sock|fcgi://localhost" # Intermediate configuration SSLEngine on SSLCompression off SSLProtocol -all +TLSv1.2 +TLSv1.3 SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 SSLHonorCipherOrder off SSLSessionTickets off ServerSignature off # Logs LogLevel warn CustomLog \${APACHE_LOG_DIR}/access.log combined ErrorLog \${APACHE_LOG_DIR}/error.log # Document root folder DocumentRoot $NCPATH # The Nextcloud folder Options Indexes FollowSymLinks AllowOverride All Require all granted Satisfy Any # This is to include all the Nextcloud rules due to that we use PHP-FPM and .htaccess aren't read Include $NCPATH/.htaccess # Deny access to your data directory Require all denied # Deny access to the Nextcloud config folder Require all denied Dav off # The following lines prevent .htaccess and .htpasswd files from being viewed by Web clients. Require all denied SetEnv HOME $NCPATH SetEnv HTTP_HOME $NCPATH # Disable HTTP TRACE method. TraceEnable off # Disable HTTP TRACK method. RewriteEngine On RewriteCond %{REQUEST_METHOD} ^TRACK RewriteRule .* - [R=405,L] # Avoid "Sabre\DAV\Exception\BadRequest: expected filesize XXXX got XXXX" RequestReadTimeout body=0 # Avoid zero byte files (only works in Ubuntu 24.04 -->>) # See https://github.com/nextcloud/server/issues/3056 SetEnv proxy-sendcl 1 ### LOCATION OF CERT FILES ### SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key TLS_CREATE print_text_in_color "$IGreen" "$SITES_AVAILABLE/$TLS_CONF was successfully created." fi # Enable new config a2ensite "$TLS_CONF" a2ensite "$HTTP_CONF" a2dissite default-ssl restart_webserver if [ -n "$PROVISIONING" ] then choice="Calendar Contacts IssueTemplate PDFViewer Text Mail Deck Group-Folders" else choice=$(whiptail --title "$TITLE - Install apps or software" --checklist \ "Automatically configure and install selected apps or software $CHECKLIST_GUIDE" "$WT_HEIGHT" "$WT_WIDTH" 4 \ "Calendar" "" ON \ "Contacts" "" ON \ "PDFViewer" "" ON \ "Text" "" ON \ "Mail" "" ON \ "Deck" "" ON \ "Collectives" "" ON \ "Suspicious Login detection" "" ON \ "IssueTemplate" "" OFF \ "Group-Folders" "" OFF 3>&1 1>&2 2>&3) fi case "$choice" in *"Calendar"*) install_and_enable_app calendar ;;& *"Contacts"*) install_and_enable_app contacts ;;& *"IssueTemplate"*) # install_and_enable_app issuetemplate rm -rf "$NCPATH"apps/issuetemplate nextcloud_occ app:install --force --keep-disabled issuetemplate sed -i "s|20|${CURRENTVERSION%%.*}|g" "$NCPATH"/apps/issuetemplate/appinfo/info.xml nextcloud_occ_no_check app:enable issuetemplate ;;& *"PDFViewer"*) install_and_enable_app files_pdfviewer ;;& *"Text"*) install_and_enable_app text ;;& *"Mail"*) install_and_enable_app mail ;;& *"Deck"*) install_and_enable_app deck ;;& *"Collectives"*) install_and_enable_app collectives install_if_not php"$PHPVER"-sqlite3 ;;& *"Suspicious Login detection"*) install_and_enable_app suspicios_login ;;& *"Group-Folders"*) install_and_enable_app groupfolders ;;& *) ;; esac # Cleanup apt-get autoremove -y apt-get autoclean find /root "/home/$UNIXUSER" -type f \( -name '*.sh*' -o -name '*.html*' -o -name '*.tar*' -o -name '*.zip*' \) -delete # Install virtual kernels for Hyper-V, (and extra for UTF8 kernel module + Collabora and EuroOffice) # Kernel 5.4 if ! home_sme_server then if [ "$SYSVENDOR" == "Microsoft Corporation" ] then # Hyper-V install_if_not linux-virtual install_if_not linux-image-virtual install_if_not linux-tools-virtual install_if_not linux-cloud-tools-virtual install_if_not linux-azure # linux-image-extra-virtual only needed for AUFS driver with Docker fi fi # Add aliases if [ -f /root/.bash_aliases ] then if ! grep -q "nextcloud" /root/.bash_aliases then { echo "alias nextcloud_occ='sudo -u www-data php /var/www/nextcloud/occ'" echo "alias run_update_nextcloud='bash /var/scripts/update.sh'" } >> /root/.bash_aliases fi elif [ ! -f /root/.bash_aliases ] then { echo "alias nextcloud_occ='sudo -u www-data php /var/www/nextcloud/occ'" echo "alias run_update_nextcloud='bash /var/scripts/update.sh'" } > /root/.bash_aliases fi # Fix GRUB defaults if grep -q 'GRUB_CMDLINE_LINUX_DEFAULT="maybe-ubiquity"' /etc/default/grub then sed -i "s|GRUB_CMDLINE_LINUX_DEFAULT=.*|GRUB_CMDLINE_LINUX_DEFAULT=|g" /etc/default/grub fi # Set secure permissions final (./data/.htaccess has wrong permissions otherwise) bash "$SECURE" & spinner_loading # Put IP address in /etc/issue (shown before the login) if [ -f /etc/issue ] then printf '%s\n' "\4" >> /etc/issue fi # Fix Realtek on PN51 if asuspn51 then if ! version "$LATEST_VERSION" "$DISTRO" "$SUPPORTED_VERSION_MAX" then # Upgrade Realtek drivers print_text_in_color "$ICyan" "Upgrading Realtek firmware..." curl_to_dir https://raw.githubusercontent.com/nextcloud/vm/main/network/asusnuc pn51.sh "$SCRIPTS" bash "$SCRIPTS"/pn51.sh fi fi # Update if it's the Home/SME Server if home_sme_server then # Upgrade system print_text_in_color "$ICyan" "System will now upgrade..." run_script STATIC update fi # Force MOTD to show correct number of updates if is_this_installed update-notifier-common then sudo /usr/lib/update-notifier/update-motd-updates-available --force fi # It has to be this order: # Download scripts # chmod +x # Set permissions for ncadmin in the change scripts print_text_in_color "$ICyan" "Getting scripts from GitHub to be able to run the first setup..." # Get needed scripts for first bootup download_script GITHUB_REPO nextcloud-startup-script download_script STATIC instruction download_script STATIC history download_script NETWORK static_ip # Moved from the startup script 2021-01-04 download_script LETS_ENC activate-tls download_script STATIC update download_script STATIC setup_secure_permissions_nextcloud download_script STATIC change_db_pass download_script STATIC nextcloud download_script MENU menu download_script MENU server_configuration download_script MENU nextcloud_configuration download_script MENU additional_apps download_script MENU desec_menu # Make $SCRIPTS excutable chmod +x -R "$SCRIPTS" chown root:root -R "$SCRIPTS" # Prepare first bootup check_command run_script STATIC change-ncadmin-profile check_command run_script STATIC change-root-profile # Disable hibernation print_text_in_color "$ICyan" "Disable hibernation..." systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target # Reboot if [ -z "$PROVISIONING" ] then msg_box "Installation almost done, system will reboot when you hit OK. After reboot, please login to run the setup script." fi reboot