一个服务器怎么装两个php?有哪些方法?

一个服务器装两个 php 完全可行,主流方案是 Docker 容器隔离或 PHP-FPM 多实例共存,配置得当互不干扰。这两种方式我都实际折腾过,下面把具体操作、坑点、选型逻辑一次说清。

为什么一台服务器要装两个 php

老项目跑在 PHP 5.6 或 7.4,新项目想用 PHP 8.2,这是最常见的场景,据 PHP 官方支持政策,PHP 7.4 安全支持在 2026 年 11 月已终止,PHP 8.0 在 2026 年 11 月终止,但很多存量业务代码就是升级不动,强行改代码成本太高。

2、同一服务器部署多个网站|网站部署教程|Nginx|1Panel
加载中
2、同一服务器部署多个网站|网站部署教程|Nginx|1Panel

再一个场景是同一台机器跑多个客户的站点,不同客户锁定的框架版本不一样,要是全用同一个 php,总有一方跑不起来,行业共识是版本隔离比强行统一更务实。

有人问能不能直接改系统默认 php 版本?能,但治标不治本,你改完命令行生效了,nginx 的 fastcgi 进程可能还连着旧的 php-fpm socket,到时候新旧请求混在一起,排查起来头疼,核心诉求是互不干扰地跑两套版本,而不是表面上切换个默认版本。

用 Docker 装两个 php 容器

这是我最推荐的方式,干净利落,不用碰宿主机环境。

我给一个 docker-compose.yml 的骨架,分别跑 php7.4 和 php8.2:

services:
  php74:
    image: php:7.4-fpm
    container_name: php74
    volumes:
      - /var/www/site-a:/var/www/html
    networks:
      - web
    command: php-fpm
  php82:
    image: php:8.2-fpm
    container_name: php82
    volumes:
      - /var/www/site-b:/var/www/html
    networks:
      - web
    command: php-fpm
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80"
    volumes:
      - /var/www:/var/www
      - ./nginx/conf.d:/etc/nginx/conf.d
    networks:
      - web
networks:
  web:
    driver: bridge

nginx 配置里分别把不同站点指到不同容器:

