• 后端
  • 电商
  • 前端

【免费下载链接】CRMEB

🔥CRMEB开源商城免费开源多语言商城系统,Tp6框架商城,系统可商用;包含小程序商城、H5商城、公众号商城、PC商城、App,支持分销、拼团、砍价、秒杀、优惠券、积分、会员等级、小程序直播、页面DIY,前后端分离,方便二开,更有详细使用文档、接口文档、数据字典、二开文档/视频教程,欢迎大家提出宝贵意见和建议

项目地址: https://gitcode.com/gh_mirrors/cr/CRMEB
点击查看 免费下载

导读

本文基于 CRMEB 仓库中 docker-compose/MacArm/README.md 编写,完整讲解如何在 Apple 芯片(M1/M2/M3 等 ARM 架构)Mac 上,利用 Docker Compose 一键拉起 CRMEB 商城所需的 MySQL、Redis、PHP-FPM 与 Nginx 四套容器,并完成商城系统的访问与安装。读完本文,你将掌握 MacArm 目录下的全套部署流程、docker-compose.yml 的每个关键配置项含义、进入 PHP 容器启动定时任务(timer)、长连接(workerman)与消息队列(queue)的命令,以及端口占用、IP 冲突、M1 镜像兼容等常见问题的排查思路。

一、部署前的环境准备

CRMEB 的 Docker 部署依赖宿主机具备 Docker 与 Docker Compose 运行环境。Mac 上最便捷的方式是安装 Docker Desktop(自带 docker-compose 支持),也可以使用命令行方式安装 Docker。

# 通过脚本方式安装 Docker
curl -sSL https://get.daocloud.io/docker | sh

安装完成后,确认 Docker 与 Compose 版本可用:

docker --version
docker-compose --version

随后从代码托管平台获取 CRMEB 最新开源代码,解压后目录结构满足下述布局即可开始部署(crmeb 为程序运行目录,docker-compose 为部署编排目录):

项目根目录/
├── crmeb/                  # CRMEB 程序代码
└── docker-compose/
    ├── MacArm/             # Apple 芯片专用编排目录(本文核心)
    ├── MacIntel/           # Intel Mac 专用编排目录
    ├── linux/              # Linux 编排目录
    └── window/             # Windows 编排目录

说明:仓库中的通用版部署说明可参考 docker-compose/README.md,其流程与 MacArm 版本基本一致,差异主要体现在 MySQL 镜像与容器命名上。

二、启动项目:make run 与 docker-compose 命令

进入 MacArm 部署目录并启动项目:

cd ./docker-compose/MacArm

Mac 上推荐使用仓库自带的 Makefile(支持 make 命令),一条命令即可完成容器创建与后台启动:

make run

如果当前环境不支持 make 命令,则直接使用 docker-compose 原始命令:

docker-compose up -d

两条命令的效果一致:-d 表示以守护进程方式在后台运行容器。启动完成后,Makefile 会打印后台地址与数据库、Redis 的登录信息(详见 docker-compose/MacArm/Makefile):

[后台地址]   http://localhost:8011/
[MySql信息]  host:192.168.10.11:3306  user:root password:123456 database:crmeb
[Redis信息]  host:192.168.10.10:6379 password:123456

Makefile 还封装了其他常用操作,便于日常管理:

make build    # 重新构建 php 镜像
make down     # 停止并删除容器
make logs     # 跟随查看容器日志
make status   # 查看容器状态

三、docker-compose.yml 配置逐项解析

MacArm 的编排文件位于 docker-compose/MacArm/docker-compose.yml,共定义 4 个服务容器,统一挂入名称为 app_net 的桥接网络,网段为 192.168.10.0/24,并为每个容器固定了子网 IP。下表汇总各容器核心配置:

容器名镜像固定 IP对外端口职责
crmeb_mysql_armmysql/mysql-server(指定 platform: linux/arm64/v8)192.168.10.113306商城数据库
crmeb_redisredis:alpine192.168.10.106379缓存与队列存储
crmeb_phpcrmeb_php(本地构建)192.168.10.909000、40001、40002、40003PHP-FPM、定时任务、长连接、队列
crmeb_nginxnginx:alpine192.168.10.808011(映射容器 80)Web 入口

1. MySQL 容器

mysql:
  container_name: crmeb_mysql_arm
  image: mysql/mysql-server
  platform: linux/arm64/v8      # 明确指定 ARM 平台,确保 M 芯片拉取到正确架构镜像
  ports:
    - 3306:3306
  environment:
    TZ: Asia/Shanghai
    MYSQL_USER: 'root'
    MYSQL_PASSWORD: '123456'
    MYSQL_DATABASE: 'crmeb'
  privileged: true
  working_dir: /var/lib/mysql
  volumes:
    - ./mysql/my.cnf:/etc/my.cnf    # 挂载自定义 MySQL 配置
  networks:
    app_net:
      ipv4_address: 192.168.10.11

关键点:platform: linux/arm64/v8 是 M 芯片部署的核心——普通 mysql:5.7 镜像在 Apple Silicon 上可能无法正常运行,因此该编排显式约束架构。环境变量直接完成数据库 crmeb 的自动创建与 root 密码初始化;配置文件 docker-compose/MacArm/mysql/my.cnf 挂载到 /etc/my.cnf,其中设置了 skip-name-resolve 提升容器内连接性能,并配置了 STRICT_TRANS_TABLES 等严格 SQL 模式。

2. Redis 容器

redis:
  container_name: crmeb_redis
  image: 'redis:alpine'
  ports:
    - 6379:6379
  command: redis-server /usr/local/etc/redis/redis.conf
  volumes:
    - ./redis/redis.conf:/usr/local/etc/redis/redis.conf
  networks:
    app_net:
      ipv4_address: 192.168.10.10

Redis 通过 command 指定启动时加载挂载进来的自定义配置文件 docker-compose/MacArm/redis/redis.conf。其中几个与 CRMEB 运行直接相关的配置项:

  • requirepass 123456:设置连接密码,对应 README 中的 Redis 密码;
  • protected-mode no:允许容器网络内非本机连接(PHP 容器通过固定 IP 访问);
  • appendonly yes、appendfsync everysec:开启 AOF 持久化,每秒刷盘,兼顾性能与数据安全;
  • databases 16:提供 16 个逻辑库,CRMEB 默认使用 db 0。

3. PHP 容器(重点:目录挂载与三个运行进程)

phpfpm:
  container_name: crmeb_php
  image: crmeb_php
  build:
    context: ./php
    dockerfile: Dockerfile
  restart: always
  ports:
    - 9000:9000
    - 40001:40001   # workerman admin 服务
    - 40002:40002   # workerman chat 服务
    - 40003:40003   # workerman channel 服务
  tmpfs: /var/temp
  working_dir: /var/www
  volumes:
    - ../../crmeb:/var/www                  # 程序运行目录挂载
    - ../../crmeb/runtime:/var/www/temp     # 程序缓存目录挂载
    - ./php/php-ini-overrides.ini:/etc/php/7.4/fpm/conf.d/99-overrides.ini
  networks:
    app_net:
      ipv4_address: 192.168.10.90

这里有三点值得注意:

  • 宿主机与容器目录的映射关系:../../crmeb:/var/www 把仓库根目录下的 crmeb 程序目录挂载为容器内 /var/www,因此宿主上修改代码即时在容器内生效,适合本地开发调试;
  • 端口 40001/40002/40003 与 CRMEB 的长连接服务一一对应,对应关系见 crmeb/config/workerman.php:admin 监听 40001(后台新订单/新退款弹窗通知),chat 监听 40002(客服消息),channel 监听 40003(内部通讯);
  • php.ini 覆盖文件 docker-compose/MacArm/php/php-ini-overrides.ini 设定了 upload_max_filesize = 100M、post_max_size = 108M、上传临时目录 upload_tmp_dir = /var/www/temp,并禁用了 system、exec、shell_exec 等一系列高风险函数,兼顾商城后台大文件上传与容器安全。

PHP 镜像由 docker-compose/MacArm/php/Dockerfile 基于 phpdockerio/php:7.4-fpm 构建,通过 apt 安装 CRMEB 依赖的关键扩展:

php7.4-bcmath    # 数学计算扩展(分佣、价格精度计算依赖)
php7.4-redis     # Redis 驱动(缓存与队列)
php7.4-mysqli    # MySQL 驱动
php7.4-gd        # 图片处理(海报、二维码生成依赖)

同时写入 open_basedir = /tmp:/var,与 php.ini 覆盖文件一起构成双层的目录访问限制。

4. Nginx 容器

nginx:
  container_name: crmeb_nginx
  image: 'nginx:alpine'
  restart: always
  ports:
    - 8011:80
  depends_on:
    - phpfpm                    # 先启动 PHP,再启动 Nginx
  volumes_from:
    - phpfpm                    # 继承 PHP 容器的挂载目录
  volumes:
    - ./nginx/vhost.conf:/etc/nginx/conf.d/default.conf
  networks:
    app_net:
      ipv4_address: 192.168.10.80

8011:80 将容器 80 端口映射到宿主机 8011,这是 README 中访问地址 http://localhost:8011/ 的来源。volumes_from 使 Nginx 共享 PHP 容器的 /var/www 挂载,从而能直接读到 crmeb 程序文件。

