May 22

Server Migration (httpd.conf & mysql)

Tags:

———————————————————————
– OVERVIEW / THOUGHT PROCESS –
———————————————————————

The following will be a small experiment to answer some questions that have peaked my curiosity. In this scenario, I have two separate CentOS servers with two different public IP addresses. Both have SSH enabled through the firewall and I need to move multiple websites from server 1 to server 2.

The web configuration will be apache and virtual servers will be configured in the httpd.conf file so that server 2 can house all of the multiple websites using one public IP address.

In addition, some of the sites are stand-alone, and others require an sql database to provide the information. Therefore, moving the sql databases will be part of the migration to server 2.

———————————————————————
NEW (VIRTUAL) HTTPD.CONF FILE:
———————————————————————

The following is located on the bottom portion of my httpd.conf file. Website 1 already existed on the new server as apache’s default. This virtual website 2 entry was added so that apache will recognize the requests for website 2 and send browsers to the appropriate directory. I left the entry for website 1, but commented out to remind me that website 1 was the default, but it will not be used in this configuration as a virtual site.

My theory in this example was that since apache recognized website 1 as its default, it would simply send the request to the directory /var/www/html/website1.com. Requests other than website 1 would be routed to the appropriate directory using the <VirtualHost> entry for website 2 below.

#NameVirtualHost *:80

# <VirtualHost *:80>
# ServerAdmin user@website1.com
# DocumentRoot “/var/www/html/website1.com”
# ServerName website1.com
# ServerAlias www.website1.com
# ErrorLog “logs/website1.com/error_log”
# CustomLog “logs/website1.com/access_log” common
# </VirtualHost>

<VirtualHost *:80>
ServerAdmin user@website2.com
DocumentRoot “/var/www/html/virtual/website2.com”
ServerName website2.com
ServerAlias www.website2.com
ErrorLog “logs/website2.com/error_log”
CustomLog “logs/website2.com/access_log” common
</VirtualHost>

– Now that the configuration on server 2 is complete for the httpd.conf file, I need to move the webpage files over and restart the httpd service to have apache recognize the changes.

# SERVER 1:
$ sudo scp /var/www/html/website2.com user@<server 2 ip>:/var/www/html/virtual/

NOTE: Root owns the website2.com files and therefore sudo must be used to move them to another server. If you are unable to scp into server 2 because root owns the directories, you may need to make a temporary directory for a normal user and copy the files to the appropriate location on server 2 after they have been migrated from server 1.

#SERVER 2:
$ sudo mkdir /var/log/httpd/website2.com
$ sudo nano error_log
$ sudo nano access_log
$ sudo service httpd restart

– The only thing left to do is to change the DNS ‘A’ entry for website 2 and direct it to the new public IP address for server 2. Once that’s complete and the changes take effect, I’ll go visit https://website1.com and https://website2.com to see if everything worked properly.

RESULTS?!?: Using this configuration, https://website1.com resolves to website2.com. I thought that the default configuration for the httpd.conf file (not shown here) would bring the website1.com request to the home directory of /var/www/html and to an index page that redirected to the https:// version using port 443, but I was wrong.
Website2.com still resolves to the proper directory of /var/www/html/virtual/website2.com, so we now know that apache is recognizing this entry. The question is, why is it not resolving website1.com? As a reminder, the virtual entry for website1.com is commented out at this point and we were relying on the default settings in the httpd.conf file. Those default settings were over-taken by the VirtualHost entry for website2.com… so let’s try something else.

 

———————————————————————
WEBSITE 2 VIRTUAL DIRECTORY:
———————————————————————

Because the default settings didn’t resolve website1.com to the /var/www/html/ directory like I thought it would, I created a second VirtualHost entry for website1.com.

#NameVirtualHost *:80

<VirtualHost *:80>
ServerAdmin user@website1.com
DocumentRoot “/var/www/html/virtual/website1.com”
ServerName website1.com
ServerAlias www.website1.com
ErrorLog “logs/website1.com/error_log”
CustomLog “logs/website1.com/access_log” common
</VirtualHost>

<VirtualHost *:80>
ServerAdmin user@website2.com
DocumentRoot “/var/www/html/virtual/website2.com”
ServerName website2.com
ServerAlias www.website2.com
ErrorLog “logs/website2.com/error_log”
CustomLog “logs/website2.com/access_log” common
</VirtualHost>

– Upon restart of the httpd service, this is the message I received:

$ sudo service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [Tue May 21 23:16:04 2013] [warn] _default_ VirtualHost overlap on port 80, the first has precedence [ OK ]

– Since the “first has precedence” the request for website2.com resolved to website1.com (first entry). In the same respect, the virtual folder is being used now (/var/www/html/virtual/website1.com) for all references to the root directory for the site.

 

