NextcloudRestore.sh 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. #!/bin/bash
  2. #
  3. # Bash script for restoring backups of Nextcloud.
  4. #
  5. # Version 3.0.3
  6. #
  7. # Requirements:
  8. # - pigz (https://zlib.net/pigz/) for using backup compression. If not available, you can use another compression algorithm (e.g. gzip)
  9. #
  10. # Supported database systems:
  11. # - MySQL/MariaDB
  12. # - PostgreSQL
  13. #
  14. # Usage:
  15. # - With backup directory specified in the script: ./NextcloudRestore.sh <BackupName> (e.g. ./NextcloudRestore.sh 20170910_132703)
  16. # - With backup directory specified by parameter: ./NextcloudRestore.sh <BackupName> <BackupDirectory> (e.g. ./NextcloudRestore.sh 20170910_132703 /media/hdd/nextcloud_backup)
  17. #
  18. # The script is based on an installation of Nextcloud using nginx and MariaDB, see https://decatec.de/home-server/nextcloud-auf-ubuntu-server-20-04-lts-mit-nginx-mariadb-php-lets-encrypt-redis-und-fail2ban/
  19. #
  20. # Make sure the script exits when any command fails
  21. set -Eeuo pipefail
  22. # Variables
  23. working_dir=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
  24. configFile="${working_dir}/NextcloudBackupRestore.conf" # Holds the configuration for NextcloudBackup.sh and NextcloudRestore.sh
  25. restore=${1:-}
  26. _backupMainDir=${2:-}
  27. # Function for error messages
  28. errorecho() { cat <<< "$@" 1>&2; }
  29. #
  30. # Check if config file exists
  31. #
  32. if [ ! -f "${configFile}" ]
  33. then
  34. errorecho "ERROR: Configuration file $configFile cannot be found!"
  35. errorecho "Please make sure that a configuration file '$configFile' is present in the main directory of the scripts."
  36. errorecho "This file can be created automatically using the setup.sh script."
  37. exit 1
  38. fi
  39. source "$configFile" || exit 1 # Read configuration variables
  40. if [ -n "$_backupMainDir" ]; then
  41. backupMainDir="$_backupMainDir"
  42. fi
  43. echo "Backup directory: $backupMainDir"
  44. currentRestoreDir="${backupMainDir}/${restore}"
  45. #
  46. # Check if parameter(s) given
  47. #
  48. if [ $# != "1" ] && [ $# != "2" ]
  49. then
  50. errorecho "ERROR: No backup name to restore given, or wrong number of parameters!"
  51. errorecho "Usage: NextcloudRestore.sh 'BackupDate' ['BackupDirectory']"
  52. exit 1
  53. fi
  54. #
  55. # Check for root
  56. #
  57. if [ "$(id -u)" != "0" ]
  58. then
  59. errorecho "ERROR: This script has to be run as root!"
  60. exit 1
  61. fi
  62. #
  63. # Check if backup dir exists
  64. #
  65. if [ ! -d "${currentRestoreDir}" ]
  66. then
  67. errorecho "ERROR: Backup ${restore} not found!"
  68. exit 1
  69. fi
  70. #
  71. # Check if the commands for restoring the database are available
  72. #
  73. if [ "${databaseSystem,,}" = "mysql" ] || [ "${databaseSystem,,}" = "mariadb" ]; then
  74. if ! [ -x "$(command -v mysql)" ]; then
  75. errorecho "ERROR: MySQL/MariaDB not installed (command mysql not found)."
  76. errorecho "ERROR: No restore of database possible!"
  77. errorecho "Cancel restore"
  78. exit 1
  79. fi
  80. elif [ "${databaseSystem,,}" = "postgresql" ] || [ "${databaseSystem,,}" = "pgsql" ]; then
  81. if ! [ -x "$(command -v psql)" ]; then
  82. errorecho "ERROR: PostgreSQL not installed (command psql not found)."
  83. errorecho "ERROR: No restore of database possible!"
  84. errorecho "Cancel restore"
  85. exit 1
  86. fi
  87. fi
  88. #
  89. # Set maintenance mode
  90. #
  91. echo "$(date +"%H:%M:%S"): Set maintenance mode for Nextcloud..."
  92. sudo -u "${webserverUser}" php ${nextcloudFileDir}/occ maintenance:mode --on
  93. echo "Done"
  94. echo
  95. #
  96. # Stop web server
  97. #
  98. echo "$(date +"%H:%M:%S"): Stopping web server..."
  99. systemctl stop "${webserverServiceName}"
  100. echo "Done"
  101. echo
  102. #
  103. # Delete old Nextcloud directories
  104. #
  105. # File directory
  106. echo "$(date +"%H:%M:%S"): Deleting old Nextcloud file directory..."
  107. rm -rf "${nextcloudFileDir}"
  108. mkdir -p "${nextcloudFileDir}"
  109. echo "Done"
  110. echo
  111. # Data directory
  112. echo "$(date +"%H:%M:%S"): Deleting old Nextcloud data directory..."
  113. rm -rf "${nextcloudDataDir}/*"
  114. echo "Done"
  115. echo
  116. # Local external storage
  117. if [ ! -z "${nextcloudLocalExternalDataDir+x}" ] ; then
  118. echo "Deleting old Nextcloud local external storage directory..."
  119. rm -rf "${nextcloudLocalExternalDataDir}/*"
  120. echo "Done"
  121. echo
  122. fi
  123. #
  124. # Restore file and data directory
  125. #
  126. # File directory
  127. echo "$(date +"%H:%M:%S"): Restoring Nextcloud file directory..."
  128. if [ "$useCompression" = true ] ; then
  129. `$extractCommand "${currentRestoreDir}/${fileNameBackupFileDir}" -C "${nextcloudFileDir}"`
  130. else
  131. tar -xmpf "${currentRestoreDir}/${fileNameBackupFileDir}" -C "${nextcloudFileDir}"
  132. fi
  133. echo "Done"
  134. echo
  135. # Data directory
  136. echo "$(date +"%H:%M:%S"): Restoring Nextcloud data directory..."
  137. if [ "$useCompression" = true ] ; then
  138. `$extractCommand "${currentRestoreDir}/${fileNameBackupDataDir}" -C "${nextcloudDataDir}"`
  139. else
  140. tar -xmpf "${currentRestoreDir}/${fileNameBackupDataDir}" -C "${nextcloudDataDir}"
  141. fi
  142. echo "Done"
  143. echo
  144. # Local external storage
  145. if [ ! -z "${nextcloudLocalExternalDataDir+x}" ] ; then
  146. echo "$(date +"%H:%M:%S"): Restoring Nextcloud local external storage directory..."
  147. if [ "$useCompression" = true ] ; then
  148. `$extractCommand "${currentRestoreDir}/${fileNameBackupExternalDataDir}" -C "${nextcloudLocalExternalDataDir}"`
  149. else
  150. tar -xmpf "${currentRestoreDir}/${fileNameBackupExternalDataDir}" -C "${nextcloudLocalExternalDataDir}"
  151. fi
  152. echo "Done"
  153. echo
  154. fi
  155. #
  156. # Restore database
  157. #
  158. echo "$(date +"%H:%M:%S"): Dropping old Nextcloud DB..."
  159. if [ "${databaseSystem,,}" = "mysql" ] || [ "${databaseSystem,,}" = "mariadb" ]; then
  160. mysql -h localhost -u "${dbUser}" -p"${dbPassword}" -e "DROP DATABASE ${nextcloudDatabase}"
  161. elif [ "${databaseSystem,,}" = "postgresql" ]; then
  162. sudo -u postgres psql -c "DROP DATABASE ${nextcloudDatabase};"
  163. fi
  164. echo "Done"
  165. echo
  166. echo "$(date +"%H:%M:%S"): Creating new DB for Nextcloud..."
  167. if [ "${databaseSystem,,}" = "mysql" ] || [ "${databaseSystem,,}" = "mariadb" ]; then
  168. if [ ! -z "${dbNoMultibyte+x}" ] && [ "${dbNoMultibyte}" = true ] ; then
  169. # Database from the backup DOES NOT use UTF8 with multibyte support (e.g. for emoijs in filenames)
  170. mysql -h localhost -u "${dbUser}" -p"${dbPassword}" -e "CREATE DATABASE ${nextcloudDatabase}"
  171. else
  172. # Database from the backup uses UTF8 with multibyte support (e.g. for emoijs in filenames)
  173. mysql -h localhost -u "${dbUser}" -p"${dbPassword}" -e "CREATE DATABASE ${nextcloudDatabase} CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"
  174. fi
  175. elif [ "${databaseSystem,,}" = "postgresql" ] || [ "${databaseSystem,,}" = "pgsql" ]; then
  176. sudo -u postgres psql -c "CREATE DATABASE ${nextcloudDatabase} WITH OWNER ${dbUser} TEMPLATE template0 ENCODING \"UNICODE\";"
  177. fi
  178. echo "Done"
  179. echo
  180. echo "$(date +"%H:%M:%S"): Restoring backup DB..."
  181. if [ "${databaseSystem,,}" = "mysql" ] || [ "${databaseSystem,,}" = "mariadb" ]; then
  182. mysql -h localhost -u "${dbUser}" -p"${dbPassword}" "${nextcloudDatabase}" < "${currentRestoreDir}/${fileNameBackupDb}"
  183. elif [ "${databaseSystem,,}" = "postgresql" ] || [ "${databaseSystem,,}" = "pgsql" ]; then
  184. sudo -u postgres psql "${nextcloudDatabase}" < "${currentRestoreDir}/${fileNameBackupDb}"
  185. fi
  186. echo "Done"
  187. echo
  188. #
  189. # Start web server
  190. #
  191. echo "$(date +"%H:%M:%S"): Starting web server..."
  192. systemctl start "${webserverServiceName}"
  193. echo "Done"
  194. echo
  195. #
  196. # Set directory permissions
  197. #
  198. echo "$(date +"%H:%M:%S"): Setting directory permissions..."
  199. chown -R "${webserverUser}":"${webserverUser}" "${nextcloudFileDir}"
  200. chown -R "${webserverUser}":"${webserverUser}" "${nextcloudDataDir}"
  201. if [ ! -z "${nextcloudLocalExternalDataDir+x}" ] ; then
  202. chown -R "${webserverUser}":"${webserverUser}" "${nextcloudLocalExternalDataDir}"
  203. fi
  204. echo "Done"
  205. echo
  206. #
  207. # Disbale maintenance mode
  208. #
  209. echo "$(date +"%H:%M:%S"): Switching off maintenance mode..."
  210. sudo -u "${webserverUser}" php ${nextcloudFileDir}/occ maintenance:mode --off
  211. echo "Done"
  212. echo
  213. #
  214. # Update the system data-fingerprint (see https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/occ_command.html#maintenance-commands-label)
  215. #
  216. echo "$(date +"%H:%M:%S"): Updating the system data-fingerprint..."
  217. sudo -u "${webserverUser}" php ${nextcloudFileDir}/occ maintenance:data-fingerprint
  218. echo "Done"
  219. echo
  220. echo
  221. echo "DONE!"
  222. echo "$(date +"%H:%M:%S"): Backup ${restore} successfully restored."