Nginx 站点配置 docker-compose/MacArm/nginx/vhost.conf 完成了三件事:

  • 站点根目录指向 /var/www/public,对不存在的请求 rewrite 到 index.php(适配 ThinkPHP 单入口);
  • 对 gif|jpg|jpeg|png|bmp|swf 静态资源设置 30 天缓存,对 js|css 设置 12 小时缓存,并关闭静态资源访问日志;
  • 将 /notice 反向代理到 192.168.10.90:40002(chat 长连接)、将 /msg 代理到 192.168.10.90:40003(channel 内部通讯),并开启 WebSocket 升级所需的 Upgrade/Connection 头,保证前端长连接消息可达。

四、进入 PHP 容器启动定时任务、长连接与队列

CRMEB 的业务依赖三个常驻进程协同工作:定时任务(timer)、长连接(workerman)、消息队列(queue)。仓库 Makefile 已封装快捷入口:

make phprun

该命令会执行 docker exec -it crmeb_php /bin/bash 进入 PHP 容器,并提示接下来要执行的三个命令。也可使用原生命令:

docker exec -it crmeb_php /bin/bash
cd /var/www

进入容器内的项目目录 /var/www 后,依次启动三个服务:

# 1. 定时任务
php think timer start --d

# 2. 长连接(workerman)
php think workerman start --d

# 3. 消息队列
php think queue:listen --queue

三个命令均以 --d 守护进程方式后台运行。执行后可用 php think timer stop、php think workerman stop 等对应参数管理进程。

1. 定时任务命令底层原理

php think timer start --d 对应 CRMEB 自定义控制台指令 timer,命令类注册于 crmeb/config/console.php('timer' => \crmeb\command\Timer::class),其实现位于 crmeb/crmeb/command/Timer.php。

从源码看,该命令基于 Workerman 的 Worker 实现,支持 start/stop/reload/status/connections 五种状态参数,并额外提供 -i 选项自定义执行间隔(可精确到 0.001 秒)。进程 PID 写入 runtime/timer.pid。Worker 启动后调用 SystemCrontabServices 的 crontabCommandRun():

  • 每 6 秒写入一次 runtime/.timer 文件,作为"定时任务进程存活"的探测标记;
  • 从 system_crontab 表中读取所有启用状态的定时任务,将数据库中的 cron 表达式注册为 Workerman Crontab;
  • 任务命中后,把 mark 字段转小驼峰映射到 CrontabRunServices 的具体方法执行(customTimer 分支支持执行后台配置的自定义代码)。

因此,定时任务中的任务列表、执行周期、启停状态都可在系统后台的"定时任务"页面维护,命令行只需保证 timer 进程常驻。

2. 长连接命令底层原理

php think workerman start --d 对应 crmeb/crmeb/command/Workerman.php 实现的 workerman 指令。该指令支持可选的第二参数 admin/chat/channel,不带参数时同时创建三类服务:

  • admin(端口 40001):后台新订单、新退款单的实时弹窗提醒;
  • chat(端口 40002):H5/小程序客服与客户间的即时消息;
  • channel(端口 40003):内部通讯总线,负责 admin 与 chat 之间的消息转发。

服务地址、协议与进程数均来自 crmeb/config/workerman.php 配置,并通过 bindHandle() 将连接、消息、启动、断开四类回调分别绑定到 WorkermanService 与 ChatService。nginx 的 /notice、/msg 反向代理正是把前端长连接请求转发到上述两个 WebSocket 端口。

3. 消息队列命令说明

php think queue:listen --queue 基于 ThinkPHP 的 think-queue 扩展(crmeb/composer.json 中引入 topthink/think-queue: ^3.0)。队列驱动默认为 redis,配置见 crmeb/config/queue.php:

'default' => 'redis',
'connections' => [
    'redis' => [
        'driver'     => 'redis',
        'queue'      => 'CRMEB' . Env::get('queue.queue_name', ''),
        'host'       => Env::get('redis.redis_hostname', '127.0.0.1'),
        'port'       => Env::get('redis.port', 6379),
        'password'   => Env::get('redis.redis_password', ''),
        'select'     => Env::get('redis.select', 0),
        ...
    ],
],

即队列消息实际存放在 Redis 中。CRMEB 的订单创建、退款、短信/微信模板消息、海报生成、自动评价等大量异步任务都会投递到该队列,由 queue:listen 常驻消费(对应源码见 crmeb/app/jobs 目录下的 OrderJob、RefundOrderJob、SmsJob、PosterJob 等 Job 类)。

