草履虫也能学会的LNMP安装与配置

2021/11/6·5 views
草履虫也能学会的LNMP安装与配置

以下所有软件均安装在/usr/local目录,如果修改,需要注意配置文件中的路径。所有软件配置用户和用户组均为www,系统采用Ubuntu20或者Centos8 (opencloudos) 。

linux 安装与配置:不赘述,一般采用云服务器

创建用户和用户组

shell 复制代码
groupadd -g 1000 www  # 新增用户组www,组id为1000
useradd -g www -d /home/www -s /bin/bash www # 添加用户指定组,家目录,登录命令和用户名www
mkdir /home/www && chown www:www /home/www # 如果没有,手动创建家目录并修改属组和用户

如果报错,可以看下是不是组id或者用户已经存在,或者参考博客中的其他文章

Nginx安装

获取源码

官网: https://nginx.org/en/
pcre 下载: https://sourceforge.net/projects/pcre/files/pcre/ 或 直接安装对应软件包

编译安装

shell 复制代码
apt install build-essential
tar -zxf nginx-1.22.1.tar.gz  # 解压源码
cd nginx-1.22.1/
./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_flv_module --with-http_mp4_module --with-pcre
make && make install

修改配置文件

shell 复制代码
vim /usr/local/nginx/conf/nginx.conf # 将user更改为www。 ;pid        logs/nginx.pid; 取消注释

如果不够详细可以参考:https://zhuanlan.zhihu.com/p/128579141

编译模块

shell 复制代码
./configure --with-http_ssl_module # 官方模块
./configure --add-module=/path-to-module # 第三方模块

新增模块可以用nginx -V 查看之前的编译参数,带上新的参数重新编译

服务化

service

shell 复制代码
ln -s /usr/local/nginx/sbin/nginx /sbin/
vim /etc/init.d/nginx

加入

shell 复制代码
#!/bin/sh

### BEGIN INIT INFO
# Provides:       nginx
# Required-Start:    $local_fs $remote_fs $network $syslog $named
# Required-Stop:     $local_fs $remote_fs $network $syslog $named
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the nginx web server
# Description:       starts nginx using start-stop-daemon
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/nginx
NAME=nginx
DESC=nginx

# Include nginx defaults if available
if [ -r /etc/default/nginx ]; then
        . /etc/default/nginx
fi

STOP_SCHEDULE="${STOP_SCHEDULE:-QUIT/5/TERM/5/KILL/5}"

test -x $DAEMON || exit 0

. /lib/init/vars.sh
. /lib/lsb/init-functions

# Try to extract nginx pidfile
PID=$(cat /usr/local/nginx/conf/nginx.conf | grep -Ev '^\s*#' | awk 'BEGIN { RS="[;{}]" } { if ($1 == "pid") print $2 }' | head -n1)
if [ -z "$PID" ]; then
        PID=/run/nginx.pid
fi

if [ -n "$ULIMIT" ]; then
        # Set ulimit if it is set in /etc/default/nginx
        ulimit $ULIMIT
fi

start_nginx() {
        # Start the daemon/service
        #
        # Returns:
        #   0 if daemon has been started
        #   1 if daemon was already running
        #   2 if daemon could not be started
        start-stop-daemon --start --quiet --pidfile $PID --exec $DAEMON --test > /dev/null \
                || return 1
        start-stop-daemon --start --quiet --pidfile $PID --exec $DAEMON -- \
                $DAEMON_OPTS 2>/dev/null \
                || return 2
}

test_config() {
        # Test the nginx configuration
        $DAEMON -t $DAEMON_OPTS >/dev/null 2>&1
}

stop_nginx() {
        # Stops the daemon/service
        #
        # Return
        #   0 if daemon has been stopped
        #   1 if daemon was already stopped
        #   2 if daemon could not be stopped
        #   other if a failure occurred
        start-stop-daemon --stop --quiet --retry=$STOP_SCHEDULE --pidfile $PID --name $NAME
        RETVAL="$?"
        sleep 1
        return "$RETVAL"
}

