应使用官方 php:8.1-fpm-alpine 镜像而非从 alpine:latest 自建,因其已预编译常用扩展、体积仅约45mb、启动快、攻击面小;需合并run指令并清理apk缓存,禁用文件日志改用stdout/stderr,生产环境必须内置代码而非挂载,并补全tzdata和locale配置。

用 php:8.1-fpm-alpine 做基础镜像,别自己从 alpine:latest 起手
直接 FROM alpine:latest 再手动编译 PHP,看似可控,实则极易翻车:musl libc 兼容性问题、扩展编译失败、时区/SSL 证书缺失、甚至 php -v 都报错。官方 php:8.1-fpm-alpine 已预编译好所有常用扩展(pdo_mysql、mbstring、opcache 等),体积仅约 45MB,启动快、攻击面小。
关键点在于:它已内置 docker-php-ext-install 和 apk,你只需追加依赖,不重造轮子。
- 不要写
FROM alpine:latest && apk add php7—— 这是过时的 Alpine 3.14 以前写法,PHP 包名和路径已变 - 避免在构建中运行
php --version检查,某些 Alpine 衍生镜像会因/etc/ssl/certs缺失而静默失败 - 优先选带具体 patch 版本的 tag,例如
php:8.1.28-fpm-alpine3.18,比php:8.1-fpm-alpine(可能漂移)更稳定
合并 RUN 指令 + 删除 apk 缓存必须一步到位
每条 RUN 都生成一层镜像,apk add 后不清理缓存,会把下载的 .apk 包、解压临时文件全留在层里,徒增 10–20MB。必须把安装、启用扩展、清理缓存写在同一行 RUN 中,否则中间层残留无法被删除。
正确写法示例:
RUN apk add --no-cache \
libzip-dev \
icu-dev \
oniguruma-dev \
&& docker-php-ext-install \
zip \
intl \
mbstring \
pdo_mysql \
&& apk del .build-deps libzip-dev icu-dev oniguruma-dev
-
--no-cache阻止 apk 缓存索引,但不删已下载的包;apk del才真正清空 - 扩展编译依赖(如
libzip-dev)和运行时依赖(如libzip)要分开:编译完立刻删掉-dev包 - 别用
apk clean—— 它只清索引,不删包;rm -rf /var/cache/apk/*也无效,因为 apk 默认不存包到该路径
禁用默认日志文件,强制输出到 stdout/stderr
Alpine 下 PHP-FPM 默认把错误日志写进 /var/log/php-fpm/error.log,容器内无 logrotate,日志会无限增长并撑爆磁盘。生产环境必须关掉文件日志,改用标准流输出,让 docker logs 可捕获。
在 Linux 上通过 Docker 运行 OpenClaw,并使用 Tailscale 实现远程访问。⚠️ 涉及 sudo、Docker、Tailscale和凭证挂载——请先查阅安全章节...
两处关键配置需覆盖:
- 在
www.conf中设catch_workers_output = yes和php_flag[display_errors] = off,避免 worker 输出污染 - 修改
php-fpm.conf:将error_log = /var/log/php-fpm/error.log改为error_log = /proc/self/fd/2 - 启动命令必须用
php-fpm -F(前台模式),不能用service php-fpm start或daemonize = yes,否则主进程退出容器就停了
挂载代码 or 构建进镜像?生产必须二选一
开发时用 -v ./src:/var/www/html 很方便,但生产严禁这么做:挂载目录权限不可控、宿主机路径失效、无法做镜像签名与版本追溯。
生产构建应把代码固定进镜像:
- 先
COPY composer.json composer.lock /var/www/,再RUN cd /var/www && composer install --no-dev --optimize-autoloader - 最后
COPY . /var/www/,确保 vendor 目录不被覆盖 - 务必加
.dockerignore,排除vendor/、node_modules/、.git/、tests/,否则 COPY 会拖慢构建且引入冗余 - 若用多阶段构建,第一阶段装 Composer 和依赖,第二阶段只
COPY --from=0 /var/www/vendor /var/www/vendor,可再减 15MB
最易被忽略的是时区和 locale:Alpine 默认无 /usr/share/zoneinfo/Asia/Shanghai,也无 UTF-8 locale。RUN 中漏掉 apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime,会导致 date() 返回 UTC、json_encode() 中文乱码。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










