推荐写法是image: php:8.1-apache,开箱即用;若需扩展则基于该镜像自定义Dockerfile安装pdo_mysql、redis等,并在docker-compose.yml中通过build: ./php引用,同时用服务名(如mysql)而非localhost连接数据库。

docker-compose.yml 里怎么写 PHP 8.1 的服务定义
直接用官方 php:8.1-apache 镜像最稳妥,不用自己编译或折腾源码。但要注意:这个镜像是带 Apache 的,如果你用 Nginx 反代,得关掉 Apache 或换 php:8.1-cli + 自配 Web 服务器。
常见错误是写成 php:8.1(没后缀),结果拉到的是 CLI-only 镜像,没有 /var/www/html、没内置 Web 服务,跑起来就 404 或直接退出。
- 推荐写法:
image: php:8.1-apache(开箱即用,适合快速验证) - 挂载代码用
volumes,别只靠build:本地开发时改 PHP 文件要实时生效,./src:/var/www/html比 COPY 进镜像更实际 - 扩展不是默认全开的,比如
pdo_mysql、gd得手动启用——要么在Dockerfile里docker-php-ext-install,要么用php-extension官方推荐方式(见下一条)
PHP 扩展怎么在 Compose 里安全启用
别在 command 里写 docker-php-ext-install 启动时执行——容器重启就重装,可能失败,且不幂等。正确做法是单独写个 Dockerfile,用 FROM php:8.1-apache 基础镜像再安装扩展。
例如要加 Redis 和 MySQL 支持:
FROM php:8.1-apache RUN apt-get update && apt-get install -y libzip-dev zlib1g-dev && rm -rf /var/lib/apt/lists/* RUN docker-php-ext-install pdo pdo_mysql mysqli zip RUN pecl install redis && docker-php-ext-enable redis
然后在 docker-compose.yml 中引用它:build: ./php(假设 Dockerfile 在 ./php 目录)。这样构建一次,启动多次都稳定。
- 注意
libzip-dev和zlib1g-dev是zip扩展的编译依赖,漏掉会报错“zip not found” -
pecl install后必须跟docker-php-ext-enable,否则扩展只是下载了,没写进php.ini - 如果项目用 Composer,建议在同一个 PHP 构建层里也装上:
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
PHP 8.1 和 MySQL/Redis 怎么连通不报错
网络通不了,90% 是因为 PHP 容器里用 localhost 当数据库地址——这在 Docker 里指向自己,不是 MySQL 容器。必须用服务名,比如 mysql 或 redis(取决于 docker-compose.yml 里你给的服务起的 service name)。
典型错误配置:
- PHP 代码里写
$pdo = new PDO('mysql:host=localhost;...', ...)→ 连不上 - 正确写法:
$pdo = new PDO('mysql:host=mysql;...', ...),前提是docker-compose.yml里有叫mysql的服务 - 还要确认 MySQL 服务暴露了
3306端口,并且MYSQL_ROOT_PASSWORD或普通用户权限已设好;PHP 里连接用的账号密码,得和 MySQL 容器启动时传的environment对得上 - Redis 同理,
host: redis,不是127.0.0.1,且确保redis服务用了默认端口6379,没被映射干扰(ports:段只用于本机访问,容器间通信走内部网络)
为什么 PHP 8.1 的 opcache 或时区总不对
PHP 配置不能只靠环境变量覆盖,php.ini 的加载顺序和自定义路径容易被忽略。Docker 官方镜像默认读 /usr/local/etc/php/php.ini,但有些设置(如 opcache.enable=1)在默认 ini 里是注释掉的,不显式开启就等于关着。
解决方法:挂载自定义 php.ini,或者用 php-ini-overrides.ini 方式(更轻量):
- 在项目目录放
php/conf.d/opcache.ini,内容:opcache.enable=1、date.timezone=Asia/Shanghai - 然后在
docker-compose.yml的 PHP 服务里加:volumes: - ./php/conf.d/:/usr/local/etc/php/conf.d/ - 别用
environment设PHP_INI_SCAN_DIR,容易和默认路径冲突;优先走/usr/local/etc/php/conf.d/这个标准扩展目录 - 改完记得
docker-compose down && docker-compose up -d,单纯restart不会重读 ini 文件
PHP 8.1 的 opcache 默认是关闭的,这点和旧版本不同,不手动开,性能会明显差一截,而且某些框架(如 Laravel)的缓存机制会悄悄退化。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











