How to Set Up a LAMP Stack on Red Hat Enterprise Linux 7
Depending on your organizational needs, your server may have a GUI, or you may simply have terminal access. With either option, you can use RHEL 7 to set up a LAMP stack.
Join the DZone community and get the full member experience.
Join For FreeSo, you have been asked to create a LAMP stack. Whether you’re thinking “Lamp stack, as in lights and bulbs?” or “OK, let’s build a web server,” this guide will help get you working quickly.
First, for those that do not know, a LAMP stack (also known simply as LAMP) refers to an acronym for a Linux/UNIX server with Apache as the server engine, MySQL/MariaDB as the database engine, and PHP as the primary server-side script language.
These steps are based on RHEL 7.2/7.3, but should work for all versions of RHEL with minimal changes.
Just a couple things that you will need to be ready:
- A decent Internet connection.
- A non-production server to use with this guide.
- This guide assumes that the server was installed with minimal options and is properly registered with a Red Hat subscription.
- Access to the server that allows you Sudo (admin) access.
Depending on your organizational needs, your server may have a graphical user interface (GUI), or you may simply have terminal access. With either option, it is suggested that you go through this guide first on a non-production server in case you need to go through it a couple times.
If you have a GUI, go to the Applications menu, then within the Utilities sub-menu, find the Terminal application and open it.
Within Terminal (whether in the GUI or through SSH), follow these steps to make things easier. You can copy and paste the commands into the Terminal window.
Note: With the yum commands below, this guide does not automatically install any piece of the LAMP stack. After you understand what you are doing, you can use the -y
command to automatically install.
# Will not automatically update
sudo yum update
# Will not automatically install Apache/HTTPD
sudo yum install httpd
# Will automatically update
sudo yum -y update
# Will automatically install Apache/HTTPD
sudo yum -y install httpd
LAMP Installation Steps
- Check your Red Hat registration. The script below will help with that. If you are properly registered, you will receive a message saying “Properly Registered.” Otherwise, you will receive prompts to type in the Red Hat username and password along with the hostname of the server.
if [ "$(sudo subscription-manager status| grep "Overall Status")" != "Overall Status: Unknown" ]; then clear echo "Properly Registered" else clear echo -e "3[32mRed Hat Registration - Start3[0m" if [ -z ${1+x} ]; then echo -e "3[01m\e[4mType your username for RedHat.com, followed by [ENTER]:\e[0m3[0m" read rhUser else declare rhUser= fi if [ -z ${2+x} ]; then echo -e "3[01m\e[4mType your password for RedHat.com, followed by [ENTER]:\e[0m3[0m" read -s rhPass else declare rhPass= fi clear echo -e "3[32mSet Server Hostname - Start3[0m" if [ -z ${3+x} ]; then echo -e "3[01m\e[4mType your desired hostname for the server, followed by [ENTER]:\e[0m3[0m" read hostname sudo hostnamectl set-hostname $hostname else declare hostname= sudo hostnamectl set-hostname $hostname fi echo -e "3[32mSet Server Hostname - Stop3[0m" # Register Red Hat Server - Start sudo subscription-manager register --username $rhUser --password $rhPass --auto-attach clear sudo subscription-manager refresh clear history -c sudo subscription-manager identity # Register Red Hat Server - Stop echo -e "3[32mRed Hat Registration - Stop3[0m" fi
- Update the System first:
# Update system first sudo yum update
- Install useful applications:
#Install useful applications # nano - text editor alternative to vi # curl / wget - terminal based downloaders # bind-utils / telnet - useful for testing domain and port problems sudo yum install nano curl wget bind-utils telnet
- Install LAMP components.
# Install LAMP # httpd - Base Apache # mod_ssl & openssl - Needed for HTTPS/SSL secure websites # mariadb-server & mariadb - MariaDB Database (latest DB based on MySQL after Oracle bought MySQL) # php - Base PHP # php-mysql - Allow PHP to work with MariaDB/MySQL (depreciated in newer repositories) # php-mysqlnd - Allow PHP to work with MariaDB/MySQL # php-gd - Allow PHP to create/manipulate images # php-mbstring - Allow PHP to work with multi-byte strings - http://php.net/manual/en/book.mbstring.php sudo yum install httpd mod_ssl openssl mariadb-server mariadb php php-mysqlnd php-gd php-mbstring
- Enable Services to have them load at startup.
# Enable Services to have them load at startup sudo systemctl enable httpd.service sudo systemctl enable mariadb.service
- Open Firewall for HTTP and HTTPS.
# Open Firewall for HTTP and HTTPS sudo firewall-cmd --permanent --zone=public --add-service=http sudo firewall-cmd --permanent --zone=public --add-service=https sudo firewall-cmd --reload
- Create a simple PHP info page to verify PHP is working in Apache. The main purpose of this file is to make sure that PHP is working in Apache, but it is also a good file to review for each project to make sure you have all needed PHP modules/extensions installed.
# Create simple PHP Info page to verify PHP is working in Apache sudo echo "" | sudo tee /var/www/html/info.php echo "<?PHP echo 'Server URL: ' . $_SERVER['SERVER_NAME'] . ' Document Root: ' . $_SERVER['DOCUMENT_ROOT']; ?>" | sudo tee /var/www/html/index.php
- Add PHP configuration into Apache. This is a needed step in order to have PHP handled properly in Apache.
# Create a backup of your original Apache configuration sudo cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.original sudo sed -i -e 's/^[ \t]*//' /etc/httpd/conf/httpd.conf sudo sed -i "s|IncludeOptional|#IncludeOptional|" /etc/httpd/conf/httpd.conf sudo sed -i "s|#ServerName www.example.com:80|ServerName localhost|" /etc/httpd/conf/httpd.conf sudo sed -i "s|DirectoryIndex index.html|DirectoryIndex index.html index.php|" /etc/httpd/conf/httpd.conf # Add PHP configuration into Apache echo "AddType application/x-httpd-php .php" | sudo tee -a /etc/httpd/conf/httpd.conf
- Secure MariaDB/MySQL. This is a needed step to protect your MariaDB/MySQL server. This command will first start the service then ask a series of questions, based on the needs of the project the answers will vary.
This is what you will see:# Secure MariaDB/MySQL sudo systemctl start mariadb.service clear sudo /usr/bin/mysql_secure_installation
$ sudo /usr/bin/mysql_secure_installation NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY! In order to log into MariaDB to secure it, we'll need the current password for the root user. If you've just installed MariaDB, and you haven't set the root password yet, the password will be blank, so you should just press enter here. Enter current password for root (enter for none):
- Start Apache:
# Start Apache sudo systemctl start httpd.service
- Load your site. If you are in a GUI, you may or may not have an internet browser on your machine. If you have a browser, you can open it and simply go to http://localhost/info.php. If you are in SSH/Terminal, the code below should load HTML of the default site for you if everything is working:
curl http://localhost/info.php
At this point, you should have a working HTTP LAMP stack but it will only run one website.
Multi-Site Installation Steps
Very few LAMP stacks are set up specifically to run only one website. The steps below will help you get your server serving multiple websites — again, with little effort on your part.
- For multi-site to work, we need to change SELinux to run in permissive mode. Note: Check with your company’s IT security. Some companies may have a problem with this where others may have no problem with it. Running the below script will change the setting for you and then restart the server.
clear sudo cp /etc/selinux/config /etc/selinux/config.original sudo sed -i '/^#/d' /etc/selinux/config sudo sed -i '/^$/d' /etc/selinux/config SELinuxStatus=$(cat /etc/selinux/config | grep SELINUX=|cut -d'=' -f2) echo "Current Status: $SELinuxStatus" sudo sed -i "s|SELINUX=$SELinuxStatus|SELINUX=permissive|" /etc/selinux/config SELinuxStatus=$(cat /etc/selinux/config | grep SELINUX=|cut -d'=' -f2) echo "New Status: $SELinuxStatus" sudo shutdown -r now
- Create a file called
websites.csv
. Within this file, we will define the additional sites for the server.
ThisDomainName, HTTP_Port, HTTPS_Port,SSLCertificateFile,SSLCertificateKeyFile
websites.csv
file has some logic tied to it in that if you do not define theHTTPS_Port
,SSLCertificateFile
, andSSLCertificateKeyFile
, your site will simply be HTTP and not a secure site (HTTPS). This script below will create the header of the CSV for you and then load the file in the nano text editor. Type in the values, remembering to add a comma as the delimiter (make sure not to add spacing). When you are done, hold down the Ctrl key and type the X key to close the file. The system will ask you if you want to save. Type Y for yes or N for no then tap the Return key.
Here is an example of what the final file could look like:echo -e "DomainName, HTTP_Port, HTTPS_Port,SSLCertificateFile,SSLCertificateKeyFile\n" | sudo tee /var/www/websites.csv sudo nano /var/www/websites.csv
DomainName, HTTP_Port, HTTPS_Port,SSLCertificateFile,SSLCertificateKeyFile test.someurl.local,80,443,/etc/httpd/ssl/SSLCRT.crt,/etc/httpd/ssl/SSLKey.key test2.someurl.local,80
- Where you put your SSL certificate files may differ from how this guide suggests. The guide will focus on the location of the files as
/etc/httpd/ssl
. Make sure you have the CRT and key files both in the/etc/httpd/ssl
directory (or the directory you choose). - Set some basic variables for the following steps:
# Declare main variables - start declare netAdapter=$(nmcli device status | grep en | cut -d " " -f1) if [ -z "$netAdapter" ]; then netAdapter=$(nmcli device status | grep eth | cut -d " " -f1) fi declare netIP=$(/sbin/ip -o -4 addr list $netAdapter | awk '{print }' | cut -d/ -f1) #declare netCIDR=$(/sbin/ip -o -4 addr list $netAdapter | cut -d ' ' -f7) declare netMask=$(ipcalc -m $netIP | cut -d '=' -f2) declare netCIDR=$(ipcalc -p $netIP $netMask | cut -d '=' -f2) declare netWork=$(ipcalc -n $netIP $netMask | cut -d '=' -f2) echo -e "Hostname: $(hostname)\n$netAdapter: $netIP\nNetmask: $netMask\nCIDR: $netWork/$netCIDR" declare AzureServer=$(awk -v address="$netIP" -f /opt/DSP/checkIP.awk /opt/DSP/AzureIPRange.txt) LoggedInUser=$(whoami) echo $LoggedInUser # Declare main variables - stop
- OPTIONAL: Remove GUI desktop.
sudo yum remove gnome-desktop*
- In the situation that you have multiple web developers, a web developer group is helpful.
# Create Web Developer Group sudo groupadd webdev # Add users to Web Developer Group sudo usermod -G webdev -a $LoggedInUser sudo usermod -G webdev -a apache sudo usermod -G webdev -a root # Create webdev User and add it to the Web Developer Group sudo useradd -g webdev -m webdev USR=webdev # This will generate a random, 8-character password: PASS=`tr -dc A-Za-z0-9_ < /dev/urandom | head -c8` echo $PASS > ~/webdev_temp_password.txt # This will actually set the password: echo "$USR:$PASS" | sudo chpasswd # List all users in webdev group sudo lid -g webdev | cut -f1 -d'('
- Configure Apache to handle multiple sites:
sudo mkdir /etc/httpd/sites-available sudo mkdir /etc/httpd/sites-enabled sudo cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.original sudo sed -i -e 's/^[ \t]*//' /etc/httpd/conf/httpd.conf sudo sed -i "s|IncludeOptional|#IncludeOptional|" /etc/httpd/conf/httpd.conf sudo sed -i "s|#ServerName www.example.com:80|ServerName localhost|" /etc/httpd/conf/httpd.conf sudo sed -i "s|DirectoryIndex index.html|DirectoryIndex index.html index.php|" /etc/httpd/conf/httpd.conf echo "IncludeOptional /etc/httpd/sites-available/*.conf" | sudo tee -a /etc/httpd/conf/httpd.conf cat /etc/httpd/conf/httpd.conf | grep IncludeOptional cat /etc/httpd/conf/httpd.conf | grep DirectoryIndex
- Let the CSV define the additional sites:
# Read websites.csv file and create virtual host for each site - start sed 1d /var/www/websites.csv | while IFS=$’,’ read -r -a site do echo "Reading CSV File" echo "Domain Name: ${site[0]}" echo "HTTP Port: ${site[1]}" echo "HTTPS Port: ${site[2]}" echo "SSL CRT File: ${site[3]}" echo "SSL Key File: ${site[4]}" if [ -n "${site[1]}" ]; then echo "Configuring HTTP for ${site[0]}" echo -e "\n"\ "ServerName ${site[0]}\n"\ "DocumentRoot /var/www/${site[0]}/public_html\n"\ "ErrorLog /var/www/${site[0]}/error.log\n"\ "CustomLog /var/www/${site[0]}/requests.log combined\n"\ "\n"\ "Options All\n"\ "AllowOverride All\n"\ "Require all granted\n"\ "\n"\ "" | sudo tee /etc/httpd/sites-available/${site[0]}.conf fi if [ -n "${site[2]}" ]; then if [ -z "${site[3]}" ] || [ -z "${site[4]}" ]; then echo "HTTPS Requested but SSL Parameters are not filled" exit 0 fi echo "Configuring HTTPS for ${site[0]}" echo -e "\n"\ "ServerName ${site[0]}\n"\ "DocumentRoot /var/www/${site[0]}/public_html\n"\ "ErrorLog /var/www/${site[0]}/error.log\n"\ "CustomLog /var/www/${site[0]}/requests.log combined\n"\ "\n"\ "Options All\n"\ "AllowOverride All\n"\ "Require all granted\n"\ "\n"\ "SSLEngine on\n"\ "SSLCertificateFile ${site[3]}\n"\ "SSLCertificateKeyFile ${site[4]}\n"\ "" | sudo tee /etc/httpd/sites-available/${site[0]}_secure.conf fi sudo ln -s /etc/httpd/sites-available/${site[0]}.conf /etc/httpd/sites-enabled/${site[0]}.conf sudo mkdir -p /var/www/${site[0]}/public_html echo "$ip ${site[0]}" | sudo tee -a /etc/hosts # Download Test index.php file in place cd /var/www/${site[0]}/public_html echo "<?PHP echo 'Server URL: ' . $_SERVER['SERVER_NAME'] . ' Document Root: ' . $_SERVER['DOCUMENT_ROOT']; ?>" | sudo tee /var/www/${site[0]}/public_html/index.php # Test SSL openssl s_client -connect ${site[0]}:443 done # Read websites.csv file and create virtual host for each site - stop sudo cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.bk sudo sed -i '/^#/d' /etc/httpd/conf/httpd.conf sudo sed -i '/^$/d' /etc/httpd/conf/httpd.conf
- Reassign permissions to the
/var/www/
directory to allow the web dev group read and write access:clear sudo chown -cR apache:webdev /var/www/ sudo chgrp -cRv webdev /var/www/ sudo chmod g+w -Rv /var/www/ sudo chmod -Rv 774 /var/www/
- Test configuration:
apachectl configtest httpd -D DUMP_VHOSTS
- Restart Apache service:
sudo apachectl restart
And you're done!
Published at DZone with permission of David Kittell. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments