服务名称 英文名 端口号 版本号 服务类别
数据库 mysql 3306 v8.26 环境依赖
搜索引擎 es 9201 3.1.9 环境依赖
缓存 Redis 6379 v8 环境依赖
消息队列 RocketMQ 2.3.0 环境依赖
注册中心 nacos 8848 v2.2.0 环境依赖
网关服务 easylive-cloud-gateway 7071 java8 项目
分布式事务 Seata 7091 2021.0.5.0 环境依赖
对象存储 Minio 9000 2024-09-13T20-26-02Z 环境依赖
管理端服务 easylive-cloud-admin 7070 java8 项目
用户端服务 easylive-cloud-web 7072 java8 项目
交互服务 easylive-cloud-interact 7073 java8 项目
资源服务 easylive-cloud-resource 7074 java8 项目

微服务项目部署指导

Exported on 2025/10/6 at GMT+8 0:12:27 from Cursor (1.4.2)


User

整个项目已经完结,请你仔细查看一下项目的结构,我现在想要把这个微服务项目部署到一个我已经准备好的4核4g的服务器上该如何部署,是选择用宝塔面板还是用docker compose部署呢,请你指引着我一步步完成部署@c:\Users\wanglei\Desktop\项目部署.md


Cursor

我先快速查看各微服务的配置文件端口与外部依赖(Nacos、Redis、RocketMQ、Minio 等)的指向,确保 docker-compose 方案能一次性把依赖与服务都编排好。随后我会给出一步步部署清单与可直接使用的 compose 文件与构建命令。

我将先创建一个部署任务清单,随后直接给出推荐方案(Docker Compose)与可运行的命令、配置与文件模板。接下来我会把全部步骤一次性写全,便于你按部就班执行。

我先并行打开各微服务的配置文件,确认注册中心、配置名与端口设置,以便给出可直接可用的 docker-compose 参数和环境变量。接着我会确定采用 Docker Compose 的总体策略并开始给出脚本。

我已确认各服务的 bootstrap.yml 通过 Nacos 加载共享配置且默认指向 127.0.0.1:8848,容器化时需用环境变量覆盖为 nacos:8848。现在我先确定采用 Docker Compose 方案,并开始给出安装与编排文件。接下来把“安装 Docker/Compose”设为进行中。

我将并行打开各服务的 dev 配置文件,确认数据库、存储和消息队列的连接信息,以便在 docker-compose 中正确注入环境变量。

我将把“安装 Docker/Compose”完成并开始“创建目录结构与 .env 机密变量”,随后给出.envdocker-compose.yml模板与执行命令。接着我会继续推进依赖与应用编排等步骤,并同步勾选对应待办。

我已经确定采用 Docker Compose 部署,并开始输出目录结构、.env 与依赖编排模板,随后给出后端镜像构建与应用编排、前端与 Nginx 配置。接着我会把“创建目录结构与 .env”标记完成,并开启“依赖服务编排”和“应用编排”。

我已确认采用 Docker Compose 并核对了各微服务的 Nacos 配置与端口。现在我会直接给出一步步部署清单、必要命令与可用模板(.env、docker-compose、Dockerfile、Nginx),你可以按顺序执行。随后我会把清单项勾选完成。### 结论与建议

  • 建议使用 Docker Compose 部署。原因:
    • 多个基础依赖(MySQL/Redis/Nacos/RocketMQ/Minio/ES/Seata)与 5 个 SpringBoot 微服务需要统一编排、网络与持久化,更易复现与维护。
    • 日志、重启策略、资源限制、备份与迁移都更容易标准化。
  • 4 核 4G 机器资源偏紧。建议先上线核心链路(MySQL、Redis、Nacos、Minio、网关与核心三服务),RocketMQ/ES/Seata如非强依赖可延后启用,或按需独立机器。

端口规划(来自你的部署文档)

  • 数据库 MySQL: 3306
  • Nacos: 8848
  • 网关 easylive-cloud-gateway: 7071
  • 管理端 easylive-cloud-admin: 7070
  • 用户端 easylive-cloud-web: 7072
  • 交互 easylive-cloud-interact: 7073
  • 资源 easylive-cloud-resource: 7074
  • Redis: 6379
  • Minio: 9000(服务) + 9001(控制台)
  • RocketMQ/ES/Seata:按需启用(建议后置)

