Skip to content

快速参考

  • 由……维护
    Docker 社区

  • 何处获取帮助:
    Docker 社区 Slack、服务器故障、Unix & Linux 或 Stack Overflow

支持的标签及相应的 Dockerfile 链接

快速参考(续)

什么是 PHP?

PHP 是一种为网页开发设计的服务器端脚本语言,但也可被用作通用编程语言。PHP 可被添加到纯 HTML 中,或者可与各种模板引擎和网页框架一起使用。PHP 代码通常由一个解释器处理,该解释器要么作为网页服务器上的一个原生模块实现,要么作为一个通用网关接口(CGI)实现。

维基百科.org/wiki/PHP

logo

如何使用此图像

在你的 PHP 项目中创建一个 Dockerfile

FROM php:8.2-cli
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
CMD [ "php", "./your-script.php" ]

然后,运行命令来构建和运行 Docker 镜像:

$ docker build -t my-php-app .
$ docker run -it --rm --name my-running-app my-php-app

运行单个 PHP 脚本

对于许多简单的单文件项目,你可能会发现编写完整的 Dockerfile 很不方便。在这种情况下,你可以直接使用 PHP Docker 镜像来运行一个 PHP 脚本:

$ docker run -it --rm --name my-running-script -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:8.2-cli php your-script.php

如何安装更多的 PHP 扩展

许多扩展已经编译到镜像中,所以在费力编译更多之前,值得检查 php -mphp -i 的输出。

我们提供辅助脚本 docker-php-ext-configuredocker-php-ext-installdocker-php-ext-enable ,以便更轻松地安装 PHP 扩展。

为了保持图像较小,PHP 的源代码保存在压缩的 tar 文件中。为了便于将 PHP 的源代码与任何扩展链接,我们还提供了辅助脚本 docker-php-source 以轻松提取 tar 或删除提取的源代码。注意:如果您确实使用 docker-php-source 提取源代码,请务必在 Docker 镜像的同一层中删除它。

FROM php:8.2-cli
RUN docker-php-source extract \
    # do important things \
    && docker-php-source delete

PHP 核心扩展

例如,如果你想要一个带有 gd 扩展名的 PHP-FPM 镜像,你可以继承你喜欢的基础镜像,并像这样编写你自己的 Dockerfile

FROM php:8.2-fpm
RUN apt-get update && apt-get install -y \
        libfreetype-dev \
        libjpeg62-turbo-dev \
        libpng-dev \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j$(nproc) gd

请记住,你必须手动为你的扩展安装依赖项。如果一个扩展需要自定义 configure 参数,你可以像这个例子一样使用 docker-php-ext-configure 脚本。在这种情况下,不需要手动运行 docker-php-source ,因为这是由 configureinstall 脚本处理的。

如果您在确定在 docker-php-ext-install 之前需要安装哪些 Debian 或 Alpine 软件包时遇到困难,那么请查看 install-php-extensions 项目。此脚本基于 docker-php-ext-* 脚本构建,并通过自动添加和删除 Debian(apt)和 Alpine(apk)软件包来简化 PHP 扩展的安装。例如,要安装 GD 扩展,您只需运行 install-php-extensions gd 。此工具由社区成员贡献,不包含在镜像中,请参考其 Git 仓库以获取安装、使用和问题的相关信息。

另请参阅“将编译软件进行 Docker 化”,以了解 Tianon 用于确定任何一点软件所需的构建时依赖项的技术(该技术直接适用于编译 PHP 扩展)。

默认扩展

一些扩展是默认编译的。这取决于你正在使用的 PHP 版本。在容器中运行 php -m 以获取针对你特定版本的列表。

PECL 扩展

有些扩展未随 PHP 源代码提供,而是通过 PECL 提供。要安装 PECL 扩展,使用 pecl install 下载并编译它,然后使用 docker-php-ext-enable 启用它:

FROM php:8.2-cli
RUN pecl install redis-5.3.7 \
    && pecl install xdebug-3.2.1 \
    && docker-php-ext-enable redis xdebug


FROM php:8.2-cli
RUN apt-get update && apt-get install -y libmemcached-dev libssl-dev zlib1g-dev \
    && pecl install memcached-3.2.0 \
    && docker-php-ext-enable memcached

