Ubuntu 22.04 安装 PHP 8.2 需先装 software-properties-common、添加 ppa:ondrej/php 源并执行 apt update,再按 Web 服务器类型安装 php8.2-fpm(Nginx)或 libapache2-mod-php8.2(Apache),最后用 update-alternatives 设置默认版本。

直接用 php:8.2-cli 或随便找个 Ubuntu 镜像装 Apache + PHP,基本等于给后续踩坑铺路——不是扩展加载失败,就是权限错乱、.htaccess 不生效、opcache 配置白改。
选对基础镜像:apache 还是 fpm-alpine?
别凭感觉选。用 Apache 一键跑通就选 php:8.2-apache;要和 Nginx 配合、或追求轻量就选 php:8.2-fpm-alpine。前者自带 mod_rewrite,但默认禁用 .htaccess;后者体积小,但 gd、intl 等扩展得手动装依赖,且 date.timezone 必须显式设置,否则 DateTime 构造会报 Warning。
-
php:8.2-apache:适合 ThinkPHP/Laravel 的快速验证,RUN a2enmod rewrite后还得在虚拟主机配置里加AllowOverride All -
php:8.2-fpm-alpine:生产环境更常见,但RUN apk add --no-cache libpng-dev jpeg-dev freetype-dev && docker-php-ext-configure gd --with-freetype --with-jpeg && docker-php-ext-install gd这三步缺一不可 - 绝对不要用
php:8.2-cli跑 Web 服务——没apache2,没php-fpm,暴露不了 80/9000 端口,CMD ["php -S"]只能临时调试
装扩展必须用 docker-php-ext-install,别 apt-get
官方 PHP 镜像的扩展路径和编译方式是固定的,apt-get install php-gd 会把扩展装到系统路径,PHP 进程根本找不到,php -m | grep gd 永远为空。正确做法是用镜像内置的安装工具,且所有 RUN 命令末尾加 && rm -rf /var/lib/apt/lists/*(Debian/Ubuntu)或 && apk del .build-deps(Alpine)清理缓存。
- Debian/Ubuntu 基础镜像:
RUN docker-php-ext-install pdo_mysql opcache gd,装前可能需RUN apt-get update && apt-get install -y libpng-dev libjpeg-dev && rm -rf /var/lib/apt/lists/* - Alpine 镜像:
RUN apk add --no-cache --virtual .build-deps $PHPIZE_DEPS && docker-php-ext-install gd && apk del .build-deps - 扩展参数别漏:比如
gd要先docker-php-ext-configure gd --with-freetype --with-jpeg,否则编译失败
php.ini 和 conf.d 配置怎么才生效?
把自定义 php.ini COPY 进去,phpinfo() 里路径是对的,但 memory_limit 没变?大概率是没重启进程,或者配置被 /usr/local/etc/php/conf.d/ 下其他文件覆盖了。PHP 官方镜像按字母序加载 conf.d/ 下所有 .ini 文件,docker-php-ext-enable 生成的文件名(如 10-opcache.ini)会排在你自定义文件前面。
立即学习“PHP免费学习笔记(深入)”;
- 主配置只放核心项:
memory_limit、upload_max_filesize、max_execution_time写进php.ini - 扩展配置拆开管理:
COPY ./conf/opcache.ini /usr/local/etc/php/conf.d/opcache.ini,生产环境删掉xdebug.ini就行 - 改完必须重启容器,
docker exec -it xxx php --ini确认路径,php -m看扩展是否列出来,比phpinfo()更可靠
多阶段构建不是可选项,是必须项
把 composer install 和源码一起 COPY 进最终镜像,等于把 composer、git、临时编译文件全打包进去,镜像体积翻倍,还带安全风险。多阶段构建第一阶段装 Composer 并执行安装,第二阶段只 COPY vendor/ 和代码,不带任何构建工具。
- 第一阶段:
FROM composer/composer:2 AS composer或FROM php:8.2-cli AS builder,RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer - 第二阶段:
COPY --from=builder /var/www/html/vendor /var/www/html/vendor,再COPY . /var/www/html - 注意:ThinkPHP 的
runtime和storage目录不能被 COPY 覆盖,得在最终镜像里RUN chown -R www-data:www-data /var/www/html/runtime /var/www/html/storage
最常被跳过的一步:确认 www-data 用户对 runtime、storage 有写权限,且 opcache.enable=1 在 conf.d/ 下生效——这两点出问题,日志写不进、缓存不命中,查半天才发现是权限或配置没真正加载。



















