EspoCRM 完整部署指南:从零跑通开源 CRM 的环境配置到运维
【免费下载链接】espocrmEspoCRM – Open Source CRM Application项目地址: https://gitcode.com/GitHub_Trending/es/espocrm
它解决的是什么问题
很多团队不缺客户数据,缺的是一套"数据在自己手里、规则自己说了算"的系统。EspoCRM 把线索、客户、商机、工单、邮件往来装进同一个界面,免费开源(AGPLv3),一台入门级云服务器就能长期跑,省掉按人头收的订阅费。它特别适合两类人:想摆脱 SaaS CRM 数据锁定风险的中小团队,以及愿意按自己业务习惯改字段、改流程的技术型团队。
理解这套系统,抓住三个机制就够了:
- 元数据驱动:实体和字段全部定义在 JSON 配置里(如 Lead 的实体定义),改配置就能改变系统行为,大部分定制不需要碰代码;
- 前后端解耦:前端是自研的单页应用,后端是 PHP 的 REST API,两者走标准 HTTP 通信,接口可以直接开放给其他业务系统调用;
- Job 队列 + Cron:邮件收发、通知推送、定时任务都靠后台任务队列驱动,由系统根目录的 cron.php 每分钟拉一轮。
本文从环境准备讲到上线后的维护,共四个阶段:安装落地、Web 服务托管、高频定制、踩坑与运维。
动手之前:看懂内部构造
排错快不快,很大程度取决于你知道报错来自哪层。先看目录怎么分工:
application/Espo/ ├── Core/ # 核心引擎:缓存、邮件、权限、字段校验、依赖注入 ├── Controllers/ # API 入口控制器,每个对应一类资源 ├── Entities/ # 内置实体定义 ├── Services/ # 业务服务层 ├── Repositories/ # 数据访问层 ├── Modules/Crm/ # CRM 业务模块(客户、线索、商机、工单等) └── Resources/ # 元数据、布局、多语言、路由等 JSON 配置 client/src/ # 前端 SPA 源码,构建后产出浏览器可加载的静态资源 data/ # 运行期写入:缓存、日志、上传文件、config.php custom/ # 定制内容,升级时不会被动有两个设计值得花一分钟记住,后面能省大量排错时间:
第一,CRM 模块是独立目录。Modules/Crm/与主程序解耦,这意味着你可以按需裁剪它,甚至照它的结构写自己的模块,业务逻辑不会和框架核心缠在一起。第二,data/与custom/是仅有的两个运行期可写目录——系统报错十有八九出在这两处的权限,而不是代码本身。
技术栈一览:
| 组件 | 选型 / 版本 | 备注 |
|---|---|---|
| 运行语言 | PHP 8.3 – 8.5 | 版本门槛写在 composer.json,需pdo_mysql/pdo_pgsql、gd、zip、mbstring、openssl等扩展 |
| 数据库 | MySQL 8.0+ / MariaDB 10.6+ / PostgreSQL 15+ | 通过 Doctrine DBAL 统一抽象,换库不改代码 |
| 前端 | 自研 SPA,Node 20+ / npm 8+ | 构建工具 Grunt,源码在client/src/ |
| 依赖管理 | Composer(后端)+ npm(前端) | 两边都要装,缺一不可 |
| 任务调度 | Cron + 内置 Job 队列 | 命令定义见 consoleCommands 元数据 |
安装落地:四个阶段,每步都有验证
先别急着敲命令,整个流程按"环境准备 → 依赖与构建 → 数据层与权限 → 应用初始化与定时任务"推进,每个阶段结尾有一条验证动作,通过了再往下走。
阶段一:环境与代码
目的:确认 PHP 环境达标,拉取代码并装齐前后端依赖。
php -v php -m | grep -E "pdo_mysql|pdo_pgsql|gd|zip|mbstring|json|openssl"扩展缺项要先补装再继续,这是后面安装向导"自检不过"最常见的根源。
git clone https://gitcode.com/GitHub_Trending/es/espocrm cd espocrm composer install npm install npm run buildnpm run build这一步卡住的人最多:它把client/src/编译成浏览器能直接加载的静态资源,跳过它页面会白屏或样式全乱。
验证:php command.php version能输出版本号,且client/下能看到构建产物(css、js 文件)。
阶段二:数据层与运行配置
建库建账号,单独建库建账号,不要用 root:
CREATE DATABASE espocrm CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'espocrm_user'@'localhost' IDENTIFIED BY '<DB_PASSWORD>'; GRANT ALL PRIVILEGES ON espocrm.* TO 'espocrm_user'@'localhost'; FLUSH PRIVILEGES;再在php.ini里放宽几个关键参数,否则导入数据、批量发邮件时容易撞墙:
memory_limit = 256M max_execution_time = 300 upload_max_filesize = 50M post_max_size = 50M改完重载 PHP:systemctl reload php8.3-fpm。
验证:php command.php db:check,数据库连通性与结构检查应无报错。
阶段三:目录权限
运行期可写的只有三处,把属主交给 Web/PHP 进程用户即可:
chown -R www-data:www-data /var/www/espocrm chmod -R 775 /var/www/espocrm/data chmod -R 775 /var/www/espocrm/custom chmod -R 775 /var/www/espocrm/client/custom验证:php command.php checkFilePermissions,输出应无失败项。
阶段四:应用初始化与定时任务
把域名解析到服务器,浏览器打开安装入口(安装器代码在 install/),按向导走:接受协议 → 环境自检(PHP 版本、扩展、目录权限全绿再继续)→ 填数据库连接 → 设管理员账号和站点名 → 等初始化完成。
安装向导做的本质上是两件事:把数据库配置写入data/config.php、建全部数据表。这个文件里带明文数据库密码,务必收紧权限:
chmod 600 /var/www/espocrm/data/config.php最后把后台任务挂上 cron,邮件收发和通知推送全靠它:
* * * * * /usr/bin/php /var/www/espocrm/cron.php > /dev/null 2>&1验证:手动跑一次php command.php cron:run --force无报错;php command.php appCheck综合检查通过。
Web 服务托管:Nginx 与 Apache 怎么取舍
两者都能跑,差异主要在重写机制和配置心智负担:
| 维度 | Nginx | Apache |
|---|---|---|
| 配置复杂度 | 需手写路由与静态资源映射 | 依赖.htaccess即可 |
| 重写机制 | location+try_files | mod_rewrite(.htaccess) |
| 适用场景 | 生产环境、高并发 | 快速搭测试环境、共享主机 |
一个关键前提两种方案都成立:站点根指向public/目录,client/静态资源单独做映射。根目录里那句"you need to configure your webserver"的提示页,就是在提醒你还没做对这一步。
Nginx 最小可用配置:
server { listen 80; server_name your-domain.com; root /var/www/espocrm/public; index index.php; client_max_body_size 50M; location /client/ { alias /var/www/espocrm/client/; } location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include fastcgi_params; fastcgi_pass unix:/var/run/php/php8.3-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } }改完执行systemctl reload nginx,浏览器打开首页应能看到登录页。高频踩坑点:root写成项目根目录而不是public/——后果是/client/下所有 JS、CSS 404,页面打开就是一堆报错的空白壳,把 root 指回public/并保留/client/的 alias 即可解决。
Apache 最小可用配置:
<VirtualHost *:80> ServerName your-domain.com DocumentRoot /var/www/espocrm/public Alias /client/ /var/www/espocrm/client/ <Directory /var/www/espocrm/public> Options -Indexes +FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost>systemctl reload apache2后刷新验证。踩坑点在AllowOverride All:它不开,public/下的.htaccess重写规则和文件保护全部失效,API 路径会 404、甚至暴露不该暴露的文件;共享主机上改不了主配置时,这一行就是生死开关。
装好只是起点:三个最值得先做的改造
给线索加一个你独有的字段
- 需求:录入线索时要能记"预算范围",方便筛选跟进优先级。
- 操作:后台「实体管理 → 字段」给 Lead 新增枚举字段(参考 Lead 的默认字段定义 里
status、source的写法),再到「布局管理」把字段拖进列表页和详情页。 - 效果:销售在录入界面直接看到新字段,列表可筛选,全程零后端代码。
用后台任务 + 公式接管重复劳动
- 需求:商机赢单后自动建一条跟进任务并通知负责人。
- 操作:在「计划任务」中确认相关 Job 处于启用状态,配合记录钩子/公式引擎做字段级联动(如按金额回填折扣价)。
- 效果:规则由系统自动兜底,销售不用手动记挂,漏跟单的概率大幅下降。
用 REST API 把 CRM 接进其他系统
- 需求:官网表单提交后自动创建线索,订单系统能按条件拉取客户。
- 操作:后台创建 App 获取 API 密钥,直接调标准 REST 接口:
curl -X POST https://your-domain.com/api/v1/Lead \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <API_TOKEN>" \ -d '{ "firstName": "Zhang", "lastName": "Xiaoming", "emailAddress": "zhangxm@example.com", "source": "Web Site" }'- 效果:字段名与实体定义一一对应,查询支持
where过滤参数,对接微信公众号、订单系统这类外部业务非常直接。
踩坑速查
| 现象 | 大概率原因 | 定位命令 / 动作 |
|---|---|---|
| 页面能开但接口 500 | PHP 层报错或数据库异常 | 看data/logs/当天日志 + FPM 日志(如/var/log/php8.3-fpm.log) |
| 升级后白屏、样式错乱 | 元数据缓存没清 | php command.php clearCache && php command.php rebuild |
| 频繁报权限错误 | data/、custom/属主不对 | php command.php checkFilePermissions,对照输出重跑 chown |
| 管理员密码丢失、进不了后台 | 无法通过 UI 重置 | php command.php setPassword <USERNAME> <NEW_PASSWORD> |
| 定时报表、邮件队列不触发 | cron 没真正在跑 | crontab -l确认计划,php command.php cron:run --force手动触发验证 |
| 数据库结构异常 | 连接或表结构漂移 | php command.php db:check逐条看报告 |
| 首页显示"请配置 webserver"提示页 | 站点根没指到public/ | 回到上一节,改 Nginxroot/ ApacheDocumentRoot |
通用建议:排查永远先看日志——应用日志按日期落在data/logs/,Web 服务器错误日志(Nginx 的 error.log / Apache 的 error_log)和 FPM 日志三方对照才能定位是哪一层的问题。提交 issue 时附上appCheck输出、version输出和对应的日志片段,能省掉来回追问的时间。
上线后的运维节奏
- 备份:数据库导出 + 文件打包,两者缺一不可,建议保留最近一周:
mysqldump -u espocrm_user -p'<DB_PASSWORD>' espocrm > espocrm_db_$(date +%Y%m%d).sql tar -czf espocrm_files_$(date +%Y%m%d).tar.gz /var/www/espocrm- HTTPS:在 Web 层配证书并强制跳转,避免登录凭据明文传输。
- 升级前:每次升级前先做一轮全量备份,后台右上角的升级提示别无视。
- 日志监控:
data/logs/持续膨胀时,检查是否有异常外部请求或死循环任务。 - 权限基线:
data/config.php保持 600,可写目录只给运行用户,不开目录浏览。
跑通之后,接下来做什么
如果你刚部署完,建议按顺序做这三件事:
- 把团队的真实销售流程画出来,对照默认实体字段逐项增删改——默认字段是"通用最优解",不是"你的最优解";
- 挑一个高频小动作配自动化(比如赢单通知、新线索自动分配),跑通一个再扩展,别一上来就做复杂工作流;
- 建立固定节奏:每周备份一次、每月查一次系统升级通知。
EspoCRM 的长期价值就在于"元数据驱动"这四个字:字段、布局、流程、接口全部可配置,掌握配置规律之后,系统会跟着你的业务持续演进,而不用推倒重写。
【免费下载链接】espocrmEspoCRM – Open Source CRM Application项目地址: https://gitcode.com/GitHub_Trending/es/espocrm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考