Skip to content

CatchAdmin 部署指南

详细的 CatchAdmin 生产环境部署教程和最佳实践

WARNING

很多开发者在部署 CatchAdmin 时遇到问题,这里提供了完整详细的部署文档。本文档包含了从前端构建到服务器配置的全部步骤,基本涵盖了所有部署场景。

请仔细阅读文档,大部分问题都能在这里找到解决方案。如果遇到特殊情况确实需要协助,目前提供付费部署支持服务,收费标准为 100 元/次。先付费后服务,感谢理解 🙏

前端项目

在构建 CatchAdmin 前端项目前,需要先配置生产环境的 API 地址。在前端项目根目录下创建或编辑 .env.production 文件:

# base api
// 例如 https://api.catchadmin.com/api/

VITE_BASE_URL = '正式环境的 API 地址'

配置完成后,使用以下命令构建 CatchAdmin 前端项目:

bash
yarn run build
# 或者使用 npm
npm run build

打包出现报错

如果打包出现 ts 过多的类型错误,而你对类型又不太敏感的话,对应用没有影响。一个快速的解决办法就是修改 package.json 文件 build 命令

json
{
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc --noEmit && vite build", 
    "build": "vite build", 
    "preview": "vite preview"
  }
}

构建完成后,前端项目根目录会生成 dist 目录,这是 CatchAdmin 前端的生产版本,包含经过优化的静态资源文件,可直接部署到 Web 服务器。

性能优化建议

  1. 建议在 Web 服务器上启用 Gzip 压缩,可显著提升页面加载速度
  2. 配置静态资源缓存策略,提升用户体验
  3. 使用 CDN 加速静态资源访问 :::

后端

CatchAdmin 后端基于 PHP 开发,部署相对简单。将 PHP 项目代码上传到服务器即可。

推荐部署方式

  1. 上传源代码到服务器,不包含 vendor 目录
  2. 在服务器上执行 composer install --no-dev 安装生产环境依赖
  3. 配置正确的文件权限和目录结构

如果遇到依赖安装的网络问题,请参考 使用镜像 解决方案。

重要提醒

如果使用了 CatchAdmin 脚手架初始化项目,部署时需要注意:

  • 排除 web 目录:这是前端开发目录,不需要与后端一起上传
  • 前端部署:只需要上传构建后的 dist 目录
  • 分离部署:前后端建议分开部署,便于维护和扩展 :::

上线注意点

  • .env 环境文件是否配置好?

  • 数据库表是否同步?

  • 数据表的数据是否同步,主要是权限菜单permissions里是否同步

  • 模块如果正常开启的状态下,路由还是无法正常工作 (这个步骤只针对 Laravel 主项目)

    TIP

    • 首先是用 php artian route:clear
    • 然后查看路由 php artisan route:list
    • 最后缓存路由 php artisan route:cache :::

部署

WARNING

如果你使用的是宝塔相关的,一定不要完全复制下面的配置。因为宝塔有很多预配置项,例如 https ssl 配置是不需要你自己手动配置

分开部署(双域名)

推荐的 CatchAdmin 部署方式是前后端分离部署,分别使用不同的域名或子域名:

部署架构示例

  • 前端项目:admin.yourdomain.com/www/admin 目录
  • 后端 API:api.yourdomain.com/www/api 目录

部署建议

  • 目录路径可根据实际服务器环境调整

  • 分离部署便于独立维护和扩容

  • 支持前后端独立更新,降低部署风险 :::

  • /www/admin 上传 dist 目录内容到 admin 目录中

  • /www/api 上传后端项目到 api 目录中

php
server
{
    listen 80;
    server_name admin.catchadmin.com;
    return 301 https://admin.catchadmin.com$request_uri;
}

server
{
    listen  443  ssl http2;
    server_name admin.catchadmin.com;
    index.html index.php index.htm default.php default.htm default.html;


    ssl_certificate       # pem文件的路径
    ssl_certificate_key   # key文件的路径

    # ssl验证相关配置
    ssl_session_timeout  5m;    #缓存有效期
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;

    root /www/admin;
    location / {
    	try_files $uri $uri/ /index.html =404;
    }
}
php
server
{
    listen 80;
    server_name api.catchadmin.com;
    return 301 https://api.catchadmin.com$request_uri;
}


server
{
    listen  443  ssl http2;
    server_name api.catchadmin.com;
    index index.html index.php index.htm default.php default.htm default.html;
    root /www/api/public;

    ssl_certificate     /etc/nginx/acme/catchadmin.com/catchadmin.com.cer;  # pem文件的路径
    ssl_certificate_key  /etc/nginx/acme/catchadmin.com/catchadmin.com.key; # key文件的路径
    ssl_session_timeout  5m;    #缓存有效期
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;

    location / {
       if (!-e $request_filename) {
        rewrite  ^(.*)$  /index.php?s=/$1  last;
        break;
      }
    }

   # PHP 支持
    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
    ## nginx log 自己配置
    access_log;
    error_log;
}