reload_nginx() {
        # Function that sends a SIGHUP to the daemon/service
        start-stop-daemon --stop --signal HUP --quiet --pidfile $PID --name $NAME
        return 0
}

rotate_logs() {
        # Rotate log files
        start-stop-daemon --stop --signal USR1 --quiet --pidfile $PID --name $NAME
        return 0
}

upgrade_nginx() {
        # Online upgrade nginx executable
        # http://nginx.org/en/docs/control.html
        #
        # Return
        #   0 if nginx has been successfully upgraded
        #   1 if nginx is not running
        #   2 if the pid files were not created on time
        #   3 if the old master could not be killed
        if start-stop-daemon --stop --signal USR2 --quiet --pidfile $PID --name $NAME; then
                # Wait for both old and new master to write their pid file
                while [ ! -s "${PID}.oldbin" ] || [ ! -s "${PID}" ]; do
                        cnt=`expr $cnt + 1`
                        if [ $cnt -gt 10 ]; then
                                return 2
                        fi
                        sleep 1
                done
                # Everything is ready, gracefully stop the old master
                if start-stop-daemon --stop --signal QUIT --quiet --pidfile "${PID}.oldbin" --name $NAME; then
                        return 0
                else
                        return 3
                fi
        else
                return 1
        fi
}

case "$1" in
        start)
                log_daemon_msg "Starting $DESC" "$NAME"
                start_nginx
                case "$?" in
                        0|1) log_end_msg 0 ;;
                        2)   log_end_msg 1 ;;
                esac
                ;;
        stop)
                log_daemon_msg "Stopping $DESC" "$NAME"
                stop_nginx
                case "$?" in
                        0|1) log_end_msg 0 ;;
                        2)   log_end_msg 1 ;;
                esac
                ;;
        restart)
                log_daemon_msg "Restarting $DESC" "$NAME"

                # Check configuration before stopping nginx
                if ! test_config; then
                        log_end_msg 1 # Configuration error
                        exit $?
                fi

                stop_nginx
                case "$?" in
                        0|1)
                                start_nginx
                                case "$?" in
                                        0) log_end_msg 0 ;;
                                        1) log_end_msg 1 ;; # Old process is still running
                                        *) log_end_msg 1 ;; # Failed to start
                                esac
                                ;;
                        *)
                                # Failed to stop
                                log_end_msg 1
                                ;;
                esac
                ;;
        reload|force-reload)
                log_daemon_msg "Reloading $DESC configuration" "$NAME"

                # Check configuration before stopping nginx
                #
                # This is not entirely correct since the on-disk nginx binary
                # may differ from the in-memory one, but that's not common.
                # We prefer to check the configuration and return an error
                # to the administrator.
                if ! test_config; then
                        log_end_msg 1 # Configuration error
                        exit $?
                fi

                reload_nginx
                log_end_msg $?
                ;;
        configtest|testconfig)
                log_daemon_msg "Testing $DESC configuration"
                test_config
                log_end_msg $?
                ;;
        status)
                status_of_proc -p $PID "$DAEMON" "$NAME" && exit 0 || exit $?
                ;;
        upgrade)
                log_daemon_msg "Upgrading binary" "$NAME"
                upgrade_nginx
                log_end_msg $?
                ;;
        rotate)
                log_daemon_msg "Re-opening $DESC log files" "$NAME"
                rotate_logs
                log_end_msg $?
                ;;
        *)
                echo "Usage: $NAME {start|stop|restart|reload|force-reload|status|configtest|rotate|upgrade}" >&2
                exit 3
                ;;
esac
shell 复制代码
chmod 0755 /etc/init.d/nginx # 保存后修改权限

systemd

shell 复制代码
vim /lib/systemd/system/nginx.service

加入

shell 复制代码
[Unit]
Description=Nginx
After=syslog.target network.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -USR2 $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

执行下面的命令reload

shell 复制代码
systemctl daemon-reload

就可以使用下面的命令管理nginx了

shell 复制代码
systemctl status/start/stop/restart/enable/disable nginx.service

MySQL

资料暂时缺失

PHP

依赖安装

Ubuntu

shell 复制代码
git clone https://github.com/kkos/oniguruma.git oniguruma
cd oniguruma
./autogen.sh
./configure
make
make install
shell 复制代码
apt install make -y 
apt install build-essential -y 
apt install libxml2-dev -y 
apt install libssl-dev -y 
apt install libpng-dev -y 
apt install gcc -y
apt install openssl -y
apt install curl -y
apt install libbz2-dev -y
apt install libxml2-dev -y
apt install libjpeg-dev -y
apt install libpng-dev -y
apt install libfreetype6-dev -y
apt install libzip-dev -y
apt install libssl-dev -y
apt install libsqlite3-dev -y
apt install libcurl4-openssl-dev -y
apt install libgmp3-dev -y
apt install libonig-dev -y
apt install libreadline-dev -y
apt install libxslt1-dev -y
apt install libffi-dev -y
apt install libsqlite3-dev -y 
apt install zlib1g-dev -y 
apt install libcurl4-openssl-dev -y 
apt install libtidy-dev -y 
apt install autoconf -y 
apt-get install -y automake 
apt-get install -y m4
apt install libtool -y 
apt install pkg-config -y 

zlib1g-dev 或者 libbz2-dev

扩展对应的依赖(可选择性的安装)

shell 复制代码
apt-get install -y libxml2-dev
apt-get install -y libpcre3-dev
apt-get install -y libjpeg62-dev
apt-get install -y libfreetype6-dev
apt-get install -y libpng12-dev libpng3 libpnglite-dev
apt-get install -y libiconv-hook-dev libiconv-hook1
apt-get install -y libmcrypt-dev libmcrypt4
apt-get install -y libmhash-dev libmhash2
apt-get install -y libltdl-dev libssl-dev
apt-get install -y libcurl4-openssl-dev
apt-get install -y libmysqlclient-dev
apt-get install -y libmagickcore-dev libmagickwand-dev
apt-get install -y libedit-dev

无法找到 iconv 的话可以尝试做软链

shell 复制代码
ln -s /usr/lib/libiconv_hook.so.1.0.0 /usr/lib/libiconv.so
ln -s /usr/lib/libiconv_hook.so.1.0.0 /usr/lib/libiconv.so.1

Centos

shell 复制代码
yum install -y openssl-devel
yum install -y libxml2-devel
yum install -y sqlite-devel
yum install -y bzip2-devel
yum install -y libcurl-devel
yum install -y libffi-devel
yum install -y libpng-devel
yum install -y gmp-devel
yum install -y oniguruma-devel
yum install -y readline-devel
yum install -y libxslt-devel
yum install -y libzip-devel

编译安装

获取源码: https://www.php.net/downloads.php,以下以php8.1.14示例

shell 复制代码
wget https://www.php.net/distributions/php-8.1.14.tar.gz
tar -zxf php-8.1.14.tar.gz
cd php-8.1.14
./configure --prefix=/usr/local/php/81 --with-config-file-path=/usr/local/php/81/etc --enable-pcntl --enable-fpm --enable-inline-optimization --disable-debug --disable-rpath --enable-shared  --with-xmlrpc --with-mhash --with-sqlite3 --with-zlib --enable-bcmath --with-iconv --with-bz2 --with-openssl --enable-calendar --with-curl --with-cdb --enable-dom --enable-exif --enable-fileinfo --enable-filter --with-openssl-dir --with-zlib-dir -jis-conv --with-gettext --with-gmp --with-mhash --enable-json --enable-mbstring --enable-mbregex --enable-pdo --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-pdo-sqlite --with-readline --enable-session --enable-shmop --enable-simplexml --enable-sockets  --enable-sysvmsg --enable-sysvsem --enable-sysvshm --with-xsl --enable-mysqlnd-compression-support --with-pear --enable-opcache
make -j && make install