下面步骤直接可执行,按顺序来。

1) 安装 Docker & Compose(以 Ubuntu 20.04/22.04 为例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 1) 基础依赖
sudo apt-get update -y
sudo apt-get install -y ca-certificates curl gnupg lsb-release

# 2) Docker 仓库
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update -y

# 3) 安装
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 4) 免 sudo(重新登录生效)
sudo usermod -aG docker $USER

2) 目录结构与时区

1
2
3
4
sudo mkdir -p /opt/easylive/{mysql/data,mysql/init,redis,data,nacos,data,minio/data,nginx/conf.d,frontend/{web,admin},logs}
sudo mkdir -p /opt/easylive/{gateway,admin,web,interact,resource}/config
sudo mkdir -p /opt/easylive/{rocketmq/{namesrv,broker},es/data,seata}
sudo timedatectl set-timezone Asia/Shanghai

3) .env(放到 /opt/easylive/.env)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
TZ=Asia/Shanghai

# MySQL
MYSQL_ROOT_PASSWORD=YourStrongRootPass!
MYSQL_DATABASE=easylive

# Nacos
NACOS_VERSION=v2.2.0

# Minio
MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=YourStrongMinioPass!

# Java 内存建议(4G 机器尽量克制)
JAVA_XMS=256m
JAVA_XMX=512m

4) docker-compose.yml(放到 /opt/easylive/docker-compose.yml)

为节省内存,RocketMQ/ES/Seata 先注释,核心链路先跑通。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
version: "3.9"
name: easylive
networks:
easylive-net: {}

volumes:
mysql-data:
redis-data:
nacos-data:
minio-data:
es-data:

services:
mysql:
image: mysql:8.0
container_name: mysql
command:
- --default-authentication-plugin=mysql_native_password
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
environment:
- TZ=${TZ}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL","mysqladmin ping -uroot -p${MYSQL_ROOT_PASSWORD} | grep 'mysqld is alive'"]
interval: 10s
timeout: 5s
retries: 30
networks: [easylive-net]
restart: always

redis:
image: redis:6.2
container_name: redis
command: [ "redis-server", "--appendonly", "yes" ]
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks: [easylive-net]
restart: always

nacos:
image: nacos/nacos-server:${NACOS_VERSION}
container_name: nacos
environment:
- MODE=standalone
# 使用 MySQL 做持久化(推荐)
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=mysql
- MYSQL_SERVICE_DB_NAME=nacos_config
- MYSQL_SERVICE_PORT=3306
- MYSQL_SERVICE_USER=root
- MYSQL_SERVICE_PASSWORD=${MYSQL_ROOT_PASSWORD}
# JVM 缩小
- JVM_XMS=256m
- JVM_XMX=512m
- JVM_XMN=256m
- TZ=${TZ}
depends_on:
mysql:
condition: service_healthy
ports:
- "8848:8848"
networks: [easylive-net]
restart: always

minio:
image: minio/minio:RELEASE.2024-09-13T20-26-02Z
container_name: minio
environment:
- MINIO_ROOT_USER=${MINIO_ROOT_USER}
- MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
- TZ=${TZ}
command: server /data --console-address ":9001"
volumes:
- minio-data:/data
ports:
- "9000:9000"
- "9001:9001"
networks: [easylive-net]
restart: always

