Backing up, Setting up, and Migrating Linux Webservers

Linux webservers like Ubuntu (and CentOS, etc) can sometimes be confusing for new admins who aren’t sure how to do proper backups or migrate websites and databases between servers. It takes awhile, but you eventually get a toolkit of scripts, commands, or techniques that work for you. If you’re lucky, you actually write them down!

Here are mine.

This is my install command, for prepping an Ubuntu server to be an Apache webserver with MySQL and PHP. Git is in there for version control which you should be using if you’re a coder at all. Add vsftpd to this list if for some horrible reason you need FTP (protip: use SCP instead.)

apt-get install apache2 git-core mysql-server php5 php5-gd php5-curl php5-mysql php5-xsl php5-cli libapache2-mod-php5

To set up Apache for hosting multiple websites, I add the following to httpd.conf:

NameVirtualHost YOURIPADDRESS:80

UserDir /home/*/public_html

Options ExecCGI
SetHandler cgi-script

I also edit /etc/apache2/mods-enabled/php5.conf and comment out the IfModule mod_userdir.c lines to allow users to run PHP in their sites.

This is my backup script (crontab) — to make a crontab, type crontab -e

# Below is for regular backups.
10 19 * * * /usr/bin/mysqldump --opt -uUSER DBNAME > /backups/DBNAME.sql
14 19 * * * /usr/bin/mysqldump --opt -uUSER mysql > /backups/mysql.sql
16 19 * * * tar -zcf /backups/etc-backup.tgz /etc
18 19 * * * tar -zcf /backups/www-backup.tgz /var/www

For the root user, create a ~/.my.cnf file (as root) with the following content:

Note that USER, PASSWORD, and DBNAME should be replaced appropriately. Formerly the crontab script included a -pPASSWORD option (without a space) but this is less secure and reliable than the .my.cnf method.

Make sure you create /backups and that it is writeable by root (or whoever the cron job runs as.) Test the command before putting it in your crontab.

You’ll see that I’m doing a mysqldump of the database named ‘mysql’ — this is intentional as it is the database that holds configuration information including database users which you’ll probably want during a restoration.

Also, I’m doing a backup of /etc which is where most configuration files are stored. Half of a website is how it’s configured, so you’ll definitely want that during a restoration.

This should take care of most Apache/MySQL websites as long as all websites are stored in /var/www — if not, modify the script as needed.

Finally, it would be a good idea to encrypt these files or at least make sure they’re chmod 700 — readable only by the folder owner and nobody else — because they will invariably contain passwords in the config files and mysql tables. Your mileage may vary and it’s your responsibility to make sure you’re adequately secured.

To copy the backups to another server and extract the www backup, use this (from the new server):

cd ~
scp"/backups/etc-backup.tgz /backups/www-backup.tgz /backups/DBNAME.sql /backups/mysql.sql" .

Replace USER, EXAMPLE, and DBNAME with your own values.

To restore these backups to a blank server (possibly during a migration) use these commands (mysql password should have been set during mysql-server install):

rm /var/www/index.html
cd /
tar -zxvf ~/www-backup.tgz
mysql -u root -pPASSWORD
create database DBNAME;
create user 'USER'@'localhost' identified by 'PASSWORD';
GRANT ALL ON DBNAME.* TO 'USER'@'localhost';

Again, replace PASSWORD, DBNAME, and USER with your own values. If you use a password of “password” I’m sure $deity WILL go on a kitten-killing rampage so DON’T DO IT.

Remember to restart apache and mysql with service apache2 restart and service mysql restart (varies based on OS).


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s