#!/bin/bash source /opt/webinoly/lib/general source /opt/webinoly/lib/headers readonly cores=$(grep ^processor /proc/cpuinfo | wc -l) readonly swapm=$(($(grep SwapTotal /proc/meminfo | cut -f 2 -d ':' | tr -d ' ' | cut -f 1 -d 'k')/1024)) readonly swap=$(($swapm/1000)) readonly ramk=$(grep MemTotal /proc/meminfo | cut -f 2 -d ':' | tr -d ' ' | cut -f 1 -d 'k') readonly ramb=$(($ramk/1000)) [[ $(($ramb%1000)) -gt 700 ]] && readonly ram=$((($ramb/1000)+1)) || readonly ram=$(($ramb/1000)) [[ $(($ramb*30)) -lt 65535 ]] && readonly fd_per_process=65535 || readonly fd_per_process=$(($ramb*30)) # File descriptors per process 3% # Validation [[ $cores =~ ^[0-9]+$ ]] || echo "${red}[ERROR] System info (cores) retrieve corrupted!${end}" [[ $swapm =~ ^[0-9]+$ ]] || echo "${red}[ERROR] System info (swap) retrieve corrupted!${end}" [[ $ramk =~ ^[0-9]+$ ]] || echo "${red}[ERROR] System info (ram) retrieve corrupted!${end}" if [[ $(conf_read db-engine) == "mysql" && $ram -lt 1 ]]; then echo "${red}[ERROR] MySQL is set as database engine!${dim} (Not enough RAM: ${ramb}MB)" echo "You should consider MariaDB instead for small servers under 2GB.${end}" exit 1 fi linux_optim() { api-events_update in4 [[ $(conf_read linux-optim) == "true" ]] && return # Kernel Optimization if [[ $(conf_read kernel-optim) != "false" ]]; then echo "${gre}Wait while Webinoly optimize your Ubuntu Operating System...${end}" api-events_update in5 [[ -f /etc/sysctl.d/90-webinoly.conf ]] && sudo rm -rf /etc/sysctl.d/90-webinoly.conf sudo cp /opt/webinoly/templates/general/sysctl /etc/sysctl.d/90-webinoly.conf sudo modprobe tcp_bbr # https://github.com/amazonlinux/autotune # https://github.com/amzn/amzn-drivers/blob/master/kernel/linux/ena/ENA_Linux_Best_Practices.rst # https://www.brendangregg.com/Slides/AWSreInvent2017_performance_tuning_EC2.pdf # https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/performance_tuning_guide/s-memory-tunables # https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/performance_tuning_guide/sect-red_hat_enterprise_linux-performance_tuning_guide-configuration_tools-configuring_system_memory_capacity if [[ $ram -gt 28 ]]; then # https://mariadb.com/kb/en/configuring-swappiness/ sudo sed -i "/vm.swappiness =/c \vm.swappiness = 1" /etc/sysctl.d/90-webinoly.conf sudo sed -i "/vm.min_free_kbytes =/c \vm.min_free_kbytes = $(($ramb*20))" /etc/sysctl.d/90-webinoly.conf sudo sed -i "/vm.dirty_ratio =/c \vm.dirty_ratio = 0" /etc/sysctl.d/90-webinoly.conf sudo sed -i "/vm.dirty_background_ratio =/c \vm.dirty_background_ratio = 0" /etc/sysctl.d/90-webinoly.conf sudo sed -i "/vm.dirty_expire_centisecs =/c \vm.dirty_expire_centisecs = 500" /etc/sysctl.d/90-webinoly.conf sudo sed -i "/#vm.dirty_bytes =/c \vm.dirty_bytes = 5505024000" /etc/sysctl.d/90-webinoly.conf sudo sed -i "/#vm.dirty_background_bytes =/c \vm.dirty_background_bytes = 917504000" /etc/sysctl.d/90-webinoly.conf sudo sed -i "/#vm.dirty_writeback_centisecs =/c \vm.dirty_writeback_centisecs = 100" /etc/sysctl.d/90-webinoly.conf elif [[ $ram -gt 2 ]]; then # Default is 65M, if RAM >= 3Gb take 3%, and > 28Gb only 2% sudo sed -i "/vm.min_free_kbytes =/c \vm.min_free_kbytes = $(($ramb*30))" /etc/sysctl.d/90-webinoly.conf # https://lonesysadmin.net/2013/12/22/better-linux-disk-caching-performance-vm-dirty_ratio/ sudo sed -i "/vm.dirty_ratio =/c \vm.dirty_ratio = 30" /etc/sysctl.d/90-webinoly.conf sudo sed -i "/vm.dirty_expire_centisecs =/c \vm.dirty_expire_centisecs = 900" /etc/sysctl.d/90-webinoly.conf sudo sed -i "/vm.swappiness =/c \vm.swappiness = 5" /etc/sysctl.d/90-webinoly.conf fi if [[ $ram -gt 1 ]]; then local shmmni=$(($ram*256)) local msgmni=$(($ram*1024)) else local shmmni=256 local msgmni=1024 fi # Although you can apply values larger than 32768 by using the boot parameter ipcmni_extend, the values are still capped to 32768 internally. [[ $shmmni -gt 32768 ]] && local shmmni=32768 [[ $msgmni -gt 32768 ]] && local msgmni=32768 # https://www.ibm.com/docs/en/db2/11.1?topic=unix-modifying-kernel-parameters-linux sudo sed -i "/kernel.shmmni =/c \kernel.shmmni = $shmmni" /etc/sysctl.d/90-webinoly.conf sudo sed -i "/kernel.shmmax =/c \kernel.shmmax = $(($ramk*800))" /etc/sysctl.d/90-webinoly.conf # Less than 80% of total ram sudo sed -i "/kernel.shmall =/c \kernel.shmall = $(($(getconf PAGE_SIZE)*2))" /etc/sysctl.d/90-webinoly.conf sudo sed -i "/kernel.msgmni =/c \kernel.msgmni = $msgmni" /etc/sysctl.d/90-webinoly.conf sudo sed -i "/kernel.sem =/c \kernel.sem = 250 1024000 32 $shmmni" /etc/sysctl.d/90-webinoly.conf # Also: 'sudo service procps force-reload' but we prefer this method to better display errors (just in case) sudo sysctl -p -q /etc/sysctl.d/90-webinoly.conf api-events_update in6 fi # File directors per process [[ -n $(ulimit -Hn) && $fd_per_process -lt $(ulimit -Hn) ]] && local rootfd=$(ulimit -Hn) || local rootfd=$fd_per_process sudo sed -i "/End of file/i \# WebinolyStart - Don't delete" /etc/security/limits.conf sudo sed -i "/End of file/i \root - nofile ${rootfd}" /etc/security/limits.conf sudo sed -i "/End of file/i \* - nofile ${fd_per_process}" /etc/security/limits.conf # https://mariadb.com/kb/en/configuring-linux-for-mariadb/ sudo sed -i "/End of file/i \mysql soft core unlimited" /etc/security/limits.conf sudo sed -i "/End of file/i \mysql hard core unlimited" /etc/security/limits.conf sudo sed -i "/End of file/i \mysql soft nofile 65535" /etc/security/limits.conf sudo sed -i "/End of file/i \mysql hard nofile 65535" /etc/security/limits.conf sudo sed -i "/End of file/i \# WebinolyEnd" /etc/security/limits.conf # File directors for Nginx [[ ! -d /etc/systemd/system/nginx.service.d ]] && sudo mkdir /etc/systemd/system/nginx.service.d [[ ! -f /etc/systemd/system/nginx.service.d/nofile_limit.conf ]] && sudo touch /etc/systemd/system/nginx.service.d/nofile_limit.conf [[ ! -s /etc/systemd/system/nginx.service.d/nofile_limit.conf ]] && sudo echo "[Service] LimitNOFILE=$fd_per_process" >> /etc/systemd/system/nginx.service.d/nofile_limit.conf # Disable Transparent Huge Pages # Just to be sure is disabled, most cloud providers bring this settings disabled by default. # "madvise" can be good in some cases. if [[ ! -f /etc/systemd/system/webinoly-disable-thp.service ]]; then sudo touch /etc/systemd/system/webinoly-disable-thp.service echo "[Unit] Description=Disable Transparent Huge Pages (THP) [Service] Type=simple ExecStart=/bin/sh -c \"echo never > /sys/kernel/mm/transparent_hugepage/enabled && echo never > /sys/kernel/mm/transparent_hugepage/defrag\" [Install] WantedBy=multi-user.target" >> /etc/systemd/system/webinoly-disable-thp.service fi sudo systemctl start webinoly-disable-thp sudo systemctl enable webinoly-disable-thp > /dev/null 2>&1 # RAM: By default linux takes 10% for /run, we increase this value to 25%! https://github.com/QROkes/webinoly/issues/19 echo "tmpfs /run tmpfs nodev,nosuid,size=$(check_var run-folder-size)%,mode=755 0 0" >> /etc/fstab sudo mount -o remount tmpfs swap_create [[ -n $(conf_read timezone) ]] && set_timezone sudo systemctl daemon-reload [[ $(conf_read nginx) == "true" ]] && sudo systemctl restart nginx # We need to kill the process, don't use reload conf_write linux-optim true api-events_update in9 } linux_purge() { if [[ $(conf_read linux-optim) == "true" ]]; then api-events_update pn7 sudo rm -rf /etc/systemd/system/nginx.service.d sudo rm -rf /etc/sysctl.d/90-webinoly.conf sudo sed -i '/WebinolyStart/,/WebinolyEnd/{/.*/d}' /etc/security/limits.conf #sudo sysctl -p -q /etc/sysctl.d/90-webinoly.conf - reload all sysctl, webinoly file doesn't exist at this point! sudo service procps force-reload sudo sed -i '/\/run/d' /etc/fstab sudo mount -o remount tmpfs # Check in case of upgrading old stacks (before 1.14.0) when this service still not included if [[ -f /etc/systemd/system/webinoly-disable-thp.service ]]; then sudo systemctl stop webinoly-disable-thp sudo systemctl disable webinoly-disable-thp > /dev/null 2>&1 sudo rm /etc/systemd/system/webinoly-disable-thp.service fi [[ $recalculate == "on" ]] && swap_delete sudo systemctl daemon-reload # Never reload/restart nginx here! conf_write linux-optim purged api-events_update pn8 fi } nginx_install() { api-events_update in1 sudo apt -y install nginx [[ ! -d /var/www ]] && sudo mkdir /var/www [[ ! -d /etc/nginx/sites-available ]] && sudo mkdir /etc/nginx/sites-available [[ ! -d /etc/nginx/sites-enabled ]] && sudo mkdir /etc/nginx/sites-enabled [[ ! -d /etc/nginx/apps.d ]] && sudo mkdir /etc/nginx/apps.d # In reinstalation (after purge with keep-data) this file don't exist if [[ -f /etc/nginx/conf.d/default.conf ]]; then sudo sed -i 's/listen.*80;/listen 80 default_server;/' /etc/nginx/conf.d/default.conf sudo sed -i 's/listen.*\[::\]:80;/listen [::]:80 default_server;/' /etc/nginx/conf.d/default.conf sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/sites-available/default sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default fi sudo nginx -t && sudo systemctl start nginx sudo systemctl enable nginx conf_write nginx true echo "${gre}Nginx has been installed successfully! ${end}" api-events_update in2 } php_install() { api-events_update ip1 if [[ -n $(conf_read php-ver) && $(check_php_version $(conf_read php-ver)) == "true" ]]; then echo "${gre}PHP version '$(conf_read php-ver)' is set as default.${end}" else # Default PHP version conf_write php-ver $php_default fi local ver=$(conf_read php-ver) sudo apt -y install php${ver}-common php${ver}-cli php${ver}-fpm php${ver}-curl php${ver}-gd php${ver}-imap php${ver}-readline php${ver}-mysql php${ver}-mbstring php${ver}-bcmath php${ver}-mysql php${ver}-opcache php${ver}-zip php${ver}-xml php${ver}-soap php${ver}-imagick php${ver}-msgpack php${ver}-igbinary php${ver}-intl php-pear graphviz ghostscript conf_write php true api-events_update ip2 echo "${gre}PHP has been installed successfully! ${end}" } mysql_install() { api-events_update im1 echo "${gre}MySQL/MariaDB version '$(conf_read mysql-ver)' is set as default.${end}" # debconf-utils for unattended scripts # debconf-get-selections | grep phpmyadmin <<-- list conf variables # Generate mysql user passwords if [[ -z $(conf_read mysql-root) || -z $(conf_read mysql-admin) ]]; then local AUTOGENPASS_ROOT=`pwgen -s -1 16` local AUTOGENPASS_ADMIN=`pwgen -s -1 16` local enc_pass_root=$( echo $AUTOGENPASS_ROOT | openssl enc -a -salt ) local enc_pass_admin=$( echo $AUTOGENPASS_ADMIN | openssl enc -a -salt ) conf_write mysql-root $enc_pass_root conf_write mysql-admin $enc_pass_admin else # In case of re-installation after purge with keep-data option. local AUTOGENPASS_ROOT=$( echo $(conf_read mysql-root) | openssl enc -d -a -salt ) local AUTOGENPASS_ADMIN=$( echo $(conf_read mysql-admin) | openssl enc -d -a -salt ) local reinstall="true" fi # MySQL/MariaDB Installation if [[ $(conf_read db-engine) == "mysql" ]]; then echo "mysql-community-server mysql-community-server/root-pass password $AUTOGENPASS_ROOT" | debconf-set-selections echo "mysql-community-server mysql-community-server/re-root-pass password $AUTOGENPASS_ROOT" | debconf-set-selections echo "mysql-community-server mysql-server/default-auth-override select Use Strong Password Encryption (RECOMMENDED)" | debconf-set-selections sudo apt -y install mysql-server else local ver=$(conf_read mysql-ver) echo "mariadb-server-${ver} mysql-server/root_password password $AUTOGENPASS_ROOT" | debconf-set-selections echo "mariadb-server-${ver} mysql-server/root_password_again password $AUTOGENPASS_ROOT" | debconf-set-selections sudo apt -y install apt-transport-https dirmngr mariadb-server fi conf_write mysql true # MySQL/MariaDB login data (tmp) mysql_login_cnf echo "[client] user = root password = $AUTOGENPASS_ROOT host = localhost" >> $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly-login.cnf # https://mariadb.com/kb/en/mysql_upgrade/ # The mysql_upgrade client is deprecated in MySQL 8. (This process is done automatically) if [[ $reinstall == "true" && $(conf_read db-engine) != "mysql" ]]; then echo "${blu}${dim}Seems like you are reinstalling MySQL/MariaDB... Upgrading your old tables!${end}" sudo mysql_upgrade --user=root --force --silent fi #Instead of mysql_secure_installation we do this: (same but manually, because not acept unattended) sudo mysql --user=root <<_EOF_ DELETE FROM mysql.user WHERE User=''; DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1'); DROP DATABASE IF EXISTS test; DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'; CREATE USER IF NOT EXISTS 'admin'@'localhost' IDENTIFIED BY '${AUTOGENPASS_ADMIN}'; GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' WITH GRANT OPTION; FLUSH PRIVILEGES; _EOF_ sudo rm -rf $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly-login.cnf api-events_update im4 echo "${gre}MySQL/MariaDB has been installed successfully! ${end}" } mysql_client_install() { api-events_update im2 [[ $(conf_read db-engine) != "mysql" ]] && sudo apt -y install mariadb-client || sudo apt -y install mysql-client conf_write mysql-client true api-events_update im3 echo "${gre}MySQL/MariaDB Client has been successfully installed!${end}" } #NGINX OPTIM nginx_optim() { api-events_update in3 # Check if exists in case of server-reset [[ ! -f /opt/webinoly/templates/source/default ]] && sudo cp -p /etc/nginx/sites-available/default /opt/webinoly/templates/source/ [[ ! -f /opt/webinoly/templates/source/nginx.conf ]] && sudo cp -p /etc/nginx/nginx.conf /opt/webinoly/templates/source/ sudo chown -R www-data:www-data /var/www [[ $(conf_read login-www-data) == "true" ]] && sudo chown root:root /var/www if [[ ! -f /etc/ssl/dhparam.pem ]]; then sudo openssl dhparam -out /etc/ssl/dhparam.pem 2048 sudo chmod 600 /etc/ssl/dhparam.pem fi sudo cp -R /opt/webinoly/templates/nginx/common /etc/nginx/common sudo cp -R /opt/webinoly/templates/nginx/conf.d/* /etc/nginx/conf.d/ sudo cat /opt/webinoly/templates/nginx/nginx.conf > /etc/nginx/nginx.conf sudo sed -i "/client_max_body_size /c \ client_max_body_size $(check_var max-mb-uploads)m;" /etc/nginx/nginx.conf sudo sed -i "/worker_rlimit_core /c \worker_rlimit_core $fd_per_process;" /etc/nginx/nginx.conf sudo sed -i "/worker_rlimit_nofile /c \worker_rlimit_nofile $fd_per_process;" /etc/nginx/nginx.conf sudo sed -i "/open_file_cache max /c \ open_file_cache max=$(($fd_per_process/3)) inactive=5m;" /etc/nginx/nginx.conf # Locations sudo sed -i "s&&$(check_var locations-deny-extensions)&" /etc/nginx/common/locations.conf sudo sed -i "s##$(check_var locations-deny-files)#" /etc/nginx/common/locations.conf # WP Cache [[ $(check_var wpcache-query-strings) == "all" ]] && sudo sed -i '/# URL with a query string should always go to php/,/\} #End/{/.*/d}' /etc/nginx/common/wpfc.conf sudo sed -i "s##$(check_var wpcache-exclude-url)#" /etc/nginx/common/wpfc.conf sudo sed -i "s##$(check_var wpcache-exclude-cookie)#" /etc/nginx/common/wpfc.conf # Remove it, then add it again to prevent multiple # for each server-reset sudo sed -i '/ SERVER_NAME /s/#//' /etc/nginx/fastcgi_params sudo sed -i '/ SERVER_NAME /s/^/#/' /etc/nginx/fastcgi_params # Needed to prevent duplicates in server-reset, also in reinstallation (after purge with keep-data) sudo sed -i '/WebinolyCustom/,/WebinolyCustomEnd/{/.*/d}' /etc/nginx/fastcgi_params echo '# WebinolyCustom fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_param SERVER_NAME $host; fastcgi_param HTTP_HOST $http_host; fastcgi_param HTTP_PROXY ""; fastcgi_param HTTP_ACCEPT_ENCODING ""; # WebinolyCustomEnd' >> /etc/nginx/fastcgi_params # FastCGI Cache size: We take 90% of /run folder size! https://github.com/QROkes/webinoly/issues/19 sudo sed -i "/fastcgi_cache_path/c \fastcgi_cache_path /run/nginx-cache levels=1:2 keys_zone=WORDPRESS:50m max_size=$(((9*$ramb*$(check_var run-folder-size))/1000))m inactive=7d;" /etc/nginx/conf.d/fastcgi.conf sudo sed -i "/fastcgi_read_timeout/c \fastcgi_read_timeout $(check_var php-max-time)s;" /etc/nginx/conf.d/fastcgi.conf # www-data sftp default uploads permissions 755 and 644, instead of 775 and 664. sudo sed -i '/USERGROUPS_ENAB/c \USERGROUPS_ENAB no' /etc/login.defs # Check for dynamic variables. sudo systemctl restart nginx # We need to kill the process, don't use reload (I don't know why here, but it's needed!) [[ -n $(conf_read default-response) ]] && sudo webinoly -default-site=$(conf_read default-response) [[ -n $(conf_read tools-port-set) ]] && sudo webinoly -tools-port=$(conf_read tools-port-set) [[ -n $(conf_read tools-site) ]] && sudo webinoly -tools-site=$(conf_read tools-site) [[ $(conf_read global-access-log-off) =~ ^(false|purged)$ ]] && sudo log -only-error=off || sudo log -only-error=on [[ -n $(conf_read fastcgi-conf) ]] && sudo webinoly -cache-valid=[$(conf_read fastcgi-conf)] [[ -n $(conf_read auth-whitelist-ip) ]] && sudo httpauth -whitelist=$(conf_read auth-whitelist-ip) [[ -n $(conf_read blockip) ]] && sudo webinoly -blockip=$(conf_read blockip) [[ $(conf_read sftp-www-data) == "true" ]] && sudo webinoly -login-www-data=on [[ $(conf_read sftp-www-data) == "false" ]] && sudo webinoly -login-www-data=off http_header_referrer http_header_hsts http_header_cache_control http_header_csp http_header_permissions_policy http_header_robots http_header_xssp http_header_xcto http_header_xfo [[ $(conf_read header-custom) == "true" ]] && sudo webinoly -custom-headers=reload if [[ $(conf_read xmlrpc) =~ ^(blocked|limited|open)$ ]]; then if [[ $(conf_read xmlrpc) != "limited" ]]; then sudo sed -i '/WPxmlrpcStart/,/WPxmlrpcEnd/{/.*/d}' /etc/nginx/common/wpcommon.conf sudo sed -i '/WPxmlrpcStart/,/WPxmlrpcEnd/{/.*/d}' /etc/nginx/common/wpcommon-noauth.conf fi if [[ $(conf_read xmlrpc) == "blocked" ]]; then echo "# WPxmlrpcStart location = /xmlrpc.php { return 403; } # WPxmlrpcEnd" >> /etc/nginx/common/wpcommon.conf echo "# WPxmlrpcStart location = /xmlrpc.php { return 403; } # WPxmlrpcEnd" >> /etc/nginx/common/wpcommon-noauth.conf fi echo "${gre}WordPress XMLRPC successfully configured!${dim} ($(conf_read xmlrpc))${end}" fi # Create Direct Access for easy navigation if [[ ! -L $CURRENT_HOME/sites-available ]]; then ln -s /etc/nginx/sites-available $CURRENT_HOME sudo chown -h ${CURRENT_USER}:${CURRENT_USER} $CURRENT_HOME/sites-available fi if [[ ! -L $CURRENT_HOME/www ]]; then ln -s /var/www $CURRENT_HOME sudo chown -h ${CURRENT_USER}:${CURRENT_USER} $CURRENT_HOME/www fi conf_write server-version $svr_version conf_write nginx-optim true sudo systemctl reload nginx api-events_update in10 echo "${gre}Nginx has been successfully Optimized by Webinoly! ${end}" } # PHP OPTIM php_optim() { api-events_update ip3 # Check if exist in case of server-reset local ver=$(conf_read php-ver) [[ ! -f /opt/webinoly/templates/source/php.ini ]] && sudo cp -p /etc/php/${ver}/fpm/php.ini /opt/webinoly/templates/source/ [[ ! -f /opt/webinoly/templates/source/www.conf ]] && sudo cp -p /etc/php/${ver}/fpm/pool.d/www.conf /opt/webinoly/templates/source/ [[ ! -f /opt/webinoly/templates/source/php-fpm.conf ]] && sudo cp -p /etc/php/${ver}/fpm/php-fpm.conf /opt/webinoly/templates/source/ sudo sed -i -r "/^[;]?max_execution_time =/c\max_execution_time = $(check_var php-max-time)" /etc/php/$ver/fpm/php.ini sudo sed -i -r '/^[;]?session.cookie_httponly =/c\session.cookie_httponly = 1' /etc/php/$ver/fpm/php.ini sudo sed -i -r '/^[;]?expose_php =/c\expose_php = Off' /etc/php/$ver/fpm/php.ini # post_max must be a little larger and memory a little more larger - https://www.php.net/manual/en/ini.core.php#ini.post-max-size sudo sed -i -r "/^[;]?upload_max_filesize =/c\upload_max_filesize = $(check_var max-mb-uploads)M" /etc/php/$ver/fpm/php.ini sudo sed -i -r "/^[;]?post_max_size =/c\post_max_size = $(($(check_var max-mb-uploads)+1))M" /etc/php/$ver/fpm/php.ini sudo sed -i -r "/^[;]?max_file_uploads =/c\max_file_uploads = $(check_var php-max-files)" /etc/php/$ver/fpm/php.ini [[ $(check_var php-max-mem) -gt $(($(check_var max-mb-uploads)+1)) ]] && local phpmem=$(check_var php-max-mem) || local phpmem=$(($(check_var max-mb-uploads)+10)) sudo sed -i -r "/^[;]?memory_limit =/c\memory_limit = ${phpmem}M" /etc/php/$ver/fpm/php.ini sudo sed -i -r "/^[;]?max_input_vars =/c\max_input_vars = $(check_var php-max-input-vars)" /etc/php/$ver/fpm/php.ini sudo sed -i -r "/^[;]?opcache.memory_consumption=/c\opcache.memory_consumption=$(check_var php-max-mem)" /etc/php/$ver/fpm/php.ini sudo sed -i -r '/^[;]?opcache.interned_strings_buffer=/c\opcache.interned_strings_buffer=16' /etc/php/$ver/fpm/php.ini sudo sed -i -r '/^[;]?opcache.max_accelerated_files=/c\opcache.max_accelerated_files=100000' /etc/php/$ver/fpm/php.ini sudo sed -i -r '/^[;]?opcache.max_wasted_percentage=/c\opcache.max_wasted_percentage=10' /etc/php/$ver/fpm/php.ini sudo sed -i -r '/^[;]?opcache.enable_cli=/c\opcache.enable_cli=1' /etc/php/$ver/fpm/php.ini sudo sed -i -r '/^[;]?opcache.enable=/c\opcache.enable=1' /etc/php/$ver/fpm/php.ini # Not set, unless non-empty! if [[ $(check_var php-opcache-timestamps) != "false" ]]; then sudo sed -i -r "/^[;]?opcache.validate_timestamps=/c\opcache.validate_timestamps=$(check_var php-opcache-timestamps)" /etc/php/$ver/fpm/php.ini fi if [[ $(check_var php-opcache-reval) != "false" ]]; then sudo sed -i -r "/^[;]?opcache.revalidate_freq=/c\opcache.revalidate_freq=$(check_var php-opcache-reval)" /etc/php/$ver/fpm/php.ini fi [[ -n $(conf_read timezone) ]] && set_timezone sudo sed -i -r "/^[;]?pm =/c\pm = $(check_var php-pm)" /etc/php/$ver/fpm/pool.d/www.conf sudo sed -i -r "/^[;]?pm.max_children =/c\pm.max_children = $(check_var php-max-child)" /etc/php/$ver/fpm/pool.d/www.conf sudo sed -i -r "/^[;]?pm.start_servers =/c\pm.start_servers = $(($(check_var php-max-child)/3))" /etc/php/$ver/fpm/pool.d/www.conf sudo sed -i -r "/^[;]?pm.min_spare_servers =/c\pm.min_spare_servers = $(($(check_var php-max-child)/3))" /etc/php/$ver/fpm/pool.d/www.conf sudo sed -i -r "/^[;]?pm.max_spare_servers =/c\pm.max_spare_servers = $((2*($(check_var php-max-child)/3)))" /etc/php/$ver/fpm/pool.d/www.conf sudo sed -i -r "/^[;]?request_terminate_timeout =/c\request_terminate_timeout = $(check_var php-max-time)" /etc/php/$ver/fpm/pool.d/www.conf sudo sed -i -r '/^[;]?pm.max_requests =/c\pm.max_requests = 1000' /etc/php/$ver/fpm/pool.d/www.conf sudo sed -i -r '/^[;]?pm.status_path =/c\pm.status_path = /status' /etc/php/$ver/fpm/pool.d/www.conf sudo sed -i -r '/^[;]?ping.path =/c\ping.path = /ping' /etc/php/$ver/fpm/pool.d/www.conf sudo sed -i -r '/^[;]?listen = /c\listen = 127.0.0.1:9000' /etc/php/$ver/fpm/pool.d/www.conf sudo sed -i -r '/^[;]?listen.allowed_clients = /c\listen.allowed_clients = 127.0.0.1' /etc/php/$ver/fpm/pool.d/www.conf [[ $(conf_read php-tool-redis) == "true" && -n $(conf_read redis-max-mem) ]] && redis_optim conf_write php-optim true sudo systemctl restart php${ver}-fpm api-events_update ip4 echo "${gre}PHP has been successfully Optimized by Webinoly! ${end}" } # MySQL/MariaDB OPTIM mysql_optim() { api-events_update im5 mysql_default_cnf # MySQL/MariaDB login data mysql_login_cnf if [[ -n $(conf_read mysql-admin) ]]; then sudo sed -i '/\[client\]/,/# ClientEnd/{/.*/d}' $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly-login.cnf echo "[client] user = admin password = $( echo $(conf_read mysql-admin) | openssl enc -d -a -salt ) host = localhost # ClientEnd" >> $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly-login.cnf fi # If value is empty we will do nothing, to prevent undesired things (before 1.17.1 these dynvars were not used via command only conf file, now are both). [[ $(conf_read mysql-log-binary) == "true" ]] && sudo log -mysql=binary -enable [[ $(conf_read mysql-log-binary) == "false" ]] && sudo log -mysql=binary -disable [[ $(conf_read mysql-log-general) == "true" ]] && sudo log -mysql=general -enable [[ $(conf_read mysql-log-general) == "false" ]] && sudo log -mysql=general -disable [[ $(conf_read mysql-log-slow) == "true" && -z $(conf_read mysql-long-query-time) ]] && sudo log -mysql=slow -enable [[ $(conf_read mysql-log-slow) == "true" && -n $(conf_read mysql-long-query-time) ]] && sudo log -mysql=slow -enable -long-query-time=$(conf_read mysql-long-query-time) [[ $(conf_read mysql-log-slow) == "false" ]] && sudo log -mysql=slow -disable [[ $(conf_read mysql-public-access) == "true" ]] && sudo webinoly -mysql-public-access=on [[ $(conf_read mysql-public-access) == "false" ]] && sudo webinoly -mysql-public-access=off conf_write mysql-optim true api-events_update im6 echo "${gre}MySQL/MariaDB has been successfully Optimized by Webinoly! ${end}" } nginx_tool_site() { # Tools site creation [[ -z $(conf_read tools-port) ]] && conf_write tools-port $tools_port_default # Don't overwrite in case that exist (after purge with keep-data, for instance) if [[ ! -f /etc/nginx/sites-available/$ADMIN_TOOLS_SITE ]]; then sudo site $ADMIN_TOOLS_SITE -empty > /dev/null 2>&1 sudo cp /opt/webinoly/templates/general/admin_tools.conf /etc/nginx/sites-available/$ADMIN_TOOLS_SITE sudo sed -i "s//$(conf_read tools-port)/g" /etc/nginx/sites-available/$ADMIN_TOOLS_SITE sudo sed -i "s//$ADMIN_TOOLS_SITE/g" /etc/nginx/sites-available/$ADMIN_TOOLS_SITE sudo nginx -t && sudo systemctl reload nginx fi # Don't overwrite in case that exist (after purge with keep-data, for instance) if [[ ! -f /var/www/$ADMIN_TOOLS_SITE/htdocs ]]; then # Nginx Status Page sudo touch /var/www/$ADMIN_TOOLS_SITE/htdocs/nginx_status # Robots.txt file in case someone remove HTTP Auth sudo touch /var/www/$ADMIN_TOOLS_SITE/htdocs/robots.txt echo '# Just in case someone remove HTTP Auth protection. Disallow: /' > /var/www/$ADMIN_TOOLS_SITE/htdocs/robots.txt sudo chmod 644 /var/www/$ADMIN_TOOLS_SITE/htdocs/robots.txt sudo chown -R www-data:www-data /var/www/$ADMIN_TOOLS_SITE/htdocs fi # in case php was installed before nginx [[ $(conf_read php) == "true" && ! -f /var/www/$ADMIN_TOOLS_SITE/htdocs/php/index.php ]] && php_tool_site } php_tool_site() { [[ $(conf_read nginx) != "true" ]] && return # Just for legacy support when tools site were created only with PHP support, today is created since Nginx always. [[ ! -f /etc/nginx/sites-available/$ADMIN_TOOLS_SITE ]] && nginx_tool_site # Add PHP options in tools site. # Status pages sudo touch /var/www/$ADMIN_TOOLS_SITE/htdocs/ping sudo touch /var/www/$ADMIN_TOOLS_SITE/htdocs/status #PHP info site sudo mkdir -p /var/www/$ADMIN_TOOLS_SITE/htdocs/php sudo touch /var/www/$ADMIN_TOOLS_SITE/htdocs/php/index.php sudo echo '' >> /var/www/$ADMIN_TOOLS_SITE/htdocs/php/index.php sudo chown -R www-data:www-data /var/www/$ADMIN_TOOLS_SITE/htdocs } nginx_tool_ssl() { api-events_update in11 # Install LetsEncrypt local certb=0 while [[ $certb -le 3 ]] do sudo snap install --classic certbot # SNAP Repo fails a lot, so we need to be sure and retry!!! if [[ ! -f /snap/bin/certbot ]]; then local certb=$(($certb+1)) [[ $certb -le 3 ]] && echo "${red}[ERROR] Certbot installation failed!${dim} We will retry in a moment...($(($certb*30))s)${end}" [[ $certb -gt 3 ]] && echo "${red}[ERROR] Fatal Error: Certbot cannot be installed after 3 retries!${end}" || sleep $(($certb*20)) else break fi done [[ ! -L /usr/bin/certbot ]] && sudo ln -s /snap/bin/certbot /usr/bin/certbot conf_write nginx-tool-ssl true api-events_update in12 echo "${gre}Let's Encrypt (certbot) has been installed successfully! ${end}" } nginx_tool_bkp() { api-events_update in13 # Instalar Duply & Duplicity with S3 support # Now there is an Official PPA: https://launchpad.net/~duplicity-team/+archive/ubuntu/duplicity-release-git # We removed SNAP because they removed ARM support, also they are having a lot of issues, they are mentioned they are considering removing snap support. # https://gitlab.com/duplicity/duplicity/-/issues # Minimum required, most of them are already installed by default, but we need to be sure: https://gitlab.com/duplicity/duplicity/-/blob/master/debian/control # Also needed: python3-pip # Backend for S3: python3-boto3 sudo apt install -y debhelper dh-python python3 gnupg librsync-dev par2 pep8 pylint python3-pytest python3-pytest-cov python3-pytest-runner python3-dev python3-fasteners python3-future python3-mock python3-pexpect python3-setuptools python3-setuptools-scm rdiff rename rsync python3-pip python3-boto3 # Duplicity installation directly from source # Temporal fix to remove warning - wait for: https://github.com/pypa/pip/issues/10556 - remove from stack purge too! --root-user-action=ignore | Remove from update function also sudo pip3 install duplicity 2>&1 | grep -v "pip as the 'root' user" # In future, we need to do the correct way - using virtual env #sudo apt install python3-venv #sudo python3 -m venv /opt/duplicity/ #sudo /opt/duplicity/bin/pip install --upgrade pip #sudo /opt/duplicity/bin/pip install duplicity #sudo ln -s /opt/duplicity/bin/duplicity /usr/bin/duplicity # https://sourceforge.net/projects/ftplicity/files/duply%20%28simple%20duplicity%29/ sudo cp /opt/webinoly/templates/general/duply /usr/bin/ sudo chmod 755 /usr/bin/duply conf_write nginx-tool-bkp true api-events_update in14 echo "${gre}BackUp packages has been installed successfully! ${end}" } php_tool_postfix() { api-events_update ip5 # Postfix mail echo "postfix postfix/main_mailer_type select Internet Site" | debconf-set-selections echo "postfix postfix/mailname string $hostname" | debconf-set-selections sudo apt -y install postfix sudo cp -p /etc/postfix/main.cf /opt/webinoly/templates/source/ sudo sed -i '/mydestination =/c \mydestination = localhost' /etc/postfix/main.cf sudo sed -i '/smtpd_banner =/c \smtpd_banner = $myhostname ESMTP' /etc/postfix/main.cf # https://cisofy.com/lynis/controls/MAIL-8818/ sudo systemctl reload postfix conf_write php-tool-postfix true api-events_update ip6 echo "${gre}Postfix has been installed successfully! ${end}" } redis_optim() { local maxmem=$((($(grep MemTotal /proc/meminfo | cut -f 2 -d ':' | tr -d ' ' | cut -f 1 -d 'k')*$(check_var redis-max-mem))/100000)) sudo sed -i "/# maxmemory /c\maxmemory ${maxmem}mb" /etc/redis/redis.conf sudo sed -i "/^maxmemory /c\maxmemory ${maxmem}mb" /etc/redis/redis.conf sudo sed -i "/# maxmemory-policy/c\maxmemory-policy allkeys-lfu" /etc/redis/redis.conf sudo systemctl restart redis-server } php_tool_redis() { api-events_update ip7 local ver=$(conf_read php-ver) # Redis (Object Cache) sudo apt -y install redis-server php${ver}-redis redis_optim sudo systemctl enable redis-server conf_write php-tool-redis true api-events_update ip8 echo "${gre}Redis has been installed successfully! ${end}" } php_tool_memcached() { api-events_update ip9 local ver=$(conf_read php-ver) # Memcached (Object Cache) sudo apt -y install php${ver}-memcached php${ver}-memcache memcached conf_write php-tool-memcached true api-events_update ip10 echo "${gre}Memcached has been installed successfully! ${end}" } mysql_tool_pma() { api-events_update im7 echo "${blu}${dim}Downloading phpMyAdmin...${end}" sudo mkdir -p /var/www/$ADMIN_TOOLS_SITE/htdocs/pma sudo wget --timeout=15 -t 1 -qrO /var/www/$ADMIN_TOOLS_SITE/htdocs/pma.tar.xz https://www.phpmyadmin.net/downloads/phpMyAdmin-latest-all-languages.tar.xz if [[ -s /var/www/$ADMIN_TOOLS_SITE/htdocs/pma.tar.xz ]]; then sudo tar -xf /var/www/$ADMIN_TOOLS_SITE/htdocs/pma.tar.xz -C /var/www/$ADMIN_TOOLS_SITE/htdocs/pma sudo mv /var/www/$ADMIN_TOOLS_SITE/htdocs/pma/phpMyAdmin-*-all-languages/* /var/www/$ADMIN_TOOLS_SITE/htdocs/pma/ sudo rm -rf /var/www/$ADMIN_TOOLS_SITE/htdocs/pma/phpMyAdmin-*-all-languages sudo rm -rf /var/www/$ADMIN_TOOLS_SITE/htdocs/pma/test sudo rm -rf /var/www/$ADMIN_TOOLS_SITE/htdocs/pma/setup sudo rm /var/www/$ADMIN_TOOLS_SITE/htdocs/pma.tar.xz sudo cp /var/www/$ADMIN_TOOLS_SITE/htdocs/pma/config.sample.inc.php /var/www/$ADMIN_TOOLS_SITE/htdocs/pma/config.inc.php sudo sed -i "/blowfish_secret/c \$cfg['blowfish_secret'] = '$(pwgen -s -1 32)';" /var/www/$ADMIN_TOOLS_SITE/htdocs/pma/config.inc.php sudo chown -R www-data:www-data /var/www/$ADMIN_TOOLS_SITE/htdocs/pma sudo find /var/www/$ADMIN_TOOLS_SITE/htdocs/pma -type f -print0 | sudo xargs -r -0 chmod 644 sudo find /var/www/$ADMIN_TOOLS_SITE/htdocs/pma -type d -print0 | sudo xargs -r -0 chmod 755 conf_write mysql-tool-pma true echo "${gre}phpMyAdmin has been installed successfully! ${end}" else echo "${red}[ERROR] Downloading phpMyAdmin failed!${end}" fi api-events_update im8 } set_timezone() { if [[ -n $(conf_read timezone) ]] && grep -Fxq $(conf_read timezone) /opt/webinoly/lib/timezone.dat; then sudo timedatectl set-timezone $(conf_read timezone) if [[ $(conf_read php) == "true" ]]; then sudo sed -i "/date.timezone =/c\date.timezone = $(conf_read timezone)" /etc/php/$(conf_read php-ver)/fpm/php.ini # Don't reload if running inside php-optim process. [[ $(conf_read status-api) != "ip3" ]] && sudo systemctl reload php$(conf_read php-ver)-fpm fi sudo systemctl restart cron echo "${gre}Timezone has been successfully set!${dim} ($(conf_read timezone)) ${end}" else echo "${red}Timezone not found or not valid!${end}" return 1 fi } swap_delete() { if [[ -n $swap && $swap =~ ^[0-9]+$ && $(conf_read swap-owner) == "webinoly" ]]; then api-events_update pn9 sudo swapoff -a -v && sudo rm -rf /swapfile if [[ ! -f /swapfile ]]; then sudo sed -i '/\/swapfile/d' /etc/fstab conf_write swap-owner purged api-events_update pn10 else echo "${dim}SWAP file is busy or can't be removed!${end}" fi fi } swap_create() { # Need a fresh value here, not use the global var. local sw=$(($(grep SwapTotal /proc/meminfo | cut -f 2 -d ':' | tr -d ' ' | cut -f 1 -d 'k')/1024000)) # https://help.ubuntu.com/community/SwapFaq if [[ -z $sw || $sw == "0" ]]; then api-events_update in7 if [[ -n $(conf_read swap-mem) && $(conf_read swap-mem) =~ ^[0-9]+$ ]]; then local newswap=$(conf_read swap-mem) elif [[ $ram -le 2 ]]; then local newswap="1" elif [[ $ram -le 6 ]]; then local newswap="2" elif [[ $ram -le 12 ]]; then local newswap="3" elif [[ $ram -le 16 ]]; then local newswap="4" elif [[ $ram -le 24 ]]; then local newswap="5" elif [[ $ram -le 32 ]]; then local newswap="6" elif [[ $ram -le 64 ]]; then local newswap="8" elif [[ $ram -le 128 ]]; then local newswap="11" elif [[ $ram -le 256 ]]; then local newswap="16" elif [[ $ram -le 512 ]]; then local newswap="23" elif [[ $ram -le 1024 ]]; then local newswap="32" elif [[ $ram -le 2048 ]]; then local newswap="46" elif [[ $ram -le 4096 ]]; then local newswap="64" elif [[ $ram -le 8192 ]]; then local newswap="91" elif [[ $ram -gt 8192 ]]; then local newswap="100" else local newswap="0" fi # Check if disk available space is enough! local avail=$(df -hBG --output=avail / | grep -Eo "[0-9]+" | head -n 1) if [[ -n $avail && -n $newswap && $(($newswap+1)) -ge $avail ]]; then echo "${red}[ERROR] No disk space available for SWAP!${dim} (Needed: ${newswap}Gb Available: ${avail}Gb ) ${end}" local newswap="0" else echo "${blu}${dim}Swap size: ${newswap}Gb (Available: ${avail}Gb) ${end}" fi if [[ -z $newswap || $newswap == 0 ]]; then echo "${red}[ERROR] Webinoly could not create a new SWAP file! ${end}" else # Create SWAP Partition sudo dd if=/dev/zero of=/swapfile bs=${newswap}M count=1024 sudo echo "/swapfile none swap sw 0 0" >> /etc/fstab sudo chown root:root /swapfile sudo chmod 0600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile conf_write swap-owner webinoly echo "${gre}A new SWAP file (${newswap}Gb) has been created! ${end}" fi api-events_update in8 elif [[ -n $sw && $sw =~ ^[0-9]+$ ]]; then [[ $(conf_read swap-owner) != "webinoly" ]] && conf_write swap-owner system echo "${gre}SWAP file (${sw}Gb) detected!${end}" else echo "${red}[ERROR] Unexpected error while trying to read your SWAP file!${end}" fi } messagend_install() { local ROOT_PW=$( echo $(conf_read mysql-root) | openssl enc -d -a -salt ) local ADMIN_PW=$( echo $(conf_read mysql-admin) | openssl enc -d -a -salt ) echo "" echo "${gre}" echo "****************************************************************************" echo "******${bol} INSTALLATION HAS FINISHED SUCCESSFULLY ${end}${gre}******" echo "****************************************************************************" echo "******** Save your DB access password in a secure place: ********" echo "******${dim} root: ${ROOT_PW} admin: ${ADMIN_PW} ${end}${gre}******" echo "****************************************************************************" echo "${blu}Never change these passwords! Read:${end}${dim} https://webinoly.com/documentation/webinolys/#dbpass" echo "${end}" } message_welcome() { echo "${blu}" echo "***************************************************************" echo "***************** ${bol}Welcome to Webinoly ${end}${blu}*********************" echo "********** ${dim}Stack Builder & Configuration Manager ${end}${blu}**********" echo "***************************************************************" if [[ $1 =~ ^(full|basic|light|partial)$ ]]; then echo "${dim} - - - - - - - - - - - - ${end}${blu}" echo "" [[ $1 == "full" ]] && echo "Build Profile: ${dim}Full Stack (Nginx, PHP, MySQL/MariaDB and ALL the additional tools)" [[ $1 == "basic" ]] && echo "Build Profile: ${dim}Basic Stack (Only the most essential tools)" [[ $1 == "light" ]] && echo "Build Profile: ${dim}Light Stack (Only core packages, NO additional tools will be installed)" [[ $1 == "partial" ]] && echo "Build Profile: ${dim}Partial Stack" fi echo "${end}" } stack_builder() { # Example: stack_builder nginx php mysql # Example: stack_builder nginx false false # Example: stack_builder false false mysql-client # Example: stack_builder - just update and install pre-packs # Prevent asking for restaring services when installing packages. if [[ -f /etc/needrestart/needrestart.conf && ! -f /etc/needrestart/conf.d/webinoly.conf ]]; then sudo touch /etc/needrestart/conf.d/webinoly.conf echo "\$nrconf{restart} = 'a';" >> /etc/needrestart/conf.d/webinoly.conf fi # Backups can be installed alone... [[ $4 == "letsencrypt" || $4 == "pma" ]] && check_for_nginx -ask [[ $4 == "postfix" || $4 == "redis" || $4 == "memcached" || $4 == "pma" ]] && check_for_php -ask [[ $4 == "pma" ]] && check_for_mysql -ask && local code=0 # Check for missing essential packages if [[ $(conf_read pre-packs) != true ]]; then # Set Welcome Message [[ -n $4 ]] && local mess=$4 || local mess="partial" # We trust in build variable validation [[ -n $lemp && -z $4 ]] && local mess="full" message_welcome $mess # Any action run after the meesage is displayed! api-events_update i1 sudo apt -qq update # Usually comes by default with Ubuntu. Ensure we have it always! (software-properties-common debconf-utils zip) # Webinoly tools (pwgen unzip) # Fix issue installing in some Digital Ocean droplets (dialog) sudo apt -y -qq install software-properties-common debconf-utils zip pwgen unzip dialog # Snap is installed by default since 16.04, but better be sure! sudo snap install core sudo snap refresh core linux_optim conf_write pre-packs true api-events_update i2 fi # PPA's if [[ $1 == "nginx" && $(conf_read nginx) != "true" ]]; then [[ $nginx =~ ^(stable|mainline)$ ]] && conf_write nginx-ppa $nginx [[ $lemp =~ ^(stable|mainline)$ ]] && conf_write nginx-ppa $lemp if [[ $(lsb_release -c | cut -d':' -f 2 | xargs) =~ ^(bionic|focal)$ ]]; then sudo apt-key adv --fetch-keys 'https://nginx.org/keys/nginx_signing.key' if [[ $(conf_read nginx-ppa) == "mainline" ]]; then echo | sudo add-apt-repository "deb https://nginx.org/packages/mainline/ubuntu/ $(check_osname) nginx" else echo | sudo add-apt-repository "deb https://nginx.org/packages/ubuntu/ $(check_osname) nginx" fi else [[ ! -s /usr/share/keyrings/nginx-archive-keyring.gpg ]] && sudo rm -rf /usr/share/keyrings/nginx-archive-keyring.gpg # Prevent issues! [[ ! -f /usr/share/keyrings/nginx-archive-keyring.gpg ]] && wget -nv -O- https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg if [[ $(conf_read nginx-ppa) == "mainline" ]]; then echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://nginx.org/packages/mainline/ubuntu/ $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list else echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://nginx.org/packages/ubuntu/ $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list fi fi local code="run" elif [[ $1 == "nginx" ]]; then echo "${dim}Nginx is already installed!${end}" local code=0 fi if [[ $2 == "php" && $(conf_read php) != "true" ]]; then if [[ $(lsb_release -c | cut -d':' -f 2 | xargs) =~ ^(bionic|focal)$ ]]; then # Fix ondrej issue - https://github.com/oerdnj/deb.sury.org/issues/56 #sudo apt install -y language-pack-en-base sudo LC_ALL=C.UTF-8 add-apt-repository -y ppa:ondrej/php else [[ ! -s /usr/share/keyrings/php-archive-keyring.gpg ]] && sudo rm -rf /usr/share/keyrings/php-archive-keyring.gpg # Prevent issues! [[ ! -f /usr/share/keyrings/php-archive-keyring.gpg ]] && wget -nv -O- 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c' | sudo gpg --dearmor -o /usr/share/keyrings/php-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/php-archive-keyring.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/php.list fi local code="run" elif [[ $2 == "php" ]]; then echo "${dim}PHP is already installed!${end}" [[ $code != "run" ]] && local code=0 fi if [[ ( $2 == "php" || $4 == "redis" ) && $(conf_read php-tool-redis) != "true" ]] && ! [[ $4 =~ ^(light|basic)$ ]]; then if [[ $(lsb_release -c | cut -d':' -f 2 | xargs) =~ ^(bionic|focal)$ ]]; then # Now there is an Official PPA: https://github.com/redis/redis-debian - https://launchpad.net/~redislabs/+archive/ubuntu/redis # Snap is available but it has no support for ARM architecture: https://snapcraft.io/redis echo | sudo add-apt-repository ppa:redislabs/redis else [[ ! -s /usr/share/keyrings/redis-archive-keyring.gpg ]] && sudo rm -rf /usr/share/keyrings/redis-archive-keyring.gpg # Prevent issues! [[ ! -f /usr/share/keyrings/redis-archive-keyring.gpg ]] && wget -nv -O- https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list fi local code="run" fi if [[ $3 =~ ^(mysql|mysql-client)$ && $(conf_read mysql-client) != "true" ]]; then if [[ -n $(conf_read mysql-ver) && $(check_mysql_version $(conf_read mysql-ver)) == "true" ]]; then echo "${blu}Retrieving a saved MySQL/MariaDB version configured before...${dim}${end}" else echo "${blu}Setting the default MySQL/MariaDB version...${dim}${end}" [[ $(conf_read db-engine) == "mysql" ]] && conf_write mysql-ver $mysql_default || conf_write mysql-ver $mariadb_default fi # REMOVE: when a new LTS is released and jammy supports more than one version. if [[ $(conf_read db-engine) != "mysql" && $(conf_read mysql-ver) != "10.6" && $(lsb_release -c | cut -d':' -f 2 | xargs) == "jammy" ]]; then conf_write mysql-ver 10.6 echo "${gre}Force MariaDB 10.6 because is the only LTS version supported in Ubuntu 22.04!${end}" fi if [[ $(conf_read db-engine) == "mysql" ]]; then [[ ! -s /usr/share/keyrings/mysql-archive-keyring.gpg ]] && sudo rm -rf /usr/share/keyrings/mysql-archive-keyring.gpg # Prevent issues! [[ ! -f /usr/share/keyrings/mysql-archive-keyring.gpg ]] && wget -nv -O- 'https://repo.mysql.com/RPM-GPG-KEY-mysql-2022' | sudo gpg --dearmor -o /usr/share/keyrings/mysql-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/mysql-archive-keyring.gpg] http://repo.mysql.com/apt/ubuntu $(lsb_release -cs) mysql-8.0" | sudo tee /etc/apt/sources.list.d/mysql.list # https://mariadb.org/download/?t=repo-config elif [[ $(lsb_release -c | cut -d':' -f 2 | xargs) =~ ^(bionic|focal)$ ]]; then sudo apt-key adv --fetch-keys 'https://mariadb.org/mariadb_release_signing_key.asc' echo | sudo add-apt-repository "deb [arch=amd64,arm64,ppc64el] http://mirrors.syringanetworks.net/mariadb/repo/$(conf_read mysql-ver)/ubuntu $(check_osname) main" else [[ ! -s /usr/share/keyrings/mariadb-archive-keyring.gpg ]] && sudo rm -rf /usr/share/keyrings/mariadb-archive-keyring.gpg # Prevent issues! [[ ! -f /usr/share/keyrings/mariadb-archive-keyring.gpg ]] && wget -nv -O- 'https://mariadb.org/mariadb_release_signing_key.asc' | sudo gpg --dearmor -o /usr/share/keyrings/mariadb-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/mariadb-archive-keyring.gpg] http://mirrors.syringanetworks.net/mariadb/repo/$(conf_read mysql-ver)/ubuntu $(check_osname) main" | sudo tee /etc/apt/sources.list.d/mariadb.list fi local code="run" elif [[ $3 == "mysql-client" && $(conf_read mysql-client) == "true" ]]; then echo "${dim}MySQL/MariaDB Client is already installed!${end}" [[ $code != "run" ]] && local code=0 elif [[ $3 == "mysql" && $(conf_read mysql) == "true" ]]; then echo "${dim}MySQL/MariaDB is already installed!${end}" [[ $code != "run" ]] && local code=0 elif [[ $3 == "mysql" && $(conf_read mysql-client) == "true" ]]; then echo "${dim}MySQL/MariaDB Client is already installed!${end}" local code="run" fi # Exit before update! # Don't run the "update" if nothing will be installed! # This validation only runs when core package is already instaled, so we need to check if a tool will be installed. # We need this validation, because for example, LEMP can install additional tools when main package is already installed. if [[ $code == 0 && $4 != "light" ]]; then [[ ( $1 == "nginx" || $4 == "letsencrypt" ) && $(conf_read nginx) == "true" && $(conf_read nginx-tool-ssl) != "true" ]] && unset code [[ ( $1 == "nginx" || $4 == "backups" ) && $(conf_read nginx-tool-bkp) != "true" ]] && unset code # Backups doesn't need nginx, can be installed alone! [[ ( $2 == "php" || $4 == "postfix" ) && $(conf_read php) == "true" && $(conf_read php-tool-postfix) != "true" ]] && unset code if [[ $4 != "basic" ]]; then #[[ ( $2 == "php" || $4 == "redis" ) && $(conf_read php) == "true" && $(conf_read php-tool-redis) != "true" ]] && unset code # Unset in PPA [[ ( $2 == "php" || $4 == "memcached" ) && $(conf_read php) == "true" && $(conf_read php-tool-memcached) != "true" ]] && unset code [[ -n $code && ( $3 == "mysql" || $4 == "pma" ) && $(conf_read mysql) == "true" && $(conf_read mysql-tool-pma) != "true" ]] && local code="noupd" fi fi if [[ $code != 0 ]]; then # PMA doesn't need update! [[ $code != "noupd" ]] && sudo apt -qq update # Install Packages! [[ $1 == "nginx" && $(conf_read nginx) != "true" ]] && nginx_install && nginx_optim && nginx_tool_site [[ ( $1 == "nginx" || $4 == "letsencrypt" ) && $(conf_read nginx) == "true" && $(conf_read nginx-tool-ssl) != "true" && $4 != "light" ]] && nginx_tool_ssl [[ ( $1 == "nginx" || $4 == "backups" ) && $(conf_read nginx-tool-bkp) != "true" && $4 != "light" ]] && nginx_tool_bkp # Backups doesn't need nginx, can be installed alone! [[ $2 == "php" && $(conf_read php) != "true" ]] && php_install && php_optim && php_tool_site [[ ( $2 == "php" || $4 == "postfix" ) && $(conf_read php) == "true" && $(conf_read php-tool-postfix) != "true" && $4 != "light" ]] && php_tool_postfix [[ ( $2 == "php" || $4 == "redis" ) && $(conf_read php) == "true" && $(conf_read php-tool-redis) != "true" ]] && ! [[ $4 =~ ^(light|basic)$ ]] && php_tool_redis [[ ( $2 == "php" || $4 == "memcached" ) && $(conf_read php) == "true" && $(conf_read php-tool-memcached) != "true" ]] && ! [[ $4 =~ ^(light|basic)$ ]] && php_tool_memcached [[ $3 == "mysql-client" && $(conf_read mysql-client) != "true" ]] && mysql_client_install [[ $3 == "mysql" && $(conf_read mysql) != "true" ]] && mysql_client_install && mysql_install && local mysql_pass_display="true" && mysql_optim [[ ( $3 == "mysql" || $4 == "pma" ) && $(conf_read mysql) == "true" && $(conf_read mysql-tool-pma) != "true" ]] && ! [[ $4 =~ ^(light|basic)$ ]] && mysql_tool_pma [[ $mysql_pass_display == "true" && -z $block_password_display ]] && messagend_install fi [[ $code != 0 || -n $(conf_read stack-build-error-flag) ]] && sudo webinoly -verify=critical || return 0 # Never end a function with negative open! }