哞菇神社

从零开始的LNMP手动编译生活

2016.09.08 / 技术 / 点击 / 回复 12 / PHP, 运维, lnmp, 编译, 捣鼓, linux, nginx, mysql

因为小学期,8月初就开学了,回到学校之后,学校叮叮铛铛开始装修起机房,高端大气的机柜,排的整整齐齐的线缆,搞得和IDC一样,好厉害啊。
结果在这个过程中,一台服务器不知道为啥访问不到了。经过多次卖萌后重新分配了新的服务器。
挠挠脑袋想装一套web环境来搞测试之用,辣鸡学校不给服务器外网,只有一个内网的yum源镜像,一顿翻找之后发现学校的公共源里面似乎没有nginx、php和mysql,又不好意思抱菊苣大腿,只好自己动手丰衣足食。

神在第六日,终于想起来该干活了,于是他开始敲下第一行命令。
rm -rf /

于是,从零开始的LNMP手动编译便开始了……

♩♫这里需要播放一些OP♪♬~ ♩♬动词大呲大动词♪♫~

注:这篇文章的环境是
Centos6 64位
Nginx/1.10.1
PHP/5.6.25
MySQL/5.7.14
本文发布的时候用的都是最新版,刚开始照着老版本的教程来的,踩了不少坑,版本更新之后很多方法可能会改变,请注意哦

一切的开始:准备

哼哧哼哧的打开浏览器,先跑去nginx官网php官网mysql官网下载对应的包

http://nginx.org/en/download.html
http://php.net/downloads.php
http://dev.mysql.com/downloads/mysql/

除了这些,还有php需要的一堆组件libiconv、libmcrypt、mhash、mcrypt需要下载

http://www.gnu.org/software/libiconv/
https://sourceforge.net/projects/mcrypt/files/Libmcrypt/
https://sourceforge.net/projects/mcrypt/files/MCrypt/
https://sourceforge.net/projects/mhash/files/

nginx和php都简洁明了,下载最新的稳定版本ok。
php的那一车组件只要点最新版,下载.tar.gz后缀的就ok。
然而mysql藏得比较深,打开下载页成山的版本可供下载,看的眼睛有点疼,这啥啥啥咋还几百兆大,为了配合本次装逼,当蓝是下源码啦,记得要选择source code并拉到最下面Generic Linux - Includes Boost Headers版本,至于为什么要Includes Boost Headers,后文再说,总之下这个会方便点Orz。

我建了个文件夹,起名叫/neko/soft/,把刚才的文件用sftp丢上去,开饭前先合个影。
LNMP所需文件合影

顺便说,看到不少教程都叫你先卸载掉apache和自带的mysql,不过咱是新系统,试了一下根本没有,这是符合基本法的。
(后来我就对这句话后悔了,请一定要检查自带的)

然后接下来连上ssh就开工吧,正式开始之前噼里啪啦先怼一堆软件,这都是等会编译过程中会用到的东西

yum install -y gcc gcc-c++ gd gd2 gd-devel gd2-devel ncurses ncurses-devel bison bison-devel pcre pcre-devel zlib zlib-devel openssl openssl-devel libxml2-devel curl curl-devel libcurl-devel bzip2-devel readline-devel libedit-devel cmake

大小姐一样的:MySQL

这是为什么呢?为什么要先从数据库开始呢?明明是我先的……
其实我也不知道,咨询了菊苣好像是说这样就能方便php配置了,嘛管他呢。

首 先 卸 载 掉 Centos最小化安装自带的mysql,一定要检查好自己有没有清理干净再开工
我被这个问题坑死了,尼玛如果不卸载,无论怎么初始化就是不成功!!
mysql给出的日志一般也都是迷迷糊糊的,根本找不到问题在哪,花了不知道多久才发现问题原来出在这里!!

#检查安装与否
rpm -qa|grep mysql 
#强制卸载 
rpm -e 上面搜索到的软件名 --nodeps

然后就可以准备开始咯

#创建一个用户组
groupadd mysql
#创建一个用户,不允许登陆和不创主目录 
useradd -s /sbin/nologin -g mysql -M mysql
#解压
tar zxvf mysql-boost-5.7.14.tar.gz
#开始cmake!
cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_DATADIR=/data/mysql \
-DSYSCONFDIR=/etc \
-DWITH_MYISAM_STORAGE_ENGINE=1 \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_MEMORY_STORAGE_ENGINE=1 \
-DWITH_READLINE=1 \
-DMYSQL_UNIX_ADDR=/data/mysql/mysql.sock \
-DMYSQL_TCP_PORT=3306 \
-DENABLED_LOCAL_INFILE=1 \
-DWITH_PARTITION_STORAGE_ENGINE=1 \
-DEXTRA_CHARSETS=all \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_BOOST=boost/boost_1_59_0/

