docker非常方便, 使用docker构建php镜像后, 以后就能重复使用.
构建php镜像和直接安装在linux系统上没区别, 重点在于扩展的安装. 我打算在官方构建好的镜像基础上, 因为官方已经帮我们配置好了很多工具, 更加方便构建.
三种安装扩展的方式
内置扩展安装(只是帮我们下载了源码, 还没有安装)
官方已经帮我们存放了很多未编译的扩展, 我们不需要下载源码, 可以进行快速安装.
下面是官方安装示范, 这个示范比较复杂,
首先去远程下载gd的三个依赖扩展,
然后通过
docker-php-ext-configure
对gd进行配置, 主要是告诉gd依赖扩展的位置, 该命令类似于phpize
+./configure
最后通过
docker-php-ext-install
真实安装, 该命令类似于make
+make install
,-j$(nproc)
是固定写法, 安装扩展就固定这样写.FROM php:7.4-fpm RUN apt-get update && apt-get install -y
libfreetype6-dev
libjpeg62-turbo-dev
libpng-dev
&& docker-php-ext-configure gd --with-freetype --with-jpeg
&& docker-php-ext-install -j$(nproc) gd
PECL扩展安装
pecl是php安装包的中央仓库, 类似于java的maven, node的npm.
下面也是官方示例
首先使用pecl命令直接安装redis和xdebug, pecl已经内置在了该镜像中, 有一点需要注意, 安装时必须指定具体版本, 因为pecl不会检测版本, 不指定的话会安装最新版本, 容易导致不兼容.
然后使用
docker-php-ext-enable
命令开启redis和xdebug, 这个相当于在php.ini配置文件中打开这两个配置项.FROM php:7.4-fpm RUN pecl install redis-5.1.1
&& pecl install xdebug-2.8.1
&& docker-php-ext-enable redis xdebug
其他扩展安装
有很多扩展没有被收入到PECL中, 那么就需要我们自己下载源码, 编译安装.
下面还是官方示例, 如果你原来在linux上面编译安装过php扩展, 就有种熟悉的感觉.
首先去远程下载xcache源码包, 意思是使用重定向下载, 如果出错不生成记录错误的html文件, 下载时不显示进度信息, 但会显示错误提示.
curl的参数解释:
f
表示fail, 当有错误时, 默认会返回包含错误信息的html文件, 使用了该参数后, 当发生错误时, 丢弃该错误信息文件.s
表示不输出错误和进度信息S
表示只输出错误信息, 一般和s
连用L
表示跟随重定向.o
表示把服务器响应内容保存为文件, 等同于wget
命令.然后就是正常解压编译安装.
tar参数解析:
x
表示extract, 提取文件的意思.f
表示提取哪个文件.C
表示指定解压到哪个文件夹.--strip-components=n
表示解压后去除n层目录结构最后使用
docker-php-ext-enable
激活php.ini配置选项.FROM php:7.4-fpm RUN curl -fsSL 'https://xcache.lighttpd.net/pub/Releases/3.2.0/xcache-3.2.0.tar.gz' -o xcache.tar.gz
&& mkdir -p xcache
&& tar -xf xcache.tar.gz -C xcache --strip-components=1
&& rm xcache.tar.gz
&& (
cd xcache
&& phpize
&& ./configure --enable-xcache
&& make -j "$(nproc)"
&& make install
)
&& rm -r xcache
&& docker-php-ext-enable xcache
如果大家能用内置安装就用内置, 不能用内置就用pecl, 都不能用就外部编译安装.
内置变量
官方镜像除了内置了脚本命令外, 还内置了几个环境变量, 我们可以直接拿来用.
PHP_INI_DIR: php.ini配置文件目录
PHPIZE_DEPS: 包含gcc, g++等编译辅助软件名称
TZ: 时区
需要的扩展
redis
: 生产环境都要用到缓存提高速度, 这个很有必要. opcache
: 这个是文件缓存, 生产环境也有必要. gd
: 图片处理库, 必装. pdo_mysql
: mysql链接库, 必装. mbstring
: 对字符串的很多操作, 必装.
构建准备
我们把一些单独扩展的配置放入conf.d
文件夹, 然后让php.ini
引入, 方便以后修改, 学习nginx的做法.
date.ini
date.timezone = Asia/Shanghai
opcache.ini
# OPCACHE_ENABLE用来控制是否开启opcache, 0不开启, 1开启
opcache.enable=${OPCACHE_ENABLE}
enable_clopcache.enable_cli=1
opcache.revalidate_freq=60
opcache.max_accelerated_files=100000
opcache.validate_timestamps=1
开始构建
我使用的是7.3.28-fpm-alpine3.14
基础镜像作为构建.
安装内置扩展 gd pdo_mysql opcache mbstring
首先是安装内置扩展, 使用docker run 7.3.28-fpm-alpine3.14 php -m
命令就能看到内置了哪些扩展. 这个命令不能显示内置的ZEND Module
.(www.hedaoshe.com)
RUN apk add --no-cache freetype libpng libjpeg-turbo freetype-dev libpng-dev libjpeg-turbo-dev \
&& apk update \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd pdo_mysql opcache mbstring
安装PECL扩展 redis
这个就要去https://pecl.php.net/
找, 常用的都有.
记住一定要使用确定的版本, pecl不会检测版本号的兼容性.
我们能发现PECL需要安装
$PHPIZE_DEPS
编译包, 而内置的不需要, 是因为docker-php-ext-install
命令已经集成了安装完成后别忘了卸载编译包, 该动作也被
docker-php-ext-install
集成了, 但docker-php-ext-enable
没集成RUN apk add --no-cache $PHPIZE_DEPS
&& apk update
&& pecl install redis-4.3.0
&& docker-php-ext-enable redis
&& apk del $PHPIZE_DEPS
完整代码
FROM php:7.3.28-fpm-alpine3.14
# 设置容器时区, 世界时间+8
ENV TZ "Asia/Shanghai"
# 设置是否开启opcache缓存, 0表示不开启, 1表示开启
ENV OPCACHE_ENABLE=0
# www.conf配置路径
ENV WWW_CONF_PATH="/usr/local/etc/php-fpm.d/www.conf"
# 配置apk包国内地址, 下载慢就开启. 不过开启了还是慢, 最好用vpn
# RUN echo 'https://mirrors.aliyun.com/alpine/v3.9/main/' > /etc/apk/repositories && \
# echo 'https://mirrors.aliyun.com/alpine/v3.9/community/' >> /etc/apk/repositories
# 安装内置扩展 gd pdo_mysql opcache mbstring
RUN apk add --no-cache freetype libpng libjpeg-turbo freetype-dev libpng-dev libjpeg-turbo-dev \
&& apk update \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd pdo_mysql opcache mbstring
# 安装PECL扩展 redis
RUN apk add --no-cache $PHPIZE_DEPS \
&& apk update \
&& pecl install redis-4.3.0 \
&& docker-php-ext-enable redis \
&& apk del $PHPIZE_DEPS
# 获取php.ini
RUN cp "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# 配置php.ini
COPY ./conf.d/ $PHP_INI_DIR/conf.d/
# 配置php-fpm.conf
RUN sed -i 's/;emergency_restart_threshold.*/emergency_restart_threshold = 10/' php-fpm.conf \
&& sed -i 's/;emergency_restart_interval.*/emergency_restart_interval = 1m/' php-fpm.conf \
&& sed -i 's/;process_control_timeout.*/process_control_timeout = 10s/' php-fpm.conf
# 配置www.conf, 这个自己配置, 服务器不同配置不同
# COPY ./www.conf $WWW_CONF_PATH
# END
# 大家以这个镜像构建时, 有两个变量能用:
# OPCACHE_ENABLE, 0不开启opcache, 1开启opcache
# WWW_CONF_PATH, www.conf的路径, 用来被你的配置覆盖
总结
构建一次, 终生使用, 还等什么, 快到碗里来.