PHP结合Vue怎么部署

wen PHP项目 1

PHP与Vue前后端分离项目的生产环境部署实战指南(Nginx + Docker + CI/CD)


目录导读

  1. 为什么需要关注PHP+Vue的部署架构?
  2. 部署前的核心认知:动态接口与静态资源的边界
  3. 经典Nginx反向代理(同域名部署)
  4. Docker容器化独立部署(高可用)
  5. 环境变量与API地址的动态切换(前端构建的坑)
  6. 常见故障排查(404、跨域、Session失效)
  7. 高频问答(FAQ)与面试知识点

为什么需要关注PHP+Vue的部署架构?

PHP结合Vue怎么部署

很多开发者本地开发时使用php artisan servenpm run dev,一路顺畅,但一到线上服务器就崩溃,核心原因在于:PHP(Laravel/ThinkPHP等)是服务端渲染动态脚本,而Vue是客户端静态资源,它们本质上是两套运行机制,部署时必须明确分离:

  • PHP代码运行在php-fpm进程中,处理/api路由、数据库交互。
  • Vue构建后生成纯静态的index.htmlJSCSS,需要Web服务器(Nginx/Apache)直接读取。

若不做特殊处理,用户访问域名根路径时,Nginx会优先去找index.html,然后Vue路由跳转/user/1时,Nginx又去请求PHP找不到对应文件,直接404,这就是部署混乱的根源。

部署前的核心认知:动态接口与静态资源的边界

在写任何配置前,先在Vue项目里确定所有请求PHP的URL前缀,通常为/apiaxios.get('/api/user/info'),部署时唯一的目标就是:Nginx将所有/api开头的请求转发给PHP-FPM,其余所有请求返回Vue的index.html


方案一:经典Nginx反向代理(同域名部署)

这是中小项目最推荐的方案,不涉及跨域,且配置简单,假设你的域名是https://example.com,服务器目录结构如下:

/var/www/project/
├── backend/          # PHP代码(Laravel)
└── frontend/         # Vue打包产物
    ├── index.html
    └── static/

Nginx核心配置(/etc/nginx/sites-available/project.conf):

server {
    listen 80;
    server_name example.com;
    # 1. Vue静态资源根目录
    root /var/www/project/frontend;
    index index.html;
    # 2. 关键:处理Vue History模式路由(避免404)
    location / {
        try_files $uri $uri/ /index.html;
    }
    # 3. 动态API转发给PHP-FPM(Laravel)
    location /api {
        alias /var/www/project/backend/public;
        try_files $uri @backend;
        # 或者更标准的方式:
        # rewrite ^/api/(.*)$ /$1 break;
        # 然后转发到fastcgi
    }
    location @backend {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /var/www/project/backend/public/index.php;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    }
    # 4. 禁止访问隐藏文件
    location ~ /\.ht { deny all; }
}

部署步骤:

  • 前端执行npm run build,将dist拷贝到frontend/
  • 后端执行composer install --no-dev,确保.env配置了APP_URL=https://example.com
  • 重启Nginx和PHP-FPM。

重点陷阱: Laravel的public/目录下必须有.htaccess(Apache)或依赖Nginx的try_files逻辑,若使用alias方式,务必注意SCRIPT_FILENAME的路径计算。


方案二:Docker容器化独立部署(高可用)

对于微服务架构或需要水平扩展的场景,建议将PHP和Nginx(Vue静态文件)拆成两个容器,通过Docker Compose编排。

docker-compose.yml核心服务示例:

version: '3.8'
services:
  backend:
    image: php:8.2-fpm
    volumes:
      - ./backend:/var/www/html
    environment:
      - DB_HOST=mysql
    networks:
      - app-network
  frontend:
    image: nginx:alpine
    volumes:
      - ./frontend/dist:/usr/share/nginx/html:ro
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
    ports:
      - "8080:80"
    depends_on:
      - backend
    networks:
      - app-network

nginx.conf(容器内)关键配置:

location /api {
    proxy_pass http://backend:9000;  # 关键:通过容器名访问PHP-FPM
    # 注意:不需要fastcgi_pass,这里是用HTTP代理到PHP的内置服务器
    # 实际需要将PHP-FPM监听TCP端口(需在PHP容器内改配置)
}
location / {
    try_files $uri $uri/ /index.html;
}

注意: 要让PHP-FPM支持TCP访问,需修改php-fpm.d/www.conflisten = 9000,并注释掉listen = /var/run/php/php-fpm.sock

优势: 前端服务可挂CDN,后端服务可独立扩容,但需自行处理跨域(如Access-Control-Allow-Origin)。


环境变量与API地址的动态切换(前端构建的坑)

很多前端团队会把API地址写死在axios里,导致每次换环境都要重新构建,解决思路有两种:

  • 构建时注入:package.json中设置环境变量VUE_APP_API_BASE,打包时通过--mode staging切换。
  • 运行时动态读取: 在Vue的public/目录下放置一个config.js,里面定义window.API_BASE = 'https://api.example.com',然后在index.html中引入,这样运维只需修改config.js即可,无需重新构建。

常见故障排查

  • 刷新页面404: 确保Nginx配置了try_files $uri $uri/ /index.html;
  • API请求401/Session失效: PHP的SESSION_DOMAIN必须设置为顶级域名,且Vue请求需携带withCredentials: true
  • 跨域(CORS): 若前后端分离部署不同域名,在Laravel中配置cors.php,允许allowed_origins为前端域名。

高频问答(FAQ)

Q1:一定要用Nginx吗?Apache可以吗? A:可以,Apache使用mod_rewrite实现相同效果:RewriteRule ^(.*)$ /index.php [QSA,L]处理Vue路由,ProxyPass /api转发给PHP,但Nginx静态文件性能高出30%以上。

Q2:前端用Hash路由(带)是不是就不用配try_files了? A:对,Hash路由不向后端发请求,但不利于SEO且URL不美观,强烈建议使用History路由并正确配置服务器。

Q3:如何让Vue的构建产物自动部署到服务器? A:推荐使用GitHub Actions或GitLab CI,在代码推送时,触发npm run build,然后通过rsync同步到服务器frontend/目录,并执行nginx -s reload

Q4:PHP端需要开启OPcache吗? A:需要,生产环境执行php artisan optimize,并在php.ini中开启opcache.enable=1,可提升30%-50%的API响应速度。


部署的本质是理清“谁处理静态文件,谁处理动态请求”,Nginx作为门卫,负责分流;PHP-FPM干活;Vue静态文件则像“一张刻好的光盘”,只需被正确读取,掌握上述方法,无论项目大小,你都能游刃有余地应对线上发布,最后建议:在服务器上先用curl -I https://example.com/user测试路由,再用curl https://example.com/api/health测试接口,两步验证部署是否成功。

抱歉,评论功能暂时关闭!