上面有很多参数一看就懂,还是很方便的

关于这里一开始我遇到了一个boost错误,卡了半天

从MySQL 5.7.5开始Boost库是必需的,有几种解决方案
PlanA 简单:下载自带boost的mysql-boost-5.7.12.tar.gz,并在 cmake 指定参数 -DWITH_BOOST=boost/boost_1_59_0/
PlanB 方便:直接cmake指定参数 -DDOWNLOAD_BOOST=1 -DWITH_BOOST= 系统会下载 boost
PlanC 抖M:自己下载boost并编译然后在 cmake 指定参数 -DWITH_BOOST=

我这服务器又没有外网,所以只能选PlanA,所以开头我们下载的是 Includes Boost Headers版本,内置了boost,只要在编译的时候加上路径就好,便利

#Link Start!!
make&make install

喝会茶刷刷群,整个编译过程需要很长时间……很长时间……很长时间……
不过这种等待配合屏幕上滚的花花绿绿的信息,为这一过程加强了仪式感

随着天阳的下山,数据库终于编译好了,如果没有任何error,我们就可以继续了

#建一个刚才指定的数据库文件存储目录
mkdir -p /data/mysql
#搞搞权限
chmod +w /usr/local/mysql
chown -R mysql:mysql /usr/local/mysql
#复制一份官方范例的mysql启动脚本到/etc/init.d便于启动
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
#权限
chmod +x /etc/init.d/mysqld
#编辑一下配置文件
cp /usr/local/mysql/support-files/my-default.cnf /etc/my.cnf
vim /etc/my.cnf
#在[mysqld]内添加如下内容
basedir = /usr/local/mysql
datadir = /data/mysql
log-error = /data/logs/mysql/mysql_error.log
pid-file = /data/mysql/mysql.pid

#创建日志目录
mkdir -p /data/logs/mysql
#给个权限
chmod +w /data/logs/mysql
chown -R mysql:mysql /data/logs/mysql

#使用空密码,初始化数据库
/usr/local/mysql/bin/mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql

#添加开机启动
chkconfig --add mysqld
chkconfig mysqld on

#启动一下试试
service mysqld start

