Docker未安装PHP模块排查:为何模块无法加载?附Dockerfile
我来帮你捋捋这个问题——用php:5.6-apache镜像时遇到PHP模块装不上或者加载失败,结合你给出的Dockerfile片段,大概率是这几个环节没处理好:
1. 只装了系统依赖,缺模块编译/启用步骤
你在Dockerfile里只安装了buildDeps和runtimeDeps,但很多PHP模块(比如GD、LDAP、Memcached这些)必须手动编译并启用,光装系统依赖根本不够。针对你列的依赖,补充对应的编译步骤才对:
# 接你原来的apt-get install命令之后 # 配置并编译GD扩展(需要指定freetype和jpeg的路径) RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \ && docker-php-ext-install gd bz2 intl ldap mcrypt mysqli pdo_mysql pdo_pgsql pgsql xmlrpc zip # 安装兼容PHP5.6的Memcached PECL模块,并启用 RUN pecl install memcached-2.2.0 \ && docker-php-ext-enable memcached
划重点:PHP5.6对应Memcached的PECL版本得选2.2.0,高版本已经不支持PHP5.x了,装错版本肯定失败。
2. 系统依赖路径不匹配,导致编译失败
就拿LDAP扩展来说,php:5.6-apache基于Debian镜像,系统库的路径和PHP编译预期的路径不一致,必须先做软链接才能找到库文件:
RUN ln -s /usr/lib/x86_64-linux-gnu/libldap.so /usr/lib/ \ && ln -s /usr/lib/x86_64-linux-gnu/liblber.so /usr/lib/ \ && docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ \ && docker-php-ext-install ldap
不做这一步,编译LDAP扩展时会直接报错找不到ldap.h或者相关库。
3. 遗漏PECL模块的启用命令
像Memcached、Redis这类PECL模块,安装后不会自动添加到PHP配置里,必须手动执行docker-php-ext-enable命令。如果你只跑了pecl install但没启用,PHP完全识别不到这个模块。
4. 清理依赖的时机不对,丢了必要文件
很多人为了减小镜像体积,会在安装后清理buildDeps,但如果分多个RUN命令做这件事,就会因为Docker的分层缓存,把编译模块用到的依赖删掉。正确的做法是把安装、编译、清理放到同一个RUN命令里:
RUN buildDeps=" \ libbz2-dev \ libmemcached-dev \ libmysqlclient-dev \ libsasl2-dev \ " \ runtimeDeps=" \ curl \ git \ libfreetype6-dev \ libicu-dev \ libjpeg-dev \ libldap2-dev \ libmcrypt-dev \ libmemcachedutil2 \ libpng12-dev \ libpq-dev \ libxml2-dev \ " && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y $buildDeps $runtimeDeps \ # 在这里执行所有模块编译、启用命令 && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \ && docker-php-ext-install gd bz2 intl ldap mcrypt mysqli pdo_mysql pdo_pgsql pgsql xmlrpc zip \ && pecl install memcached-2.2.0 && docker-php-ext-enable memcached \ # 最后清理build依赖和apt缓存 && apt-get purge -y --auto-remove $buildDeps \ && rm -rf /var/lib/apt/lists/*
这样能保证编译模块时依赖都在,清理后也不会影响已编译好的模块。
5. 验证模块是否成功加载
镜像构建完后,启动容器跑php -m,或者访问phpinfo()页面,确认模块有没有在列表里。如果还是找不到,就去这两个地方查:
- 容器内
/usr/local/etc/php/conf.d/目录,看有没有对应模块的配置文件(比如memcached.ini) - 查看Apache的错误日志(路径是
/var/log/apache2/error.log),里面会有模块加载失败的具体原因(比如找不到.so文件)
内容的提问来源于stack exchange,提问作者Atr_Max