server {
    listen 80;
    server_name old-site.com;
    root /var/www/site-a;
    location ~ .php$ {
        fastcgi_pass php74:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        

一个服务器怎么装两个php?有哪些方法?

include fastcgi_params; } } server { listen 80; server_name new-site.com; root /var/www/site-b; location ~ .php$ { fastcgi_pass php82:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }

docker 方案最省心的点在于,每个容器内部的 php 扩展、依赖库完全独立,你不需要考虑系统是 centos 还是 ubuntu,更不需要纠结 apt 源里有没有你要的 php 版本,跑起来就两个字:隔离。

配 mysql 也简单,做个 mariadb 容器出来,两个 php 都能连,只要把容器加入同一个 docker network。

服务器怎么装两个 php 不用 Docker,原生共存

不想用 Docker 或者机器配置太老的,也可以原生装两个 php-fpm,思路很简单:分别编译安装两个版本,监听不同端口或 socket 文件,nginx 按站点转发。

先装依赖,这个各家系统大同小异,以 ubuntu 22.04 为例:

apt update
apt install -y build-essential libxml2-dev libssl-dev libcurl4-openssl-dev pkg-config libpng-dev libjpeg-dev libonig-dev libzip-dev

下载编译 php7.4:

curl -O https://www.php.net/distributions/php-7.4.33.tar.gz
tar xzf php-7.4.33.tar.gz
cd php-7.4.33
./configure --prefix=/usr/local/php74 --with-config-file-path=/usr/local/php74/etc --enable-fpm --with-mysqli --with-pdo-mysql --with-openssl --with-zlib --enable-mbstring
make -j$(nproc)
make install

编译 php8.2 同理,把 –prefix 改成 /usr/local/php82 即可。

然后配置两个 fpm 的监听端口:

php74 的 pool 配置文件 /usr/local/php74/etc/php-fpm.d/www.conf:

listen = 127.0.0.1:9074

php82 的 pool 配置文件 /usr/local/php82/etc/php-fpm.d/www.conf:

listen = 127.0.0.1:9082

端口别用 9000,很多老教程默认 9000,两个版本要是都配 9000,第二个起不来,端口只要机器上没被占用,随便挑。

启动各自的 fpm:

/usr/local/php74/sbin/php-fpm
/usr/local/php82/sbin/php-fpm

接着改 nginx,把 fastcgi_pass 指过去:

一个服务器怎么装两个php?有哪些方法?

server {
    listen 80;
    server_name legacy.com;
    root /var/www/legacy;
    location ~ .php$ {
        fastcgi_pass 127.0.0.1:9074;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}
server {
    listen 80;
    server_name modern.com;
    root /var/www/modern;
    location ~ .php$ {
        fastcgi_pass 127.0.0.1:9082;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

重载 nginx:

nginx -s reload

到这一步,一个服务器装两个 php 就落地了,旧站走 9074,新站走 9082,互不打扰。

原生共存方式的优点是不依赖 docker 那套 verbose 的镜像拉取过程,内存占用也小一些,缺点是编译耗时、后期扩展管理麻烦,装上 redis 扩展得分别给两套 php 各编译一遍。

Docker 和原生共存怎么选

对比维度 Docker 双容器 原生 PHP-FPM 多实例
隔离性 强,进程和文件系统全隔离 中等,共用宿主机内核
部署速度 快,镜像拉下来就能起 慢,编译安装花时间
内存占用 相对较高 低,更适合小内存机器
扩展管理 各自容器内独立安装 两套 php 都要重复编译扩展
维护成本 低,重装即还原 高,依赖手动管理
适合场景 线上多项目隔离 一台机器跑两个老项目

内存低于 2G 的机器,我建议原生共存,跑 docker daemon 本身就要吃一部分内存,内存够大(4G 以上)就无脑 docker。

一台服务器安装多个 php 版本之后,日常怎么切

项目多了以后,命令行下经常要确认当前用哪个 php:

which php
php -v

原生共存方式下,系统默认 php 是你编译时最后加入 PATH 的那个,需要临时切换时:

一个服务器怎么装两个php?有哪些方法?

export PATH=/usr/local/php74/bin:$PATH
php -v

想让站点目录自带版本识别,我习惯在项目根目录放一个 .env,标记“本目录运行 PHP 7.4,fastcgi 端口 9074”,方便运维同事日后查。

排查 502 时常用两条命令,一条看 php-fpm 进程是否存活:

ps aux | grep php-fpm

另一条直接请求 fpm 的 status 接口,在 pool 配置里打开 pm.status_path,curl 访问就有结果。

关于这个配置的常见疑问

一个服务器装两个 php 怎么保证端口不冲突

监听端口必须唯一,原方案里一个用 9074,一个用 9082,就不可能撞,如果用了 unix socket 文件,则确保 socket 文件路径不同,/tmp/php74-fpm.sock 和 /tmp/php82-fpm.sock,nginx 里 fastcgi_pass 的写法对应改成 unix:/tmp/php74-fpm.sock; 这种格式。

两个 php 共存会不会拖慢网站速度

不会,php-fpm 是按 worker 进程数吃资源的,多一套 php 就多几个常驻进程,内存增加幅度大概每个 worker 20-40MB,站点并发低时几乎没有感知,真正拖慢速度的是业务代码自身有没有性能瓶颈,而不是多跑了一个 php 版本,需要留意的是别把两个 php-fpm 的 worker 数都调得极大,比如都设成 max_children=50,那内存占用就会比较可观,合理控制 worker 数量,即便 2G 内存的机器也能跑两个 php 实例加一个小型数据库。

怎么验证当前站点跑的是哪个 php 版本

在站点根目录放一个 phpinfo 文件最直接:

echo "<?php phpinfo(); ?>" > /var/www/legacy/info.php

浏览器访问 http://your-domain/info.php,页面顶部显示 PHP Version 那一行就是当前站点实际使用的版本,确认完立刻删掉这个文件,生产环境留着 phpinfo 等于给攻击者送信息。

验证完别忘了一件事,分别访问旧项目和新项目的 phpinfo 页面,确认它们确实走到了不同端口对应的 php-fpm,这一步做完,整个方案才算闭环。

首发原创文章,作者:王坚‌,如若转载,请注明出处:https://idctop.com/article/681108.html

赞 (0)
如何让v6服务器手动下发RA报文?,v6服务器RA报文配置方法?
上一篇 2026年9月23日 19:57
如何修改服务器FTP登录密码,忘记密码怎么办?
下一篇 2026年9月23日 19:58

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注