Docker - phpfpm镜像下的php扩展安装配置

AI 摘要: 本文介绍了 PHP 容器内容的基本知识,包括 PHP 核心库的安装方法和相关参考资料。

php 的容器内容基于 php:alpine 镜像安装

1. PHP 核心库安装

  • docker-php-ext-configure:编译过程中,通过 docker-php-ext-configure 可以指定相关编程参数;
  • docker-php-ext-install:安装核心扩展,并 enbale 扩展到配置文件,或者通过指定目录安装第三方扩展;
  • docker-php-ext-enable:通过 pecl 安装的标准扩展后,需要通过 enable 加入到php.ini,extension 扩展中(有的是基于单独 ini 扩展配置文件,单独放在conf.d下管理)
  • docker-php-source:轻松提取 tar 或删除提取的源,请务必将其删除在 docker 镜像的同一层中,这块用得不多
1
2
3
4
FROM php:7.2-cli
RUN docker-php-source extract \
    # do important things \
    && docker-php-source delete

2. 安装前的准备

php 的扩展基于 c 来编写的,需要有对应的 gcc 编译环境,否则会遇到编译器缺失的错误

2.1. 编译器缺失

Alpine 系统中的 gcc 编译环境安装

参考:

安装 php 扩展过程中报错,镜像选择的是 php-apline 镜像

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
/usr/local/etc # apk add build-base
(1/19) Installing binutils (2.30-r5)
(2/19) Installing libmagic (5.32-r0)
(3/19) Installing file (5.32-r0)
(4/19) Installing gmp (6.1.2-r1)
(5/19) Installing isl (0.18-r0)
(6/19) Installing libgomp (6.4.0-r9)
(7/19) Installing libatomic (6.4.0-r9)
(8/19) Installing pkgconf (1.5.3-r0)
(9/19) Installing libgcc (6.4.0-r9)
(10/19) Installing mpfr3 (3.1.5-r1)
(11/19) Installing mpc1 (1.0.3-r1)
(12/19) Installing libstdc++ (6.4.0-r9)
(13/19) Installing gcc (6.4.0-r9)
(14/19) Installing musl-dev (1.1.19-r10)
(15/19) Installing libc-dev (0.7.1-r0)
(16/19) Installing g++ (6.4.0-r9)
(17/19) Installing make (4.2.1-r2)
(18/19) Installing fortify-headers (0.9-r0)
(19/19) Installing build-base (0.5-r1)
Executing busybox-1.28.4-r1.trigger
OK: 177 MiB in 50 packages

2.2. 缺少 autoconf

1
2
3
4
5
6
7
/usr/local/etc # apk add autoconf
(1/4) Installing m4 (1.4.18-r1)
(2/4) Installing libbz2 (1.0.6-r6)
(3/4) Installing perl (5.26.3-r0)
(4/4) Installing autoconf (2.69-r2)
Executing busybox-1.28.4-r1.trigger
OK: 216 MiB in 54 packages

3. PHP Core Extensions

php 除了常见已经安装的扩展,可以通过php -m查看,对应的配置路径可以基于php-config查看,其余相关的扩展安装涉及:

php 核心库包含在内置的PHP source包中,可以通过docker-php-ext-install直接安装,诸如 opcache、sockets、curl、bcmath 等

3.1. 核心库基于 docker-php-ext-install 命令安装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
/usr/local/etc # docker-php-ext-install -h
usage: /usr/local/bin/docker-php-ext-install [-jN] ext-name [ext-name ...]
   ie: /usr/local/bin/docker-php-ext-install gd mysqli
       /usr/local/bin/docker-php-ext-install pdo pdo_mysql
       /usr/local/bin/docker-php-ext-install -j5 gd mbstring mysqli pdo pdo_mysql shmop

if custom ./configure arguments are necessary, see docker-php-ext-configure

Possible values for ext-name:
bcmath bz2 calendar ctype curl dba dom enchant exif fileinfo filter ftp gd gettext gmp hash iconv imap interbase intl json ldap mbstring mysqli oci8 odbc opcache pcntl pdo pdo_dblib pdo_firebird pdo_mysql pdo_oci pdo_odbc pdo_pgsql pdo_sqlite pgsql phar posix pspell readline recode reflection session shmop simplexml snmp soap sockets sodium spl standard sysvmsg sysvsem sysvshm tidy tokenizer wddx xml xmlreader xmlrpc xmlwriter xsl zend_test zip

3.2. 安装 gd 扩展

alpine 与其他系统的包名有些许差别:https://github.com/docker-library/php/issues/225

1
2
3
4
5
6
7
8
// 在phpfpm容器内部
apk update && apk add \
    freetype-dev \
    libjpeg-turbo-dev \
    libpng-dev \
&& docker-php-ext-install -j$(nproc) iconv \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd

4. PECL extensions

PECL 是 PHP Extensions 的存储库,提供了用于下载和开发 PHP 扩展的所有已知扩展和托管工具的目录,PECL 使用的包装和分销系统与其姐妹 PEAR 共享。