make -j 可以加快编译速度,但是可能会导致错误。如果configure过程中还提示缺少依赖,可以使用apt search <名称> 或者 yum search <名称> 搜索后安装dev或者devel的包

配置

配置文件

shell 复制代码
cp ./php.ini-development /usr/local/php/81/etc/php.ini
# 如果你不使用FPM可以忽略下面三行
cd /usr/local/php/81/etc
mv php-fpm.conf.default php-fpm.conf
mv php-fpm.d/www.conf.default php-fpm.d/www.conf

FPM

shell 复制代码
vim php-fpm.conf  # 找到 ;pid = run/php-fpm.pid 注释掉前面的;
vim php-fpm.d/www.conf # 将user和group更改为www,如果你需要监听本地套接字而不是tcp端口,则需要修改listen=var/run/php-fpm.sock

找到下面的配置,取消注释,修改用户名和组名

ini 复制代码
user = www
group = www
# 如果是监听本地套接字,就需要改下这个
listen.owner = www
listen.group = www
listen.mode = 0660

服务化php-fpm

systemd

shell 复制代码
vim /lib/systemd/system/php-fpm-81.service

加入下面的配置

复制代码
[Unit]
Description=The PHP FastCGI Process Manager
After=syslog.target network.target

[Service]
Type=forking
PIDFile=/usr/local/php/81/var/run/php-fpm.pid
ExecStart=/usr/local/php/81/sbin/php-fpm
ExecReload=/bin/kill -USR2 $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

执行下面的命令reload

shell 复制代码
systemctl daemon-reload

就可以使用下面的命令管理php-fpm了

shell 复制代码
systemctl status/start/stop/restart/enable/disable php-fpm-81.service

service

脚本在源码目录

shell 复制代码
cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm-81
chmod 0755 /etc/init.d/php-fpm-81

就可以使用下面的命令管理php-fpm服务了

shell 复制代码
service php-fpm-81 start/stop/restart

软链或者环境变量

如果你想在任意地方使用php命令,就可以做软链,否则添加环境变量即可

软链

shell 复制代码
ln -s /usr/loca/php/81/bin/php /bin

环境变量

shell 复制代码
cd 
vim .bashrc

加入下面任意一条

shell 复制代码
export PATH=${PATH}:/usr/local/php/81/bin
alias php="/usr/local/php/81/bin/php"

如果你使用了composer,而且要在多个php版本下运行,就可以做下面的配置

shell 复制代码
alias composer81="/usr/local/php/81/bin/php /bin/composer"

PHP常用命令

shell 复制代码
php -i | grep configure
php --ini # 查看加载的配置信息
php -m # 查看扩展列表
php --ri gd # 查看gd扩展信息
php -l index.php # 检查语法错误

apt安装PHP

首先,请确保您的系统中具有add-apt-repository命令实用程序。

shell 复制代码
sudo apt-get install software-properties-common

现在,您可以添加存储库并更新系统中的程序包缓存。

shell 复制代码
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update

最后,要在Linux系统中安装PHP 8,请使用安装命令。

markup 复制代码
sudo apt install php8.1

安装pecl

复制代码
wget http://pear.php.net/go-pear.phar
php go-pear.phar

或者

复制代码
apt install php-pear

PHP安装扩展

amqp

准备

怼最新版
https://github.com/alanxz/rabbitmq-c/releases

下载后解压

安装

没有安装cmake的需要先安装

shell 复制代码
apt install cmake

解压后进入解压目录执行

shell 复制代码
mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/rabbitmq-c ..
make && make install 

pecl

php 复制代码
pecl install amqp

指定下librabbmitmq的位置,回车再按照添加配置

源码

pecl下载源码包,

