Last Updated: September 17, 2019

Hardware Requirement

We suggest using servers with Xeon CPU. Depending on the nature of the application, if the application requires analyzing user's input in real time, e.g., running lengthy R-scripts, Homer or other 3rd party tools, then a faster CPU or cluster setup (multiple servers) is preferred.

For standard applications that does not require using 3rd party tools in the backend in real time, a single server setup is sufficient.

As of September, 2019, the machine we use is: Intel Xeon E5 2.6GHz, 8 cores and 64GB of memory for hosting simple web applications that have less than 500 of concurrent users.


Software Requirement

Operating System: Linux. Prefer RHEL, CentOS
Database Requirement:
Minimum: MySQL 5.5; Prefer: MariaDB 10.1(Performance Reason)
If you are using MySQL 8.0+, please see the notes below.
Database Server Location: Can be local or remote with low latency.
Memory Database: Redis, prefer local because of low latency.
Webserver Requirement: Apache 2.4+, PHP 7.0 (7.1/7.2/7.3 are known to break certain existing features. Please contact us for details.)

Package Installation

The following tutorial is designed for use in RHEL/CentOS 7. If your system is different, please contact us for details.

Repositories

sudo rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
sudo rpm -Uvh http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
#sudo nano /etc/yum.repos.d/remi.repo
[remi]
enabled=1

[remi-php56]
enabled=0


#sudo nano /etc/yum.repos.d/remi-php70.repo
[remi-php70]
enabled=1

#sudo nano /etc/yum.repos.d/CentOS-Base.repo
[centosplus]
enabled=1

#sudo nano /etc/yum.repos.d/elrepo.repo
[elrepo-testing]
enabled=1

[elrepo-kernel]
enabled=1

[elrepo-extras]
enabled=1


#sudo nano /etc/yum.repos.d/CentOS-fasttrack.repo
[fasttrack]
enabled=1

#sudo nano /etc/yum.repos.d/CentOS-CR.repo
[cr]
enabled=1

Apache 2.4

sudo yum install httpd mod_ssl -y
sudo nano /etc/httpd/conf/httpd.conf
     
<Directory/>
    Options FollowSymLinks
    AllowOverride All
</Directory>

PHP 7.0

We recommand the following packages:

yum install php php-common php-cli php-gd php-mbstring php-xml php-session php-json php-bcmath php-mcrypt php-dba php-tidy php-ldap php-intl php-gmp php-imap php-odbc php-enchant php-pdo_pgsql php-pgsql php-snmp php-soap php-pspell php-recode php-xmlrpc php-mysqlnd php-redis php-zip php-lz4 php-redis redis

Edit /etc/php.ini:

max_execution_time  = 600
max_input_time      = 600
memory_limit        = 8192M
max_input_vars      = 1000000
expose_php          = Off
error_reporting     = E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE & ~E_WARNING
post_max_size       = 1024M
upload_max_filesize = 1024M
short_open_tag      = On
upload_tmp_dir      = /tmp
max_file_uploads    = 100;

Run the following commands to activate the new settings:

sudo systemctl restart httpd.service

MySQL / MariaDB 10.1

By default, RHEL / CentOS includes the MariaDB 5.5 in the repository. You will need to include the 10.1 repository. Please follow this guide to include it in your system.

sudo yum install mariadb-server mariadb -y

Edit /etc/my.cnf:

[mysqld]
max_allowed_packet = 512M
max_connections = 3000
sql_mode=""

[mysqldump]
quick
max_allowed_packet = 512M

Depending on the nature of your hosting environment, if it is a shared server with many databases, you may need to raise the limit of the number of tables (one MySQL table uses three files) used by the system concurrently :

sudo mkdir -p /etc/systemd/system/mariadb.service.d/
sudo nano /etc/systemd/system/mariadb.service.d/limits.conf
[Service]
LimitNOFILE=500000

Run the following commands to activate the new settings:

#If you are using MySQL
sudo systemctl restart mysql.service

#If you are using MariaDB
sudo systemctl restart mariadb.service

Make sure that the MySQL user has full access to the database. Here is an example of creating a database user:

CREATE USER mysql_username@php_application_server_address IDENTIFIED BY 'database_password';
GRANT ALL ON *.* TO 'mysql_username'@'php_application_server_address';

MySQL 8+

By default, MySQL 8.0+ has changed the authentication method, also the default SQL mode will prevent the application from inserting data in some situations. We will need to modify the database settings.

Edit /etc/my.cnf:

[mysqld]
default_authentication_plugin= mysql_native_password
sql_mode=""

Run the following commands to activate the new settings:

sudo systemctl restart mysql.service

Update your MySQL user such that it will use the native authentication method:

mysql -u root -p -h mysql_server_address

#Please modify the highlighted values to match your own server settings.
ALTER USER 'mysql_username'@'php_application_server_address' IDENTIFIED WITH mysql_native_password BY 'mysql_password';

FLUSH PRIVILEGES;

Redis

sudo yum install php-redis redis -y

sudo systemctl start redis
sudo systemctl enable redis

Performance Testing

Create a script in any directory, e.g., /tmp:

nano test.php
<?php

$before = microtime(true);

for ($i=0 ; $i<10000 ; $i++) {

        unset($list);
        for ($j = 0; $j <= 10000; $j++){
                $list[$j] = $j*$j;
        }

        $temp = json_encode($list);
        unset($temp);
}

$after = microtime(true);
echo ($after-$before)/$i . " sec/action\n";

?>

Run the test script:

php test.php

It will output something like the following:

0.00029415340423584 sec/action

The smaller the number, the better the performance. In general, we are looking for 0.0004 or below.