2015-08-28

I am new Red Hat Enterprise Linux version 7 user/sysadmin/developer. This version made the big number change for RHEL 7/CentOS 7. How can I install LAMP (Linux, Apache, MariaDB, PHP) stack on a RHEL version 7 or CentOS Linux version 7 using CLI or over ssh based session?

RHEL 7 has been released and CentOS Linux 7 is on its way with many notable changes. This guide explains how to install LAMP server.

More about LAMP

LAMP is nothing but a software bundle or a platform consisting of Linux operating system, Apache web-server, MySQL database server and PHP (or Perl/Python)scripting language. The LAMP stack is used for building heavy-duty dynamic web sites entirely out of free and open-source software. In this tutorial, I'm going to explain how to Linux, Apache, MySQL/MariaDB (drop in replacement for MySQL), PHP (LAMP) stack On CentOS 7 or RHEL 7.

Check CentOS version:

# cat /etc/redhat-release

Set up Network:

# ip addr

# vi /etc/sysconfig/network-scripts/ifcfg-eno16777736

Note: USERCTL=no // Non-root users are not allowed to control this device.

# systemctl restart network

# ip addr

# /bin/ipcalc --netmask 192.168.6.9

# cat /etc/resolv.conf

Change hostname:

# hostnamectl status

# hostnamectl set-hostname cent-dev.local

# hostnamectl status

# cat /etc/hostname

Set up timezone:

# timedatectl
# timedatectl list-timezones
# timedatectl set-timezone America/Vancouver
# timedatectl

Set up date and time:

# date +%Y%m%d -s "20081128"
# date +%T -s "10:13:13"

To sync date and time automatically:

# yum -y update

# yum -y install ntp

# ntpdate 0.us.pool.ntp.org

Note: ntpdate is deprecated as of September 2012

You can change which ntp server to use:

# vi /etc/ntp.conf

Set ntpd to start up on boot time:

# systemctl enable ntpd.service
# systemctl restart ntpd.service

# ps auxww|grep -i ntpd
# ntpstat
# timedatectl

Set the Hardware Clock to the current System Time:

# hwclock --systohc

Note: hwclock is a utility for accessing the hardware clock. Hardware clock is independent of the operation system you use and works even when the machine is shut down. This program is used to find out the time from the hardware clock and set the system time at boot time.

Update the ~/.bashrc configuration:

# vi ~/.bashrc

# source ~/.bashrc

Update the ~/.inputrc configuration:

# vi ~/.inputrc

Make sure there is a swap space on your system:

# cat /proc/meminfo | grep -i swap

Note: if your system does not have the swap space, please refer to http://blog.ijun.org/2015/04/add-swap-to-amazon-ec2-instance-ebs.html for more information.

Install EPEL and additional repositories on CentOS and Red Hat:

# yum install wget
# yum install epel-release

http://blog.ijun.org/2014/11/install-epel-and-additional.html
https://fedoraproject.org/wiki/EPEL

To find which package provides the ifconfig command:

# yum provides ifconfig

To get the ifconfig command into our system:

# yum install net-tools

# ifconfig | awk '/inet /{print $2}'

Install tmux:
# yum install tmux

# vi ~/.tmux.conf

# tmux
or
# tmux a -d

Install vim-enhanced:

# vim --version
-syntax
-python

# yum install vim-enhanced

# vim --version
+syntax
+python

# yum list installed | grep -i vim
# yum info vim-enhanced

Install tree:

# yum install tree

Install Glances:

# yum install glances

Install Git:

# yum install git

Install firewalld:

# yum install firewalld firewall-config

# systemctl enable firewalld

# systemctl restart firewalld

Install MariaDB:

# yum install mariadb-server

# systemctl enable mariadb.service

# systemctl restart mariadb.service

# systemctl is-active mariadb.service

# /usr/bin/mysql_secure_installation

Setting UTF8 defaults for MySQL:

We recommend against MySQL's utf8 character set, since it does not support 4-byte unicode characters, and strings containing them will be truncated. This is fixed by the newer utf8mb4 character set.

