php docker容器的使用
Table of Contents
不同镜像可能具体还会有些细微区分,本文以php:7.4-fpm-bullseye
这个镜像为例。
运行php docker容器
我们使用以下命令运行php:7.4-fpm-bullseye
镜像
docker run -it --name php -d php:7.4-fpm-bullseye
运行该镜像后进入该容器
docker exec -it php bash
在容器的/usr/local/bin/
目录下有五个docker-php-
开头的命令,分别为
docker-php-entrypoint
docker-php-ext-configure
docker-php-ext-enable
docker-php-ext-install
docker-php-source
docker-php-entrypoint
docker-php-entrypoint
是Dockerfile中ENTRYPOINT ["docker-php-entrypoint"]
这样用的,就是进入容器后默认会执行它,相信对Dokcerfile有一定了解的朋友应该是知道entrypoint的。
docker-php-entrypoint
其实是一个bash脚本,具体解释见这篇文章:Shell扩展(Shell Expansions)-参数扩展(Shell Parameter Expansion)。
docker-php-source
source表示源码,它是用于管理php源码的,如下所示,进入容器后,在容器中的/usr/src/
文件夹下有以下文件
root@e25821dafa4e:/usr/src# ls -l
total 10184
-rw-r--r-- 1 root root 10420144 Nov 15 06:00 php.tar.xz
-rw-r--r-- 1 root root 833 Nov 15 06:00 php.tar.xz.asc
其中“php.tar.xz”就是php源码包,用xz是因为它压缩比比较大,体积小,而“php.tar.xz.asc”是PGP数字签名,用于检验文件完整性。当我们需要编译扩展时,需要用到php源码中的ext目录中的源码,所以我们需要把“php.tar.xz”解压出来,安装完之后再删除解压出来的包,以免占用空间(因为留着它也没什么用,需要用的时候再解压就行)。
我们直接在容器中运行docker-php-source
命令,可以看到它有两个参数可以用,一个是extract
用于解压,一个是delete
用于删除解压后的源码文件夹
root@e25821dafa4e:/usr/src# docker-php-source
usage: /usr/local/bin/docker-php-source COMMAND
Manage php source tarball lifecycle.
Commands:
extract extract php source tarball into directory /usr/src/php if not already done.
delete delete extracted php source located into /usr/src/php if not already done.
即用法为:
# 解压源码文件夹(解压出来的文件夹也在当前文件夹,即“/usr/src/”文件夹,解压出来的文件夹名为“php”)
docker-php-source extract
# 删除解压出来的源码文件夹
docker-php-source delete
docker-php-ext-enable
用于启用某个扩展,扩展安装(编译)好之后,是一个.so
文件,需要在php.ini(或者它的子目录conf.d)中添加一句,比如添加extension=curl
来启用curl扩展,而docker-php-ext-enable
命令就是做这个事情的。
特别注意:源码编译php时,./configure
指定一些编译选项,有些是--enable-
开头的,注意区分,那些enable开头的并不能直接在这里用docker-php-ext-enable
开启,docker-php-ext-enable
在这里特指已经编译出xxx.so
了,执行docker-php-ext-enable xxx
就会在php.ini
中添加extension=xxx
以启用它(当然这里实际上是在php.ini的子目录中添加的,因为直接修改php.ini不方便管理,所以是在子目录以“一个文件一个扩展”的形式来管理的,这样添加一个文件就启用了一个扩展,删除一个文件就停用了一个扩展)。
docker-php-ext-install
比如docker-php-ext-install -j$(nproc) gd
,表示安装gd库。
-j
其实是make
命令的参数,因为docker-php-ext-install
只是一个bash脚本,它内部也是调用make
命令来编译扩展的源码的,可以看下make
命令-j
的作用,就是指定编译任务并发量,目的是为了加快编译速度
-j [jobs], --jobs[=jobs]
Specifies the number of jobs (commands) to run simultaneously. If there is more than one -j option,
the last one is effective. If the -j option is given without an argument, make will not limit the
number of jobs that can run simultaneously.
你可以使用-j8
表示允许最多8个线程并行编译,用于加快编译速度,$(nproc)
本质上也是一个数字,只不过它是系统允许的最大进程数,可能每个系统不一样,我们需要用$(nproc)
来动态获取这个数字而已。
docker-php-ext-install
用于安装扩展,安装完之后它会自动启用docker-php-ext-enable
来启用你安装的扩展。但是如果你是用pecl安装的扩展,那么就需要使用docker-php-ext-enable
来启用它了,因为pecl不是自定义的docker-php-ext-install
脚本,所以它不会自动调用docker-php-ext-enable
来启用它安装好的插件。
make本质是调用gcc编译,对make来说,-j8
表示8个线程,但对gcc来说就是进程。
nproc是操作系统级别对每个用户创建的进程数的限制,在Linux下运行多线程时,每个线程的实现其实是一个轻量级的进程,对应的术语是:light weight process(LWP)。怎么知道一个用户创建了多少个进程呢,默认的ps是不显示全部进程的,需要‘-L’ 才能看到所有的进程。
举例1:查看所有用户创建的进程数,使用命令:
ps h -Led -o user | sort | uniq -c | sort -n
docker-php-ext-configure
docker-php-ext-configure
用于配合docker-php-ext-install
使用,因为在安装之前需要先configure,就好像你源码编译php时,要先./configure
后面添加很多选项,运行完之后,才是make && make install
(当然也可以直接make install
)。
但是它与./configure
又有所不同,它的语法是这样的
usage: /usr/local/bin/docker-php-ext-configure ext-name [configure flags]
ie: /usr/local/bin/docker-php-ext-configure gd --with-jpeg-dir=/usr/local/something
即需要针对某个扩展来指定该扩展需要什么编译选项,比如我们在源码编译php时指定mysqli
扩展使用mysqlnd
驱动,在源码编译时,可指定--with-mysqli=mysqlnd
这个编译选项,这个对应到docker-php-ext-configure
,就要写成以下这样,意思是编译mysqli时,使用--with-mysqli=mysqlnd
选项来指定mysqlnd
作为mysqli的驱动
docker-php-ext-configure mysqli --with-mysqli=mysqlnd
docker-php-ext-install mysqlnd
解决“Cannot find config.m4.”问题
cp /usr/src/php/ext/mysqlnd/config9.m4 /usr/src/php/ext/mysqlnd/config.m4
又会报“No package ‘openssl’ found”,这是因为没有openssl dev包造成的,需要安装libssl-dev
(apt install libssl-dev
就可以)。
查看php扩展(xxx.so)所在目录
php -i | grep extension_dir