Migrating WHMCS to a new server

If you ever have to migrate WHMCS to a new server, you will want to make sure that your automation is working (cron entry installed), and that the date.timezone setting is correct in your php.ini file.

I had migrated WHMCS to a new server recently and it was driving me crazy that the daily 9:00 am automation set up in the Automation Settings was not occurring at the proper time. Sometimes it was 2 hours off, sometimes 4 hours off. Eventually I figured it out – I had edited the php.ini but forgot to set the timezone at all.

date.timezone = “America/New_York”

Bingo. That’s all it took. I manually forced a run of my WHMCS cron command. And afterwards, in the Automation Status section of WHMCS it showed the proper number of hours until the next daily automation was to occur.

cPanel WHM 64 – migrating from EA3 to EA4

All of my machines are [currently] CentOS6 boxes converted to CloudLinux, running cPanel (WHM 64).   Because of cPanel’s new policy on LTS releases, WHM 64 will not go into LTS.   That means that as soon as WHM 66 is in Stable, if one wanted to stay on WHM 64 they would receive no future security updates.   If I want to update to WHM 66 as it comes into Release [and I do], my servers have to be running EasyApache 4, since EasyApache 3 is not supported in WHM 66.

Given that, and the fact that the EasyApache 3 support has been deprecated and is scheduled to be removed altogether at the beginning of 2018, I figured I better get moving on doing some EA3–>EA4 migrations.