php 复制代码
phpize
./configure --with-php-config=/path-to/php-config --with-amqp --with-librabbitmq-dir=/usr/local/rabbitmq-c

源码安装如果报错

shell 复制代码
/usr/local/rabbitmq-c-0.11.0/lib -lrabbitmq
...
/usr/bin/ld: cannot find -lrabbitmq

那就找到rabbitmq-c的链接库做下软连接

shell 复制代码
ln -s /usr/local/rabbitmq-c-0.11.0/lib/x86_64-linux-gnu/librabbitmq.so /usr/local/rabbitmq-c-0.11.0/lib/
ln -s /usr/local/rabbitmq-c-0.11.0/lib/x86_64-linux-gnu/librabbitmq.so.4 /usr/local/rabbitmq-c-0.11.0/lib/

gd

复制代码
phpize
./configure --with-webp-dir --with-freetype-dir --with-jpeg-dir --with-png-dir --with-xpm-dir --with-php-config=<path-to-php-config>
make & make install

如果有依赖相关报错,可以安装以下包

复制代码
yum install libwebp-devel libjpeg-turbo-devel libpng-devel libXpm-devel freetype-devel

如果是和php编译在一起的,就需要重新编译php,使用php -i | grep configure查看原始编译参数,然后把相关参数添加到编译参数中。如果是yum或者apt安装的php,则可以通过以下方式重新添加gd扩展

复制代码
cp modules/gd.so /usr/lib64/php/modules/my_gd.so

vim /etc/php.d/gd.ini  
;extension=gd.so  
extension=my_gd.so

libsodium

报错 configure: error: Package requirements (libsodium >= 1.0.8) were not met:

shell 复制代码
wget https://download.libsodium.org/libsodium/releases/libsodium-1.0.18-stable.tar.gz
tar -zxf libsodium-1.0.18-stable.tar.gz
cd libsodium-stable
./configure 
make && make install
 
方法一:临时生效,重新登录即失效
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
方法二:永久生成
vim /etc/profile
在profile文件加上
export  PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
然后执行
source /etc/profile

执行一下命令能看到图示结果证明安装成功了

shell 复制代码
pkg-config --list-all | grep libsodium
pkg-config --modversion libsodium #查看版本,如果版本不一致,则需要配置PKG_CONFIG_PATH

zip

安装libzip,如果需要新版则需要编译安装,否则可以使用libzip-devel或者yum命令安装

libzip 官方下载下面:https://libzip.org/download/

libzip 提供了两种类型的压缩包格式,XZ(扩展名为 .xz)和 Gzip(扩展名为 .gz),可根据自己的需要选择,本文以 XZ 格式为例。

切换到系统的源代码存放目录,将 libzip 的源代码压缩包下载下来:

复制代码
cd /usr/local/src
curl -LO https://libzip.org/download/libzip-1.8.0.tar.xz

解压缩 libzip 源代码压缩包,并切换到源代码所在目录(注意,除非有说明,所有操作都会在该目录下进行,切勿离开):

复制代码
tar -xvf libzip-1.8.0.tar.xz
cd libzip-1.8.0

由于编译 libzip 需要依赖很多函数库(Library),所以需要在正式编译前准备好这些库。具体依赖哪些库可以查看源代码目录下的 INSTALL.md 文件,里面有详细说明。如果缺少某些库,在运行下面给出的 cmake 命令后会中断并给出提示。

为节省时间,你可以直接运行以下命令为操作系统安装所有依赖库:

复制代码
yum install zlib-devel bzip2-devel xz-devel \
libzstd-devel openssl-devel 

注意,libzip 支持五种 AES(高级加密标准)实现,分别是 Apple’s CommonCrypto、GnuTLS、mbed TLS、OpenSSL 和 Microsoft Windows Cryptography Framework,但是只需要选择其中一种。本文示例选用的是 OpenSSL,所以安装了 openssl-devel。

接下来就可以运行下面这三条命令生成含有 Makefile 文件的项目构建系统:

