开源版本镜像提交

This commit is contained in:
Kris
2025-12-29 22:29:50 +08:00
commit 4da99fad5e
12 changed files with 2988 additions and 0 deletions

14
.gitignore vendored Normal file
View File

@@ -0,0 +1,14 @@
*.swp
*.log
*~
\.#*
\#*
espier-retail-manage
espier-bloated
data
docker-compose.test.yml
ECShopX
ECShopX_admin-frontend
ECShopX_desktop-frontend
ECShopX_mobile-frontend
.env

14
php74/.env.example Normal file
View File

@@ -0,0 +1,14 @@
# ECShopX Docker 环境变量配置
# 这些路径使用相对路径,相对于 docker-compose.yml 所在目录
# 后端 API 路径
ECShopX=./ECShopX
# 前端项目路径
ECShopX_ADMIN_FRONTEND=./ECShopX_admin-frontend
ECShopX_DESKTOP_FRONTEND=./ECShopX_desktop-frontend
ECShopX_MOBILE_FRONTEND=./ECShopX_mobile-frontend
# MySQL 数据卷配置
# 默认使用命名卷 mysql_data你也可以指定主机路径如 ./mysql-data:/var/lib/mysql
MYSQL_VOLUME=mysql_data:/var/lib/mysql

559
php74/README.md Executable file
View File

