Building and Scaling a Website – Part 1

The Basics

In Part 1 of this guide we will show you how to increase your website performance using the most basic and typical server setup.

This guide assumes that you have a single Cloud Server running CentOS 7 where you plan on hosting a single WordPress site that you will scale in the future by adding additional CPU/RAM. More advanced options for scaling and redundancy will come in future guides.

At the end of Part 1 you will have a new WordPress Website running Apache, PHP 7.3, MariaDB 10.2, and secured with a Let’s Encrypt SSL.

1). yum update

2). vi /etc/yum.repos.d/MariaDB.repo

[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.2/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1 

3). yum install MariaDB-client MariaDB-server

4). service mariadb start

5). mysql_secure_installation

6). yum -y install httpd

7). systemctl enable httpd

8). systemctl start httpd

9). yum install epel-release yum-utils

10). yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm

11). yum-config-manager –enable remi-php73

12). yum install php php-common php-opcache php-mcrypt php-cli php-gd php-curl php-mysqlnd

Configuration

You now have a CentOS 7 server configured with Apache 2.4, MariaDB 10.2, and PHP 7.3. We will now get a WordPress site up and running and secure it with an SSL using Let’s Encrypt.

1). mkdir /var/www/mywebsite.com

2). vi /etc/httpd/conf.d/mywebsite.conf

<VirtualHost *:80>
    ServerName mywebsite.com
    ServerAlias www.mywebsite.com
    DocumentRoot "/var/www/mywebsite.com"
</VirtualHost>

3). systemctl restart httpd

4). mkdir /etc/certbot

5). yum install git

6). cd /etc/certbot

7). git clone https://github.com/certbot/certbot

8). cd certbot

9). ./certbot-auto certonly –webroot -w /var/www/mywebsite.com -d mywebsite.com

10). vi /etc/httpd/conf.d/mywebsite.conf

<VirtualHost *:80>
    ServerName mywebsite.com
    ServerAlias www.mywebsite.com
    DocumentRoot "/var/www/mywebsite.com"
</VirtualHost>
<VirtualHost *:443>
    ServerName mywebsite.com
    ServerAlias www.mywebsite.com
    DocumentRoot "/var/www/mywebsite.com"
    SSLEngine on
    SSLCertificateFile "/etc/letsencrypt/live/mywebsite.com/cert.pem"
    SSLCACertificateFile "/etc/letsencrypt/live/mywebsite.com/chain.pem"
    SSLCertificateKeyFile "/etc/letsencrypt/live/mywebsite.com/privkey.pem"
</VirtualHost>

11). systemctl restart httpd

12). crontab -e

0 23 * * * /etc/certbot/certbot/certbot-auto renew --register-unsafely-without-email --post-hook "apachectl -k restart"

13). mysql -uroot -p

Create DATABASE wp;
CREATE USER 'wordpress'@'%' IDENTIFIED BY 'Xsfd2V^dg1';
GRANT ALL PRIVILEGES ON *.* TO wordpress@'%' IDENTIFIED BY 'Xsfd2V^dg1' WITH GRANT OPTION;

14). cd /var/www/mywebsite.com

15). wget https://wordpress.org/latest.zip

16). yum install bsdtar

17). bsdtar –strip-components=1 -xvf latest.zip

18). chown -R apache:root /var/www/mywebsite.com/

19). Go to mywebsite.com

20). Complete the WordPress setup using the Database information used in Step 13.

Force HTTPS

1). Check to make sure HTTPS is working on your site, then perform the following: vi /etc/httpd/conf/httpd.conf

In the section for Directory “/var/www/html” edit the following:

AllowOverride All

2). vi /etc/httpd/conf.d/mywebsite.conf

<Directory "/var/www/mywebsite.com">
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^(.*)$ https://mywebsite.com/$1 [R=301,L]
</Directory>
<VirtualHost *:80>
    ServerName mywebsite.com
    ServerAlias www.mywebsite.com
    DocumentRoot "/var/www/mywebsite.com"
</VirtualHost>
<VirtualHost *:443>
    ServerName mywebsite.com
    ServerAlias www.mywebsite.com
    DocumentRoot "/var/www/mywebsite.com"
    SSLEngine on
    SSLCertificateFile "/etc/letsencrypt/live/mywebsite.com/fullchain.pem"
    SSLCertificateKeyFile "/etc/letsencrypt/live/mywebsite.com/privkey.pem"
</VirtualHost>

3). vi /var/www/mywebsite.com/.htaccess

Add this to the top of your .htacess file

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^(.*)$ https://mywebsite.com/$1 [R=301,L]

4). apachectl -k restart

SSL Security

1). Test your website’s SSL using: https://www.ssllabs.com/ssltest/

It should look like the following.

2). We will now correct these issues. Typically this will be done in /etc/httpd/conf.d/ssl.conf however if these settings don’t have any effect add them into /etc/httpd/conf/httpd.conf instead:

SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"

3). apachectl -k restart

4). Retest your site and it should now look like the following.

Site performance improvements

These actions will further speed up the site by enabling compression and static asset caching.

1). vi /etc/httpd/conf.d/mod_deflate.conf

<filesMatch "\.(js|html|css)$">
    SetOutputFilter DEFLATE
</filesMatch>

2). vi /etc/httpd/conf.d/expires.conf

ExpiresActive on
ExpiresDefault "access plus 14 days"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType text/x-javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/x-shockwave-flash "access plus 1 month"
ExpiresByType text/css "now plus 1 month"
ExpiresByType image/ico "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 month"
ExpiresByType text/html "access plus 1 days"

3). apachectl -k restart

Conclusion of Part 1

In Part 1 we have got a brand new WordPress site setup and configured on a single Cloud Server. It is light, lean, and should function well.

For further performance improvements and redundancy you can now setup with a 3rd-party CDN such as Cloudflare and/or increase your server’s available CPU/RAM resources as needed.

You may also want to configure a cache/minify plugin for WordPress such as W3TotalCache.

Also be sure to test the site metrics with tools such as webpagetest.org to see if there are any additional minor improvements you can perform such as compressing images.

In Part 2 we will improve this setup by including multiple servers for additional performance, scalability, and redundancy in order to handle large amount of traffic.

Mohammed has written 63 articles

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>