Install LNMP on CentOS 6

2017-09-17|Categories: Linux|Tags: |

Preparation

# create 2 dirs to store source code and applications separately
mkdir /src /apps

NginX

install

yum install -y pcre-devel openssl-devel
useradd -r -s /sbin/nologin nginx

cd /src
wget http://nginx.org/download/nginx-1.xx.x.tar.gz
tar xf nginx-1.xx.x.tar.gz
cd nginx-1.xx.x
./configure \
    --prefix=/apps/nginx-1.xx.x     \
    --user=nginx                    \
    --group=nginx                   \
    --with-http_stub_status_module  \
    --with-http_ssl_module
make && make install

ln -s /apps/nginx-1.xx.x /apps/nginx
ln -s /apps/nginx/sbin/nginx /usr/local/sbin/nginx

configure nginx.conf and virtual hosts

Main configuration:

vim /apps/nginx/conf/nginx.conf
worker_processes        auto;
error_log               logs/error.log;
events {
    worker_connections  1024;
}
http {
    include             mime.types;
    default_type        application/octet-stream;
    sendfile            on;
    keepalive_timeout   70;
    server_tokens       off;
    client_max_body_size        8m;
    log_format          main    '$remote_addr - $remote_user [$time_local] "$request" '
                                '$status $body_bytes_sent "$http_referer" '
                                '"$http_user_agent" "$http_x_forwarded_for"';
    include             vhosts/*;
}

Virtual hosts configuration:

mkdir /apps/nginx/conf/vhosts
vim /apps/nginx/conf/vhosts/nginx_www.conf
# http
server {
        listen          80;
        server_name     www.liyang85.com liyang85.com;
        return          302 https://$server_name$request_uri;
}

# https
server {
        listen          443 ssl;
        server_name     www.liyang85.com liyang85.com;
        root            html/www;

        ssl_certificate         /etc/letsencrypt/live/www.liyang85.com/fullchain.pem;
        ssl_certificate_key     /etc/letsencrypt/live/www.liyang85.com/privkey.pem;

        ssl_session_cache       shared:SSL:10m;
        ssl_session_timeout     10m;
        keepalive_timeout       70;

        ssl_prefer_server_ciphers       on;

        location / {
                if (-f $request_filename/index.html){
                        rewrite (.*) $1/index.html break;
                }
                if (-f $request_filename/index.php){
                        rewrite (.*) $1/index.php;
                }
                if (!-f $request_filename){
                        rewrite (.*) /index.php;
                }
        }

        location ~ \.php(.*)$ {
                fastcgi_pass    127.0.0.1:9000;
                fastcgi_index   index.php;
                include         fastcgi.conf;
        }
}    

rotate access log everyday

write a log rotation script

mkdir /scripts
cd /scripts

vim rotate_nginx_log.sh

    #!/bin/bash
    
    # rotate_nginx_log.sh: rotate nginx's access log.
    
    date_format=$(date +%Y%m%d)
    ngx_dir='/apps/nginx'
    ngx_log_dir="${ngx_dir}/logs"
    log_name='access_www'
    
    [[ -d ${ngx_log_dir} ]] && cd ${ngx_log_dir} || exit 1
    [[ -f ${log_name}.log ]] || exit 1
    /bin/mv ${log_name}.log ${date_format}_${log_name}.log
    ${ngx_dir}/sbin/nginx -s reload

chmod +x rotate_nginx_log.sh

create a cron task

vim /etc/crontab
59 23 * * * root /bin/bash /scripts/rotate_nginx_log.sh

write an init script

#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
# 
# modified from https://www.nginx.com/resources/wiki/start/topics/examples/redhatnginxinit/
#
# chkconfig:   2345 85 15
# description:  NGINX is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /apps/nginx/conf/nginx.conf
# pidfile:     /apps/nginx/logs/nginx.pid

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

nginx="/apps/nginx/sbin/nginx"
prog=$(basename $nginx)

NGINX_CONF_FILE="/apps/nginx/conf/nginx.conf"

lockfile=/var/lock/subsys/nginx

make_dirs() {
   # make required directories
   user=`$nginx -V 2>&1 | grep "configure arguments:.*--user=" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
   if [ -n "$user" ]; then
      if [ -z "`grep $user /etc/passwd`" ]; then
         useradd -M -s /bin/nologin $user
      fi
      options=`$nginx -V 2>&1 | grep 'configure arguments:'`
      for opt in $options; do
          if [ `echo $opt | grep '.*-temp-path'` ]; then
              value=`echo $opt | cut -d "=" -f 2`
              if [ ! -d "$value" ]; then
                  # echo "creating" $value
                  mkdir -p $value && chown -R $user $value
              fi
          fi
       done
    fi
}

start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    make_dirs
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

restart() {
    configtest || return $?
    stop
    sleep 1
    start
}

reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
}

force_reload() {
    restart
}

configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}

rh_status() {
    status $prog
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac

MySQL

download and extract binary tarball

cd /src
wget https://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.57-linux-x86_64.tar.gz
tar xf mysql-5.5.57-linux-x86_64.tar.gz
mv mysql-5.5.57-linux-x86_64 /apps/mysql-5.5.57
ln -s /apps/mysql-5.5.57 /apps/mysql

echo 'export PATH="/apps/mysql/bin:$PATH"' >> /etc/profile.d/lnmp.sh
source /etc/profile.d/lnmp.sh

# use full path `cp` to overwrite `/etc/my.cnf` without prompt
/bin/cp /apps/mysql/support-file/my-huge.cnf /etc/my.cnf

initialize database

useradd -r -s /sbin/nologin mysql
chown -R mysql.mysql /apps/mysql/
/apps/mysql/scripts/mysql_install_db \
    --basedir=/apps/mysql            \
    --datadir=/apps/mysql/data       \
    --user=mysql

add init script

cp /apps/mysql/support-files/mysql.server /etc/init.d/mysqld
chmod +x /etc/init.d/mysqld
sed -i 's#/usr/local/mysql#/apps/mysql#g' /etc/init.d/mysqld /apps/mysql/bin/mysqld_safe

start server

/etc/init.d/mysqld start

chkconfig --add mysqld
# chkconfig mysqld on

security configuration

change root's password

mysqladmin -u root password 'your_password'

delete useless users

mysql -u root -p 'your_password'
mysql> select user,host from mysql.user;
mysql> drop user 'root'@'::1';
mysql> drop user ''@'localhost';
mysql> drop user ''@'your_host_name';
mysql> drop user 'root'@'your_host_name';
mysql> flush privileges;

delete the test database

mysql> drop database test;

PHP

install dependencies

# Part 1: yum install
yum install -y \
    freetype-devel         \
    gd-devel               \
    libcurl-devel          \
    libjpeg-turbo-devel    \
    libpng-devel           \
    libxml2-devel          \
    libxslt-devel          \
    readline-devel         \
    zlib-devel

# Part 2: yum install from epel
# install epel repo
yum install epel-release
# or install epel repo from aliyun
# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
yum install -y libmcrypt-devel mcrypt mhash

# Part 3: compile libiconv
wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz
tar xf libiconv-1.14.tar.gz
cd libiconv-1.14
./configure --prefix=/usr/local/libiconv
make && make install

download php-7 and extract it

cd /src
wget --content-disposition http://php.net/get/php-7.1.10.tar.gz/from/this/mirror
tar xpf php-7.1.10.tar.gz

php-7 configuration options

cd php-7.1.10
./configure \
    --prefix=/apps/php-7.1.10               \
    --disable-rpath                         \
    --enable-bcmath                         \
    --enable-fpm                            \
    --enable-ftp                            \
    --enable-gd-native-ttf                  \
    --enable-inline-optimization            \
    --enable-mbregex                        \
    --enable-mbstring                       \
    --enable-pcntl                          \
    --enable-shmop                          \
    --enable-short-tags                     \
    --enable-soap                           \
    --enable-sockets                        \
    --enable-static                         \
    --enable-sysvsem                        \
    --enable-xml                            \
    --with-curl                             \
    --with-fpm-group=nginx                  \
    --with-fpm-user=nginx                   \
    --with-freetype-dir                     \
    --with-gd                               \
    --with-iconv-dir=/usr/local/libiconv    \
    --with-jpeg-dir                         \
    --with-libxml-dir=/usr                  \
    --with-mcrypt                           \
    --with-mhash                            \
    --with-mysqli=mysqlnd                   \
    --with-openssl                          \
    --with-pdo-mysql=mysqlnd                \
    --with-png-dir                          \
    --with-readline                         \
    --with-xmlrpc                           \
    --with-xsl                              \
    --with-zlib

compile php-7

make -j 4 && make install
ln -s /apps/php-5.3.27 /apps/php

add php to $PATH

echo 'export PATH="/apps/php/bin:$PATH"' >> /etc/profile.d/lnmp.sh
source /etc/profile.d/lnmp.sh

copy php.ini

cp php.ini-production /apps/php/etc/php.ini

configure opcache

PHP official doc recommends to use below related settings in php.ini:

opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1

The meaning of all the options can be read at official opcache doc.

run php as fastcgi mode

cd /apps/php/etc/php-fpm.d
cp www.conf.default www.conf
# copy the init script from php source dir to /etc
cp /src/php-7.1.10/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
chmod +x /etc/init.d/php-fpm

# edit php-fpm init script
vim /etc/init.d/php-fpm
    # ensure below 5 lines have been set
    prefix=/apps/php-7.1.10
    exec_prefix=${prefix}
    php_fpm_BIN=${exec_prefix}/sbin/php-fpm
    php_fpm_CONF=${prefix}/etc/php-fpm.conf
    php_fpm_PID=/var/run/php-fpm.pid

# start php-fpm
service php-fpm start
service php-fpm status

# set php-fpm start on boot
chkconfig --add php-fpm
# chkconfig php-fpm on

Leave A Comment