———————————————————————
DUHHH!!
———————————————————————

You may have noticed that I was leaving the key variable to virtual hosting on apache in each of my examples above. This is because, as is in many cases, syntax was the problem all along and I was so quick to change my entries, I didn’t notice. The ‘NameVirtualHost’ portion is commented out by default on my httpd.conf file and I was using the default configuration on server 2. You sort of need that header in order for the server to recognize your virtual hosts….

When the comment was removed, both website1.com and website2.com resolved correctly. My redirection to port 443 for website1.com worked as well as it now recognized the new root directory for website1.com.

———————————————————————
MOVING THE SQL FILES:
———————————————————————

For a wordpress installations, there are two entities to move. The website files and the database. After creating an entry in the httpd.conf file for the new website3.com virtual server, I moved the website files from server 1 to server 2 using the scp command under a sudo user since root owns them. Then, I backed up the database from server 1 and restored it to the database on server 2. As you will see below, the mysqldump command can be used for this sql backup process.

SERVER 1:
$ sudo scp /var/www/html/website3.com user@<server 2 ip>:~/var/www/html/virtual/
$ cd ~
$ mysqldump -u root -p website3database > website3database.sql
Enter password:
$ scp ~/website3database.sql user@<server 2 ip>:~/sql_restore_directory/

NOTE: you’d need to enter your user’s password for scp unless you install the private/public key. Since root doesn’t own the .sql backup files, you won’t need to run it as a sudo user. Refer to Fedora (let’s make a server) ‘Create SSH Key on Local Machine’ section for more details.

SERVER 2:
$ mysql -u root -p
mysql> create database website3database;
$ mysql -u root -p website3database < ~/sql_restore_directory/website3database.sql
Enter password:
$ mysql -u root -p
mysql> GRANT ALL PRIVILEGES ON websitedatabase.* TO owner@localhost IDENTIFIED BY ‘password’;
mysql> flush privileges;
mysql> quit

Then, I changed the DNS ‘A’ entry for the site from my old server to the new one.

RESULTS?!?: After waiting a few minutes for the DNS entry to take effect, I visited website3.com, but was presented with a blank white page. Through past experience, I know that this is because the files in the requested directory can’t be read by the apache group.

After looking over the permission, I was correct. The owner and group was still set to root after copying them to the next server. I changed the group permissions to apache and the site started working. Now I’ll have to look over the rest of the permissions to give write permissions where needed.

 

———————————————————————
RESTORE SQL WITHOUT ‘GRANT’
———————————————————————

There was one thing I was curious about… if I restore a database, does it keep the ‘GRANT’ privileges that I assigned in mysql on server 1? To answer this, I migrated website4.com with a database, moved the site files and the database, and visited website4.com after changing the group privileges to apache.

SERVER 1:
$ sudo scp /var/www/html/website4.com user@<server 2 ip>:~/var/www/html/virtual/
$ cd ~
$ mysqldump -u root -p website4database > website4database.sql
Enter password:
$ scp ~/website4database.sql user@<server 2 ip>:~/sql_restore_directory/

SERVER 2:
$ mysql -u root -p
Enter password:
mysql> create database website4database;
mysql> quit
$ mysql -u root -p website4database < ~/new_sql_directory/website4database.sql
Enter password:
$ sudo chgrp -R apache /var/www/html/virtual/website2.com

NOTE: here’s where you change the DNS ‘A’ entry for website4 to the new server 2 IP. The effects were immediate in my case.

# Now restart the httpd service to have the httpd.conf file changes take effect:
$ sudo service httpd restart

RESULT?!?: I got the error that appears when the website can’t talk to the database. Specifically, it says “Error establishing a database connection.”

# So let’s go ahead and grant access to the database and see what happens. I think it should work:
$ mysql -u root -p
Enter password:
mysql> GRANT ALL PRIVILEGES ON website4database.* TO user@localhost IDENTIFIED BY ‘password’;
mysql> flush privileges;
mysql> quit

RESULT?!?: Yep, it worked just fine. So the grant privileges don’t transfer when restoring a database.

 

———————————————————————
SUMMARY
———————————————————————

THE PROCESS:
1. Copy the website files from server 1 to server 2 using scp and sudo user
2. Ensure the permissions are correct (apache group)
3. Backup the database and copy the .sql file to server 2 using scp
4. Create the same database name on server 2 with mysql and restore the backup .sql file to it
5. Make the appropriate changes to your httpd.conf file on server 2
6. Make sure you create the log file directories in /var/log/httpd/ with error_log and access_log in them
7. Restart your httpd service on server 2
8. Ensure functionality / troubleshoot as appropriate

—————————————–

Always remember… WHAT IF AND WHY NOT?!?