Alpine镜像需装tzdata、复制时区文件并设php.ini timezone,同时启用Swoole/Redis等扩展;挂载宿主机localtime在Alpine中易失效,应优先构建时配置。

Hyperf 容器化部署时,用 Alpine 镜像跑起来时间总是慢 8 小时、date 显示 UTC、日志时间戳对不上——这不是 Hyperf 的问题,是 Alpine 基础镜像没配好时区 + 缺关键 PHP 扩展导致的。直接改 Dockerfile 或启动参数就能解决,不用换镜像。
Alpine 镜像里 date 显示 UTC?必须装 tzdata 并显式链接
Alpine 默认不带时区数据,/etc/localtime 是个空链接或指向 UTC。光设 TZ 环境变量没用,PHP、CLI、系统命令都读不到真实时区。
-
RUN apk add --no-cache tzdata是前提,不装这个,后面所有操作都无效 -
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime必须执行,让date命令生效 -
RUN echo "Asia/Shanghai" > /etc/timezone补上这个,部分 PHP 函数(如date_default_timezone_get())依赖它 - 装完立刻
apk del tzdata,避免镜像体积膨胀(tzdata占 4MB+)
Hyperf 启动后 date('Y-m-d H:i:s') 还是 UTC?检查 PHP 是否读取了系统时区
PHP 默认不自动同步系统时区,尤其 Alpine 下更易失效。不能只靠 TZ 环境变量,得双保险。
- 在
php.ini中显式设置:date.timezone = Asia/Shanghai - 或在 Hyperf 启动前加环境变量:
docker run -e "PHP_INI_SCAN_DIR=/etc/php/conf.d" ...,配合挂载含该配置的文件 - 验证方式:进容器执行
php -r "echo date_default_timezone_get();",输出必须是Asia/Shanghai,不是UTC或空 - 注意:如果用了
opcache,改了php.ini要重启 PHP 进程,单纯 reload 不生效
Hyperf 报错 “Class 'Swoole\Http\Server' not found” 或 Redis 连接失败?Alpine 缺扩展
Hyperf 依赖 Swoole、Redis、PDO 等扩展,但官方 hyperf/hyperf:alpine-v4.0 等镜像默认只装了最简集,生产环境几乎必补。
- Swoole 必须启用:Alpine 下用
pecl install swoole,再echo "extension=swoole.so" > /etc/php/conf.d/swoole.ini - Redis 扩展不能只靠
composer require predis/predis,那是纯 PHP 客户端;要用原生扩展就得pecl install redis - PDO MySQL:先
apk add mysql-client,再pecl install pdo_mysql,否则Db::select()会报驱动不存在 - 所有
pecl install后都要运行apk del $pkgname-dev和清理缓存,不然镜像多出 20MB+
为什么 -v /etc/localtime:/etc/localtime:ro 在 Alpine 容器里可能失效?
宿主机的 /etc/localtime 通常是符号链接(比如指向 /usr/share/zoneinfo/Asia/Shanghai),而 Alpine 容器内没有 /usr/share/zoneinfo 目录,挂载后链接目标丢失,date 仍回退到 UTC。
- 该挂载方式在 Ubuntu/Debian 镜像中可靠,但在 Alpine 中建议放弃,改用构建时
cp方式 - 若坚持挂载,需额外挂载整个
/usr/share/zoneinfo:-v /usr/share/zoneinfo:/usr/share/zoneinfo:ro,但体积大、权限复杂,不推荐 - Kubernetes 场景下,ConfigMap 挂载
/etc/timezone文件 + initContainer 预装tzdata更稳妥
真正麻烦的从来不是“怎么配”,而是配完没验证:进容器跑 date、php -r "echo date();"、php --ri swoole | grep version 这三行,缺一不可。Alpine 的精简哲学意味着每一步都得亲手确认,不能假设“设了 TZ 就万事大吉”。


