4.1. PHP Extension Community Library

PECL 代表 PHP 扩展社区库 - PHP Extension Community Library它具有用 C 编写的扩展,可以加载到 PHP 中以提供其他功能。您需要具有管理员权限,C 编译器和相关工具链才能安装这些扩展。

4.2. PHP Extension and Application Repository

PEAR 是 PHP 扩展和应用程序库 - PHP Extension and Application Repository它具有用 PHP 编写的库和代码,只需下载,安装并包含在您的代码中即可。(这块目前大都被 composer 包管理统一了,可以认为 composer 是 pear 安装程序的继承者)

4.3. PECL 标准库基于 pecl 命令安装 socks、redis、xdebug

因为是 C 扩展,注意提前安装好对应的 gcc 编译环境!

1
2
3
// 在phpfpm容器内部
pecl install redis \
    && docker-php-ext-enable redis xdebug

注意:强烈建议用户使用其明确的版本号 pecl install 的调用,以确保适当的 PHP 版本兼容性:

例如,memcached-2.2.0 没有 PHP 版本约束(https://pecl.php.net/package/memcached/2.2.0),但memcached-3.0.4需要PHP 7.0.0 或更新版本(https://pecl.php.net/package/memcached /3.0.4)。pecl install memcached 在 PHP 5.6 上执行(没有特定版本)时,PECL 将尝试安装最新版本并失败。

1
2
3
4
// 搜索对应的扩展,并加入版本
/usr/local/etc # pecl search redis

pecl install redis-4.3.0

5. 非核心库

某些扩展不通过 Core 或 PECL 提供; 这些也可以安装,但过程自动化程度较低,大致的流程:

  1. 通过 curl 下载对应的包
  2. 创建对应的目录
  3. 解压包到指定目录
  4. 编译安装
  5. 清理下载的包,以及安装过程中产生的中间信息,降低镜像包的大小
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 通过phpize解压,make安装后,再通过docker-php-ext-enable加入到ini配置文件中
cd /tmp \
    && 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 \
    && ( \
        cd xcache \
        && phpize \
        && ./configure --enable-xcache \
        && make -j "$(nproc)" \
        && make install \
    ) \
    && docker-php-ext-enable xcache \
    && rm -r xcache \
    && rm xcache.tar.gz \

// 或者通过docker-php-ext-configure、docker-php-ext-install安装
cd /tmp \
    && curl -fsSL 'https://xcache.lighttpd.net/pub/Releases/3.2.0/xcache-3.2.0.tar.gz' -o xcache.tar.gz \
    && mkdir -p /tmp/xcache \
    && tar -xf xcache.tar.gz -C /tmp/xcache --strip-components=1 \
    && docker-php-ext-configure /tmp/xcache --enable-xcache \
    && docker-php-ext-install /tmp/xcache \
    && rm -r /tmp/xcache \
    && rm xcache.tar.gz

6. Dockerfile - 完整版本

以上都是基于容器内部安装的,我们可以把上述内容,提取出来,放入Dockerfile内部,做成自己的 php 环境镜像包,以便后续引入,避免重复执行下载、编译、安装的流程!

  1. 将容器中的 php.ini 复制出来
  2. 修改 php.ini 以及基于自己需要安装的扩展,撰写对应的 Dockerfile
  3. 可以通过将配置文件复制到$PHP_INI_DIR/conf.d/目录中来自定义默认配置
  4. 其他类似的 php 配置可以基于 COPY 或者 RUN 编辑修改
  5. 注意:这里适当 RUN 分开了,没有遵循最佳实践,为了更清晰表述
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    # phpfpm Dockerfile
    FROM php:7.3-alpine

    # php扩展安装
    RUN apk update && apk add build-base autoconf\
        && pecl install xdebug redis \
        && docker-php-ext-enable redis xdebug \
        && docker-php-ext-install sockets

    # gb扩展
    RUN apk update && apk add \
        freetype-dev \
        libjpeg-turbo-dev \
        libpng-dev \
    && docker-php-ext-install -j$(nproc) iconv \
    && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) gd

    # xdebug配置,macOS下的remote需要通过特殊的dns `host.docker.internal`解析
    RUN sed -i '$a \
    xdebug.collect_vars=on\n\
    xdebug.collect_params=4\n\
    xdebug.remote_autostart=on\n\
    xdebug.idekey=phpstorm\n\
    xdebug.remote_enable=on\n\
    xdebug.remote_host=host.docker.internal\n\
    xdebug.remote_port=9801\n\
    ' $PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini

    # php.ini设置
    WORKDIR /usr/local/etc/
    COPY ./php.ini $PHP_INI_DIR/php.ini

7. PHP-FPM 进程信号操作

1
2
3
4
SIGINT,SIGTERM: immediate termination
SIGQUIT: graceful stop
SIGUSR1: re-open log file
SIGUSR2: graceful reload of all workers + reload of fpm conf/binary

8. 参考