@@ -0,0 +1,559 @@
# ECShopX Docker 开发环境
ECShopX 采用前后端分离的方式开发,代码结构由后端 API 和多个前端组成。
- **后端 API**:基于 Lumen 开发,包含 Web、Scheduler、Worker
- **前端**管理端、小程序、PC端、H5端
## 📋 目录
- [准备工作](#准备工作)
- [快速开始](#快速开始)
- [详细步骤](#详细步骤)
- [脚本说明](#脚本说明)
- [常见问题](#常见问题)
- [访问地址](#访问地址)
## 🚀 快速开始
### 1. 克隆项目
```bash
git clone https://github.com/shopex/ecshopx-open-docker.git
cd ecshopx-open-docker/php74
cp .env.example .env
```
### 2. 初始化子项目代码
```bash
chmod +x setup.sh init-api.sh
./setup.sh
```
### 3. 配置 Docker Desktop 文件共享重要macOS 用户必须操作)
```bash
# 打开 Docker Desktop → Settings → Resources → File Sharing
# 添加项目所在目录(如 /Users/你的用户名/data/ecshopx-open-docker/php74
```
### 4. 启动 Docker 容器
```bash
docker-compose up -d
```
### 5. 一键初始化 API包含数据库迁移
```bash
./init-api.sh
```
### 6. 访问应用
```bash
# 管理后台: http://127.0.0.1:8080
# 移动端: http://127.0.0.1:8081
# PC端: http://127.0.0.1:8082
```
## 📦 准备工作
### 1. 系统要求
- Docker DesktopmacOS/Windows或 Docker EngineLinux
- Docker Compose
- Git
- 至少 4GB 可用内存
- 至少 10GB 可用磁盘空间
Docker 会自动处理不同 CPU 架构的兼容性问题,无需手动配置。
### 2. 克隆项目
```bash
git clone https://github.com/shopex/ecshopx-open-docker.git
cd ecshopx-open-docker/php74
```
### 3. macOS 用户重要配置 ⚠️
**Docker Desktop 文件共享配置(必须操作)**
1. 打开 Docker Desktop 应用
2. 点击右上角 **⚙️ Settings**
3. 进入 **Resources****File Sharing**
4. 添加项目所在目录(例如:`/Users/你的用户名/data/ecshopx-open-docker/php74`
5. 点击 **Apply & Restart**
> **为什么需要这一步?**
> macOS 的 Docker Desktop 默认只允许访问某些目录。如果不配置文件共享,容器内将看不到挂载的文件,导致应用无法正常运行。
## 📖 详细步骤
### 第一步:初始化代码
#### 方式一:使用 setup.sh 自动拉取(推荐)
```bash
chmod +x setup.sh
./setup.sh
```
运行脚本后会交互式询问是否拉取子项目代码:
-**Y/y****回车** → 自动从 GitHub 拉取所有子项目
-**N/n** → 跳过拉取,使用本地已有的代码
#### 方式二:手动放置代码
如果你已经下载了代码包,可以手动复制到对应目录:
- `管理端`代码 → `ECShopX_admin-frontend/` 目录
- `API端`代码 → `ECShopX/` 目录
- `PC端`代码 → `ECShopX_desktop-frontend/` 目录
- `H5端`代码 → `ECShopX_mobile-frontend/` 目录
#### 完成后的目录结构
```
php74/
├── .env # Docker Compose 环境变量(需创建)
├── docker-compose.yml # Docker 编排配置
├── setup.sh # 子项目代码初始化脚本
├── init-api.sh # API 服务一键初始化脚本
├── config/ # 配置文件目录
│ ├── nginx/
│ └── php/
├── ECShopX/ # 后端 API 代码
│ ├── app/
│ ├── bootstrap/
│ ├── config/
│ ├── .env # API 配置(自动生成)
│ └── ...
├── ECShopX_admin-frontend/ # 管理端前端代码
├── ECShopX_desktop-frontend/ # PC端前端代码
└── ECShopX_mobile-frontend/ # H5端前端代码
```
### 第二步:创建 Docker Compose 环境变量
在 php74 目录创建 `.env` 文件:
```bash
cp .env.example .env
```
> **说明**:这个 `.env` 文件用于 docker-compose.yml 中的卷映射配置。使用相对路径使项目更便于移动。
### 第三步:启动 Docker 容器
```bash
# 后台启动所有服务
docker-compose up -d
# 查看容器状态
docker-compose ps
# 查看日志(可选)
docker-compose logs -f
```
> **首次启动说明**
> - 第一次启动需要拉取 Docker 镜像,可能需要等待几分钟
> - 镜像地址:`shopexhub/php:ecx-7.4.32-fpm-alpine3.16`
> - 如果拉取失败,可能需要配置 Docker 镜像加速或使用代理
### 第四步:一键初始化 API推荐
使用 `init-api.sh` 脚本一键完成所有配置:
```bash
chmod +x init-api.sh
./init-api.sh
```
**脚本会自动完成以下操作**
1. ✅ 检查容器运行状态
2. ✅ 复制 `.env.full``.env`(如果不存在)
3. ✅ 验证文件挂载是否正常
4. ✅ 安装 Composer 依赖(使用阿里云镜像加速)
5. ✅ 安装 Supervisor、Curl、Vim
6. ✅ 配置并启动 Supervisor
7. ✅ 设置存储目录权限
8. ✅ 自动配置数据库和 Redis 连接
9. ✅ 创建数据库
10. ✅ 生成应用密钥
11. ✅ 运行数据库迁移
整个过程约需 3-5 分钟,完成后即可直接使用。
### 第五步:手动配置(可选,如果不使用 init-api.sh
如果你想手动配置,可以按照以下步骤操作:
#### 1. 进入容器
```bash
docker exec -it ecshopx-api sh
cd /data/httpd
```
#### 2. 配置 `.env` 文件
```bash
# 复制配置文件
cp .env.full .env
# 编辑配置
vi .env
```
修改以下配置项:
```env
# 数据库配置
DB_CONNECTION=default
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=ecshopx
DB_USERNAME=root
DB_PASSWORD=root
# Redis 配置
REDIS_CLIENT=predis
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=123456
```
#### 3. 安装依赖
```bash
# 配置 Composer 镜像
php composer.phar config repo.packagist composer https://mirrors.aliyun.com/composer/
# 安装依赖(需要较大内存)
php -d memory_limit=-1 composer.phar install --optimize-autoloader
```
#### 4. 创建数据库
```bash
# 退出容器
exit
# 进入 MySQL 容器创建数据库
docker exec ecshopx-open-docker_mysql_1 mysql -uroot -proot -e \
"CREATE DATABASE IF NOT EXISTS ecshopx CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
```
#### 5. 初始化数据库
```bash
# 重新进入 API 容器
docker exec -it ecshopx-api sh
cd /data/httpd
# 生成应用密钥
php artisan key:generate
# 运行数据库迁移
php artisan doctrine:migrations:migrate
```
### 第六步:编译前端代码(可选)
如果需要开发前端,需要在宿主机安装 Node.js 并编译:
```bash
# 进入前端项目目录
cd ECShopX_admin-frontend
# 安装依赖
npm install
# 开发模式
npm run dev
# 生产构建
npm run build
```
详细步骤请参考各前端项目的 README.md。
## 🌐 访问地址
服务启动后,可以通过以下地址访问:
| 服务 | 地址 | 说明 |
|------|------|------|
| **管理后台** | http://127.0.0.1:8080 | 商城管理端 |
| **移动端** | http://127.0.0.1:8081 | H5 移动端 |
| **PC端** | http://127.0.0.1:8082 | PC 桌面端 |
| **后端 API** | http://127.0.0.1:8080/api | RESTful API |
| **phpMyAdmin** | http://127.0.0.1:8083 | 数据库管理工具 |
### 数据库连接信息
| 配置项 | 值 |
|--------|-----|
| 主机 | `mysql` (容器内) / `127.0.0.1:3306` (宿主机) |
| 用户名 | `root` |
| 密码 | `root` |
| 数据库 | `ecshopx` |
### Redis 连接信息
| 配置项 | 值 |
|--------|-----|
| 主机 | `redis` (容器内) / `127.0.0.1:6379` (宿主机) |
| 密码 | `123456` |
| 数据库 | `0` |
## 🛠 脚本说明
### setup.sh - 子项目代码初始化
**功能**:自动从 GitHub 克隆所有子项目代码
**使用方法**
```bash
chmod +x setup.sh
./setup.sh
```
**工作流程**
1. 交互式询问是否拉取代码
2. 检查各子项目目录是否已存在
3. 如果不存在,则从 GitHub 克隆
4. 如果已存在,则跳过
**克隆的子项目**
- `ECShopX` - 后端 API
- `ECShopX_admin-frontend` - 管理端前端
- `ECShopX_desktop-frontend` - PC端前端
- `ECShopX_mobile-frontend` - H5端前端
### init-api.sh - API 服务一键初始化
**功能**:自动完成 API 服务的所有初始化配置
**使用方法**
```bash
chmod +x init-api.sh
./init-api.sh
```
**详细功能**
| 步骤 | 说明 | 技术细节 |
|------|------|----------|
| 检查环境 | 验证 docker-compose.yml 和容器状态 | 确保在正确目录运行 |
| 配置文件 | 自动复制 `.env.full``.env` | 仅在 .env 不存在时复制 |
| 验证挂载 | 检查容器内文件是否可见 | 解决 macOS 文件共享问题 |
| Composer | 安装 PHP 依赖包148个 | 使用 `-d memory_limit=-1` 避免内存不足 |
| 系统工具 | 安装 supervisor、curl、vim | Alpine Linux 包管理 |
| Supervisor | 配置进程管理器 | 管理队列和 WebSocket 服务 |
| 权限设置 | 设置 storage 目录权限 | 确保日志和缓存可写 |
| 数据库配置 | 自动替换 DB/Redis 配置 | 使用 sed 批量替换 |
| 创建数据库 | 创建 ecshopx 数据库 | UTF-8MB4 字符集 |
| 应用密钥 | 生成 Laravel 应用密钥 | 用于加密 session 等 |
| 数据库迁移 | 执行 64 个数据库迁移 | 创建所有表结构 |
**脚本亮点**
- ✅ 智能内存管理:使用 `-d memory_limit=-1` 解决 Composer 内存不足
- ✅ 镜像加速:配置阿里云 Composer 镜像,加快依赖下载
- ✅ 自动配置:无需手动编辑配置文件
- ✅ 错误检测:每步都有状态检查和错误提示
- ✅ 幂等性:可以重复执行,不会造成数据问题
## ❓ 常见问题
### 1. 容器内看不到挂载的文件
**症状**:运行 `docker exec ecshopx-api ls /data/httpd` 显示为空
**原因**macOS Docker Desktop 文件共享权限未配置
**解决方案**
```bash
# 1. 打开 Docker Desktop
# 2. Settings → Resources → File Sharing
# 3. 添加项目所在目录(如 /Users/你的用户名/data/ecshopx-open-docker/php74
# 4. Apply & Restart
# 5. 重启容器
docker-compose down
docker-compose up -d
```
详见:[VOLUME_ISSUE_SOLUTION.md](./VOLUME_ISSUE_SOLUTION.md)
### 2. Composer 安装失败:内存不足
**症状**
```
Fatal error: Allowed memory size of 1610612736 bytes exhausted
```
**解决方案**:使用 `-d memory_limit=-1` 参数
```bash
docker exec ecshopx-api sh -c "cd /data/httpd && php -d memory_limit=-1 composer.phar install"
```
`init-api.sh` 脚本已自动处理此问题。
### 3. 数据库连接失败
**症状**
```
SQLSTATE[HY000] [2002] Connection refused
```
**解决方案**
检查 `.env` 配置中数据库主机是否正确:
```bash
# 容器内必须使用服务名
DB_HOST=mysql # ✅ 正确
DB_HOST=127.0.0.1 # ❌ 错误(容器内不可用)
DB_HOST=localhost # ❌ 错误(容器内不可用)
```
### 4. Redis 连接失败
**症状**
```
Connection refused [tcp://127.0.0.1:6379]
```
**解决方案**
检查 `.env` 配置:
```env
REDIS_HOST=redis # ✅ 正确
REDIS_PASSWORD=123456 # 必须配置密码
```
### 5. 端口冲突
**症状**
```
Bind for 0.0.0.0:8080 failed: port is already allocated
```
**解决方案**
```bash
# 方式一:停止占用端口的程序
lsof -ti:8080 | xargs kill
# 方式二:修改 docker-compose.yml 中的端口映射
# 例如:将 8080:80 改为 8090:80
```
### 6. 查看容器日志
```bash
# 查看所有容器日志
docker-compose logs
# 查看特定容器日志
docker-compose logs ecshopx-api
# 实时跟踪日志
docker-compose logs -f ecshopx-api
# 查看最近 100 行日志
docker-compose logs --tail=100 ecshopx-api
```
### 7. 重启服务
```bash
# 重启所有服务
docker-compose restart
# 重启特定服务
docker-compose restart ecshopx-api
# 停止并删除容器(不会删除数据)
docker-compose down
# 完全清理(包括卷和网络)
docker-compose down -v
```
## 🔧 开发命令
### 进入容器
```bash
# 进入 API 容器
docker exec -it ecshopx-api sh
# 进入 MySQL 容器
docker exec -it ecshopx-open-docker_mysql_1 mysql -u root -p
# 进入 Redis 容器
docker exec -it ecshopx-redis redis-cli -a 123456
```
### 常用 Artisan 命令
```bash
# 进入 API 容器
docker exec -it ecshopx-api sh
cd /data/httpd
# 查看路由
php artisan route:list
# 清除缓存
php artisan cache:clear
# 清除配置缓存
php artisan config:clear
# 生成 API 文档
php artisan swagger:generate
# 运行队列
php artisan queue:work
# 查看所有命令
php artisan list
```
### 数据库操作
```bash
# 运行迁移
docker exec -w /data/httpd ecshopx-api php artisan doctrine:migrations:migrate
# 回滚迁移
docker exec -w /data/httpd ecshopx-api php artisan doctrine:migrations:rollback
# 查看迁移状态
docker exec -w /data/httpd ecshopx-api php artisan doctrine:migrations:status
```
## 📚 更多资源
- [ECShopX 官方文档](https://op.shopex.cn/doc_ecshopx_dev/docs/readme.html)
- [Docker 官方文档](https://docs.docker.com/)
- [Docker Compose 文档](https://docs.docker.com/compose/)
- [Lumen 框架文档](https://lumen.laravel.com/)
---
如有问题,请提交 [Issue](https://github.com/shopex/ecshopx-open-docker/issues)。

140
php74/config/nginx/default.conf Executable file
View File

@@ -0,0 +1,140 @@
# 后台动态编译
server {
listen 80;
server_name _;
location /api/ {
proxy_pass http://localhost:8090;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 32m;
client_body_buffer_size 256k;
}
location /wechatAuth/ {
proxy_pass http://localhost:8090;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 32m;
client_body_buffer_size 256k;
}
location / {
root /data/httpd/ECShopX_admin-frontend/dist/;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
location ~* \.(ini|sql|conf|bak)$ {
return 404;
}
location ~* ^/(themes|images|logs|data|demo|wap_themes)/.*\.(php|php5)$ {
deny all;
}
location ~ /\.(svn|git|)/ {
deny all;
}
}
server {
listen 8090;
server_name _;
index index.html index.htm index.php;
root /data/httpd/ECShopX/public;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
#add_header Access-Control-Allow-Origin *;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header Access-Control-Allow-Headers "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With";
add_header Access-Control-Expose-Headers "Authorization";
add_header Access-Control-Allow-Methods "DELETE, GET, HEAD, POST, PUT, OPTIONS, TRACE, PATCH";
if ($request_method = OPTIONS ) {
return 200;
}
#fastcgi_pass localhost:9000;
fastcgi_pass ecshopx-api:9000;
fastcgi_read_timeout 150;
fastcgi_index index.php;
fastcgi_buffers 4 128k;
fastcgi_buffer_size 128k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 256k;
fastcgi_temp_path /dev/shm;
fastcgi_param SCRIPT_FILENAME /data/httpd/public/index.php;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
location ~* \.(ini|sql|conf|bak)$ {
return 404;
}
location ~* ^/(themes|images|logs|data|demo|wap_themes)/.*\.(php|php5)$ {
deny all;
}
location ~ /\.(svn|git|)/ {
deny all;
}
}
server {
listen 81;
server_name _;
location / {
root /data/httpd/ECShopX_mobile-frontend/dist/h5/;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
location ~* \.(ini|sql|conf|bak)$ {
return 404;
}
location ~* ^/(themes|images|logs|data|demo|wap_themes)/.*\.(php|php5)$ {
deny all;
}
location ~ /\.(svn|git|)/ {
deny all;
}
}
server {
listen 82;
server_name _;
location / {
root /data/httpd/ECShopX_desktop-frontend/dist/h5/;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
location ~* \.(ini|sql|conf|bak)$ {
return 404;
}
location ~* ^/(themes|images|logs|data|demo|wap_themes)/.*\.(php|php5)$ {
deny all;
}
location ~ /\.(svn|git|)/ {
deny all;
}
}

View File

@@ -0,0 +1 @@
;zend_extension=opcache.so

View File

@@ -0,0 +1,2 @@
extension=swoole_loader72.so
swoole_license_files=/app/license.zl

View File

@@ -0,0 +1,125 @@
;;;;;;;;;;;;;;;;;;;;;
; FPM Configuration ;
;;;;;;;;;;;;;;;;;;;;;
; All relative paths in this configuration file are relative to PHP's install
; prefix (/usr/local). This prefix can be dynamically changed by using the
; '-p' argument from the command line.
;;;;;;;;;;;;;;;;;;
; Global Options ;
;;;;;;;;;;;;;;;;;;
[global]
; Pid file
; Note: the default prefix is /usr/local/var
; Default Value: none
;pid = run/php-fpm.pid
; Error log file
; If it's set to "syslog", log is sent to syslogd instead of being written
; into a local file.
; Note: the default prefix is /usr/local/var
; Default Value: log/php-fpm.log
;error_log = log/php-fpm.log
; syslog_facility is used to specify what type of program is logging the
; message. This lets syslogd specify that messages from different facilities
; will be handled differently.
; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
; Default Value: daemon
;syslog.facility = daemon
; syslog_ident is prepended to every message. If you have multiple FPM
; instances running on the same server, you can change the default value
; which must suit common needs.
; Default Value: php-fpm
;syslog.ident = php-fpm
; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
;log_level = notice
; If this number of child processes exit with SIGSEGV or SIGBUS within the time
; interval set by emergency_restart_interval then FPM will restart. A value
; of '0' means 'Off'.
; Default Value: 0
;emergency_restart_threshold = 0
; Interval of time used by emergency_restart_interval to determine when
; a graceful restart will be initiated. This can be useful to work around
; accidental corruptions in an accelerator's shared memory.
; Available Units: s(econds), m(inutes), h(ours), or d(ays)
; Default Unit: seconds
; Default Value: 0
;emergency_restart_interval = 0
; Time limit for child processes to wait for a reaction on signals from master.
; Available units: s(econds), m(inutes), h(ours), or d(ays)
; Default Unit: seconds
; Default Value: 0
;process_control_timeout = 0
; The maximum number of processes FPM will fork. This has been designed to control
; the global number of processes when using dynamic PM within a lot of pools.
; Use it with caution.
; Note: A value of 0 indicates no limit
; Default Value: 0
; process.max = 128
; Specify the nice(2) priority to apply to the master process (only if set)
; The value can vary from -19 (highest priority) to 20 (lowest priority)
; Note: - It will only work if the FPM master process is launched as root
; - The pool process will inherit the master process priority
; unless specified otherwise
; Default Value: no set
; process.priority = -19
; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging.
; Default Value: yes
;daemonize = yes
; Set open file descriptor rlimit for the master process.
; Default Value: system defined value
;rlimit_files = 1024
; Set max core size rlimit for the master process.
; Possible Values: 'unlimited' or an integer greater or equal to 0
; Default Value: system defined value
;rlimit_core = 0
; Specify the event mechanism FPM will use. The following is available:
; - select (any POSIX os)
; - poll (any POSIX os)
; - epoll (linux >= 2.5.44)
; - kqueue (FreeBSD >= 4.1, OpenBSD >= 2.9, NetBSD >= 2.0)
; - /dev/poll (Solaris >= 7)
; - port (Solaris >= 10)
; Default Value: not set (auto detection)
;events.mechanism = epoll
; When FPM is built with systemd integration, specify the interval,
; in seconds, between health report notification to systemd.
; Set to 0 to disable.
; Available Units: s(econds), m(inutes), h(ours)
; Default Unit: seconds
; Default value: 10
;systemd_interval = 10
;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;
; Multiple pools of child processes may be started with different listening
; ports and different management options. The name of the pool will be
; used in logs and stats. There is no limitation on the number of pools which
; FPM can handle. Your system will tell you anyway :)
; Include one or more files. If glob(3) exists, it is used to include a bunch of
; files from a glob(3) pattern. This directive can be used everywhere in the
; file.
; Relative path can also be used. They will be prefixed by:
; - the global prefix if it's been set (-p argument)
; - /usr/local otherwise
include=etc/php-fpm.d/*.conf

1918
php74/config/phpfpm/php.ini Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
[global]
daemonize = no
[www]
listen = 9000

82
php74/docker-compose.yml Executable file
View File

@@ -0,0 +1,82 @@
services:
ecshopx:
# build:
# context: .
# dockerfile: ./docker-new/Dockerfile
image: shopexhub/php:ecx-7.4.32-fpm-alpine3.16 #这是官方镜像需要自己安装supervisor
#image: wykrisdev/shopex-docker:php74-ECShopX-Open
container_name: ecshopx-api
links:
- mysql
- redis
volumes:
- "./config/php/conf.d/docker-php-ext-opcache.ini:/usr/local/etc/php/conf.d/docker-php-ext-opcache.ini:ro"
# 后端代码:完全绑定挂载(包括 vendor
- "${ECShopX:-./ECShopX}:/data/httpd:cached"
networks:
- webnet
dns: 8.8.8.8
nginx:
image: nginx:latest
container_name: ecshopx-nginx
ports:
- "8080:80" #管理后台
- "8081:81" #移动端
- "8082:82" #PC
links:
- ecshopx
- phpmyadmin
volumes:
- "./config/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro"
# 前端:只挂载 dist 目录,使用 delegated 模式提升性能
- "${ECShopX_ADMIN_FRONTEND:-./ECShopX_admin-frontend}/dist:/data/httpd/ECShopX_admin-frontend/dist:delegated"
- "${ECShopX_DESKTOP_FRONTEND:-./ECShopX_desktop-frontend}/dist:/data/httpd/ECShopX_desktop-frontend/dist:delegated"
- "${ECShopX_MOBILE_FRONTEND:-./ECShopX_mobile-frontend}/dist:/data/httpd/ECShopX_mobile-frontend/dist:delegated"
networks:
- webnet
redis:
image: redis:4.0.14-alpine
command: redis-server --requirepass 123456
container_name: ecshopx-redis
networks:
- webnet
mysql:
image: mysql:8.0
container_name: ecshopx-mysql
ports:
- "33061:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=ecshopx
volumes:
- mysql74_data:/var/lib/mysql
networks:
- webnet
command: --default-authentication-plugin=mysql_native_password
# 健康检查配置
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
timeout: 20s
retries: 10
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
ports:
- "8083:80"
links:
- mysql
environment:
- PMA_HOST=mysql
networks:
- webnet
volumes:
mysql74_data:
driver: local
networks:
webnet:
driver: bridge

84
php74/init-api.sh Executable file
View File

@@ -0,0 +1,84 @@
#!/bin/bash
echo "开始初始化 ecshopx-api 服务..."
# 检查是否在正确的目录
if [ ! -f "docker-compose.yml" ]; then
echo "错误: 未找到 docker-compose.yml 文件,请在项目根目录运行此脚本"
exit 1
fi
# 等待 ecshopx-api 容器启动
echo "等待 ecshopx-api 服务启动..."
sleep 10
# 检查容器是否运行
if ! docker ps | grep -q ecshopx-api; then
echo "错误: ecshopx-api 容器未运行"
exit 1
fi
# 检查 .env 文件是否存在,如果不存在从 .env.full 复制
ENV_FILE_EXISTS=$(docker exec ecshopx-api test -f /data/httpd/.env && echo "yes" || echo "no")
if [ "$ENV_FILE_EXISTS" = "no" ]; then
ENV_FULL_EXISTS=$(docker exec ecshopx-api test -f /data/httpd/.env.full && echo "yes" || echo "no")
if [ "$ENV_FULL_EXISTS" = "yes" ]; then
echo "复制 .env.full 到 .env..."
docker exec ecshopx-api cp /data/httpd/.env.full /data/httpd/.env
else
echo "错误: .env 和 .env.full 都不存在"
exit 1
fi
fi
# 检查宿主机上的 ECShopX 目录是否已挂载(通过检查是否为空)
CONTAINER_FILE_COUNT=$(docker exec ecshopx-api ls -A /data/httpd/ 2>/dev/null | wc -l)
if [ "$CONTAINER_FILE_COUNT" -eq 0 ]; then
echo "警告: 容器内 /data/httpd 目录为空"
# 检查是否存在环境变量定义的目录
if [ -n "$ECShopX" ] && [ -d "$ECShopX" ]; then
echo "使用环境变量 ECShopX 定义的目录: $ECShopX"
# 因为使用环境变量,这里需要使用 docker cp 命令
docker cp $ECShopX/. ecshopx-api:/data/httpd/
else
echo "错误: ECShopX 环境变量未设置或指向的目录不存在"
exit 1
fi
else
echo "容器中检测到 $CONTAINER_FILE_COUNT 个文件,挂载可能正常"
fi
# 执行composer install
echo "在容器中运行 composer install..."
docker exec ecshopx-api sh -c "cd /data/httpd && chmod +x composer.phar && php composer.phar config repo.packagist composer https://mirrors.aliyun.com/composer/ && php -d memory_limit=-1 composer.phar install --optimize-autoloader"
# 安装必要的软件
echo "安装 Supervisor 和 Curl..."
docker exec ecshopx-api apk add --no-cache supervisor curl vim
echo "创建 Supervisor 配置目录...并启动"
docker exec ecshopx-api mkdir -p /etc/supervisor.d/
docker exec ecshopx-api sh -c "cp -r /data/httpd/docker-new/supervisor/* /etc/supervisor.d/ && cp /data/httpd/docker-new/supervisord.conf /etc/supervisord.conf"
docker exec ecshopx-api sh -c "supervisord -c /etc/supervisord.conf"
echo "设置存储目录权限..."
docker exec ecshopx-api sh -c "mkdir -p /data/httpd/storage/logs && mkdir -p /data/httpd/storage/framework/cache/laravel-excel && chown -R www-data:www-data /data/httpd/storage"
echo "修复数据库和 Redis 配置..."
docker exec ecshopx-api sed -i 's/DB_HOST=127.0.0.1/DB_HOST=mysql/g; s/REDIS_HOST=127.0.0.1/REDIS_HOST=redis/g' /data/httpd/.env
docker exec ecshopx-api sed -i 's/^DB_USERNAME=$/DB_USERNAME=root/g; s/^DB_PASSWORD=$/DB_PASSWORD=root/g; s/^DB_DATABASE=$/DB_DATABASE=ecshopx/g; s/^REDIS_PASSWORD=$/REDIS_PASSWORD=123456/g' /data/httpd/.env
echo "创建数据库..."
docker exec ecshopx-mysql mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS ecshopx CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
echo "生成应用密钥..."
docker exec -w /data/httpd ecshopx-api php artisan key:generate
echo "运行数据库迁移..."
docker exec -w /data/httpd ecshopx-api php artisan doctrine:migrations:migrate --force
echo "初始化完成!"
echo "所有服务现在应该正常运行。"
echo "您可以使用 'docker-compose ps' 检查服务状态。"

44
php74/setup.sh Executable file
View File

@@ -0,0 +1,44 @@
#!/bin/bash
echo "ECShopX 项目初始化脚本"
echo -n "是否要拉取子项目代码? [Y/n] "
read -r response
if [[ ! "$response" =~ ^([nN][oO]|[nN])$ ]] && [[ -n "$response" ]]; then
echo "正在拉取子项目代码..."
# 检查目录是否存在,不存在则拉取
if [ ! -d "ECShopX_admin-frontend" ]; then
git clone https://github.com/ShopeX/ECShopX_admin-frontend.git ECShopX_admin-frontend
else
echo "ECShopX_admin-frontend 目录已存在,跳过克隆"
fi
if [ ! -d "ECShopX" ]; then
git clone https://github.com/ShopeX/ECShopX.git ECShopX
else
echo "ECShopX 目录已存在,跳过克隆"
fi
if [ ! -d "ECShopX_desktop-frontend" ]; then
git clone https://github.com/ShopeX/ECShopX_desktop-frontend.git ECShopX_desktop-frontend
else
echo "ECShopX_desktop-frontend 目录已存在,跳过克隆"
fi
if [ ! -d "ECShopX_mobile-frontend" ]; then
git clone https://github.com/ShopeX/ECShopX_mobile-frontend.git ECShopX_mobile-frontend
else
echo "ECShopX_mobile-frontend 目录已存在,跳过克隆"
fi
echo "子项目代码拉取完成!"
else
if [[ "$response" =~ ^([nN][oO]|[nN])$ ]]; then
echo "跳过子项目代码拉取."
else
echo "输入无效,跳过子项目代码拉取."
fi
fi
echo "初始化完成!"