( EA3 Deprecation updatehttps://blog.cpanel.com/its-been-a-long-road-but-it-will-be-time-to-say-goodbye-soon/ )

My boxes run CloudLinux / CageFS / Alt-PHP / PHP Selector.    “Native” PHP is not used and is disabled.   I rely completely on CL’s Alt-PHP and PHP Selector.   My EA3 PHP Handler is suphp.   But of course I have mod_lsapi enabled serverwide.

So I downloaded/executed the EA3–>EA4 migration script from CloudLinux.   On this first box I did (dedicated customer, 16 users) it took 10 minutes all told.

cd ~; wget https://repo.cloudlinux.com/cloudlinux/sources/cloudlinux_ea3_to_ea4

sh cloudlinux_ea3_to_ea4 –convert –mod_lsapi –altphp

When I was done I had to do a few things.

For whatever reason, even though ea-mod_lsapi was installed, it didn’t automatically enable globally in EA4 even though it was globally enabled in EA3.   So I had to do this:

/usr/bin/switch_mod_lsapi –enable-global (and then restarted Apache)

This took care of the mod_lsapi issue.  All sites were running mod_lsapi like they should.

In EA3, your vhost includes are in /usr/local/apache/conf/userdata/std/2 and /usr/local/apache/conf/userdata/ssl/2.    In EA4, your vhost includes are in /etc/apache/conf.d/userdata/std/2_4 and /etc/apache/conf.d/userdata/ssl/2_4.    So I had to copy my old includes (which were available in /usr/local/apache.ea3/conf/userdata/std|ssl/2 directories after I migrated to EA4) to the new location.

I then ran:

/scripts/ensure_vhost_includes –all-users



That took care of my vhost includes

Everything is working fine.  No problems that I’m aware of, and no complaints by customers.

old:   /usr/local/apache

new:  /etc/apache2



If your configuration differs much from this, you will have to dot a lot more I’s and cross a lot more T’s.    If you are using “Native” PHP, remember that /usr/local/lib/php.ini (native global php.ini file in EA3) is now duplicated to /opt/cpanel/ea*/root/etc/php.ini, where ea* is each version of MultiPHP that is installed during the migration.

Also remember that during the migration of the old global php.ini to the new location, the migration process comments out any references to ioncube loaders, zend, etc.    You will need to manually massage your global php.ini files for each (MultiPHP) version of PHP you have installed, in /opt/cpanel/ea*/root/etc/.

I chose to completely disable the MultiPHP Manager and MultiPHP ini editor (which you disable in WHM –> Feature Editor), as my customers [and I] only wish to use CloudLinux Alt-PHP and PHP Selector.    You don’t want to keep these enabled if you aren’t using EA4s versions of PHP because it will simply confuse your customer.

If you are reading this, keep in mind that your experience will almost certainly be different if your system is not configured exactly like mine are.   So do not use this post as an instruction manual for migrating from EA3 to EA4.   This post is mainly here for my own personal documentation.   If it helps somebody out, awesome.  If not, it’s no skin off of my ass.




cPanel (the company) — Slow The Fuck Down!

As of this writing, most reputable hosting companies using cPanel software are likely on some combination of WHM 11.52, “54” or “56”.    “58” is now in Release, and “60” is in development.

Why are hosting companies behind on versions?    Because cPanel is pushing technologies into production that are not ready for production use, most obvious being EasyApache 4 ( EA4 ).

cPanel itself had never provided adequate protection for symlink attacks, nor did it provide an adequate jailed environment [at least in my opinion].   CloudLinux came along and saved the day.    Thousands upon thousands of hosting companies flocked to using CloudLinux in combination with their cPanel shared hosting to protect their servers / customers / data.   CloudLinux brought out Alt-PHP (with the PHP selector, allowing you to select any one of a number of versions of PHP) a couple of years ago.    There was no sign at the time that cPanel was going to try and do something similar.   In fact, when people would bring up the idea of multiple PHP versions in feature requests and such, it pretty much seemed to fall  upon deaf ears.

Now, way after all of the sensible admins have switched to CloudLinux with PHP Selector in their cPanel environments, cPanel is pushing hard to get EA4 (EasyApache 4) into production with its own version of multiple PHP support (MultiPHP).    This is a royal clusterfuck.

Not only is EA4 not ready for production on any server that currently hosts 100s or more domains, but cPanel is pushing hard to EOL EA3 (with “60” being the last version of WHM to support EA3).

A few thoughts:

cPanel is pushing out versions too quick, is bringing on new “features” before they are ready for a production environment, and forcing hosting companies to totally scramble and panick trying to think of ways to convert their userbase to EA4, be ride of CentOS 5 and CentOS 6 32-bit, etc.

cPanel started the whole MultiPHP thing too late.    I think that before we ever knew that cPanel was developing support for multiple PHP versions, CloudLinux already had delivered production-ready multiple PHP versions.

CloudLinux’s PHP Selector setup was a learning curve for many, including myself.   And I think that most of the admins using CloudLinux + CageFS + PHP Selector are now loving it once we’ve gotten used to it.   Now cPanel is throwing MultiPHP into the mix.

It’s obvious from the posts I see on the cPanel forums that EA4 is not ready for prime time yet.   There are some horror stories out there from admins who have converted to EA4 thus far.   And so far those reports seem to be from admins who aren’t using CloudLinux’s PHP Selector.    I can only imagine that the nightmares will become much worse for admins using CloudLinux’s PHP Selector to convert to EA4 without issues.

cPanel really needs to slow down and make absolutely positively sure that the switch to EA4 is painless for all admins, whether they are running CloudLinux + PHP Selector or not.

I think cPanel’s take is that it’s CloudLinux’s burden to figure out how in the hell to make PHP Selector work in an EA4+MultiPHP environment.   However, it is unrealistic in my mind to expect CloudLinux to work that miracle when cPanel’s EA4 isn’t refined enough for use in Production.

Now, I’m sure there are hundreds if not more new cPanel servers coming online every day, and I’m sure that WHM 58 is being deployed by default on them with EA4 and MultiPHP.   And I imagine those brand new servers will do just fine.  What I’m concerned about is all of the admins running (a) EA3 who need to convert a server with 500+ accounts to EA4 and (b) those admins who are running CloudLinux + PHP Selector who need to convert a server with 500+ accounts to EA4 AND be able to continue to use PHP Selector without issue.

Then I have to wonder what CloudLinux’s long term plans are since they and cPanel will both be devoting a lot of development time to their versions of multiple PHP support.   Is CloudLinux going to bail out of the multiple PHP version race because cPanel is now doing it?   I sure hope not.   I trust CloudLinux’s implementation — I have a tremendous amount of experience with it.   It  just works.   It’s easy to configure.   It has been done right.   It is refined.

Okay that’s the end of my rambling.

cPanel: Setting up a smarthost for specific domains

Have you ever wanted to relay emails destined for only specific recipient domains to a third-party server (smarthost) rather than being delivered directly from your cPanel server?   If the answer is yes, you’ve come to the right place.

These instructions are for a cPanel server (at this time WHM 54) but really would apply in general to any box running Exim.   Of course the WHM-specific fluff would not be applicable in that case and you would have to edit exim.conf manually.

A.  Create a file to hold your static routes

touch /etc/staticroutes

chown root:mail /etc/staticroutes

B1.  Log into WHM 106 or lower and make some changes

Log into WHM and then go to Exim Configuration Manager –> Advanced Editor

Find the empty box right under Section: ROUTERSTART and add the following:

driver = manualroute
transport = remote_smtp
route_data = ${lookup{$domain}partial-lsearch{/etc/staticroutes}}

Then click Save down at the bottom and wait for it to save changes and restart Exim.

B2.  Log into WHM 108 or newer and make some changes

Log into WHM and then go to Exim Configuration Manager –> Advanced Editor

Find the empty box right under Section: ROUTERSTART and add the following:

driver = manualroute
# if outbound, and forwarding has been done, use an alternate transport
transport = ${if eq {$local_part@$domain} \
{$original_local_part@$original_domain} \
{remote_smtp} {remote_forwarded_smtp}}
transport = remote_smtp
route_data = ${lookup{$domain}partial-lsearch{/etc/staticroutes}}

Then click Save down at the bottom and wait for it to save changes and restart Exim.

C.  edit /etc/staticroutes

Add a domain / smarthost mapping



This tells exim to send all outbound mail destined for the example.com domain to (the smarthost) for further delivery.

D.  Make sure the smarthost allows relaying

Make sure the smarthost box allows the relaying of mail without authentication from the cPanel box’s main IP address.   (since the smarthost box could be any MTA, you’ll have to figure out how to do this on your own).

If we can assume that the smarthost is also a cPanel box, then you can just add the main IP address of the cPanel box that you want to relay from into /etc/trustedmailhosts on the cPanel box that you want to relay to (smarthost).

Joomla site shows odd characters after migrating to new server

I have a customer who has a slew of Joomla websites.  These are all older Joomla sites that are limping along with a short life expectancy while their replacements are being built by the  customer.   The sites had been hosted on various cPanel servers of mine of the years, from the days of PHP 5.2 and MySQL 4.1 all the way up to now, with CloudLinux and MariaDB 10.    Each site has been migrated/transferred to another server multiple times over its lifetime, always to another server running a newer version of MySQL.

Fast Forward.    The customer now has a dedicated server of their own running CloudLinux, cPanel and MariaDB.    The customer wanted these sites migrated to their server, and of course I was on board with that.

I started migrating these sites only to find that after migration many of them were displaying strange characters in place of apostrophes and other “normal” characters.   Obviously some sort of character set / encoding issue.    This really baffled me, and I spent many days investigating the cause and testing different theories and changing configurations to get these sites to display properly.   At no time did I feel that modifying Joomla code or standard Apache / PHP configurations was the answer, since these sites survived numerous migrations in the past without issue.    PHP settings were exactly the same.    SQL character sets, character encoding and collation were all the same.    The databases themselves were unchanged from the dump/import done during the cPanel transfer process.

On Sunday I decided to switch from PHP 5.3 from CloudLinux’s PHP selector to “native” PHP 5.5 compiled through EasyApache 3.   Lo and behold, the sites worked fine.   Ok, I was on top something, but didn’t know what yet.    I brought up some phpinfo data from a site when running native PHP and compared it to phpinfo from a site when running PHP Selector.    After doing a stare-and-compare until my eyes were crossed, I finally realized one thing different about the two phpinfo results.

When running native PHP 5.4, the Client API versions for mysql, mysqli and pdo_mysql PHP modules showed as mysqlnd 5.0.10 – 20111026, but when running Alt-PHP PHP 5.3 from PHP Selector the API versions showed as 10.0.24-MariaDB.   Ahah, now we’re getting somewhere.   My thought that there was something fouled up with the MariaDB specific drivers shipped with CloudLinux’s Alt-PHP, such as them possibly using different collation or something.   I opened up a ticket with CloudLinux.    I had some nice back and forth exchanges with support persons at CL, each time trying something different.   Of course, as mentioned before, I was adamant that I wasn’t going to be changing code or character sets in PHP/Apache or converting databases from one character set or another.

After about an hour of troubleshooting, one of the CL guys suggested that I disable the mysql, mysqli and pdo-mysql modules and enable the nd_mysql, nd_mysqli and nd_pdo_mysql drivers.    Much to my surprise, that resolved my issue.   And now phpinfo when running Alt-PHP PHP 5.3 also showed the Client API version as mysqlnd 5.0.8-dev – 20102224.

(Historically all of my machines are set with mysql, mysqli and pdo_mysql modules enabled in PHP Selector)

So, for these specific sites I am using nd_mysql, nd_mysqli and nd_pdo_mysql modules instead of mysql, mysqli and pdo_mysql.

Obviously the reason why I never had an issue migrating before is because I was always migrating from one MySQL server to another, never to a MariaDB server.

It’s important to say that I’ve migrated 100s of sites (WordPress sites mainly) to Cloudlinux/cPanel servers running MariaDB and never had an issue.   This only cropped up when I was migrating these ancient Joomla 1.5.x sites, and only when migrating to a Cloudlinux/cPanel server running MariaDB.

I appreciate the support of the Cloudlinux crew.  I still don’t know if its a bug in the MariaDB drivers shipped with Alt-PHP or if the behavior is by design.


mysql-mysqli-pdo-mysql       nd_mysql-nd_mysqli-nd_pdo_mysql


website-before         website-after

cPanel / WHM and MariaDB 10 — STRICT_TRANS_TABLES

I’ve been migrating sites from CloudLinux cPanel (WHM 54) boxes running MySQL 5.6 to a CloudLinux cPanel box running MariaDB 10.

I was migrating an old Joomla 1.5.26 site (using PHP 5.3 from PHP Selector) and ran into a situation when attempting to upload a bulletin to the Joomla site.   I’d get through the process of uploading the bulletin (via docman), and when I’d go to save it I would be directed to a blank white screen.    Although it was a blank screen, it would show the error if you viewed the source of the blank page.

alert(‘mosDMDocument::store failed – Incorrect datetime value: ” for column ‘checked_out_time’ at row 1 SQL=INSERT INTO `jos_docman` ( `id`,`catid`,`dmname`,`dmfilename`,`dmdescription`,`dmdate_published`,`dmowner`,`published`,`dmurl`,`dmcounter`,`checked_out`,`checked_out_time`,`approved`,`dmthumbnail`,`dmlastupdateon`,`dmlastupdateby`,`dmsubmitedby`,`dmmantainedby`,`dmlicense_id`,`dmlicense_display`,`access`,`attribs` ) VALUES ( ‘0’,’5′,’COH’,’COH.pdf’,'<p>Test 123</p>’,’2016-02-21 23:33:50′,’-1′,’0′,”,’0′,’0′,”,’1′,”,’2016-02-21 23:34:37′,’62’,’62’,’-6′,’0′,’0′,’0′,’crc_checksum=\nmd5_checksum=’ )’); window.history.go(-1);

It was attempting to store an incorrect value in checked_out_time.   I think it either had to be in valid datetime format or had to be 0 or NULL.   Instead, it was trying to store nothing at all.

As it turns out, when you switch to MariaDB in WHM, the following sql_mode is set in /usr/my.cnf:


In my case, I had a bunch of Joomla 1.5.x and 2.5.x sites to migrate and really needed to not have issues with docman.    So I changed the sql_mode in /usr/my.cnf to:


I restarted MariaDB and the bulletin upload functions worked fine.

I obviously would not advise anybody to remove STRICT_TRANS_TABLES  from sql_mode.    I’m betting newer versions of Joomla’s docman stuff likely is not broken like this version of docman is and thus would not trigger an error.    Much better than lessening the security of your MariaDB install would be to simply upgrade to the latest greatest Joomla / component version.   Easier said than done.   Have you ever tried to upgrade a fully customized Joomla site populated with a lot of content to a new major version (or two in this case)?    Joomla sucks.  I don’t use it — I just support it.