注意:queue 的 Redis 连接参数默认读取 .env 中的 redis.redis_hostname、redis.redis_password 等配置。容器内安装 CRMEB 时,需要保证 .env 中的 Redis 地址、密码与 docker-compose 中保持一致,否则队列消费会连接失败。

五、访问与安装 CRMEB 系统

启动完成后,浏览器访问:

http://localhost:8011/

进入安装向导。安装过程中需要的中间件连接信息如下(与 docker-compose/MacArm/Makefile 打印信息一致):

MySQL 数据库信息:

Host:     192.168.10.11
Port:     3306
user:     root
pwd:      123456
database: crmeb

Redis 信息:

Host:     192.168.10.10
Port:     6379
db:       0
pwd:      123456

这里需要特别说明:README 中给出的 192.168.10.11、192.168.10.10 是容器在 app_net 桥接网络中的固定内网 IP,而不是宿主机的局域网 IP。安装向导运行在 PHP 容器(192.168.10.90)内,与 MySQL、Redis 同处一个自定义子网,因此必须填写这两个容器 IP 才能互通。如果你准备把 MySQL/Redis 的对外映射端口(3306、6379)暴露给宿主机上的其他程序使用,则宿主机侧应使用 127.0.0.1 加映射端口访问。

CRMEB 程序会读取 .env 环境变量来覆盖 crmeb/config/database.php 中的数据库默认配置(hostname、database、username、password、hostport 等),安装完成后确认 .env 与上述连接信息一致即可。

六、常见问题排查

1. 端口被占用

Docker 启动时若提示端口冲突,进入 docker-compose/MacArm/docker-compose.yml 修改对应服务的 ports 映射,例如将 nginx 的 8011:80 改为 8012:80,改完后重新执行启动命令。

2. docker-compose up -d 启动失败

启动失败多与镜像相关。查看 docker-compose/MacArm/docker-compose.yml 中每个服务使用的 image 与 build 配置,确认镜像名正确、网络可拉取;必要时更换为本地可用的镜像源。

3. Error response from daemon: Address already in use

该报错通常是固定 IP 被占用:当前宿主机 Docker 已存在占用了 app_net 子网内某个 IP 的容器。处理方式为修改某个冲突容器的 networks.app_net.ipv4_address,换成子网 192.168.10.0/24 内的其他空闲地址(例如 192.168.10.91),同时注意同步修改 nginx 配置中反向代理指向的 IP。

4. MySQL 容器无法启动且没有任何日志

这是 Apple 芯片环境最典型的坑:M1 等 M 系列芯片下需要使用支持 ARM 架构的 MySQL 镜像,README 中给出的兼容方案是 daocloud.io/library/mysql:5.7.5-m15;其他任何情况下统一使用 mysql:5.7 镜像。MacArm 编排文件中已通过 platform: linux/arm64/v8 搭配 mysql/mysql-server 镜像解决该问题;若自行调整了镜像,务必参照此原则。

七、本文涉及的仓库文件索引

用途相对路径
MacArm 部署说明(本文主体)docker-compose/MacArm/README.md
容器编排配置docker-compose/MacArm/docker-compose.yml
Makefile 快捷命令docker-compose/MacArm/Makefile
PHP 镜像构建docker-compose/MacArm/php/Dockerfile
PHP 运行时配置docker-compose/MacArm/php/php-ini-overrides.ini
Nginx 站点配置docker-compose/MacArm/nginx/vhost.conf
MySQL 配置docker-compose/MacArm/mysql/my.cnf
Redis 配置docker-compose/MacArm/redis/redis.conf
定时任务指令实现crmeb/crmeb/command/Timer.php
长连接指令实现crmeb/crmeb/command/Workerman.php
长连接端口配置crmeb/config/workerman.php
队列配置crmeb/config/queue.php
控制台指令注册crmeb/config/console.php
定时任务调度核心crmeb/app/services/system/crontab/SystemCrontabServices.php
数据库默认配置crmeb/config/database.php
异步任务 Job 目录crmeb/app/jobs
  • 后端
  • 电商
  • 前端

【免费下载链接】CRMEB

🔥CRMEB开源商城免费开源多语言商城系统,Tp6框架商城,系统可商用;包含小程序商城、H5商城、公众号商城、PC商城、App,支持分销、拼团、砍价、秒杀、优惠券、积分、会员等级、小程序直播、页面DIY,前后端分离,方便二开,更有详细使用文档、接口文档、数据字典、二开文档/视频教程,欢迎大家提出宝贵意见和建议

项目地址: https://gitcode.com/gh_mirrors/cr/CRMEB
点击查看 免费下载

更多推荐