biu的一下success就成功了(为了看见这个success之前遇到了那么多坑真感动
然后把mysql添加进bash,这样就可以直接运行mysql打头的命令了

#修改/etc/profile文件
vi /etc/profile
#在文件末尾添加
PATH=/usr/local/mysql/bin:$PATH
export PATH
#让设置立即生效
source /etc/profile

#给mysql先设置一个空密码
/usr/local/mysql/bin/mysqladmin -uroot -p password '你的密码'

#登录数据库试试看
mysql -uroot -p

看到那熟悉的mysql>,好感动啊
mysql编译大成功!!

可以同时被几万人上也不会崩坏的萌妹:NGINX

听说之前大家都是用Aapche的……直到有一天,Nginx出现了……
不过我用Nginx的原因是我不会配置Apache啊,你看Nginx还可以方便的帮我转发小黄网,多好啊,诶嘿~☆(

cd /neko/soft/
tar zxvf nginx-1.10.1.tar.gz
cd nginx-1.10.1

建立nginx用户和组
groupadd nginx
useradd -g nginx nginx -M -s/sbin/nologin
创建目录赋予权限
mkdir -p /data/logs/nginx
chmod +w /data/logs/nginx
chown -R nginx:nginx /data/logs/nginx

./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--error-log-path=/data/logs/nginx/error.log \
--http-log-path=/data/logs/nginx/access.log \
--with-http_ssl_module

make&make install

vi /usr/local/nginx/conf/nginx.conf

对应修改
user nginx nginx;
worker_processes 4;
error_log /data/logs/nginx/error.log;

#做个软连接 方便nginx 调用
ln -s /usr/local/nginx/sbin/nginx /usr/bin/

#顺便做个service,方便使用
vim /etc/init.d/nginx  

复制以下(不包括分割线)

=================================

#!/bin/sh 
# 
# nginx - this script starts and stops the nginx daemon 
# 
# chkconfig:   - 85 15 
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \ 
#               proxy and IMAP/POP3 proxy server 
# processname: nginx 
# config:      /etc/nginx/nginx.conf 
# config:      /etc/sysconfig/nginx 
# pidfile:     /var/run/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="/usr/local/nginx/sbin/nginx" 
prog=$(basename $nginx) 

NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf" 

[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx 

lockfile=/var/lock/subsys/nginx 

start() { 
    [ -x $nginx ] || exit 5 
    [ -f $NGINX_CONF_FILE ] || exit 6 
    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 
killall -9 nginx 
} 

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  

=================================

:wq保存退出
#给予全部用户运行的权限
chmod a+x /etc/init.d/nginx

#添加启动项
chkconfig --add nginx

#LinkStart!!
service nginx start

访问地址,应该就能看到Welcome to Nginx了。
相比起其他两个,nginx多么可爱,安上就能用,而且十分耐艹。(比隔壁Apache娘性能好多了
WelcomeNginx

能干,但是难以调教的马猴烧酒:PHP

终于进入了最后一步,在开始之前请和我一起喊出我们的口号:“PHP是世界上坠吼的语言!
(虽然附近的小伙伴们纷纷被Python和Node.js吸引过去,成为了更加高级的毛猴烧酒,但是PHP依旧是坠吼的~!坠吼的!)

首先编译并安装这一大堆依赖libiconv、libmcrypt、mhash、mcrypt
进入机械化的工作……

cd /neko/soft/
tar zxvf libiconv-1.14.tar.gz
cd libiconv-1.14
./configure --prefix=/usr/local 
make && make install

cd /neko/soft/
tar zxvf libmcrypt-2.5.8.tar.gz
cd libmcrypt-2.5.8
./configure --enable-ltdl-install 
make && make install

#64位系统
ln -sf /usr/local/lib/libmcrypt.la /usr/lib64/libmcrypt.la
ln -sf /usr/local/lib/libmcrypt.so /usr/lib64/libmcrypt.so
ln -sf /usr/local/lib/libmcrypt.so.4 /usr/lib64/libmcrypt.so.4
ln -sf /usr/local/lib/libmcrypt.so.4.4.8 /usr/lib64/libmcrypt.so.4.4.8
ln -sf /usr/local/bin/libmcrypt-config /usr/bin/libmcrypt-config
ln -sf /usr/local/lib/libiconv.so.2 /usr/lib64/libiconv.so.2

#32位系统
ln -sf /usr/local/lib/libmcrypt.la /usr/lib/libmcrypt.la
ln -sf /usr/local/lib/libmcrypt.so /usr/lib/libmcrypt.so
ln -sf /usr/local/lib/libmcrypt.so.4 /usr/lib/libmcrypt.so.4
ln -sf /usr/local/lib/libmcrypt.so.4.4.8 /usr/lib/libmcrypt.so.4.4.8
ln -sf /usr/local/bin/libmcrypt-config /usr/bin/libmcrypt-config
ln -sf /usr/local/lib/libiconv.so.2 /usr/lib/libiconv.so.2

cd /neko/soft/
tar zxvf mhash-0.9.9.9.tar.gz
cd mhash-0.9.9.9
./configure
make && make install

64位系统的话还需要做一下几个软链接32位请略过
ln -s /usr/lib64/libjpeg.so /usr/lib/libjpeg.so
ln -s /usr/lib64/libldap.so /usr/lib/libldap.so
ln -s /usr/lib64/libpng.so /usr/lib/libpng.so

cd /neko/soft/
tar zxvf mcrypt-2.6.8.tar.gz
cd mcrypt-2.6.8.tar.gz
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
./configure
make && make install

ln -s /usr/local/lib/libmcrypt.la /usr/lib/libmcrypt.la 
ln -s /usr/local/lib/libmcrypt.so /usr/lib/libmcrypt.so 
ln -s /usr/local/lib/libmcrypt.so.4 /usr/lib/libmcrypt.so.4 
ln -s /usr/local/lib/libmcrypt.so.4.4.8 /usr/lib/libmcrypt.so.4.4.8 
ln -s /usr/local/lib/libmhash.a /usr/lib/libmhash.a 
ln -s /usr/local/lib/libmhash.la /usr/lib/libmhash.la 
ln -s /usr/local/lib/libmhash.so /usr/lib/libmhash.so 
ln -s /usr/local/lib/libmhash.so.2 /usr/lib/libmhash.so.2 
ln -s /usr/local/lib/libmhash.so.2.0.1 /usr/lib/libmhash.so.2.0.1 
ln -s /usr/local/bin/libmcrypt-config /usr/bin/libmcrypt-config

#64位,你可能需要
ln -sf /usr/local/lib/libmcrypt.la /usr/lib64/libmcrypt.la
ln -sf /usr/local/lib/libmcrypt.so /usr/lib64/libmcrypt.so
ln -sf /usr/local/lib/libmcrypt.so.4 /usr/lib64/libmcrypt.so.4
ln -sf /usr/local/lib/libmcrypt.so.4.4.8 /usr/lib64/libmcrypt.so.4.4.8
ln -sf /usr/local/bin/libmcrypt-config /usr/bin/libmcrypt-config
ln -sf /usr/local/lib/libiconv.so.2 /usr/lib64/libiconv.so.2

当我弄完了上面大段命令,我几乎是傻的。
不创建的软链接的话很可能会导致下面编译出现Error……所以……
终于开始重点了……

tar zxvf php-5.6.25.tar.gz
cd php-5.6.25

./configure \
--prefix=/usr/local/php \
--enable-inline-optimization \
--disable-debug \
--disable-rpath \
--enable-shared \
--enable-opcache \
--enable-fpm \
--with-fpm-user=nginx \
--with-fpm-group=nginx \
--with-mysql=mysqlnd \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--with-gettext \
--enable-mbstring \
--with-iconv \
--with-mcrypt \
--with-mhash \
--with-openssl \
--enable-bcmath \
--enable-soap \
--with-libxml-dir \
--enable-pcntl \
--enable-shmop \
--enable-sysvmsg \
--enable-sysvsem \
--enable-sysvshm \
--enable-sockets \
--with-curl \
--with-zlib \
--enable-zip \
--with-bz2 \
--with-readline \
--with-gd

make ZEND_EXTRA_LIBS='-liconv'
make install

这里我带了一堆参数来开启php的相关功能,虽然后期也可以通过插件的形式开启,但是一下子都解决,岂不美哉。
不过花的时间的确不少,但是肯定要比MySQL短,坐下来再喝杯茶吧……
然后接下来就是最后的步骤了!

#给php开一个用户
useradd -M -s /sbin/nologin php

#配置php.ini
cp php.ini-development /usr/local/php/lib/php.ini
#因为mysql.sock位置不同,创建一个软链接
ln -s /data/mysql/mysql.sock /tmp/mysql.sock
#配置php-fpm
cd /usr/local/php/etc
cp php-fpm.conf.default php-fpm.conf
vim php-fpm.conf
#设置service
cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
#给权限
chmod +x /etc/init.d/php-fpm
#开机启动
chkconfig php-fpm on

PHP

夏日的终点,世界线的收束:Nginx Config

现在,我们已经配置好了三大件,最后就是编辑Nginx的配置文件,让他们开始工作的时候了。

编辑nginx.conf
vi /usr/local/nginx/conf/nginx.conf

在httpd{之内增加
include vhost/*.conf;
#创建一个文件夹
mkdir -p /usr/local/nginx/conf/vhost
#以后的配置文件都在这里写吧
vim nekotora.conf

附上我的范例

server {
        listen 80;
        index index.php index.html index.htm;
        root /data/www;

        location ~ ^(.+\.php)(.*)$ {
                fastcgi_pass   127.0.0.1:9000;
                fastcgi_index  index.php;
                fastcgi_split_path_info ^(.+\.php)(.*)$;

                fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                fastcgi_param        PATH_INFO                $fastcgi_path_info;
                fastcgi_param        PATH_TRANSLATED        $document_root$fastcgi_path_info;
                include        fastcgi_params;
        }
}

关于php,这里开启了pathifo,如果不需要也可以写成

location ~ \.php$ {
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

至此,所有的项目都配置好了,接下来就是见证奇迹的时刻

service mysqld restart
service php-fpm restart
service nginx restart

Bingo!

终于完成了,我流下了激动的鼻涕。
捣鼓的这两天踩了不少坑,本着12dora的“草泥马不会百度啊”的口号,依赖着百度、必应以及某个不存在的网站,圆满解决。

顺便稍微说点题外话吧——
现在寝室半夜好冷啊,果然夏天已经结束了吗?
看了看博客,似乎已经半年多没发东西了,时间真的好快啊。
这个夏天有好多想说的话,等有时间一起发出来吧。


蘑菇森林的边缘与无尽循环夏日的终点
2016.09.08 清晨

已有 12 条评论

  1. Whoa plenty of superb info.

  2. 其实为什么不试试手动挂载源呢

  3. coolcfan coolcfan

    膜拜菊苣!

  4. 只有 CentOS 可用吗。。

    1. 其他Unix like系统应该是通用的,但是源的使用方式可能有些不同吧(

      1. 不是,我的意思是你们学校提供的系统。。只有 CentOS 吗

        1. 应该不是,老师直接丢给我了root密码,就那么用咯(

  5. 写得好 我选择rm -rf /

  6. oott123 oott123

    先编译 MySQL 我猜应该是为了给 PHP 的 mysql 组件提供 libmysql 吧(

  7. 厉害了

  8. 写的好,赞!