复制代码
mkdir build
cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=/usr/local/libzip \
-DENABLE_OPENSSL=on \
-DENABLE_GNUTLS=off \
-DENABLE_MBEDTLS=off

注意,这里使用了四个 CMake 选项配置 libzip,其用途如下表所示:

选项 用途
CMAKE_INSTALL_PREFIX 指定 libzip 库安装位置
ENABLE_OPENSSL=on 指定使用 OpenSSL 作为 AES 实现
ENABLE_GNUTLS=off ENABLE_MBEDTLS=off 禁用被自动检测到的其它 AES 实现

配置 libzip 项目构建系统

命令执行后,如果进度达到 100% 且没有出现任何错误,即可运行以下命令正式开始编译:

复制代码
make

待编译进度达到 100% 且没有任何错误,即可运行以下命令完成安装:

复制代码
make install

至此,libzip 就成功编译安装完成了。

完成以上流程后,应该能够得到如下所示的这些可用文件或信息,有些可能会被其它软件用到。

libzip 的 pkg-config 配置文件目录:

复制代码
/usr/local/libzip/lib64/pkgconfig

libzip 头文件目录:

复制代码
/usr/local/libzip/includes

libzip 库文件目录:

复制代码
/usr/local/libzip/lib64

安装php扩展步骤和其他扩展一样

复制代码
phpize
configure --with-php-config
make -j 
make install

如果遇到下面的问题,可以使用export PKG_CONFIG_PATH=/usr/local//lib64/pkgconfig 再进行configure

复制代码
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

pecl卸载扩展

复制代码
pecl uninstall swoole

报错解决方案

php拓展安装报错:Warning: PHP Startup: Invalid library (maybe not a PHP library) '*.so' in Unknown on line *

解决方法:make clean 然后重新phpize,configure --with-php-config=,make,make install走安装流程

Ubuntu 18.04 安装 php7.4 --enable-maintainer-zts
PHP 编译安装 PHP各参数配置详解
7.2.*PHP编译安装时常见错误解决办法,php编译常见错误 - 知乎 (zhihu.com)

/ext/iconv/iconv.c:2557: undefined reference to `libiconv_close'

这个错误通常是由于缺少libiconv库或者是libiconv库版本过低导致的。可以通过安装或升级libiconv库来解决这个问题

shell 复制代码
yum install libiconv-devel

如果没有这个包,可以编译安装,然后指定libiconv目录,--with-iconv-dir=/usr/local/libiconv

shell 复制代码
wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.16.tar.gz
tar xvf libiconv-1.16.tar.gz
cd libiconv-1.16
./configure --prefix=/usr/local/libiconv make make install

还是不行的话,make的时候加上 ZEND_EXTRA_LIBS='-liconv' ,或者修改 Makefile 文件中的EXTRA_LIBS,加上-liconv

nginx&php 配置动态网页

因为安装php的时候已经修改过php-fpm配置文件了,所以下面就添加nginx配置即可

shell 复制代码
vim /usr/local/nginx/conf/enable-php-81.conf

加入

复制代码
location ~ [^/]\.php(/|$)
{
        try_files $uri =404;
        # fastcgi_pass  unix:/usr/local/php/81/var/run/php-fpm.sock;  # 监听本地套接字
        fastcgi_pass 127.0.0.1:9000;  # 监听tcp端口
        fastcgi_index index.php;
        fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
        include fastcgi_params;
}

在新建的server内加入

复制代码
include enable-php-81.conf;

reload nginx,就可以了

其他常用配置

laravel伪静态

复制代码
location / {
        try_files $uri $uri/ /index.php?$query_string;
}

禁止访问的文件和静态文件配置

复制代码
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
{
        return 404;
}

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
        expires      30d;
        error_log /dev/null;
        access_log /dev/null;
}

location ~ .*\.(js|css)?$
{
        expires      12h;
        error_log /dev/null;
        access_log /dev/null;
}