介绍
介绍
前面福哥已经教给大家使用php:7.4-apache-buster基础镜像搭建PHP运行环境了,这个是以模块方式(Module)运行PHP程序的,相比较这种方式更多人会选择主流的以FastCGI方式运行PHP程序,以FastCGI方式运行PHP程序就要用到PHP的FPM服务(FastCGI Process Manager)了。
今天福哥就带着大家使用php:7.4-fpm-buster基础镜像来搭建以FastCGI方式运行PHP程序的环境。
环境
镜像版本 | php:7.4-fpm-buster |
操作系统 | CentOS 7 x86_64 2009 |
服务器 | TFCentOS7x64 |
IP | 192.168.168.68 |
端口 | 80 |
安装
Dockerfile
基础镜像
福哥选择的是php:7.4-fpm-buster这个基础镜像,这个就是FastCGI方式的。
https://hub.docker.com/_/php/tags?page=1&name=7.4-fpm-buster
现在hub.docker.com依然打不开,大家就选这个版本吧!
拉取镜像php:7.4-fpm-buster,添加到registry.tongfu.net:5000私有仓库里面。
docker pull php:7.4-fpm-buster docker tag php:7.4-fpm-buster registry.tongfu.net:5000/php:7.4-fpm-buster docker rmi php:7.4-fpm-buster docker images | grep php
创建镜像目录
创建镜像目录php7.4nginx并切换到php7.4nginx目录下面。
mkdir /tongfu.net/data/dockerfile/tfphp7.4nginx cd /tongfu.net/data/dockerfile/tfphp7.4nginx
依赖镜像
第一行写上依赖镜像php:7.4-fpm-buster。
FROM registry.tongfu.net:5000/php:7.4-fpm-buster
维护者信息
这是福哥写的维护者信息。
# for MAINTAINER MAINTAINER Author: Andy Bogate MAINTAINER Email: tongfu@tongfu.net MAINTAINER Home page: https://tongfu.net MAINTAINER Datetime: 2023/03/18 MAINTAINER Version: v1.0
暴露端口
提供服务的端口通常情况下是80和443,我们把它们暴露出来。
# for EXPOSE EXPOSE 80 443
主目录
福哥设置镜像的主目录是/tongfu.net/web。
# for WORKDIR WORKDIR /tongfu.net/web
设置时区
默认时区是UTC,我们把它改成CST,也就是中国标准时间。
# for timezone RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ && echo "Asia/Shanghai" > /etc/timezone
安装工具和依赖库
后面的制作过程需要用到wget工具,这个需要通过apt-get安装一下。除此之外还要安装一些依赖库,包括图形库、zip和xml等等。
因为镜像本身只有一个FPM服务,FPM服务只能处理php程序,要处理其他类型的文件还得需要安装Nginx服务。
因为后面要是ps命令检测服务健康状态,所以还需要安装procps服务。
# install wget & nginx RUN apt-get update \ && apt-get -y install wget vim nginx procps RUN apt-get -y install libwebp-dev libjpeg-dev libpng-dev libfreetype6-dev RUN apt-get -y install libzip-dev RUN apt-get -y install libc-client-dev libkrb5-dev RUN apt-get -y install libxml2-dev
释放PHP源码
这个php:7.4-fpm-buster包含了PHP的源码,因为后面需要使用PHP源码安装PHP扩展,所以先要释放PHP源码。
# extract PHP source RUN docker-php-source extract
GD图形库扩展
GD图形库可以让我们通过PHP直接加工各种图片文件,这个库可以用来实现图片验证码、照片加工等等功能的。
# gd extension RUN docker-php-ext-configure gd \ --with-jpeg=/usr/include \ --with-freetype=/usr/include/ \ && docker-php-ext-install gd \ && docker-php-ext-enable gd
MySQL扩展
福哥是使用PDO来连接MySQL数据库,而MySQL的PDO库PHP资源包里包含了,只要安装起来就行了。
# extension of mysqli for MySQL RUN docker-php-ext-install mysqli \ && docker-php-ext-enable mysqli # extension of PDO for MySQL RUN docker-php-ext-install pdo_mysql \ && docker-php-ext-enable pdo_mysql
Memcached扩展
memcached库需要从PECL下载,福哥选择的是3.1.5版本,这里直接通过phpize编译后就可以通过make安装了。memcached库依赖libmemcached库,福哥选择的是1.0.18版本,尽量不要改避免版本冲突~
# library of Memcached RUN wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz \ && tar -xzvf libmemcached-1.0.18.tar.gz \ && cd libmemcached-1.0.18 \ && sed -i 's/opt_servers \=\= false/\!opt_servers/g' clients/memflush.cc \ && ./configure \ && make && make install \ && cd ../ \ && rm -f libmemcached-1.0.18.tar.gz \ && rm -rf libmemcached-1.0.18 # extension of Memcached RUN wget http://pecl.php.net/get/memcached-3.1.5.tgz \ && tar -xzvf memcached-3.1.5.tgz \ && cd memcached-3.1.5 \ && /usr/local/bin/phpize \ && ./configure --with-php-config=/usr/local/bin/php-config \ --disable-memcached-sasl \ && make && make install \ && cd ../ \ && rm -f memcached-3.1.5.tgz \ && rm -rf memcached-3.1.5 \ && docker-php-ext-enable memcached
Redis扩展
redis库需要从PECL下载,福哥选择的是4.1.0版本,这里直接通过phpize编译后就可以通过make安装了。
# extension of Redis RUN wget http://pecl.php.net/get/redis-4.1.0.tgz \ && tar -xzvf redis-4.1.0.tgz \ && cd redis-4.1.0 \ && /usr/local/bin/phpize \ && ./configure --with-php-config=/usr/local/bin/php-config \ && make && make install \ && cd ../ \ && rm -f redis-4.1.0.tgz \ && rm -rf redis-4.1.0 \ && docker-php-ext-enable redis
MongoDB扩展
MongoDB库需要从PECL下载,福哥选择的是1.7.4版本,这里直接通过phpize编译后就可以通过make安装了。
# extension of MongoDB RUN wget http://pecl.php.net/get/mongodb-1.7.4.tgz \ && tar -xzvf mongodb-1.7.4.tgz \ && cd mongodb-1.7.4 \ && /usr/local/bin/phpize \ && ./configure --with-php-config=/usr/local/bin/php-config \ && make && make install \ && cd ../ \ && rm -f mongodb-1.7.4.tgz \ && rm -rf mongodb-1.7.4 \ && docker-php-ext-enable mongodb
其他扩展
除了前面安装的几个扩展之外,福哥还安装了imap、zlib、soap、bcmath这些扩展,建议大家也把这些安装上。
# imap extension RUN docker-php-ext-configure imap \ --with-kerberos \ --with-imap-ssl \ && docker-php-ext-install imap \ && docker-php-ext-enable imap # zlib extension RUN mv /usr/src/php/ext/zlib/config0.m4 /usr/src/php/ext/zlib/config.m4 \ && docker-php-ext-install zlib \ && docker-php-ext-enable zlib # soap extension RUN docker-php-ext-install soap \ && docker-php-ext-enable soap # bcmath extension RUN docker-php-ext-install bcmath \ && docker-php-ext-enable bcmath
清理PHP源码
现在PHP的扩展都按照好了,已经不需要源码了,清理掉吧。
# source delete RUN docker-php-source delete
多进程
福哥今天制作的镜像是基于FastCGI方式运行的,这里面有FPM和Nginx两个服务,也就是说使用这个镜像启动的容器里面就会运行两个进程。但是按照Docker的设计思想一个容器里只能跑一个进程,怎么办?
其实按PHP的FastCGI方式的设计,应该是启动两个容器共同处理用户的请求。静态内容由Nginx容器负责处理,PHP程序由FPM容器负责处理。
但是福哥不想弄那么麻烦,就想把FPM服务和Nginx服务放在一起!要实现这个目的,就需要修改镜像的ENTRYPOINT。一个ENTRYPOINT只能运行一个进程,为了解决这个问题,福哥要自定义这个ENTRYPOINT,用ENTRYPOINT启动一个Shell脚本,在Shell脚本里面同时启动FPM服务和Nginx服务。
下面是福哥写的一个ENTRYPOINT启动Shell脚本start_service,用来同时启动FPM服务和Nginx服务。
#!/bin/sh # argv # functions function _main { # start fpm /usr/local/sbin/php-fpm -D # start nginx /usr/sbin/nginx # wait secs sleep 6s # service while [ 1 ] ; do if [ "" = "`ps -ef | grep -v grep | grep 'php-fpm: master process'`" ] ; then echo "php is down" exit 1 fi if [ "" = "`ps -ef | grep -v grep | grep 'nginx: master process'`" ] ; then echo "nginx is down" exit 2 fi sleep 6s done } # main _main "$@"
在创建新的镜像的时候把start_service配置文件拷贝进去,并且授权可执行权限,最后将ENTRYPOINT的命令改成start_service。
# entry point COPY start_service /usr/sbin/start_service RUN chmod +x /usr/sbin/start_service ENTRYPOINT ["/usr/sbin/start_service", ""]
php配置文件
php.ini
php.ini的存放目录是/usr/local/etc/php/,镜像提供了php-ini-development、php.ini-production两个配置文件模板,我们可以根据使用场景选择开发版本还是生产版本。
启动临时容器,从容器里复制php.ini-development出来放到镜像目录下。
docker run -tid --name ttt -h ttt registry.tongfu.net:5000/php:7.4-fpm-buster docker cp ttt:/usr/local/etc/php/php.ini-development php.ini docker rm -f ttt
设置错误日志路径,将PHP的执行错误存起来。
error_log = /tmp/php_errors.log
修改php.ini设置时区为Asia/Shanghai。
date.timezone = Asia/Shanghai
复制php.ini覆盖镜像里面的php.ini配置文件。
# php.ini COPY php.ini /usr/local/etc/php/php.ini
nginx配置文件
模块配置
镜像安装的nginx包括modules-available和modules-enabled两个模块配置目录,modules-available里面包含全部的可用模块配置文件,modules-enabled里面是启用的模块配置文件。
要启用模块就从modules-available选择模块配置文件移动到modules-enabled下面。
要停用模块就从modules-enabled选择模块配置文件移动回modules-available下面。
因为nginx默认就支持rewrite,这个模块就不用调整了!
站点配置
镜像安装的nginx包括sites-available和sites-enabled两个站点配置目录,sites-available里面包含全部的可用站点配置文件,sites-enabled里面是启用的站点配置文件。
要启用站点就从sites-available选择站点配置文件建立符号链接到sites-enabled下面。
要停用站点就将sites-enabled下面删除站点配置文件的符号链接。
因为镜像的nginx服务是福哥通过apt-get安装的,加上nginx的默认站点的配置文件default里面有很多示例的配置乱七八糟的,所以这里福哥打算自己写一个精简版本的默认站点配置文件default。
福哥在默认站点的server里面利用rewrite实现了一个PHP的伪静态重定向配置,可以将各种html请求转交给htmlRouteMap.php处理。
server { listen 80 default_server; listen [::]:80 default_server; server_name _; rewrite ^\/(.*)\.html /htmlRouteMap.php?tfphp_static_name=$1; location / { root /var/www/html; } location ~ \.php$ { client_body_buffer_size 1m; root /var/www/html; fastcgi_pass localhost:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
在创建新的镜像的时候把default配置文件拷贝进去。
# nginx sites COPY default /etc/nginx/sites-enabled/default
创建镜像
使用下面的命令创建tfphp:7.4-nginx-1.0.0镜像。
docker build -f Dockerfile \ -t registry.tongfu.net:5000/tfphp:7.4-nginx-1.0.0 ./
查看镜像
看看新的镜像,现在有apache版本、nginx版本两个tfphp的镜像了。
docker images | grep tfphp
测试
程序目录和程序文件
既然都是php环境,那么使用tfphp:7.4-apache-1.0.0的测试代码就可以了!
删除容器
因为前面我们使用apache版本的tfphp启动了一个容器了,现在要测试nginx版本的tfphp就需要先把这个tfphp容器删除掉。
docker rm -f tfphp
启动容器
使用下面的命令基于tfphp:7.4-nginx-1.0.0镜像启动一个容器,将80端口和443端口映射到宿主机上面,将/var/www/html这个nginx主目录映射到前面建立的目录上面。
docker run -tid \ --name tfphp \ -h tfphp \ -p 80:80 \ -p 443:443 \ -v /tongfu.net/data/docker/data/tfphp/html:/var/www/html \ registry.tongfu.net:5000/tfphp:7.4-nginx-1.0.0
浏览器访问
打开浏览器访问http://192.168.168.68/index.php,可以看到PHP系统信息。
可以看到Server API一栏的信息是FPM/FastCGI,证明我们的这个运行环境是FastCGI模式的。
输入网址http://192.168.168.68/tongfu.net/docker/tfphp.html,可以看到请求html资源路径被htmlRouteMap.php打印出来了。
总结
今天福哥在TFCentOS7x64服务器上面通过Dockerfile创建了一个镜像tfphp:7.4-nginx-1.0.0,并且通过这个新创建的镜像tfphp:7.4-nginx-1.0.0启动了一个容器,这个镜像用来运行基于PHP语言开发的应用程序。
后面福哥会在这个镜像tfphp:7.4-nginx-1.0.0基础之上进行二次扩展制作新的镜像,然后根据镜像的用途针对nginx和php进行自定义的配置,敬请期待~