# vim /etc/my.cnf

# mysql -u root -p

mysql> GRANT ALL PRIVILEGES ON *.* TO 'test'@'192.168.0.%' IDENTIFIED BY '123456';
mysql> FLUSH PRIVILEGES;

mysql> CREATE DATABASE mydb DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;

Set up .my.cnf configuration file:

# touch ~/.my.cnf
# chmod 600 ~/.my.cnf
# vim ~/.my.cnf

Add New Rule to firewalld to allow access to MySQL:

# firewall-cmd --permanent --zone=trusted --add-source=127.0.0.1/32
# firewall-cmd --permanent --zone=trusted --add-port=3306/tcp
# firewall-cmd --reload
# firewall-cmd --zone=trusted --list-all

or

# systemctl restart firewalld.service

Install Apache:

# yum install httpd

# systemctl enable httpd.service

# systemctl restart httpd.service

# systemctl reload httpd.service

# systemctl -l status httpd.service

# journalctl -xn

# systemctl is-active httpd.service

# apachectl configtest

# httpd -V

# apachectl graceful

httpd service default configuration files:

Default config file: /etc/httpd/conf/httpd.conf

Configuration files which load modules : /etc/httpd/conf.modules.d/ directory (e.g. PHP)

Select MPMs (Processing Model) as loadable modules [worker, prefork (default)] and event: /etc/httpd/conf.modules.d/00-mpm.conf

Default ports: 80 and 443 (SSL)

Default log files: /var/log/httpd/{access_log,error_log}

Set up a symbolic link:

# cd / ; ln -s var/www/html www

Install PHP:

# yum install php php-mysqlnd php-fpm php-gd php-mbstring php-pdo php-xml php-soap php-pear php-devel pcre-devel gcc gcc-c++ make
# systemctl restart httpd.service

Note: you need php-devel pcre-devel gcc make for PHP APC. Try to add httpd-devel if failed.

You need the php-mcrypt to run Magento:

# yum install php-mcrypt

http://blog.ijun.org/2014/11/how-to-install-php-mcrypt-on-centos-7.html

Open port 80 firewall access:

# firewall-cmd --zone=public --add-port=http/tcp
# firewall-cmd --zone=public --add-port=https/tcp

# firewall-cmd --permanent --zone=public --add-port=http/tcp
# firewall-cmd --permanent --zone=public --add-port=https/tcp

# firewall-cmd --reload
or
# systemctl restart firewalld.service

Block a IP address:

# firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="1.2.3.4" reject'

To remove the rule:

# firewall-cmd --zone=public --remove-rich-rule='rule family="ipv4" source address="1.2.3.4" reject'

If you get 403 forbidden error, then you probably have problem with SELinux, to deal with Security-Enhanced Linux (SELinux):

# namei -l /var/www/html/magento19

# ls -dZ /var/www/html
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html

# chcon -R --reference=/var/www/html /var/www/html/magento19
Or
# chcon -R --type=httpd_sys_content_t /var/www/html/magento19
Or for read and write permission:
# chcon -R -t httpd_sys_rw_content_t /var/www/html/magento19/app/etc

# ps auxwwZ | grep httpd
# ls -dZ /var/www/html/magento19/app/etc
# tail /var/log/audit/audit.log
# tail /var/log/messages

To turn off Security-Enhanced Linux (SELinux):

# setenforce 0

To turn on Security-Enhanced Linux (SELinux):

# setenforce 1

To get the status of a system running SELinux:

# sestatus

Set up Apache MPM and PHP-FPM:

With Apache 2.4, the official module to use is mod_proxy_fcgi instead of the ancient mod_fastcgi. That module, as well as mod_fcgid, were third party modules.

Note: mod_proxy_fcgi now supports network sockets since Apache 2.4.9 ( Unix socket support for mod_proxy_fcgi )

Edit mpm.conf:

# vim /etc/httpd/conf.modules.d/00-mpm.conf

Comment out the following line:

Uncomment the following line:

Make sure the following two lines exist:

# grep -E 'mod_proxy.so|mod_proxy_fcgi' /etc/httpd/conf.modules.d/00-proxy.conf

Add the "if checking" surround the following three lines:

# vim /etc/httpd/conf.d/php.conf

Add the "if checking" surround the following two lines:

# vim /etc/httpd/conf.d/php.conf

Change the following line:

# vim /etc/httpd/conf/httpd.conf

Create and Edit the vhosts file:

# vim /etc/httpd/conf.d/httpd-vhosts.conf

Setting up an SSL secured Web server:

# systemctl reload httpd.service
# httpd -t -D DUMP_VHOSTS

To enable gzip compression:

# egrep 'deflate|header' /etc/httpd/conf.modules.d/00-base.conf

# httpd -t -D DUMP_MODULES | grep deflate

# vim /etc/httpd/conf.d/mod_deflate.conf

# systemctl restart httpd.service

Install Xdebug for debugging PHP:

# pecl install Xdebug

# vim /etc/php.d/xdebug.ini

To search all other php modules:

# yum search php

Edit php.ini:

# vim /etc/php.ini

The default value is 1, which is an extremely insecure setting because it tells PHP to attempt to execute the closest file it can find if a PHP file does not match exactly. This basically would allow users to craft PHP requests in a way that would allow them to execute scripts that they shouldn't be allowed to execute.

Note: if I set it to "cgi.fix_pathinfo = 0", I would get "Access denied (403)" (see security.limit_extensions) or no input file specified error when setting up Magento. You can either:

1. commented out the cgi.fix_pathinfo = 0 line.
2. set cgi.fix_pathinfo = 1
3. try to set "security.limit_extensions = " in the /etc/php-fpm.d/www.conf file.

http://stackoverflow.com/questions/23390531/access-denied-403-for-php-files-with-nginx-php-fpm
http://serverfault.com/questions/627903/is-the-php-option-cgi-fix-pathinfo-really-dangerous-with-nginx-php-fpm

Note: make sure you do:

# touch /var/log/php_errors.log
# chmod 660 /var/log/php_errors.log
# chown root:apache /var/log/php_errors.log

# chcon -t httpd_log_t /var/log/php_errors.log
Or
# chcon -u system_u -t httpd_log_t /var/log/php_errors.log

Install XCache:

XCache is a fast, stable ​PHP opcode cacher that has been proven and is now running on production servers under high load. It is tested (on linux) and supported on all of the latest ​PHP release branches such as PHP_5_1 PHP_5_2 PHP_5_3 PHP_5_4 PHP_5_5. It is more stable than APC. APC would cause segfault segmentation fault.

# yum install php-xcache xcache-admin

# systemctl restart httpd
# systemctl restart php-fpm
# php -v

# echo -n "Your Password" | md5sum

# vim /etc/php.d/xcache.ini

# cp -r /usr/share/xcache/ /var/www/html/

# systemctl restart php-fpm

http://localhost/xcache/

Install APC:

APC would cause segfault segmentation fault. Use XCache instead.

# pecl install apc

# vim /etc/php.d/apc.ini

Copy the apc.php file:

# cp /usr/share/pear/apc.php /var/www/html

Set up php-fpm:

Apach 2.4.8 mod_proxy: Added support for unix domain sockets as the backend server endpoint.

# vim /etc/php-fpm.d/www.conf

If you are using Apach 2.4.8 or above, please change the following line from:

To:

Now, there are different ways to actually forward requests for .php files to this module, ranging from everything (using ProxyPass) to very specific or rewritten files or patterns (using mod_rewrite with the [P] flag).

The method I chose (using ProxyPassMatch) lies somewhere in between these in complexity and flexibility, since it allows you to set one rule for all PHP content of a specific vhost, but will only proxy .php files (or URLs that contain the text .php somewhere in the request).

TCP socket (IP and port) approach

Edit the configuration for a vhost of your choice, and add the following line to it:

# vim /etc/httpd/conf.d/httpd-vhosts.conf

Note: please do change /path/to/your/documentroot to for example /var/www/html/drupal8

Look confusing ? Let's run through it:

ProxyPassMatch

only proxy content that matches the specified regex pattern; in this case:

^/(.*\.php(/.*)?)$

from the documentroot onwards, match everything ending in .php (with the dot escaped), optionally followed by a slash and any continued path you like (some applications use this so-called PathInfo to pass arguments to the php script.)

The ^ (caret) and $ (dollar) signs are used to anchor both the absolute start and end of the URL, to make sure no characters from the request escape our pattern match.

The nested parentheses enable us to refer to the entire request-URI (minus the leading slash) as $1, while still keeping the trailing pathinfo optional.

fcgi://127.0.0.1:9000

forward via mod_proxy_fcgi, using the fastCGI protocol, to the port our php-fpm daemon is listening on.

This determines which fastcgi pool will serve requests proxied by this rule.

/path/to/your/documentroot/

IMPORTANT! This must exactly match the real filesystem location of your php files, because that is where the php-fpm daemon will look for them.

php-fpm just interprets the php files passed to it; it is not a web server, nor does it understand your web servers' namespace, virtualhost layout, or aliases.

IMPORTANT! Read the above again

$1

expands to the entire request-URI from the original request, minus the leading slash (because we already added that above.)

DirectoryIndex /index.php index.php index.html index.htm

Note: a request for / will need to be mapped to a resource on the fcgi backend. Failure to address this may cause a blank response, commonly known as a WSOD (White Screen of Death), especially if only a request URI containing the php extension is proxied, such as this example. The processing chain will first map a request for / to /index.php, then proxy to the PHP-FPM backend correctly.

unix domain socket (UDS) approach

Edit the configuration for a vhost of your choice, and add the following line to it:

# vim /etc/httpd/conf.d/httpd-vhosts.conf

unix:/path/to/socket.sock

the path to your fpm socket

Note that with this approach, the captured request URI ($1) is not passed after the path

Enable php-fpm to start on boot:

# systemctl enable php-fpm.service

Start our PHP processor:

# systemctl restart php-fpm.service
# systemctl restart httpd.service

Check the PHP-FPM setting:

You should see the message: Server API: FPM/FastCGI

# httpd -V

To create a locked user account:

# useradd git -m -c 'git user'

Unlock the account by issuing the passwd command to assign a password and set password aging guidelines:

# passwd git

Add the git user to the apache group:

# usermod -a -G apache git

Show The Groups a User Is In:

# groups git
# id -Gn git

Find out the primary group of a user:

# getent group git

To allow Apache to connect network and sendmail send email:

# setsebool -P httpd_can_network_connect 1
# setsebool -P httpd_can_sendmail 1

Note: -P in the above command means Persistent (across reboots)

# getsebool -a | grep -i httpd_can

# sestatus -b | grep httpd_can

To install redis server:

# yum install redis

Two important redis server configuration files:

# less /etc/redis.conf
# less /etc/redis-sentinel.conf

Start the Redis server:

# systemctl start redis.service

Check the running status of Redis server:

# systemctl status redis.service

To test the installation of Redis:

# redis-cli ping

PONG

To enable Redis server at system's booting time:

# systemctl enable redis.service

To get the listening port 6379 of Redis server:

# ss -nlp | grep redis

To install Redis PHP extension:

# pecl install redis

Add the following line to /etc/php.d/redis.ini:

# echo 'extension=redis.so' >> /etc/php.d/redis.ini

Check to see if Redis PHP extension is installed:

# pecl list | grep redis

Restart Apache and PHP-FPM:

# systemctl restart httpd.service
# systemctl restart php-fpm.service

To see if Redis extension is being loaded by PHP:

# php -m | grep redis

To allow Apache to connect to the Redis server:

# setsebool -P httpd_can_network_connect 1

Note: If you have turned on Security-Enhanced Linux (SELinux), httpd scripts by default are not allowed to connect out to the network.

To list all Redis Databases:

# redis-cli info keyspace

