Backup Your WordPress or ClassicPress Files, Configuration, and Database with a Single Script
Audience and Prerequisites
Skip to scenario if you want to jump into the main article.
This is for anyone who currently host their WordPress or ClassicPress in a virtual private server such as DigitalOcean, Linode, or any other VPS providers. Any Linux user with knowledge of command line can perform backups and restoration tasks. You must be familiar with Linux and you know how to connect to your production server via SSH.
Plus, this article assumes that you have installed and configured WordPress in your VPS server. In addition, this article assumes you can perform basic database administration tasks such as adding a new database along with creating a new user for WordPress or ClassicPress. If your hosting provider provides managed WordPress or ClassicPress hosting, then this article may not apply to you. And because this article is for those who currently run a VPS server, I am going to have to assume that you have some hands-on experience with the Linux command line. This article need not apply to non-technical Linux, Mac, and Windows users. When I say non-technical Linux users, I'm talking about those who wanted to get away from Windows or Mac and simply wanted to use Linux just to browse the Internet and not deal with the command line.
Last, but not least, I am also going to assume that you know how to configure your Apache server as well. Both Apache and NGINX (pronounced Engine-X) configurations won't be covered here, including backing up and copying certificates that you get from your hosting provider.
If you are interested in learning Linux, a tutorial from Guru99 will help get you started on learning Linux.
Are you ready? Then let's get started!
Scenario
You have your own VPS server that is running ClassicPress. Your domain name is exmaple.com and your SSH port number is (insert your TCP port number here). You have a development server for developing your own custom ClassicPress theme and you want to use your development server to backup everything from your production server.
Remote (example.com)
Skip this step if you know how to create an SSH private/public key pair. First, let's create an SSH public and private key pair so that you can login to your server without entering a password. This will be very useful when writing a script.
Open the terminal and connect to your development server via SSH.
ssh yourusername@devserver -p (your port number if it's other than port 22)
From your development server, create an SSH key pair. We are going to use id_rsa.
ssh-keygen -t id_rsa
Next, enter the location and filename. Example:
/home/yourusername/.ssh/classicpress
After that, leave the passphrase blank. Press Enter a couple of times until you get back to the prompt ending with
$
.Execute
ssh-copy-id
with the name of the public key file and specify the username and domain name.ssh-copy-id -p (your TCP port number if not 22) -i ~/.ssh/classicpress.pub yourname@example.com
You should be able to login to your server. Give it a try.
ssh -p (your port number or remove -p) -i ~/.ssh/classicpress yourname@example.com
If all goes well, you should be able to connect to your production server without been prompted for the password or passphrase. I mentioned "without passphrase" because if a Linux user executes a single script for performing a backup and has set a passphrase for the SSH identity key, then the script will prompt a Linux user for the passphrase multiple times.
For the purpose of backing up a database, this task will take you through creating a .my.cnf
file. This is a hidden file that will contain the username and password for mysqldump
command. mysqldump
allows a database administrator to backup the MySQL or MariaDB database.
Login to your production server from your development or backup server and perform the steps below.
Create a new file using either vim or nano called
.my.cnf
. This file will be saved in your home directory.mysqldump
will read the file containing the username and password. For me, I usevim
.vim .my.cnf
If you are using Vim, press the
i
key to begin theINSERT
mode and begin typing the following lines. If you are usingnano
, simply start typing the following.[mysqldump] user=yourdatabaseuser password=yourdatabasepassword
Replace
yourdatabaseusername
with your database username andyourdatabasepassword
with your database password. When installing either WordPress or ClassicPress on a VPS server, a Linux administrator must have created a database along with the username and set password during the installation process.Save your changes.
- For Vim users, exit out of
INSERT
mode by pressing theESC
key; then, type:wq
to write changes to the.my.cjnf
file and quit Vim. The:
key begins the command for Vim,w
saves the file, andq
quits Vim. If you want to not write any changes and quit Vim, then the command is:q!
. If the!
were omitted, then Vim will tell you that you need to save your changes before you quit Vim. - For nano users, the keyboard commands for saving the changes and quitting the text editor is
CTRL+O
for saving changes (press theENTER
key to confirm changes) andCTRL+X
to quit the text editor.
- For Vim users, exit out of
Once done, do a database backup of your WordPress or ClassicPress database.
mysqldump ClassicPress > test.sql
This assumes that your database name is
ClassicPress
. ReplaceClassicPress
and enter the name of the database that you created when you installed WordPress or ClassicPress in your VPS server.Your new file called
test.sql
should be in the same directory that you executed the command for testing. If you open that file up with your chosen editor, you should see all the database commands. Go ahead and close the file.- Log out of your production server by typing
exit
and pressENTER
.
If your database backup is successful, congratulations! That task is done! Your may delete the test.sql
file by using the rm
command (be careful with that rm
command; you might delete files accidentally). The benefit of having a .my.cnf
file within the home directory is that you do not want to expose your database password when executing mysqldump
. Let's use sleep 10
as an example as the mysqldump
command can be very quick once executed.
If you have a Linux machine, open up two terminals and place them side by side.
For the first terminal, execute the following command:
watch 'ps aux | grep sleep'
The
watch
command will output theps aux | grep sleep
command. Here is the output of the command:Every 2.0s: ps aux | grep sleep grayson-web: Thu Nov 17 02:28:18 2022 gpadmin+ 601423 0.0 0.1 7940 3040 pts/1 S+ 02:21 0:00 watch ps aux | grep sleep gpadmin+ 602462 0.0 0.0 7940 1020 pts/1 S+ 02:28 0:00 watch ps aux | grep sleep gpadmin+ 602463 0.0 0.0 2608 596 pts/1 S+ 02:28 0:00 sh -c ps aux | grep sleep gpadmin+ 602465 0.0 0.0 8160 720 pts/1 S+ 02:28 0:00 grep sleep
Do not worry about the entire output too much. I am only focusing in the "sleep output."
In the second terminal, execute the command:
sleep 30
In the first terminal, the
watch
command will output as follows:Every 2.0s: ps aux | grep sleep grayson-web: Thu Nov 17 02:32:07 2022 gpadmin+ 601423 0.0 0.1 7940 3040 pts/1 S+ 02:21 0:00 watch ps aux | grep sleep gpadmin+ 602971 0.0 0.0 7228 516 pts/0 S+ 02:31 0:00 sleep 30 gpadmin+ 602992 0.0 0.0 7940 1020 pts/1 S+ 02:32 0:00 watch ps aux | grep sleep gpadmin+ 602993 0.0 0.0 2608 596 pts/1 S+ 02:32 0:00 sh -c ps aux | grep sleep gpadmin+ 602995 0.0 0.0 8160 724 pts/1 S+ 02:32 0:00 grep sleep
The command
sleep 30
will be there for 30 seconds and will disappear from thewatch
output after the number of seconds have passed.- Use the
CTRL+C
key to exit out of the watch output. If you are using a Mac, the keyboard command isControl+C
.Command+C
is for copying text.
My point is, if the mysqldump
command gets executed for a long period of time while dumping the entire database, mysqldump
can show up in the list of processes. For example, let's say you executed a mysqldump
command as follows:
mysqldump -u username -ppassword MyDatabase > test.sql
This command will take about 30 seconds when dumping an entire MySQL/MariaDB database. As a result, the output will be as follows (note that this is just an example):
Every 2.0s: ps aux | grep mysqldump grayson-web: Thu Nov 17 02:32:07 2022 gpadmin+ 601423 0.0 0.1 7940 3040 pts/1 S+ 02:21 0:00 watch ps aux | grep mysqldump gpadmin+ 602971 0.0 0.0 7228 516 pts/0 S+ 02:31 0:00 mysqldump -u username -ppassword MyDatabase > test.sql gpadmin+ 602992 0.0 0.0 7940 1020 pts/1 S+ 02:32 0:00 watch ps aux | grep mysqldump gpadmin+ 602993 0.0 0.0 2608 596 pts/1 S+ 02:32 0:00 sh -c ps aux | grep mysqldump gpadmin+ 602995 0.0 0.0 8160 724 pts/1 S+ 02:32 0:00 grep sleep
This can be a big problem if an attacker gains access to your server and monitors for the list of processes. That's why it's important to avoid storing passwords in a script whenever possible. That's where .my.cnf
configuration file comes in. I did not know about this until I found out about adding a username and password in .my.cnf
file. I learn something new almost every single day.
And if you want an example of a real process list, here it is with Apache web server running in my production server:
$ ps aux | grep apache root 490142 0.0 1.8 81624 36748 ? Ss Nov15 0:13 /usr/sbin/apache2 -k start www-data 597487 0.0 1.9 1590740 39256 ? Sl 00:00 0:01 /usr/sbin/apache2 -k start www-data 597488 0.0 1.8 1590412 38320 ? Sl 00:00 0:01 /usr/sbin/apache2 -k start gpadmin+ 605240 0.0 0.1 8160 2560 pts/1 S+ 02:55 0:00 grep --color=auto apache
Okay. That's all for the remote server configuration. Let's get into some real fun part, the configuration of the development server for performing automated backups!
Development or Backup Server
Now here is the script you have all bee waiting for.
#!/bin/sh # DIRP: Directory path DIRP=~/cpbackup # FILE: Partial file name FILE=$DIRP/classicpress-$(date +%Y%m%d) # Hostname, IP address, or domain name HOST=example.com # Private key for automated logging into an SSH server (no passphrase or password) PKEY=~/.ssh/classicpress # TCP Port number (use whatever port you assigned for an SSH server in the # production server.) PORT=22 # User name assigned in the remote Linux server USER=yourusername # Let's perform some checks. Does the directory in the $DIRP variable exist? if [ ! -d $DIRP ] then echo "Directory not found: $DIRP" exit 1 fi # Does the SSH key pair exist? if [ ! -f $PKEY -a ! -f $PKEY.pub ] then echo "SSH key pair $PKEY and $PKEY.pub does not exist. Exiting." exit 1 fi # Delete any backup files older than x number of days find $DIRP -maxdepth 0 -mtime +10 -exec rm {} \; # Backup the SQL database and store them locally for later restoration. ssh -p $PORT $USER@$HOST -i $PKEY mysqldump ClassicPress > $FILE.sql # Next, change directory to /var/www and compress them to standard output # which then gets redirected to a compressed .tar.gz file. ssh -p $PORT $USER@$HOST -i $PKEY 'cd /var/www && tar czf - *' > $FILE.tar.gz # If there is a wp-config.php file stored outside /var/www, make a backup of # that configuration file as well. scp -P $PORT -i $PKEY $USER@$HOST:/var/wp-config.php $FILE-wp-config.php # After that, backup the Apache virtual host configuration file. scp -P $PORT -i $PKEY \ $USER@$HOST:/etc/apache2/sites-available/000-default.conf $FILE-apache.conf # The script ran successfully. exit 0
First, I recommend that you create a
bin
directory inside your home directory.mkdir ~/bin
Then, use a text editor in the terminal of your choice (vim, nano, pico, etc.) to create a new file called
cpbackup.sh
. That script will be in thebin
directory. In my case:vim bin/cpbackup.sh
- Copy the script that I created above. It's after the section called Development or Backup Server. The script starts with
#!/bin/sh
which is the start of the script. Copy it all the way down toexit 0
. - Paste the script in the terminal. For Linux users who use a GNOME Terminal like I do, it's
CTRL+SHIFT+V
. For Mac users who use a Terminal, it'sCommand+V
. - Make some changes to the variables, such as the host name/IP address, port number, et cetera.
- Save your changes and exit the text editor.
Give the script an executable permission.
chmod +x bin/cpbackup.sh
chmod
, called change mode, allows you to modify read, write, and execute permissions for a user, group, and others. This is beyond the scope of my article. Remember back in the Audience and Prerequisites section that I have to assume you are familiar with Linux. I will have to write another article if I have to get everyone up to speed on how to gain familiar with Linux.After that, execute the following command:
bin/cpbackup.sh
And you are done! If all goes well, all of your backup files have been stored in the backup directory. And oh, be sure you test your backups by extracting all the WordPress/ClassicPress files from the archive and put it in /var/www
. Restoring the database is as simple as:
mysql -u ClassicPress -p ClassicPress < classicpress.sql
Then, simply copy wp-config.php
file to /var
(it's a good idea to move your wp-config.php
file outside of /var/www
directory) and copy the Apache configuration file to /etc/apache2/sites-available/
, enable the virtual host using the a2ensite
command, and you are good to go.
To automatically backup your WordPress/ClassicPress site from time to time, simply execute crontab -e
and enter at the bottom of the crontab file:
0 0 * * * bin/whateveryournameofthefileis.sh
And that is done.
Summary
Hopefully you should have a backup infrastructure in place so that if anything goes wrong, you can be able to restore from a good working backup. I hope my article is helpful to anyone who needs to perform a backup of their website including the database. Stay safe and practice good security hygiene online. Oh, and backup your files in your computer to a server or a NAS if you have one. And yes, you should definitely have a home server or a NAS for backing up all your important files. Thank you for reading my article.
Article published: 2022-11-17 08:47
Categories: The World of Computers, Information Technology, Internet, Networking, Scripting and Programming,