合并部署(单域名)

如果只有一个域名或希望简化部署架构,可以将 CatchAdmin 前后端部署在同一域名下:

部署结构

  • 后端项目:yourdomain.com/api → PHP 项目根目录
  • 前端项目:yourdomain.com/ → 放置在后端项目的 public/admin 目录下

这种方式适合小型项目或资源有限的场景。

php

server
{
    listen 80;
    server_name api.catchadmin.com;
    return 301 https://api.catchadmin.com$request_uri;
}


server
{
    listen  443  ssl http2;
    server_name api.catchadmin.com;
    index index.html index.php index.htm default.php default.htm default.html;
    root /www/api/public;

    ssl_certificate     # pem文件的路径
    ssl_certificate_key  # key文件的路径
    ssl_session_timeout  5m;    #缓存有效期
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;

    # gzip 压缩 一定要开
    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 6; # 建议 6 更均衡
    gzip_vary on;
    gzip_proxied any;

    gzip_types
        text/plain
        text/css
        text/xml
        application/json
        application/javascript
        text/javascript
        application/xml
        image/svg+xml;

    gzip_disable "MSIE [1-6]\.";

    # 因为接口都是以 api.catchadmin.com/api 开头,所以可以很好的使用 location
    # 如果访问 api.catchadmin.com/api 目录 则用 php 解释下
    location /api {
       if (!-e $request_filename) {
        rewrite  ^(.*)$  /index.php?s=/$1  last;
        break;
      }
    }

    # 如果访问根目录 api.catchadmin.com/, 则直接访问前端项目
    location / {
      root /www/api/public/admin;
      try_files $uri $uri/ /index.html;
    }

    # 上传的静态目录 location
    location /uploads/ {
      alias /www/api/storage/uploads/;
      autoindex on;
    }


     #PHP 支持
    location ~ \.php$ {
          try_files $uri /index.php =404;
          fastcgi_split_path_info ^(.+\.php)(/.+)$;
          fastcgi_pass 127.0.0.1:9000;
          fastcgi_index index.php;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          include fastcgi_params;
    }
}

如果使用宝塔部署,location 配置静态目录的可能会无法工作,这是由于宝塔的预配置导致的,目前我个人使用下面如图得方法解决了

宝塔单域名部署

Octane 高性能部署

对于需要高性能的 CatchAdmin 项目,可以使用 Laravel Octane 提升并发处理能力:

Octane 优势

  • 显著提升 API 响应速度
  • 更好的内存利用率
  • 支持 WebSocket 等高级特性

适用场景:高并发访问、实时数据处理、大量 API 调用的企业级应用

php
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server
{
    listen 80;
    server_name api.catchadmin.com;
    return 301 https://api.catchadmin.com$request_uri;
}


server
{
   listen  443  ssl http2;
    server_name api.catchadmin.com;
    index index.html index.php index.htm default.php default.htm default.html;
    root /www/api/public;

    ssl_certificate     # pem文件的路径
    ssl_certificate_key  # key文件的路径
    ssl_session_timeout  5m;    #缓存有效期
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;

    # gzip 压缩 一定要开
    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 6; # 建议 6 更均衡
    gzip_vary on;
    gzip_proxied any;
    
    gzip_types
        text/plain
        text/css
        text/xml
        application/json
        application/javascript
        text/javascript
        application/xml
        image/svg+xml;

    gzip_disable "MSIE [1-6]\.";
    
    # 因为接口都是以 api.catchadmin.com/api 开头,所以可以很好的使用 location
    # 如果访问 api.catchadmin.com/api 目录 则用 php 解释下
    location /api {
       if (!-e $request_filename) {
        rewrite  ^(.*)$  /index.php?s=/$1  last;
        break;
      }
    }

    # 如果访问根目录 api.catchadmin.com/, 则直接访问前端项目
    location / {
      root /www/api/public/admin;
      try_files $uri $uri/ /index.html;
    }

    # 上传的静态目录 location
    location /uploads/ {
      alias /www/api/public/storage/uploads/;
      autoindex on;
    }

    location @octane {
        set $suffix "";

        if ($uri = /index.php) {
            set $suffix ?$query_string;
        }

        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header Scheme $scheme;
        proxy_set_header SERVER_PORT $server_port;
        proxy_set_header REMOTE_ADDR $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        proxy_pass http://172.18.0.2:9800$suffix;
    }
}