# 如无强依赖,先不启动下列服务,稳定后再启用
# rocketmq-namesrv:
# image: apache/rocketmq:5.2.0
# container_name: rmq-namesrv
# ports: ["9876:9876"]
# environment:
# - TZ=${TZ}
# - JAVA_OPT_EXT=-Xms256m -Xmx512m
# networks: [easylive-net]
# restart: always
#
# rocketmq-broker:
# image: apache/rocketmq:5.2.0
# container_name: rmq-broker
# environment:
# - NAMESRV_ADDR=rmq-namesrv:9876
# - TZ=${TZ}
# - JAVA_OPT_EXT=-Xms256m -Xmx512m
# depends_on: [rocketmq-namesrv]
# ports: ["10911:10911","10909:10909","10912:10912"]
# networks: [easylive-net]
# restart: always
#
# es:
# image: docker.elastic.co/elasticsearch/elasticsearch:7.17.22
# container_name: es
# environment:
# - discovery.type=single-node
# - xpack.security.enabled=false
# - ES_JAVA_OPTS=-Xms512m -Xmx512m
# - TZ=${TZ}
# ulimits:
# memlock:
# soft: -1
# hard: -1
# ports:
# - "9201:9200"
# volumes:
# - es-data:/usr/share/elasticsearch/data
# networks: [easylive-net]
# restart: always
#
# seata:
# image: seataio/seata-server:1.6.1
# container_name: seata
# environment:
# - SEATA_PORT=7091
# - TZ=${TZ}
# ports: ["7091:7091"]
# networks: [easylive-net]
# restart: always

# ------------------ 应用服务 ------------------
gateway:
image: easylive-cloud-gateway:latest
container_name: gateway
environment:
- TZ=${TZ}
- SERVER_PORT=7071
- SPRING_PROFILES_ACTIVE=dev
- SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR=nacos:8848
- SPRING_CLOUD_NACOS_CONFIG_SERVER_ADDR=nacos:8848
depends_on: [nacos]
ports: ["7071:7071"]
networks: [easylive-net]
restart: always

admin:
image: easylive-cloud-admin:latest
container_name: admin
environment:
- TZ=${TZ}
- SERVER_PORT=7070
- SPRING_PROFILES_ACTIVE=dev
- SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR=nacos:8848
- SPRING_CLOUD_NACOS_CONFIG_SERVER_ADDR=nacos:8848
# 覆盖数据库与 Redis(如 Nacos 未配置完整)
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/easylive?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=${MYSQL_ROOT_PASSWORD}
- SPRING_REDIS_HOST=redis
- SPRING_REDIS_PORT=6379
depends_on: [mysql, redis, nacos]
ports: ["7070:7070"]
networks: [easylive-net]
restart: always

web:
image: easylive-cloud-web:latest
container_name: web
environment:
- TZ=${TZ}
- SERVER_PORT=7072
- SPRING_PROFILES_ACTIVE=dev
- SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR=nacos:8848
- SPRING_CLOUD_NACOS_CONFIG_SERVER_ADDR=nacos:8848
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/easylive?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=${MYSQL_ROOT_PASSWORD}
- SPRING_REDIS_HOST=redis
- SPRING_REDIS_PORT=6379
depends_on: [mysql, redis, nacos]
ports: ["7072:7072"]
networks: [easylive-net]
restart: always

interact:
image: easylive-cloud-interact:latest
container_name: interact
environment:
- TZ=${TZ}
- SERVER_PORT=7073
- SPRING_PROFILES_ACTIVE=dev
- SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR=nacos:8848
- SPRING_CLOUD_NACOS_CONFIG_SERVER_ADDR=nacos:8848
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/easylive?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=${MYSQL_ROOT_PASSWORD}
- SPRING_REDIS_HOST=redis
- SPRING_REDIS_PORT=6379
depends_on: [mysql, redis, nacos]
ports: ["7073:7073"]
networks: [easylive-net]
restart: always

resource:
image: easylive-cloud-resource:latest
container_name: resource
environment:
- TZ=${TZ}
- SERVER_PORT=7074
- SPRING_PROFILES_ACTIVE=dev
- SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR=nacos:8848
- SPRING_CLOUD_NACOS_CONFIG_SERVER_ADDR=nacos:8848
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/easylive?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=${MYSQL_ROOT_PASSWORD}
- SPRING_REDIS_HOST=redis
- SPRING_REDIS_PORT=6379
# 如资源服务用到 Minio,请在 Nacos 配置或此处补充访问参数
# - MINIO_ENDPOINT=http://minio:9000
# - MINIO_ACCESS_KEY=${MINIO_ROOT_USER}
# - MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD}
# - MINIO_BUCKET=your-bucket
depends_on: [mysql, redis, nacos, minio]
ports: ["7074:7074"]
networks: [easylive-net]
restart: always

