Today, we’ll be setting up a base CentOS 5.9 server with nginx, php-fpm, mySQL, and extracting a cPanel account into it. This is useful if you have a single website you need to migrate from one provider into a dedicated environment, and you need it to run as predictably as possible with as little RAM as possible. Let’s get started by updating the operating system. Then we’ll proceed to setting up each individual service before extracting the backup into them all at once.
1. Update the Operating System
The first thing to do is make sure you’re running your latest-and-greatest before you open yourself up to the public.
yum update -y
Review the packages you just installed. If you see a kernel, reboot the system before continuing.
Next, let’s add the nginx repo. That just makes things easier, we probably don’t need to manually compile nginx.
rpm -Uvh http://nginx.org/packages/centos/5/noarch/RPMS/nginx-release-centos-5-0.el5.ngx.noarch.rpm
We also need the EPEL and IUS repositories in order to get some more updated PHP binaries as well as php-fpm.
rpm -Uvh http://mirrors.servercentral.net/fedora/epel/5/i386/epel-release-5-4.noarch.rpm
rpm -Uvh http://dl.iuscommunity.org/pub/ius/stable/Redhat/5/x86_64/ius-release-1.0-10.ius.el5.noarch.rpm
2. Install and Configure nginx
And now, let’s install (and start) nginx.
yum -y install nginx
/etc/init.d/nginx start
At this point, you should be able to go to your server’s main IP address and see the nginx default page.
3. Install mySQL
Let’s install mySQL next, so we have the client and server set up before we try to install PHP to connect to it.
yum install mysql-server
Once you’ve installed the package, you still need to configure the mysql server:
/etc/init.d/mysqld start
mysql_secure_installation
Answer some questions, and then create the file /root/.my.cnf in your favorite text editor. Add the following lines:
[client]
user=root
pass=Your new root password
This will allow you to connect to mySQL from the root user command line without specifying the mySQL root password.
4. Install PHP/php-fpm
Time to install PHP! At a minimum, you need the following packages:
yum install php53u php53u-mysql php53u-fpm
A more complete installation that would more closely mirror a typical cPanel server will look something like this:
yum install php53u php53u-fpm php53u-mysql php53u-gd php53u-mbstring php53u-devel php53u-mcrypt php53u-imap php53u-pear php53u-pdo php53u-xml php53u-soap php53u-ioncube-loader
And finally, start the php-fpm listener:
/etc/init.d/php-fpm start
5. Configure nginx to use php-fpm
Now it’s time to configure your nginx configuration file to (securely!) pass PHP files to nginx. This information comes via this blog entry, which contains some nifty information on why other blog entries on how to set up nginx and php-fpm leave you open for a really nasty attack. I’ve made a lot of modifications to the code though, so don’t copy directly from that blog, as it may not work. I found that I needed to set “root” under the PHP location as well to get the path info working.
First, open your /etc/nginx/conf.d/default.conf file in your favorite text editor. You’ll likely see the following:
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
I like to leave the default configuration example/comments intact in these files so I have something to refer back to if I break my server, so just add some empty lines below those comments and add the following:
# Pass all .php files onto a php-fpm/php-fcgi server.
location ~ \.php$ {
root /home/user/public_html;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
# fastcgi_intercept_errors on;
add_header request $request_filename;
if (-f $request_filename) {
fastcgi_pass 127.0.0.1:9000;
}
}
You’re also going to want to uncomment the lines below that in the default file:
location ~ /\.ht {
deny all;
}
At this point you can make any other changes you want, including changing the “root” location (your document root; I recommend setting the same location you had in cPanel), your listen IP/port, your server_name, your error_pages, your “index” (you probably want to add “index.php” here), etc. At this point, you should also review /etc/php-fpm.conf and /etc/php-fpm.d/www.conf. The latter file especially impacts your permissions, as you will set the user PHP runs as on this. It might be a good idea to create a system user named the same thing as your cPanel user, and make sure your files are chowned and chmoded appropriately.
6. Extract your cPanel backup
You’re halfway there! It’s time to start picking apart the elements of a cPanel backup file. Let’s look at an extracted cpmove backup file.
addons homedir.tar mysql/ resellerpackages/ userconfig/
bandwidth/ httpfiles/ mysql.sql sds userdata/
counters/ interchange/ mysql-timestamps/ sds2 va/
cp/ locale/ nobodyfiles shadow vad/
cron/ logaholic/ pds shell version
dnszones/ logs/ proftpdpasswd sslcerts/ vf/
domainkeys/ meta/ psql/ ssldomain/
fp/ mm/ quota sslkeys/
homedir/ mma/ resellerconfig/ suspended/
homedir_paths mms/ resellerfeatures/ suspendinfo/
Ouch! Okay, let’s just mess with what’s absolutely essential to get this up and running.
mv homedir.tar homedir/
cd homedir/
tar -xf homedir.tar
ls
Now this looks a little more familiar, right?
bin/ cpmove.psql/ homedir.tar php/ tmp/
cpanel3-skel/ cpmove.psql.1339066964/ mail/ public_ftp/ www/
cpbackup-exclude.conf etc/ perl5/ public_html/
Your directory structure may vary somewhat. The most important thing to us here is that public_html directory. Move it to wherever you want your document_root to be and set the ownership properly.
mv public_html /home/user/
chown -R user:user /home/user/public_html
Now it’s time to import the mySQL databases and users. Users are stored in the “mysql.sql” file at the root of the backup; individual databases are stored in the mysql directory.
cd ../
mysql < mysql.sql
for i in `ls | grep .sql | grep -v horde | grep -v roundcube | cut -d\. -f1`; do mysql < $i.create; mysql $i < $i.sql;done
6. Manual configs
Okay, now we're into some more dicey stuff this tutorial won't cover. You should check your backup file for things like PostgreSQL, cron jobs, SSL certificates, restoring log files/webalizer information, DNS, and e-mail. We might cover that in a later tutorial. At this point, however, you should have a fully-functional website! Just host DNS elsewhere, point it at your new server, and go!