]> git.p6c8.net - nextcloud-backup-restore.git/blob - NextcloudRestore.sh
v2.3.0: Bugfix double slashes; exit on error; optimizations
[nextcloud-backup-restore.git] / NextcloudRestore.sh
1 #!/bin/bash
2
3 #
4 # Bash script for restoring backups of Nextcloud.
5 #
6 # Version 2.3.0
7 #
8 # Requirements:
9 # - pigz (https://zlib.net/pigz/) for using backup compression. If not available, you can use another compression algorithm (e.g. gzip)
10 #
11 # Supported database systems:
12 # - MySQL/MariaDB
13 # - PostgreSQL
14 #
15 # Usage:
16 # - With backup directory specified in the script: ./NextcloudRestore.sh <BackupName> (e.g. ./NextcloudRestore.sh 20170910_132703)
17 # - With backup directory specified by parameter: ./NextcloudRestore.sh <BackupName> <BackupDirectory> (e.g. ./NextcloudRestore.sh 20170910_132703 /media/hdd/nextcloud_backup)
18 #
19 # 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/
20 #
21
22 #
23 # IMPORTANT
24 # You have to customize this script (directories, users, etc.) for your actual environment.
25 # All entries which need to be customized are tagged with "TODO".
26 #
27
28 # Make sure the script exits when any command fails
29 set -Eeuo pipefail
30
31 # Variables
32 restore=$1
33 backupMainDir=$2
34
35 if [ -z "$backupMainDir" ]; then
36 # TODO: The directory where you store the Nextcloud backups (when not specified by args)
37 backupMainDir='/media/hdd/nextcloud_backup'
38 fi
39
40 echo "Backup directory: $backupMainDir"
41
42 currentRestoreDir="${backupMainDir}/${restore}"
43
44 # TODO: Set this to true, if the backup was created with compression enabled, otherwiese false.
45 useCompression=true
46
47 # TOOD: The bare tar command for using compression.
48 # Use 'tar -xmpzf' if you want to use gzip compression.
49 compressionCommand="tar -I pigz -cpf"
50
51 # TODO: The directory of your Nextcloud installation (this is a directory under your web root)
52 nextcloudFileDir='/var/www/nextcloud'
53
54 # TODO: The directory of your Nextcloud data directory (outside the Nextcloud file directory)
55 # If your data directory is located under Nextcloud's file directory (somewhere in the web root), the data directory should not be restored separately
56 nextcloudDataDir='/var/nextcloud_data'
57
58 # TODO: The directory of your Nextcloud's local external storage.
59 # Uncomment if you use local external storage.
60 #nextcloudLocalExternalDataDir='/var/nextcloud_external_data'
61
62 # TODO: The service name of the web server. Used to start/stop web server (e.g. 'systemctl start <webserverServiceName>')
63 webserverServiceName='nginx'
64
65 # TODO: Your web server user
66 webserverUser='www-data'
67
68 # TODO: The name of the database system (one of: mysql, mariadb, postgresql)
69 databaseSystem='mariadb'
70
71 # TODO: Your Nextcloud database name
72 nextcloudDatabase='nextcloud_db'
73
74 # TODO: Your Nextcloud database user
75 dbUser='nextcloud_db_user'
76
77 # TODO: The password of the Nextcloud database user
78 dbPassword='mYpAsSw0rd'
79
80 # TODO: Uncomment this and set to true if the database from the backup DOES NOT use UTF8 with multibyte support (e.g. for emoijs in filenames)
81 #dbNoMultibyte=true
82
83 # File names for backup files
84 # If you prefer other file names, you'll also have to change the NextcloudBackup.sh script.
85 fileNameBackupFileDir='nextcloud-filedir.tar'
86 fileNameBackupDataDir='nextcloud-datadir.tar'
87
88 if [ "$useCompression" = true ] ; then
89 fileNameBackupFileDir='nextcloud-filedir.tar.gz'
90 fileNameBackupDataDir='nextcloud-datadir.tar.gz'
91 fi
92
93 fileNameBackupExternalDataDir=''
94
95 if [ ! -z "${nextcloudLocalExternalDataDir+x}" ] ; then
96 fileNameBackupExternalDataDir='nextcloud-external-datadir.tar'
97
98 if [ "$useCompression" = true ] ; then
99 fileNameBackupExternalDataDir='nextcloud-external-datadir.tar.gz'
100 fi
101 fi
102
103 fileNameBackupDb='nextcloud-db.sql'
104
105 # Function for error messages
106 errorecho() { cat <<< "$@" 1>&2; }
107
108 #
109 # Check if parameter(s) given
110 #
111 if [ $# != "1" ] && [ $# != "2" ]
112 then
113 errorecho "ERROR: No backup name to restore given, or wrong number of parameters!"
114 errorecho "Usage: NextcloudRestore.sh 'BackupDate' ['BackupDirectory']"
115 exit 1
116 fi
117
118 #
119 # Check for root
120 #
121 if [ "$(id -u)" != "0" ]
122 then
123 errorecho "ERROR: This script has to be run as root!"
124 exit 1
125 fi
126
127 #
128 # Check if backup dir exists
129 #
130 if [ ! -d "${currentRestoreDir}" ]
131 then
132 errorecho "ERROR: Backup ${restore} not found!"
133 exit 1
134 fi
135
136 #
137 # Check if the commands for restoring the database are available
138 #
139 if [ "${databaseSystem,,}" = "mysql" ] || [ "${databaseSystem,,}" = "mariadb" ]; then
140 if ! [ -x "$(command -v mysql)" ]; then
141 errorecho "ERROR: MySQL/MariaDB not installed (command mysql not found)."
142 errorecho "ERROR: No restore of database possible!"
143 errorecho "Cancel restore"
144 exit 1
145 fi
146 elif [ "${databaseSystem,,}" = "postgresql" ] || [ "${databaseSystem,,}" = "pgsql" ]; then
147 if ! [ -x "$(command -v psql)" ]; then
148 errorecho "ERROR: PostgreSQL not installed (command psql not found)."
149 errorecho "ERROR: No restore of database possible!"
150 errorecho "Cancel restore"
151 exit 1
152 fi
153 fi
154
155 #
156 # Set maintenance mode
157 #
158 echo "$(date +"%H:%M:%S"): Set maintenance mode for Nextcloud..."
159 sudo -u "${webserverUser}" php ${nextcloudFileDir}/occ maintenance:mode --on
160 echo "Done"
161 echo
162
163 #
164 # Stop web server
165 #
166 echo "$(date +"%H:%M:%S"): Stopping web server..."
167 systemctl stop "${webserverServiceName}"
168 echo "Done"
169 echo
170
171 #
172 # Delete old Nextcloud directories
173 #
174
175 # File directory
176 echo "$(date +"%H:%M:%S"): Deleting old Nextcloud file directory..."
177 rm -r "${nextcloudFileDir}"
178 mkdir -p "${nextcloudFileDir}"
179 echo "Done"
180 echo
181
182 # Data directory
183 echo "$(date +"%H:%M:%S"): Deleting old Nextcloud data directory..."
184 rm -r "${nextcloudDataDir}"
185 mkdir -p "${nextcloudDataDir}"
186 echo "Done"
187 echo
188
189 # Local external storage
190 if [ ! -z "${nextcloudLocalExternalDataDir+x}" ] ; then
191 echo "Deleting old Nextcloud local external storage directory..."
192 rm -r "${nextcloudLocalExternalDataDir}"
193 mkdir -p "${nextcloudLocalExternalDataDir}"
194 echo "Done"
195 echo
196 fi
197
198 #
199 # Restore file and data directory
200 #
201
202 # File directory
203 echo "$(date +"%H:%M:%S"): Restoring Nextcloud file directory..."
204
205 if [ "$useCompression" = true ] ; then
206 `$compressionCommand "${currentRestoreDir}/${fileNameBackupFileDir}" -C "${nextcloudFileDir}"`
207 else
208 tar -xmpf "${currentRestoreDir}/${fileNameBackupFileDir}" -C "${nextcloudFileDir}"
209 fi
210
211 echo "Done"
212 echo
213
214 # Data directory
215 echo "$(date +"%H:%M:%S"): Restoring Nextcloud data directory..."
216
217 if [ "$useCompression" = true ] ; then
218 `$compressionCommand "${currentRestoreDir}/${fileNameBackupDataDir}" -C "${nextcloudDataDir}"`
219 else
220 tar -xmpf "${currentRestoreDir}/${fileNameBackupDataDir}" -C "${nextcloudDataDir}"
221 fi
222
223 echo "Done"
224 echo
225
226 # Local external storage
227 if [ ! -z "${nextcloudLocalExternalDataDir+x}" ] ; then
228 echo "$(date +"%H:%M:%S"): Restoring Nextcloud local external storage directory..."
229
230 if [ "$useCompression" = true ] ; then
231 `$compressionCommand "${currentRestoreDir}/${fileNameBackupExternalDataDir}" -C "${nextcloudLocalExternalDataDir}"`
232 else
233 tar -xmpf "${currentRestoreDir}/${fileNameBackupExternalDataDir}" -C "${nextcloudLocalExternalDataDir}"
234 fi
235
236 echo "Done"
237 echo
238 fi
239
240 #
241 # Restore database
242 #
243 echo "$(date +"%H:%M:%S"): Dropping old Nextcloud DB..."
244
245 if [ "${databaseSystem,,}" = "mysql" ] || [ "${databaseSystem,,}" = "mariadb" ]; then
246 mysql -h localhost -u "${dbUser}" -p"${dbPassword}" -e "DROP DATABASE ${nextcloudDatabase}"
247 elif [ "${databaseSystem,,}" = "postgresql" ]; then
248 sudo -u postgres psql -c "DROP DATABASE ${nextcloudDatabase};"
249 fi
250
251 echo "Done"
252 echo
253
254 echo "$(date +"%H:%M:%S"): Creating new DB for Nextcloud..."
255
256 if [ "${databaseSystem,,}" = "mysql" ] || [ "${databaseSystem,,}" = "mariadb" ]; then
257 if [ ! -z "${dbNoMultibyte+x}" ] && [ "${dbNoMultibyte}" = true ] ; then
258 # Database from the backup DOES NOT use UTF8 with multibyte support (e.g. for emoijs in filenames)
259 mysql -h localhost -u "${dbUser}" -p"${dbPassword}" -e "CREATE DATABASE ${nextcloudDatabase}"
260 else
261 # Database from the backup uses UTF8 with multibyte support (e.g. for emoijs in filenames)
262 mysql -h localhost -u "${dbUser}" -p"${dbPassword}" -e "CREATE DATABASE ${nextcloudDatabase} CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"
263 fi
264 elif [ "${databaseSystem,,}" = "postgresql" ] || [ "${databaseSystem,,}" = "pgsql" ]; then
265 sudo -u postgres psql -c "CREATE DATABASE ${nextcloudDatabase} WITH OWNER ${dbUser} TEMPLATE template0 ENCODING \"UNICODE\";"
266 fi
267
268 echo "Done"
269 echo
270
271 echo "$(date +"%H:%M:%S"): Restoring backup DB..."
272
273 if [ "${databaseSystem,,}" = "mysql" ] || [ "${databaseSystem,,}" = "mariadb" ]; then
274 mysql -h localhost -u "${dbUser}" -p"${dbPassword}" "${nextcloudDatabase}" < "${currentRestoreDir}/${fileNameBackupDb}"
275 elif [ "${databaseSystem,,}" = "postgresql" ] || [ "${databaseSystem,,}" = "pgsql" ]; then
276 sudo -u postgres psql "${nextcloudDatabase}" < "${currentRestoreDir}/${fileNameBackupDb}"
277 fi
278
279 echo "Done"
280 echo
281
282 #
283 # Start web server
284 #
285 echo "$(date +"%H:%M:%S"): Starting web server..."
286 systemctl start "${webserverServiceName}"
287 echo "Done"
288 echo
289
290 #
291 # Set directory permissions
292 #
293 echo "$(date +"%H:%M:%S"): Setting directory permissions..."
294 chown -R "${webserverUser}":"${webserverUser}" "${nextcloudFileDir}"
295 chown -R "${webserverUser}":"${webserverUser}" "${nextcloudDataDir}"
296
297 if [ ! -z "${nextcloudLocalExternalDataDir+x}" ] ; then
298 chown -R "${webserverUser}":"${webserverUser}" "${nextcloudLocalExternalDataDir}"
299 fi
300
301 echo "Done"
302 echo
303
304 #
305 # Update the system data-fingerprint (see https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/occ_command.html#maintenance-commands-label)
306 #
307 echo "$(date +"%H:%M:%S"): Updating the system data-fingerprint..."
308 sudo -u "${webserverUser}" php ${nextcloudFileDir}/occ maintenance:data-fingerprint
309 echo "Done"
310 echo
311
312 #
313 # Disbale maintenance mode
314 #
315 echo "$(date +"%H:%M:%S"): Switching off maintenance mode..."
316 sudo -u "${webserverUser}" php ${nextcloudFileDir}/occ maintenance:mode --off
317 echo "Done"
318 echo
319
320 echo
321 echo "DONE!"
322 echo "$(date +"%H:%M:%S"): Backup ${restore} successfully restored."

patrick-canterino.de