Skip to content.

A Note About Website Navigation

Skip to main menu.

For users of screen readers, depending on the screen resolution, the two checkboxes are for opening and closing the side menus that appear to the left and right side of the screen. This is designed both for large screens and for mobile devices with a touch screen. Checking either the main menu or sidebar checkboxes causes the menu to open from the left or right side of the screen, respectively. Clearing the checkox in either the main menu or sidebar closes the menu. The checkboxes are visible to screen readers such as JAWS and NVDA for Windows, Voiceover for Mac, and Orca screen reader for Linux. When a screen reader says "clickable" for both main menu and sidebar, that is for the respective checkboxes. End of explaination.

Viewing Single Blog Post

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.

  1. 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)
  2. From your development server, create an SSH key pair. We are going to use id_rsa.

    ssh-keygen -t id_rsa
  3. Next, enter the location and filename. Example:

    /home/yourusername/.ssh/classicpress
  4. After that, leave the passphrase blank. Press Enter a couple of times until you get back to the prompt ending with $.

  5. 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
  6. 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.

  1. 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 use vim.

    vim .my.cnf
  2. If you are using Vim, press the i key to begin the INSERT mode and begin typing the following lines. If you are using nano, simply start typing the following.

    [mysqldump]
    user=yourdatabaseuser
    password=yourdatabasepassword

    Replace yourdatabaseusername with your database username and yourdatabasepassword 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.

  3. Save your changes.

    • For Vim users, exit out of INSERT mode by pressing the ESC 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, and q 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 the ENTER key to confirm changes) and CTRL+X to quit the text editor.
  4. Once done, do a database backup of your WordPress or ClassicPress database.

    mysqldump ClassicPress > test.sql

    This assumes that your database name is ClassicPress. Replace ClassicPress 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.

  5. Log out of your production server by typing exit and press ENTER.

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.

  1. If you have a Linux machine, open up two terminals and place them side by side.

  2. For the first terminal, execute the following command:

    watch 'ps aux | grep sleep'

    The watch command will output the ps 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."

  3. In the second terminal, execute the command:

    sleep 30
  4. 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 the watch output after the number of seconds have passed.

  5. Use the CTRL+C key to exit out of the watch output. If you are using a Mac, the keyboard command is Control+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
  1. First, I recommend that you create a bin directory inside your home directory.

    mkdir ~/bin
  2. 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 the bin directory. In my case:

    vim bin/cpbackup.sh
  3. 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 to exit 0.
  4. 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's Command+V.
  5. Make some changes to the variables, such as the host name/IP address, port number, et cetera.
  6. Save your changes and exit the text editor.
  7. 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.

  8. 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,

About Grayson Peddie

Hello! I am a web developer and I have a passion for the world of Information Technology. I currently hold 4 CompTIA certificates (A+, Network+, Security+, and CySA+) including Cisco's CCNA (Cisco Certified Network Associate) certificate. Speaking of web development, I am a web accessibility enthusiast. I make sure that users of screen readers and keyboard users who cannot use a mouse can be able to access my website with just only the keyboard. Plus, I have learned a whole lot about Web Content Accessibility Guidelines.

So what are my hobbies? Aside from web development, I watch Star Trek: The Next Generation from time to time during the nights. I listen to music from the likes of David Arkenstone, Yanni, Checkfield, Cucso, Looreena McKennitt, Clannad, 2002, Enya, and even soundtrack from EPCOT Center (1982-1994), Tomorrowland, WALL-E, and TRON: Legacy. Oh, yes! Tomorrowland, TRON: Legacy, and WALL-E are the three movies I watch during Friday nights and every Friday night is my pizza night. I'm an optimist who likes to see what kind of future the world would look like. That's why I follow The Venus Project on Twitter (here's the website to The Venus Project. I do have a lot to cover in my introductory article in my website, so if you want to go in-depth and know more about me, that is the article to visit.