实战指南:使用Docker commit命令构建包含Oracle扩展的PHP生产镜像
1. 场景需求与准备工作
最近接手一个遗留的PHP 5.6项目,需要连接Oracle数据库。由于生产环境采用Docker部署,传统方式是在宿主机安装Oracle客户端,但这样会导致环境依赖复杂。更优雅的解决方案是将Oracle扩展直接打包到PHP镜像中。
先确认基础环境要求:
- 操作系统:CentOS 7.9
- PHP版本:5.6.40
- 需要安装的扩展:OCI8和PDO_OCI
- Docker版本:20.10.17+
2. 基础镜像准备
2.1 拉取CentOS基础镜像
docker pull centos:centos7.9.20092.2 启动容器并进入
docker run -d --name php-oracle --privileged=true centos:centos7.9.2009 /usr/sbin/init docker exec -it php-oracle /bin/bash这里使用--privileged=true参数是为了后续能使用systemctl管理服务。我在实际测试中发现,如果不加这个参数,容器内的服务管理会出问题。
3. 安装编译环境
3.1 安装基础工具
yum -y install epel-release yum -y install \ gcc gcc-c++ \ make autoconf \ libaio bzip2 unzip \ libjpeg libjpeg-devel \ libpng libpng-devel \ freetype freetype-devel \ libxml2 libxml2-devel \ zlib zlib-devel \ curl curl-devel \ openssl openssl-devel3.2 编译安装PHP 5.6
下载PHP源码包:
wget https://www.php.net/distributions/php-5.6.40.tar.gz tar zxvf php-5.6.40.tar.gz cd php-5.6.40配置编译参数:
./configure --prefix=/usr/local/php \ --enable-bcmath \ --enable-calendar \ --with-curl \ --enable-ftp \ --with-gd \ --enable-mbstring \ --enable-mysqlnd \ --with-mysqli \ --with-openssl \ --with-zlib \ --with-jpeg-dir \ --with-png-dir \ --with-freetype-dir \ --enable-fpm \ --enable-session \ --enable-pdo \ --enable-tokenizer \ --enable-zip \ --with-mysql \ --with-pdo-mysql \ --with-config-file-path=/etc/php编译并安装:
make && make install4. Oracle客户端安装
4.1 准备Oracle Instant Client
从Oracle官网下载以下两个包:
- instantclient-basic-linux.x64-12.2.0.1.0.zip
- instantclient-sdk-linux.x64-12.2.0.1.0.zip
上传到容器并解压:
unzip instantclient-basic-linux.x64-12.2.0.1.0.zip unzip instantclient-sdk-linux.x64-12.2.0.1.0.zip mkdir -p /usr/lib/oracle/12.2 mv instantclient_12_2 /usr/lib/oracle/12.2/client4.2 配置环境变量
echo "/usr/lib/oracle/12.2/client" > /etc/ld.so.conf.d/oracle.conf ldconfig export ORACLE_HOME=/usr/lib/oracle/12.2/client export LD_LIBRARY_PATH=$ORACLE_HOME:$LD_LIBRARY_PATH5. 编译Oracle扩展
5.1 安装OCI8扩展
进入PHP源码的ext/oci8目录:
cd php-5.6.40/ext/oci8 /usr/local/php/bin/phpize ./configure --with-php-config=/usr/local/php/bin/php-config \ --with-oci8=instantclient,/usr/lib/oracle/12.2/client make && make install5.2 安装PDO_OCI扩展
进入ext/pdo_oci目录:
cd ../pdo_oci # 修改配置文件版本号 sed -i "s/10.1/12.2/g" config.m4 /usr/local/php/bin/phpize ./configure --with-pdo-oci=instantclient,/usr/lib/oracle/12.2/client,12.2 \ --with-php-config=/usr/local/php/bin/php-config make && make install6. PHP配置
6.1 配置php.ini
mkdir /etc/php cp php.ini-production /etc/php/php.ini添加Oracle扩展配置:
extension=oci8.so extension=pdo_oci.so6.2 配置PHP-FPM
cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf添加环境变量:
env[LD_LIBRARY_PATH] = /usr/lib/oracle/12.2/client env[ORACLE_HOME] = /usr/lib/oracle/12.2/client7. 服务配置与启动
7.1 配置systemd服务
cp sapi/fpm/php-fpm.service /usr/lib/systemd/system/编辑服务文件:
[Unit] Description=The PHP FastCGI Process Manager After=syslog.target network.target [Service] Type=simple PIDFile=/usr/local/php/var/run/php-fpm.pid ExecStart=/usr/local/php/sbin/php-fpm --nodaemonize --fpm-config /usr/local/php/etc/php-fpm.conf ExecReload=/bin/kill -USR2 $MAINPID [Install] WantedBy=multi-user.target7.2 启动服务
systemctl start php-fpm systemctl enable php-fpm8. 验证与优化
8.1 验证扩展安装
/usr/local/php/bin/php -m | grep -E 'oci|pdo'应该能看到oci8和pdo_oci模块。
8.2 创建符号链接
ln -s /usr/local/php/bin/* /usr/local/bin/ ln -s /usr/local/php/sbin/* /usr/local/bin/9. 提交镜像
9.1 清理无用文件
yum clean all rm -rf /tmp/* /var/tmp/*9.2 提交镜像
docker commit php-oracle my-php-oracle:5.69.3 验证新镜像
docker run -it --rm my-php-oracle:5.6 php -m | grep oci10. 生产部署建议
- 镜像优化:可以使用
docker export/import进一步减小镜像体积 - 安全加固:删除编译过程中的临时文件和源码
- 版本管理:建议使用标签区分不同版本,如
my-php-oracle:5.6-v1 - 数据库连接:在生产环境使用环境变量注入连接信息,而非硬编码
这个方案虽然步骤较多,但能完美解决老旧PHP项目连接Oracle的需求。我在实际项目中用这种方法部署了多个生产环境,稳定性经过验证。对于更现代的PHP版本,建议考虑使用官方Docker镜像配合pecl安装扩展会更简单。
