宿主機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測試,顯示如下畫面表示此次試驗成功。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM