Welcome to another LowEndBox Linux tutorial! In this post we’re going to design and configure a high performance server that will allow you to run multiple websites using the latest software available. Our server will be based on CentOS 7 Linux, Apache 2.4, MariaDB (a fork of MySQL) and PHP 7.3. This combination of software is referred to as a “LAMP” stack.
Why would we want to manually configure a LAMP stack instead of installing a control panel like Virtualmin or cPanel that would do it for us? Sometimes we want to build a custom server with only the specific features we desire. Or, we want to learn how all of the software works and is configured. Perhaps we want to save all of our server power for serving sites rather than dedicating some overhead to running a control panel. Whatever your reason, even a small Low End VPS can host several sites successfully with a bit of configuration.
There are many LAMP stack tutorials around of course. Some of them show you how to simply install Linux, Apache, MariaDB and PHP in a default configuration that is suitable for only hosting a single website. Furthermore, many of them rely on the default installation of CentOS which contains some rather outdated software such as PHP 5.4.
We’re going to step it up a couple of notches. In this tutorial we’ll show you how to take a default CentOS 7 installation and configure it with the latest software with a performant configuration that you’ll be proud to host multiple websites on. But we’re not stopping there. This tutorial is also going to help you understand why we’ve made the design choices we’re making and how all of the components interact with each other.
In future posts we’ll add features to it, so make sure to check back for more later!
Turning On The LAMP
As mentioned, a LAMP server is simply Linux, Apache, PHP, and MariaDB. To do it right though, there are some things to take into consideration. One of the reasons that CentOS 7 is an amazing server OS is that it favors stability and security over all else. As a result, the CentOS repositories supply PHP 5.4 and MariaDB 5.5, which is what was current when CentOS 7 was released. These are very, very old versions of PHP and MariaDB. PHP 5.4 is no longer usable with modern software such as WordPress.
To remedy these issues, we’re going to configure our server to get the software from other repositories that make PHP 7.3 and MariaDB 10.3.15 (at the time of publishing) available. For the sake of this tutorial we’re going to assume that the server has a single IP address. Our own server is a 1 core VPS with 512MB memory and 15GB disk. Let’s get started!
Pre-Configuration
Log into your VPS provider’s control panel, and start by setting the hostname for your server. It has to be what’s called a “Fully Qualified Domain Name”, or FQDN. It will look like “server.your-domainname.tld”. You must use a prefix such as “server” before any name you choose. We’ll set up hosting for “your-domainname.tld” later on in the process.
Inside your VPS provider’s control panel, they’ll will provide you with a means for installing your OS of choice.You’re going to want to choose “CentOS 7 Minimal 64 bit” or something like it. Here’s what it look on our LowEndBox:
Note down the root password and wait for the installation to complete. Once it’s done, get logged in and set up your SSH keys. If you’re not sure how to do that, don’t worry. We’ve got you covered in our other tutorial “Using SSH Keys to connect to your VPS“.
Now that you’re logged in, it’s time to take care of some basic configuration needs. The first thing we have to do is disable SELinux. Use the following command to do that:
sed -i 's/SELINUX=.*$/SELINUX=disabled/' /etc/selinux/config
Now reboot the server (Just type “reboot” and press enter) and get logged back in. Let’s make sure that SELinux is disabled with the “getenforce” command:
Disabled- perfect! Now we can continue with the next bit of preparation: allowing traffic on port 80 through the firewall. Your VPS provider may have included “FirewallD” which is CentOS 7’s built in firewall, but they might not have. Let’s check first. Use the following command to determine if it’s installed:
rpm -qa | grep firewalld
You should see the following output:
If you don’t, then FirewallD needs to be installed with the following command:
yum -y install firewalld
Now you can open up port 80 (http) and reload the firewall rules:
firewall-cmd --zone=public --add-service=http --permanent firewall-cmd --reload
The last bit of preparation is installing software sources that will provide us with the more up to date versions of PHP and MariaDB. Paste the following commands in your terminal:
curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm yum-config-manager --enable remi-php73 yum makecache fast
The Work Begins
Now that the initial configuration is done, we can start installing the things that are going to turn our minimal CentOS 7 installation into a real LAMP server. To start, we’re going to install some basic utilities that we may need down the road, including the simple Linux text editor nano. Run this command:
yum -y install sysstat lsof traceroute whois wget ftp nano yum-utils
We’re going to install Apache (the HTTP daemon, also called httpd) and MariaDB next:
yum -y install httpd mariadb-server mariadb mod_ssl
We want Apache and MariaDB to start automatically when the server boots up, and we also want to start them now:
systemctl enable httpd.service systemctl enable mariadb systemctl start httpd.service systemctl start mariadb
Now let’s clean up the MariaDB installation a bit with the command “mysql_secure_installation”. Here’s how it looked on our server:
Your current root password will be empty, so just press Enter. Now it’ll ask you to set a root password for MariaDB. This does not have to match the root password of the server. It is recommended to set a secure password just as you would for the root Linux user however. Make sure you take note of the password that you set, because it’s vital to the operation and configuration of the server. Just press Enter for the rest of the questions that the script asks.
Your results should look like the following:
PHP and Virtual Hosting
Apache is a modular program, but it doesn’t natively know how to run PHP scripts. A PHP script produces output that Apache can pass along to anyone asking for it, but PHP has to do the heavy lifting. For this, Apache has an interface called the Common Gateway Interface, or CGI. The official Apache documentation explains it this way:
“The CGI (Common Gateway Interface) defines a way for a web server to interact with external content-generating programs, which are often referred to as CGI programs or CGI scripts.”
Other methods came after CGI including DSO ,suPHP, and FastCGI. For a deeper consideration of these technologies, we recommend this fantastic article by Chris Wiegman.
The PHP handler we’re going to use isn’t mentioned in that article specifically, but PHP FastCGI Process Manager (PHP-FPM) is an implementation of FastCGI. PHP-FPM is very fast, because PHP is always ready for Apache to give it something to do. It’s secure, because PHP scripts are ran under the ownership of the website owner.
Now let’s consider the way we’re going to configure Apache for the hosting of websites. There are two kinds of hosting: Virtual and non-virtual hosting. Non-virtual hosting means that a website is directly linked to an IP address, so each website must have its own IP address. This is what you have if you upload a website directly to /var/www/html after installing Apache. It also means that you’re very limited to the number of websites you can host on a server (one).
Virtual hosting means that websites are tied to a domain name instead, and so all sites can use the same IP address. Each website will have its own Linux user, Apache configuration file, and PHP-FPM configuration file. You can add as many virtual hosts as your server can handle instead of being limited to just one website per server. Let’s get into the actual configuration work. We’ll explain it all along the way.
Setting up PHP-FPM with PHP 7.3
We installed the Remi repository earlier because the Remi repository has everything we’ll need to install PHP 7.3 with PHP-FPM. In addition to PHP-FPM, we’ll also install many of the most commonly needed modules, including the mysqlnd module that lets PHP talk to MariaDB.
Paste this command into your SSH session:
yum -y install php73 php73-php-fpm php73-php-common php73-php-fpm php73-php-gd php73-php-json \
php73-php-mbstring php73-php-mysqlnd php73-php-xml php73-php-xmlrpc php73-php-opcache \
php73-php-pecl-ssh2 php73-php-gd php73-php-bcmath php-pear-Net-Curl.noarch php73-php-pecl-imagick \
php73-php-xml php73-php-xmlrpc php73-php-pecl-mcrypt
We’ll also want to use PHP 7.3 from the command line, so we’ll invoke the Software Collection utility which makes this easy:
scl enable php73 bash
Setting up Virtual Hosting
All of the software is in place. Now it’s time to add a new user to our server and configure a website for it, and then we’ll have our first virtual host fully configured and we can start hosting websites. These steps are found in in the next installment. Click Here to go to Part 2.
Related Posts:
- CentOS 7 LAMP Server Tutorial Part 6: Moving to NGINX - July 15, 2019
- CentOS 7 LAMP Server Tutorial Part 5: Speeding up WordPress with Redis - July 1, 2019
- CentOS 7 LAMP Server Tutorial Part 4: WordPress and wp-cli - June 15, 2019
“The first thing we have to do is disable SELinux”
Will there be a part 3 or should we leave it disabled?
SELinux usually isn’t used in a web hosting environment, and we won’t be re-enabling it. There will definitely be more articles it in this series. Thanks for the comment!
I have one question. Is there any way to re-enable SELinux?
Thanks for the comment! I’m sure it’s possible to re-enable SELinux, but it’s not part of this tutorial. See the previous answer :)
If you want to enable HTTPS (443), do you need to enable HTTP (80) as well?
@Royston, Port 80 MUST be open. If you don’t open port 80 then people who don’t type in https:// will never get to your site. Let’s Encrypt uses DCV over HTTP to validate the domain when you request a certificate. If you don’t have port 80 open, then DCV will fail and you won’t get an SSL certificate.