nginx:
image: nginx:1.25
container_name: nginx
depends_on: [gateway]
ports:
- "80:80"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./frontend/web:/usr/share/nginx/html
- ./frontend/admin:/usr/share/nginx/html/admin
networks: [easylive-net]
restart: always

5) 后端服务镜像构建

建议每个服务放一个最简 Dockerfile(以 easylive-cloud-gateway 为例):

1
2
3
4
5
6
7
# 放在 easylive-server/easylive-cloud/easylive-cloud-gateway/Dockerfile
FROM eclipse-temurin:8-jre
ENV TZ=Asia/Shanghai
WORKDIR /app
COPY target/*.jar app.jar
EXPOSE 7071
ENTRYPOINT ["java","-Xms${JAVA_XMS:-256m}","-Xmx${JAVA_XMX:-512m}","-jar","/app/app.jar"]

构建步骤(在你的仓库根目录执行;其他四个服务同理更换路径与镜像名/端口):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 打包全部(跳过测试)
cd /path/to/easylive-springcloud/easylive-server
./mvnw -v || mvn -v
mvn -DskipTests clean package

# 构建镜像(五个服务)
docker build -t easylive-cloud-gateway:latest \
easylive-cloud/easylive-cloud-gateway

docker build -t easylive-cloud-admin:latest \
easylive-cloud/easylive-cloud-admin

docker build -t easylive-cloud-web:latest \
easylive-cloud/easylive-cloud-web

docker build -t easylive-cloud-interact:latest \
easylive-cloud/easylive-cloud-interact

docker build -t easylive-cloud-resource:latest \
easylive-cloud/easylive-cloud-resource

注意:

  • 端口通过 SERVER_PORT 覆盖为 7071/7070/7072/7073/7074,跟你的表一致。
  • Nacos 地址在容器间为 nacos:8848(已在 compose 中用环境变量覆盖)。
  • 数据库/Redis 在容器间为 mysql:3306redis:6379

6) Nginx 反代与前端

/opt/easylive/nginx/conf.d/easylive.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
server {
listen 80;
server_name _;

# 用户端 Web 静态
root /usr/share/nginx/html;
index index.html;

# 管理端静态(访问 /admin/)
location /admin/ {
alias /usr/share/nginx/html/admin/;
try_files $uri $uri/ /admin/index.html;
}

# 反向代理到网关(和 gateway 的路由保持一致)
location /web/ { proxy_pass http://gateway:7071/web/; }
location /interact/ { proxy_pass http://gateway:7071/interact/; }
location /user/ { proxy_pass http://gateway:7071/user/; }
location /file/ { proxy_pass http://gateway:7071/file/; }
location /adminapi/ { proxy_pass http://gateway:7071/admin/; } # 避免静态路径冲突,给管理端 API 换前缀

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

构建前端并拷贝静态资源:

1
2
3
4
5
6
7
8
9
10
11
12
# 用户端
cd /path/to/easylive-springcloud/easylive-front/easylive-front-web
npm ci || npm install
npm run build
sudo cp -r dist/* /opt/easylive/frontend/web/

# 管理端
cd /path/to/easylive-springcloud/easylive-front/easylive-front-admin
npm ci || npm install
npm run build
sudo mkdir -p /opt/easylive/frontend/admin
sudo cp -r dist/* /opt/easylive/frontend/admin/

如前端请求网关的基地址可配置,建议改为相对路径并按上面 Nginx 反代规则访问。

7) Minio 初始化(可选)

1
2
3
4
5
docker run --rm --network easylive_easylive-net -it \
minio/mc sh -c "
mc alias set minio http://minio:9000 ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD} && \
mc mb -p minio/easylive && \
mc anonymous set download minio/easylive"

8) Nacos 配置

  • 访问 http://服务器IP:8848/nacos,默认无鉴权或按镜像默认设置。
  • 为每个服务新增配置:
    • easylive-cloud-admin-dev.yml
    • easylive-cloud-web-dev.yml
    • easylive-cloud-interact-dev.yml
    • easylive-cloud-resource-dev.yml
    • 内容至少包含数据库与 Redis 连接(参考你仓库中 dev yml,将 host 从 127.0.0.1 改为 mysqlredis):
1
2
3
4
5
6
7
8
spring:
datasource:
url: jdbc:mysql://mysql:3306/easylive?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
username: root
password: ${MYSQL_ROOT_PASSWORD}
redis:
host: redis
port: 6379
  • 资源服务若使用 Minio,请在对应 yml 增加 Minio 配置项(按你项目属性命名),指向 http://minio:9000

9) 启动与验证

1
2
3
4
5
6
7
8
9
cd /opt/easylive
docker compose pull # 第一次可忽略
docker compose up -d # 启动
docker compose ps # 查看状态
docker logs -f gateway
docker logs -f admin
docker logs -f web
docker logs -f interact
docker logs -f resource
  • 浏览器访问:
    • Nacos: http://服务器IP:8848/nacos
    • Minio: http://服务器IP:9001
    • 前端: http://服务器IP/(用户端)与 http://服务器IP/admin/(管理端)
  • 后端连通性:网关 http://服务器IP:7071 下的 /web/**/interact/**/user/**/file/**/admin/**

10) 域名与 HTTPS(可选快速)

  • 用 Nginx + Certbot:
1
2
3
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your.domain.com -m your@email \
--agree-tos --no-eff-email --redirect
  • 或用 Caddy(更简单,自动签发):将 Nginx 换成 caddy:2,用 Caddyfile 一行反代网关和静态。

11) 常见资源与优化建议

  • 4G 机器内存紧张:先不上 RocketMQ/ES/Seata,JVM 堆保持 -Xms256m -Xmx512m;Nacos JVM 也已收敛。
  • MySQL/ES/Minio 数据请使用卷持久化(compose 已配置)。
  • 日志落盘到容器 stdout,建议再配 ELK/Vector 后续接入。

你现在可以按以上顺序执行;如果遇到端口/内存/配置问题,发我报错我继续帮你排查。

  • 我已经完成部署方案选择与全部步骤指引,包含 .envdocker-compose.yml、后端 Dockerfile、Nginx 反代与初始化要点。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 1) 基础依赖
sudo apt-get update -y
sudo apt-get install -y ca-certificates curl gnupg lsb-release

# 2) Docker 仓库
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update -y

# 3) 安装
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 4) 免 sudo(重新登录生效)
sudo usermod -aG docker $USER
1
2
3
4
sudo mkdir -p /opt/easylive/{mysql/data,mysql/init,redis,data,nacos,data,minio/data,nginx/conf.d,frontend/{web,admin},logs}
sudo mkdir -p /opt/easylive/{gateway,admin,web,interact,resource}/config
sudo mkdir -p /opt/easylive/{rocketmq/{namesrv,broker},es/data,seata}
sudo timedatectl set-timezone Asia/Shanghai
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
TZ=Asia/Shanghai

# MySQL
MYSQL_ROOT_PASSWORD=YourStrongRootPass!
MYSQL_DATABASE=easylive

# Nacos
NACOS_VERSION=v2.2.0

# Minio
MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=YourStrongMinioPass!

# Java 内存建议(4G 机器尽量克制)
JAVA_XMS=256m
JAVA_XMX=512m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
version: "3.9"
name: easylive
networks:
easylive-net: {}

volumes:
mysql-data:
redis-data:
nacos-data:
minio-data:
es-data:

services:
mysql:
image: mysql:8.0
container_name: mysql
command:
- --default-authentication-plugin=mysql_native_password
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
environment:
- TZ=${TZ}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL","mysqladmin ping -uroot -p${MYSQL_ROOT_PASSWORD} | grep 'mysqld is alive'"]
interval: 10s
timeout: 5s
retries: 30
networks: [easylive-net]
restart: always

redis:
image: redis:6.2
container_name: redis
command: [ "redis-server", "--appendonly", "yes" ]
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks: [easylive-net]
restart: always

nacos:
image: nacos/nacos-server:${NACOS_VERSION}
container_name: nacos
environment:
- MODE=standalone
# 使用 MySQL 做持久化(推荐)
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=mysql
- MYSQL_SERVICE_DB_NAME=nacos_config
- MYSQL_SERVICE_PORT=3306
- MYSQL_SERVICE_USER=root
- MYSQL_SERVICE_PASSWORD=${MYSQL_ROOT_PASSWORD}
# JVM 缩小
- JVM_XMS=256m
- JVM_XMX=512m
- JVM_XMN=256m
- TZ=${TZ}
depends_on:
mysql:
condition: service_healthy
ports:
- "8848:8848"
networks: [easylive-net]
restart: always

minio:
image: minio/minio:RELEASE.2024-09-13T20-26-02Z
container_name: minio
environment:
- MINIO_ROOT_USER=${MINIO_ROOT_USER}
- MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
- TZ=${TZ}
command: server /data --console-address ":9001"
volumes:
- minio-data:/data
ports:
- "9000:9000"
- "9001:9001"
networks: [easylive-net]
restart: always

# 如无强依赖,先不启动下列服务,稳定后再启用
# rocketmq-namesrv:
# image: apache/rocketmq:5.2.0
# container_name: rmq-namesrv
# ports: ["9876:9876"]
# environment:
# - TZ=${TZ}
# - JAVA_OPT_EXT=-Xms256m -Xmx512m
# networks: [easylive-net]
# restart: always
#
# rocketmq-broker:
# image: apache/rocketmq:5.2.0
# container_name: rmq-broker
# environment:
# - NAMESRV_ADDR=rmq-namesrv:9876
# - TZ=${TZ}
# - JAVA_OPT_EXT=-Xms256m -Xmx512m
# depends_on: [rocketmq-namesrv]
# ports: ["10911:10911","10909:10909","10912:10912"]
# networks: [easylive-net]
# restart: always
#
# es:
# image: docker.elastic.co/elasticsearch/elasticsearch:7.17.22
# container_name: es
# environment:
# - discovery.type=single-node
# - xpack.security.enabled=false
# - ES_JAVA_OPTS=-Xms512m -Xmx512m
# - TZ=${TZ}
# ulimits:
# memlock:
# soft: -1
# hard: -1
# ports:
# - "9201:9200"
# volumes:
# - es-data:/usr/share/elasticsearch/data
# networks: [easylive-net]
# restart: always
#
# seata:
# image: seataio/seata-server:1.6.1
# container_name: seata
# environment:
# - SEATA_PORT=7091
# - TZ=${TZ}
# ports: ["7091:7091"]
# networks: [easylive-net]
# restart: always

# ------------------ 应用服务 ------------------
gateway:
image: easylive-cloud-gateway:latest
container_name: gateway
environment:
- TZ=${TZ}
- SERVER_PORT=7071
- SPRING_PROFILES_ACTIVE=dev
- SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR=nacos:8848
- SPRING_CLOUD_NACOS_CONFIG_SERVER_ADDR=nacos:8848
depends_on: [nacos]
ports: ["7071:7071"]
networks: [easylive-net]
restart: always

admin:
image: easylive-cloud-admin:latest
container_name: admin
environment:
- TZ=${TZ}
- SERVER_PORT=7070
- SPRING_PROFILES_ACTIVE=dev
- SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR=nacos:8848
- SPRING_CLOUD_NACOS_CONFIG_SERVER_ADDR=nacos:8848
# 覆盖数据库与 Redis(如 Nacos 未配置完整)
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/easylive?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=${MYSQL_ROOT_PASSWORD}
- SPRING_REDIS_HOST=redis
- SPRING_REDIS_PORT=6379
depends_on: [mysql, redis, nacos]
ports: ["7070:7070"]
networks: [easylive-net]
restart: always

web:
image: easylive-cloud-web:latest
container_name: web
environment:
- TZ=${TZ}
- SERVER_PORT=7072
- SPRING_PROFILES_ACTIVE=dev
- SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR=nacos:8848
- SPRING_CLOUD_NACOS_CONFIG_SERVER_ADDR=nacos:8848
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/easylive?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=${MYSQL_ROOT_PASSWORD}
- SPRING_REDIS_HOST=redis
- SPRING_REDIS_PORT=6379
depends_on: [mysql, redis, nacos]
ports: ["7072:7072"]
networks: [easylive-net]
restart: always

interact:
image: easylive-cloud-interact:latest
container_name: interact
environment:
- TZ=${TZ}
- SERVER_PORT=7073
- SPRING_PROFILES_ACTIVE=dev
- SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR=nacos:8848
- SPRING_CLOUD_NACOS_CONFIG_SERVER_ADDR=nacos:8848
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/easylive?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=${MYSQL_ROOT_PASSWORD}
- SPRING_REDIS_HOST=redis
- SPRING_REDIS_PORT=6379
depends_on: [mysql, redis, nacos]
ports: ["7073:7073"]
networks: [easylive-net]
restart: always

resource:
image: easylive-cloud-resource:latest
container_name: resource
environment:
- TZ=${TZ}
- SERVER_PORT=7074
- SPRING_PROFILES_ACTIVE=dev
- SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR=nacos:8848
- SPRING_CLOUD_NACOS_CONFIG_SERVER_ADDR=nacos:8848
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/easylive?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=${MYSQL_ROOT_PASSWORD}
- SPRING_REDIS_HOST=redis
- SPRING_REDIS_PORT=6379
# 如资源服务用到 Minio,请在 Nacos 配置或此处补充访问参数
# - MINIO_ENDPOINT=http://minio:9000
# - MINIO_ACCESS_KEY=${MINIO_ROOT_USER}
# - MINIO_SECRET_KEY=${MINIO_ROOT_PASSWORD}
# - MINIO_BUCKET=your-bucket
depends_on: [mysql, redis, nacos, minio]
ports: ["7074:7074"]
networks: [easylive-net]
restart: always

nginx:
image: nginx:1.25
container_name: nginx
depends_on: [gateway]
ports:
- "80:80"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./frontend/web:/usr/share/nginx/html
- ./frontend/admin:/usr/share/nginx/html/admin
networks: [easylive-net]
restart: always
1
2
3
4
5
6
7
# 放在 easylive-server/easylive-cloud/easylive-cloud-gateway/Dockerfile
FROM eclipse-temurin:8-jre
ENV TZ=Asia/Shanghai
WORKDIR /app
COPY target/*.jar app.jar
EXPOSE 7071
ENTRYPOINT ["java","-Xms${JAVA_XMS:-256m}","-Xmx${JAVA_XMX:-512m}","-jar","/app/app.jar"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 打包全部(跳过测试)
cd /path/to/easylive-springcloud/easylive-server
./mvnw -v || mvn -v
mvn -DskipTests clean package

# 构建镜像(五个服务)
docker build -t easylive-cloud-gateway:latest \
easylive-cloud/easylive-cloud-gateway

docker build -t easylive-cloud-admin:latest \
easylive-cloud/easylive-cloud-admin

docker build -t easylive-cloud-web:latest \
easylive-cloud/easylive-cloud-web

docker build -t easylive-cloud-interact:latest \
easylive-cloud/easylive-cloud-interact

docker build -t easylive-cloud-resource:latest \
easylive-cloud/easylive-cloud-resource
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
server {
listen 80;
server_name _;

# 用户端 Web 静态
root /usr/share/nginx/html;
index index.html;

# 管理端静态(访问 /admin/)
location /admin/ {
alias /usr/share/nginx/html/admin/;
try_files $uri $uri/ /admin/index.html;
}

# 反向代理到网关(和 gateway 的路由保持一致)
location /web/ { proxy_pass http://gateway:7071/web/; }
location /interact/ { proxy_pass http://gateway:7071/interact/; }
location /user/ { proxy_pass http://gateway:7071/user/; }
location /file/ { proxy_pass http://gateway:7071/file/; }
location /adminapi/ { proxy_pass http://gateway:7071/admin/; } # 避免静态路径冲突,给管理端 API 换前缀

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
1
2
3
4
5
6
7
8
9
10
11
12
# 用户端
cd /path/to/easylive-springcloud/easylive-front/easylive-front-web
npm ci || npm install
npm run build
sudo cp -r dist/* /opt/easylive/frontend/web/

# 管理端
cd /path/to/easylive-springcloud/easylive-front/easylive-front-admin
npm ci || npm install
npm run build
sudo mkdir -p /opt/easylive/frontend/admin
sudo cp -r dist/* /opt/easylive/frontend/admin/
1
2
3
4
5
docker run --rm --network easylive_easylive-net -it \
minio/mc sh -c "
mc alias set minio http://minio:9000 ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD} && \
mc mb -p minio/easylive && \
mc anonymous set download minio/easylive"
1
2
3
4
5
6
7
8
spring:
datasource:
url: jdbc:mysql://mysql:3306/easylive?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
username: root
password: ${MYSQL_ROOT_PASSWORD}
redis:
host: redis
port: 6379
1
2
3
4
5
6
7
8
9
cd /opt/easylive
docker compose pull # 第一次可忽略
docker compose up -d # 启动
docker compose ps # 查看状态
docker logs -f gateway
docker logs -f admin
docker logs -f web
docker logs -f interact
docker logs -f resource
1
2
3
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your.domain.com -m your@email \
--agree-tos --no-eff-email --redirect

User

4核8g的服务器是否够用能把所有的环境都配上呢,保险起见我是不是应该换个4核8g的服务器


Cursor

结论先说:

  • 4核8G基本能把全套(MySQL/Redis/Nacos/Minio/ES/RocketMQ/Seata + 5个Java服务 + 网关)跑起来,但比较“紧”,需要严格限内存与低负载场景,属于可用但不太宽裕。
  • 若计划“全部组件长期开启 + 有一定并发”,建议至少换到4核8G;若要更稳,优先把 ES 或 RocketMQ 单独拆机,或直接上更高规格(如8核16G)。

快速内存预算(保守建议,单位≈GiB):

  • Nacos: 0.5
  • MySQL: 0.5–1.0(取决于 innodb_buffer_pool_size)
  • Redis: 0.1–0.3
  • Minio: 0.3–0.5
  • RocketMQ: 0.8–1.2(namesrv 0.3–0.5,broker 0.5–0.7)
  • Elasticsearch: 1.0–2.0(堆1–2G,且需 vm.max_map_count)
  • Seata: 0.3–0.5
  • 5个SpringBoot服务: 1.3–2.5(每个 256–512M)
  • 合计:约 5.3–8.5G(随设置和负载浮动)
    => 4核8G在“全部开启”时边缘可用,需非常克制的JVM与DB配置。

给你两种选择:

  • 想省事稳一点:换成4核8G(或更高),然后严格控内存即可全开;更理想是把 ES 或 RocketMQ 独立出去。
  • 先不换服务器:保留4核4G/8G,只启核心链路(MySQL/Redis/Nacos/Minio/网关+业务服务),把 ES/RocketMQ/Seata 暂时关闭或托管到云上,等业务量起来再扩。

若坚持在4核8G全开运行,务必:

  • JVM:所有Java进程统一 -Xms256m -Xmx512m(Nacos、各微服务、Seata、RocketMQ),ES 堆设 1G 起步。
  • MySQL:innodb_buffer_pool_size 512M 起;慢慢再调大。
  • 开启2–4G swap 兜底(仅兜底,不可依赖)。
  • 用 docker-compose 限制每个容器内存并监控 docker stats。
  • 优先上线无强依赖的路径;ES/RocketMQ 负载上来后优先拆分或升配。

简短建议:

  • 如果你希望“一台机全家桶 + 可留有余量”,我建议换到4核8G(更稳)或把 ES/RocketMQ 外置/托管。
  • 如果是演示/低QPS场景,4核8G可行;4核4G就建议按我给的最小化编排先跑核心链路。