To clear remove delete all data from a particular Redis database:

# redis-cli

127.0.0.1:6379> info keyspace
127.0.0.1:6379> select 0
127.0.0.1:6379> keys *
127.0.0.1:6379> flushdb
127.0.0.1:6379> keys *

To clear remove delete all data from all Redis database:

# redis-cli flushall

Dumping all key/value pairs in a Redis db:

# redis-cli -n 0 keys \*

# redis-cli -n 0 keys \* | xargs -n 1 redis-cli dump

Note: the 0 is the database number.

To store PHP sessions in Redis:

Storing PHP session files in RAM can be much more efficient than storing on disk and can also save some IO. To configure this, you should modify the main php.ini file and change session.save_handler to redis.

# vim /etc/php.ini

# systemctl restart php-fpm

# php -r 'echo phpinfo();' | grep redis

# vim test.php

# php test.php

# redis-cli info keyspace

# redis-cli -n 0 keys \*| grep -i session

Note: the 0 is the database number.

Redis setup hints

We suggest deploying Redis using the Linux operating system. Redis is also tested heavily on osx, and tested from time to time on FreeBSD and OpenBSD systems. However Linux is where we do all the major stress testing, and where most production deployments are working.

Make sure to set the Linux kernel overcommit memory setting to 1. Add vm.overcommit_memory = 1 to /etc/sysctl.conf and then reboot or run the command sysctl vm.overcommit_memory=1 for this to take effect immediately.

Make sure to disable Linux kernel feature transparent huge pages, it will affect greatly both memory usage and latency in a negative way. This is accomplished with the following command: echo never > sys/kernel/mm/transparent_hugepage/enabled.

Make sure to setup some swap in your system (we suggest as much as swap as memory). If Linux does not have swap and your Redis instance accidentally consumes too much memory, either Redis will crash for out of memory or the Linux kernel OOM killer will kill the Redis process.

Set an explicit maxmemory option limit in your instance in order to make sure that the instance will report errors instead of failing when the system memory limit is near to be reached.

If you are using Redis in a very write-heavy application, while saving an RDB file on disk or rewriting the AOF log Redis may use up to 2 times the memory normally used. The additional memory used is proportional to the number of memory pages modified by writes during the saving process, so it is often proportional to the number of keys (or aggregate types items) touched during this time. Make sure to size your memory accordingly.

Use daemonize no when run under daemontools.

Even if you have persistence disabled, Redis will need to perform RDB saves if you use replication, unless you use the new diskless replication feature, which is currently experimental.

If you are using replication, make sure that either your master has persistence enabled, or that it does not automatically restarts on crashes: slaves will try to be an exact copy of the master, so if a master restarts with an empty data set, slaves will be wiped as well.

Running Redis on EC2

Use HVM based instances, not PV based instances.

Don't use old instances families, for example: use m3.medium with HVM instead of m1.medium with PV.

The use of Redis persistence with EC2 EBS volumes needs to be handled with care since sometimes EBS volumes have high latency characteristics.

You may want to try the new diskless replication (currently experimetnal) if you have issues when slaves are synchronizing with the master.

Reference:

http://blog.ijun.org/2014/11/configuring-magento-to-use-redis.html
http://blog.ijun.org/2014/12/install-apache-24-php-56-and-mysql-56.html
http://redis.io/topics/admin
http://www.cyberciti.biz/faq/howto-install-linux-apache-mariadb-php-lamp-stack-on-centos7-rhel7/
http://serverfault.com/questions/629937/centos-7-apache2-httpd-mod-fastcgi-installation-impossible
http://blog.famillecollet.com/post/2014/08/01/Apache-httpd-server-2.4.10-and-PHP-FPM-5.6-in-Fedora-21
https://wiki.apache.org/httpd/PHP-FPM
http://sharadchhetri.com/2014/10/04/install-redis-server-centos-7-rhel-7/
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/s1-networkscripts-interfaces.html
http://technovergence-en.blogspot.ca/2012/03/mysql-from-utf8-to-utf8mb4.html

Show more