zoukankan      html  css  js  c++  java
  • 宿主机nginx使用容器php-fpm处理php请求

    宿主机Nginx使用php容器解析php请求

    环境说明

    首先,我在宿主机上已经运行了一个nginx

    [root@localhost html]# nginx -v
    nginx version: nginx/1.18.0
    

    宿主机上也安装运行了docker

    [root@localhost html]# docker version
    Client: Docker Engine - Community
     Version:           20.10.2
    ...
    

    需求:在docker里面运行php容器,然后用php容器来解析所有访问nginx的php请求。

    基于alpine定制php-fpm容器

    php官方基础镜像缺少很多扩展,一般情况下不满足实际项目的运行,所以需要定制一个符合项目运行环境的php镜像。

    了解php基础镜像

    php的官方镜像分为三个分支:

    • cli :没有开启CGI,也就是不能运行fpm,只能运行命令行。
    • fpm :开启了CGI,可以用来运行web服务也可以运行cli命令。
    • zts :开启了线程安全的版本。

    一般来说,lnmp环境使用 fpm即可。

    镜像选择

    这里我使用的php官方镜像是: php:7.3.23-fpm-alpine。php版本为7.3.23,是基于Alpine Linux 3.12基础镜像构建的,所以镜像体积会比较小。

    默认官方的镜像有如下扩展:

    /var/www/html # php -m
    [PHP Modules]
    Core
    ctype
    curl
    date
    dom
    fileinfo
    filter
    ftp
    hash
    iconv
    json
    libxml
    mbstring
    mysqlnd
    openssl
    pcre
    PDO
    pdo_sqlite
    Phar
    posix
    readline
    Reflection
    session
    SimpleXML
    sodium
    SPL
    sqlite3
    standard
    tokenizer
    xml
    xmlreader
    xmlwriter
    zlib
    
    [Zend Modules]
    

    除了以上扩展,我们还需要安装一些其他扩展:

    • redis
    • gd
    • mysqli
    • pdo_mysql
    • opcache
    • zip
    • bcmatch等
    构建准备
    # 创建目录
    $ mkdir -p /root/docker/php
    $ cd /root/docker/php
    
    # 创建配置文件目录
    $ mkdir conf.d
    
    # 设置php时区为东八区
    $ echo "date.timezone = Asia/Shanghai" >> conf.d/date.ini
    
    # 设置opcode默认的参数
    $ cat >> conf.d/opcode.ini << EOF
    opcache.enable=${OPCODE}
    enable_clopcache.enable_cli=1
    opcache.revalidate_freq=60
    opcache.max_accelerated_files=100000
    opcache.validate_timestamps=1
    EOF
    
    # 设置alpine的apk源为国内源
    $ cat >> repositories <<EOF
    http://mirrors.aliyun.com/alpine/v3.12/main
    http://mirrors.aliyun.com/alpine/v3.12/community
    EOF
    
    # 准备php-fpm配置文件
    $ cat >> www.conf << EOF
    [www]
    user = www
    group = www
    listen = 0.0.0.0:9000
    pm = dynamic
    pm.max_children = 5
    pm.start_servers = 2
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3
    EOF
    
    # 项目目录结构如下:
    [root@localhost php]# tree .
    .
    ├── conf.d
    │   ├── date.ini
    │   └── opcode.ini
    ├── Dockerfile
    ├── repositories
    └── www.conf
    

    最终的Dockerfile文件如下:

    FROM php:7.3.23-fpm-alpine
    
    LABEL maintainer="syushin 1147070314@qq.com"
    
    # 设置apk源为阿里云
    COPY repositories /etc/apk/repositories
    COPY ./conf.d/ $PHP_INI_DIR/conf.d/
    
    ENV TZ "Asia/Shanghai"
    ENV TERM xterm
    # 默认关闭opcode
    ENV OPCODE 0
    
    # 添加用户
    RUN addgroup -g 1000 -S www && adduser -s /sbin/nologin -S -D -u 1000 -G www www
    
    # PHPIZE_DEPS 包含 gcc g++ 等编译辅助类库,完成编译后删除
    RUN apk add --no-cache $PHPIZE_DEPS 
        && apk add --no-cache libstdc++ libzip-dev vim
        && apk update 
        && pecl install redis-4.3.0 
        && pecl install zip 
        && pecl install swoole 
        && docker-php-ext-enable redis zip swoole
        && apk del $PHPIZE_DEPS
    
    # 安装扩展
    RUN apk add --no-cache 
           freetype 
           libpng 
           libjpeg-turbo 
           freetype-dev 
           libpng-dev 
           jpeg-dev 
           libjpeg 
           libjpeg-turbo-dev 
           libwebp 
           libwebp-dev 
        && docker-php-ext-configure gd --with-gd --with-webp-dir --with-jpeg-dir 
           --with-png-dir --with-zlib-dir --with-freetype-dir 
        && NUMPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) 
        && docker-php-ext-install -j${NUMPROC} gd 
        && docker-php-ext-install -j${NUMPROC} pdo_mysql 
        && docker-php-ext-install -j${NUMPROC} opcache 
        && docker-php-ext-install -j${NUMPROC} bcmath  
        && docker-php-ext-install -j${NUMPROC} mysqli
    # 拷贝配置文件
    COPY  www.conf /usr/local/etc/php-fpm.d/www.conf
    
    RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
    

    说明:

    • PHP_INI_DIR:这个环境变量是在php的基础镜像Dockerfile中有定义
    • PHPIZE_DEPS:这个也是定义在基础镜像Dockerfile中,包含了扩展编译安装时需要但是php运行不需要的linux软件库。我们需要把它们挑选出来,在编译完扩展之后删除。

    构建:

    # 创建构建命令脚本文件
    $ cd /root/docker/php
    $ cat >>  build-comand.sh << EOF
    #/bin/bash
    docker build -t myphp:7.3.23-alpine .
    EOF 
    
    # 执行构建
    $ sh build-comand.sh
    
    构建完成检查

    构建完成之后,进入容器,检查定制的容器。

    # 进入容器
    [root@localhost php]# docker run -it --rm myphp:7.3.23 sh
    /var/www/html # php -m
    [PHP Modules]
    bcmath
    Core
    ctype
    curl
    date
    dom
    fileinfo
    filter
    ftp
    gd 	 # 安装的扩展
    hash
    iconv
    json
    libxml
    mbstring
    mysqli # 安装的扩展
    mysqlnd # 安装的扩展
    openssl
    pcre
    PDO
    pdo_mysql # 安装的扩展
    pdo_sqlite
    Phar
    posix
    readline
    redis # 安装的扩展
    Reflection
    session
    SimpleXML
    sodium
    SPL
    sqlite3
    standard
    swoole
    tokenizer
    xml
    xmlreader
    xmlwriter
    Zend OPcache
    zip # 安装的扩展
    zlib
    
    [Zend Modules]
    Zend OPcache
    
    /var/www/html # id www # 用户也创建了
    uid=1000(www) gid=1000(www) groups=1000(www),1000(www)
    
    # 配置文件也拷贝进来了
    /var/www/html # cat /usr/local/etc/php-fpm.d/www.conf
    [www]
    user = www
    group = www
    listen = 0.0.0.0:9000
    pm = dynamic
    pm.max_children = 5
    pm.start_servers = 2
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3
    

    这样,一个自定义的php-fpm镜像就定制完成。

    Nginx使用容器php-fpm进行解析

    Nginx是在宿主机上,所以先定义一个Nginx的虚拟主机配置文件:

    server{
        listen 80 default_server;
        server_name syushin.com;
        index index.html index.htm index.php;
        root /var/www/html;
    
        location ~ .php$
        {
            root /var/www/html;
            include fastcgi_params;
            fastcgi_pass 0.0.0.0:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
    }
    

    这里,location php里面的root很重要,这里要填php容器中php项目所在目录 而不是nginx宿主机的web路径。以往的nginx和php都在同一台机器上时不存在这个问题,现在nginx和php算是分开的,所以需要注意一下。fastcgi_param 参数配置的是nginx请求php-fpm时需要带过去的参数,SCRIPT_FILENAME 表示fpm要执行的PHP文件的路径,而 $document_root的值 就是前面的 root 参数的值,所以root要配置成php容器中的php路径。fastcgi_pass 这里的ip地址可以使用php容器的ip,这里我打算使用端口映射的方式启动php容器,用宿主机9000端口映射php容器的9000端口,所以这里直接写 0.0.0.0:9000了。

    启动自定义的php容器

    $ docker run --itd -v /home/wwwroot/syushin:/var/www/html -p 9000:9000 --name myphp myphp:7.3.23
    

    创建站点目录和测试文件

    $ mkdir -p /home/wwwroot/syushin
    $ cat index.php 
    <?php
    echo phpinfo();
    ?>
    
    $ nginx -t 
    $ nginx -s reload
    

    浏览器访问宿主机IP测试,显示如下画面表示此次试验成功。

  • 相关阅读:
    ASP.NET常见命名空间及其功能描述
    C#中的里氏替换原则
    Java中的split函数的用法
    shader之旅-7-平面阴影(planar shadow)
    OpenGL三角形的双面不同颜色的绘制
    MATLAB squeeze 函数
    matlab 常用函数汇总
    第一个OpenGL程序
    Github 留言系统
    Paging 简单自由的分页生成器
  • 原文地址:https://www.cnblogs.com/syushin/p/14266358.html
Copyright © 2011-2022 走看看