强烈建议用户在他们的 pecl install 调用中使用明确的版本号,以确保适当的 PHP 版本兼容性(PECL 在选择要安装的扩展版本时不检查 PHP 版本兼容性,但在尝试安装时会检查)。除了兼容性问题之外,确保您知道您的依赖项何时收到更新并能够直接控制这些更新也是一个好习惯。

与 PHP 核心扩展不同,PECL 扩展应依次安装,以便在出现问题时正确失败。否则,PECL 会直接跳过错误。例如,用 pecl install memcached-3.2.0 && pecl install redis-5.3.7 而不是 pecl install memcached-3.2.0 redis-5.3.7 。然而, docker-php-ext-enable memcached redis 可以在一个命令中全部完成。

其他扩展

有些扩展既不是通过核心也不是通过 PECL 提供的;这些也可以安装,尽管这个过程不太自动化:

FROM php:8.2-cli
RUN curl -fsSL '[url-to-custom-php-module]' -o module-name.tar.gz \
    && mkdir -p module-name \
    && sha256sum -c "[shasum-value]  module-name.tar.gz" \
    && tar -xf module-name.tar.gz -C module-name --strip-components=1 \
    && rm module-name.tar.gz \
    && ( \
        cd module-name \
        && phpize \
        && ./configure --enable-module-name \
        && make -j "$(nproc)" \
        && make install \
    ) \
    && rm -r module-name \
    && docker-php-ext-enable module-name

docker-php-ext-* 脚本可以接受任意路径,但它必须是绝对路径(以与内置扩展名称区分开来),所以上述示例也可以写成如下形式:

FROM php:8.2-cli
RUN curl -fsSL '[url-to-custom-php-module]' -o module-name.tar.gz \
    && mkdir -p /tmp/module-name \
    && sha256sum -c "[shasum-value]  module-name.tar.gz" \
    && tar -xf module-name.tar.gz -C /tmp/module-name --strip-components=1 \
    && rm module-name.tar.gz \
    && docker-php-ext-configure /tmp/module-name --enable-module-name \
    && docker-php-ext-install /tmp/module-name \
    && rm -r /tmp/module-name

以任意用户身份运行

对于以任意用户身份运行 Apache 变体,有几个选择:

  • 如果你的内核版本是 4.11 或更新版本,你可以添加 --sysctl net.ipv4.ip_unprivileged_port_start=0 (这将是 Docker 未来版本的默认值),然后 --user 应该像它对 FPM 所做的那样工作。
  • 如果你调整 Apache 配置以使用“非特权”端口(默认情况下大于 1024),那么无论内核版本如何, --user 都应像对 FPM 那样工作。

要以任意用户运行 FPM 变体,应使用针对 docker run--user 标志(它可以接受容器的 /etc/passwd 文件中像 --user daemon 这样的用户名/组,或者像 --user 1000:1000 这样的特定 UID/GID)。

E: Package 'php-XXX' has no installation candidate

截至 docker-library/php#542,此镜像阻止安装 Debian 的 PHP 软件包。在 docker-library/php#551(评论)中有关于此更改的一些额外讨论,但要点是在该镜像中安装 Debian 的 PHP 软件包会导致在单个镜像中出现两个相互冲突的 PHP 安装,这几乎肯定不是预期的结果。

对于那些因这一变化而受挫并在开发适当修复程序的同时寻求临时解决方法的人,在你的 Dockerfile 中添加以下简单行应可消除该阻塞(但强烈警告,这将允许安装第二个 PHP 安装程序,除非你真的知道自己在做什么,否则这肯定不是你想要的):

RUN rm /etc/apt/preferences.d/no-debian-php

此错误的正确解决方案是要么使用 FROM debian:XXX 并直接安装 Debian 的 PHP 包,要么使用 docker-php-ext-installpecl 和/或 phpize 来安装必要的额外扩展和实用程序。

配置

此图像附带默认的 php.ini-developmentphp.ini-production 配置文件。

强烈建议在生产环境中使用的图像使用生产配置!

默认配置可通过将配置文件复制到 $PHP_INI_DIR/conf.d/ 目录进行自定义。

示例

FROM php:8.2-fpm-alpine

# Use the default production configuration
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

在许多生产环境中,也建议(构建并)启用 PHP 核心 OPcache 扩展以提高性能。有关更多详细信息,请参阅上游 OPcache 文档。

图像变体

php 图像有多种类型,每种都针对特定的用例而设计。

其中一些标签可能包含诸如“书虫”或“靶心”之类的名称。这些是 Debian 发行版的套件代号,表明该镜像基于哪个发行版。如果你的镜像需要安装除镜像自带的软件包之外的任何其他软件包,你可能希望明确指定其中之一,以便在 Debian 有新版本发布时最大程度地减少损坏。

php:<version>-cli

此变体包含带有默认模块的 PHP CLI 工具。如果你需要一个 Web 服务器,这可能不是你要找的镜像。它被设计既可用作一次性容器(挂载你的源代码并启动容器以启动你的应用程序),也可用作构建其他镜像的基础。

它也是唯一包含(不推荐) php-cgi 二进制的变体,这对于像 PPM 之类的某些事情可能是必要的。

请注意, php 的所有变体都包含 PHP CLI( /usr/local/bin/php )。

php:<version>-apache

此图像包含 Debian 的 Apache httpd 与 PHP(如 mod_php )结合,并默认使用 mpm_prefork

Apache 带有 Dockerfile

FROM php:7.2-apache
COPY src/ /var/www/html/

其中 src/ 是包含你所有 PHP 代码的目录。然后,运行命令来构建和运行 Docker 镜像:

$ docker build -t my-php-app .
$ docker run -d --name my-running-app my-php-app

我们建议您添加一个 php.ini 配置文件;详情请参阅“配置”部分。

Apache 没有 Dockerfile

$ docker run -d -p 80:80 --name my-apache-php-app -v "$PWD":/var/www/html php:7.2-apache

更改 DocumentRoot (或其他 Apache 配置)

一些应用程序可能希望更改 Apache 中的默认 DocumentRoot (远离 /var/www/html )。以下展示了一种使用环境变量来实现此目的的方法(然后也可以在容器运行时修改该环境变量):

FROM php:7.1-apache

ENV APACHE_DOCUMENT_ROOT /path/to/new/root

RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf

对于其他 Apache 配置选项,可以采用类似的技术。

php:<version>-fpm

此变体包含 PHP-FPM,它是针对 PHP 的 FastCGI 实现。有关 PHP-FPM 的更多信息,请参阅 PHP-FPM 网站。

为了使用此图像变体,将需要某种反向代理(例如 NGINX、Apache 或其他支持 FastCGI 协议的工具)。

一些可能有帮助的资源:

警告:FastCGI 协议本质上是信任的,因此在私有容器网络之外暴露极其不安全——除非你确切知道自己在做什么(并且愿意承担极大风险),否则不要将 Docker 的 --publish-p )标志与这个镜像变体一起使用。

php:<version>-alpine

此镜像基于流行的 Alpine Linux 项目,在 alpine 官方镜像中可用。Alpine Linux 比大多数发行版基础镜像小得多(约 5MB),因此通常会生成更精简的镜像。

当尽可能小的最终镜像大小是你主要关心的问题时,这个变体很有用。需要注意的主要警告是,它确实使用 musl libc 而不是 glibc 及其同类,所以软件通常会根据其对 libc 要求/假设的深度而遇到问题。有关可能出现的问题以及使用基于 Alpine 的镜像的一些优缺点比较的更多讨论,请参阅此 Hacker News 评论线程。

为了最小化镜像大小,在基于 Alpine 的镜像中包含额外的相关工具(例如 gitbash )是不常见的。使用此镜像作为基础,在你自己的 Dockerfile 中添加你需要的东西(如果你不熟悉,可查看 alpine 镜像描述以获取如何安装软件包的示例)。

许可证

查看此映像中包含的软件的许可证信息。

与所有 Docker 镜像一样,这些镜像可能还包含其他可能受其他许可证约束的软件(例如来自基础发行版的 Bash 等,以及所包含的主要软件的任何直接或间接依赖项)。

一些能够自动检测到的额外许可证信息可能会在 repo-info 存储库的 php/ 目录中找到。

对于任何预构建镜像的使用,镜像用户有责任确保对此镜像的任何使用都符合其中包含的所有软件的任何相关许可证。