feat(deploy): Add 1Panel deployment configuration

- Add Docker Compose stack for single-server 1Panel deployments
- Add backend and frontend Dockerfiles for 1Panel builds
- Add Nginx and RocketMQ configuration for container orchestration
- Document required environment variables and deployment steps
This commit is contained in:
2026-08-03 20:00:32 +08:00
parent ec08426fbd
commit 0cb6a49aa5
9 changed files with 1171 additions and 0 deletions
+402
View File
@@ -0,0 +1,402 @@
# HAOVP 1Panel 单机部署指南
本文档面向一台服务器上的 1Panel 部署。目标是用 1Panel 的容器编排启动后端、基础设施、前端 Nginx,并用 1Panel 网站/OpenResty 对外提供域名访问。
## 1. 部署结构
默认编排文件:
```text
backend/docker-compose.1panel.yml
```
配套文件:
```text
backend/.env.1panel.example
backend/Dockerfile.service.1panel
backend/config/rocketmq/broker-1panel.conf
frontend/video-frontend-web/Dockerfile.1panel
frontend/video-frontend-web/deploy/nginx.1panel.conf
frontend/video-frontend-admin/Dockerfile.1panel
frontend/video-frontend-admin/deploy/nginx.1panel.conf
```
默认服务分层:
| 层级 | 服务 |
| --- | --- |
| 基础设施 | MySQL, Redis, Redis Sentinel, Nacos, RocketMQ, MinIO, Sentinel Dashboard |
| 后端 | video-gateway, video-auth, video-user, video-content, video-comment, video-recommend, video-admin |
| 前端 | frontend-web, frontend-admin |
| 可选监控 | Prometheus, Grafana, exporters,默认不启动 |
## 2. 服务器要求
建议配置:
| 用途 | 建议 |
| --- | --- |
| CPU | 最低 4 核,建议 8 核 |
| 内存 | 最低 8 GB,建议 16 GB |
| 磁盘 | 最低 80 GB,视频上传环境建议更大 |
| 系统 | Debian 12 / Ubuntu 22.04+ / CentOS Stream 类系统 |
1Panel 需已安装 Docker 和 OpenResty。首次构建后端镜像会下载 Maven 依赖,耗时较长。
## 3. 端口策略
1Panel 版默认不直接占用公网 `80/443`,避免和 1Panel OpenResty 冲突。
默认端口绑定:
| 服务 | 宿主机绑定 | 说明 |
| --- | --- | --- |
| 用户前端 | `127.0.0.1:18080` | 给 1Panel 网站反代 |
| 管理前端 | `127.0.0.1:18081` | 给 1Panel 网站反代 |
| API Gateway | `127.0.0.1:9000` | 调试用,不建议公网开放 |
| Nacos | `127.0.0.1:8848` | 控制台,仅本机 |
| MinIO API | `127.0.0.1:9100` | 对象存储 API,仅本机 |
| MinIO Console | `127.0.0.1:9101` | 控制台,仅本机 |
| Sentinel | `127.0.0.1:8880` | 控制台,仅本机 |
| Prometheus | `127.0.0.1:9090` | 可选监控 |
| Grafana | `127.0.0.1:3000` | 可选监控 |
生产环境防火墙建议只放行:
```text
80/tcp
443/tcp
1Panel 面板端口
SSH 端口
```
不要把 MySQL、Redis、Nacos、RocketMQ、MinIO Console 直接暴露到公网。
如确需临时从外部访问前端容器端口,可在 `.env.1panel` 中把:
```env
FRONTEND_BIND_ADDR=127.0.0.1
```
改为:
```env
FRONTEND_BIND_ADDR=0.0.0.0
```
不建议在生产长期这样配置。
## 4. 上传项目
在服务器上准备项目目录,例如:
```bash
cd /opt
git clone <你的仓库地址> HAOVP
cd /opt/HAOVP/backend
```
如果通过 1Panel 文件管理上传压缩包,保证目录结构仍然是:
```text
/opt/HAOVP/backend
/opt/HAOVP/frontend
```
因为 `docker-compose.1panel.yml` 会从 `../frontend/...` 构建前端镜像。
## 5. 配置环境变量
复制示例文件:
```bash
cd /opt/HAOVP/backend
cp .env.1panel.example .env.1panel
```
必须修改这些值:
```env
MYSQL_ROOT_PASSWORD=强密码
MYSQL_APP_PASSWORD=强密码
REDIS_PASSWORD=强密码
MINIO_SECRET_KEY=强密码
USER_JWT_SECRET=至少32字节随机字符串
ADMIN_JWT_SECRET=至少32字节随机字符串
SERVICE_AUTH_TOKEN=至少32字节随机字符串
ADMIN_INIT_PASSWORD=后台管理员初始密码
NACOS_AUTH_TOKEN=至少32字节随机字符串
GRAFANA_ADMIN_PASSWORD=强密码
```
首次部署建议保持:
```env
NACOS_USERNAME=nacos
NACOS_PASSWORD=nacos
```
原因:Nacos 默认初始化用户是 `nacos/nacos`。如果想改 Nacos 密码,先部署成功,再进入 Nacos 控制台修改用户密码,并同步更新 `.env.1panel` 后重启后端微服务。
## 6. 在 1Panel 创建编排
进入 1Panel:
```text
容器 -> 编排 -> 创建编排
```
推荐配置:
| 项 | 值 |
| --- | --- |
| 名称 | `haovp-1panel` |
| 工作目录 | `/opt/HAOVP/backend` |
| Compose 文件 | `docker-compose.1panel.yml` |
| 环境变量文件 | `.env.1panel` |
创建后启动编排。
首次构建会执行:
| 镜像 | 构建内容 |
| --- | --- |
| 后端微服务 | Maven 多阶段构建 |
| 用户前端 | Node 构建 Vue/Vite,然后 Nginx 托管 |
| 管理前端 | Node 构建 Vue/Vite,然后 Nginx 托管 |
| Sentinel Dashboard | 下载并打包 Sentinel Dashboard |
如果服务器网络访问 Maven/npm/Docker Hub 较慢,首次构建可能需要较长时间。
## 7. 配置 1Panel 网站反代
推荐用两个域名:
```text
www.example.com -> 用户端
admin.example.com -> 管理端
```
### 用户端
在 1Panel 创建反向代理网站:
| 项 | 值 |
| --- | --- |
| 主域名 | `www.example.com` |
| 代理地址 | `http://127.0.0.1:18080` |
### 管理端
在 1Panel 创建反向代理网站:
| 项 | 值 |
| --- | --- |
| 主域名 | `admin.example.com` |
| 代理地址 | `http://127.0.0.1:18081` |
然后在两个网站里申请 HTTPS 证书。
前端容器内部已经处理:
| 路径 | 转发目标 |
| --- | --- |
| 用户端 `/api/*` | `video-gateway:9000/*` |
| 管理端 `/api/admin/*` | `video-gateway:9000/admin/*` |
| `/media/*` | `minio:9000/*` |
所以 1Panel OpenResty 只需要代理到前端容器端口,不需要再单独配置 `/api`。
## 8. 启动验证
在服务器执行:
```bash
cd /opt/HAOVP/backend
docker compose --env-file .env.1panel -f docker-compose.1panel.yml ps
```
查看关键日志:
```bash
docker logs -f haovp-mysql
docker logs -f haovp-nacos
docker logs -f haovp-video-gateway
docker logs -f haovp-video-content
```
本机健康检查:
```bash
curl http://127.0.0.1:18080/health
curl http://127.0.0.1:18081/health
curl http://127.0.0.1:9000/actuator/health
```
浏览器访问:
```text
https://www.example.com
https://admin.example.com
```
Nacos 控制台仅建议本机 SSH 隧道或 1Panel 终端访问:
```text
http://127.0.0.1:8848/nacos
```
## 9. 可选启用监控
默认不会启动 Prometheus/Grafana,节省单机资源。
命令行启用:
```bash
cd /opt/HAOVP/backend
COMPOSE_PROFILES=monitoring docker compose --env-file .env.1panel -f docker-compose.1panel.yml up -d
```
1Panel 中可在环境变量里增加:
```env
COMPOSE_PROFILES=monitoring
```
Grafana 默认本机端口:
```text
http://127.0.0.1:3000
```
不建议直接公网开放 Grafana。
## 10. 更新部署
拉取代码后重新构建:
```bash
cd /opt/HAOVP
git pull
cd backend
docker compose --env-file .env.1panel -f docker-compose.1panel.yml up -d --build
```
只重启某个服务:
```bash
docker compose --env-file .env.1panel -f docker-compose.1panel.yml restart video-gateway
```
查看资源占用:
```bash
docker stats
```
## 11. 数据备份
先加载部署环境变量:
```bash
cd /opt/HAOVP/backend
set -a
source .env.1panel
set +a
```
MySQL:
```bash
docker exec haovp-mysql mysqldump -uroot -p"$MYSQL_ROOT_PASSWORD" --all-databases > haovp_mysql_$(date +%F).sql
```
Redis:
```bash
docker exec haovp-redis redis-cli -a "$REDIS_PASSWORD" BGSAVE
docker cp haovp-redis:/data/dump.rdb haovp_redis_$(date +%F).rdb
```
MinIO:
```bash
docker run --rm --network haovp-1panel_haovp-network -v "$PWD/backup:/backup" minio/mc sh -c \
"mc alias set local http://minio:9000 $MINIO_ACCESS_KEY $MINIO_SECRET_KEY && mc mirror local/$MINIO_BUCKET /backup/$MINIO_BUCKET"
```
也可以直接备份 Docker volume,但数据库类服务建议优先使用逻辑备份。
## 12. 常见问题
### 首次启动很慢
后端镜像会在 Docker 构建阶段执行 Maven 构建,前端镜像会执行 npm 构建。国内服务器建议提前配置 Docker、Maven、npm 镜像源,或在 CI 中构建镜像后推送到私有镜像仓库。
### 后端连接 RocketMQ 失败
1Panel 版已使用单机配置:
```text
backend/config/rocketmq/broker-1panel.conf
NAMESRV_ADDR=rmqnamesrv:9876
```
如果仍失败,检查:
```bash
docker logs haovp-rmqnamesrv
docker logs haovp-rmqbroker
docker logs haovp-video-content
```
### 前端接口 404
确认前端环境变量没有改错:
| 前端 | 构建参数 |
| --- | --- |
| 用户端 | `VITE_API_BASE_URL=/api` |
| 管理端 | `VITE_API_BASE_URL=/api/admin` |
前端 Nginx 会把用户端 `/api/auth/login` 转发为网关 `/auth/login`,把管理端 `/api/admin/auth/login` 转发为网关 `/admin/auth/login`。
### 图片或视频无法访问
前端使用:
```text
VITE_MEDIA_BASE_URL=/media/video-platform
```
前端 Nginx 会把 `/media/video-platform/...` 转发到 MinIO 的 `/video-platform/...`。确认 `minio-init` 已成功创建 bucket:
```bash
docker logs haovp-minio-init
```
### Nacos 密码修改后服务启动失败
如果在 Nacos 控制台改了 `nacos` 用户密码,必须同步修改 `.env.1panel`:
```env
NACOS_PASSWORD=新密码
```
然后重启后端服务:
```bash
docker compose --env-file .env.1panel -f docker-compose.1panel.yml restart video-gateway video-auth video-user video-content video-comment video-recommend video-admin
```
### 内存不足
降低 `.env.1panel` 中各服务 JVM 参数,例如:
```env
CONTENT_JAVA_OPTS=-Xms128m -Xmx384m
AUTH_JAVA_OPTS=-Xms96m -Xmx192m
```
同时不要启用 `monitoring` profile。
+41
View File
@@ -0,0 +1,41 @@
MYSQL_ROOT_PASSWORD=change-me-mysql-root-password
MYSQL_APP_USER=video
MYSQL_APP_PASSWORD=change-me-mysql-app-password
REDIS_PASSWORD=change-me-redis-password
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=change-me-minio-secret-password
MINIO_BUCKET=video-platform
USER_JWT_SECRET=change-me-user-jwt-secret-at-least-32-bytes
ADMIN_JWT_SECRET=change-me-admin-jwt-secret-at-least-32-bytes
SERVICE_AUTH_TOKEN=change-me-internal-service-token-at-least-32-bytes
ADMIN_INIT_PASSWORD=change-me-admin-initial-password
JWT_EXPIRATION=86400
NACOS_USERNAME=nacos
NACOS_PASSWORD=nacos
NACOS_AUTH_TOKEN=change-me-nacos-auth-token-at-least-32-bytes-long
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=change-me-grafana-password
LOCAL_BIND_ADDR=127.0.0.1
FRONTEND_BIND_ADDR=127.0.0.1
WEB_HTTP_PORT=18080
ADMIN_HTTP_PORT=18081
GATEWAY_HTTP_PORT=9000
NACOS_HTTP_PORT=8848
MINIO_API_PORT=9100
MINIO_CONSOLE_PORT=9101
SENTINEL_HTTP_PORT=8880
PROMETHEUS_HTTP_PORT=9090
GRAFANA_HTTP_PORT=3000
GATEWAY_JAVA_OPTS=-Xms128m -Xmx256m
AUTH_JAVA_OPTS=-Xms128m -Xmx256m
USER_JAVA_OPTS=-Xms128m -Xmx256m
CONTENT_JAVA_OPTS=-Xms256m -Xmx512m
COMMENT_JAVA_OPTS=-Xms128m -Xmx256m
RECOMMEND_JAVA_OPTS=-Xms128m -Xmx256m
ADMIN_JAVA_OPTS=-Xms128m -Xmx256m
+31
View File
@@ -0,0 +1,31 @@
# syntax=docker/dockerfile:1
FROM maven:3.9-eclipse-temurin-17 AS build
WORKDIR /workspace
COPY . .
ARG MODULE
RUN mvn -pl "${MODULE}" -am package -Dmaven.test.skip=true
FROM eclipse-temurin:17-jre
ARG MODULE
ARG JAR_PREFIX
ARG INSTALL_FFMPEG=false
RUN if [ "$INSTALL_FFMPEG" = "true" ]; then \
apt-get update && \
apt-get install -y --no-install-recommends ffmpeg && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*; \
fi
WORKDIR /app
COPY --from=build /workspace/${MODULE}/target/${JAR_PREFIX}-*.jar /app/app.jar
ENV JAVA_OPTS=""
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /app/app.jar"]
@@ -0,0 +1,23 @@
brokerClusterName = DefaultCluster
brokerName = broker-single
brokerId = 0
namesrvAddr = rmqnamesrv:9876
listenPort = 10911
storePathRootDir = /home/rocketmq/store
sendMessageThreadPoolNums = 8
pullMessageThreadPoolNums = 8
queryMessageThreadPoolNums = 4
flushDiskType = ASYNC_FLUSH
brokerRole = ASYNC_MASTER
fileReservedTime = 72
mapedFileSizeCommitLog = 1073741824
mapedFileSizeConsumeQueue = 300000
autoCreateTopicEnable = true
autoCreateSubscriptionGroup = true
maxMessageSize = 4194304
+542
View File
@@ -0,0 +1,542 @@
name: haovp-1panel
x-common-env: &common-env
TZ: Asia/Shanghai
x-service-env: &service-env
<<: *common-env
SPRING_PROFILES_ACTIVE: ha
NACOS_HOST: nacos
NACOS_PORT: 8848
NACOS_USERNAME: ${NACOS_USERNAME:-nacos}
NACOS_PASSWORD: ${NACOS_PASSWORD:-nacos}
SPRING_CLOUD_NACOS_DISCOVERY_USERNAME: ${NACOS_USERNAME:-nacos}
SPRING_CLOUD_NACOS_DISCOVERY_PASSWORD: ${NACOS_PASSWORD:-nacos}
SPRING_CLOUD_NACOS_CONFIG_USERNAME: ${NACOS_USERNAME:-nacos}
SPRING_CLOUD_NACOS_CONFIG_PASSWORD: ${NACOS_PASSWORD:-nacos}
MYSQL_HOST: mysql
MYSQL_PORT: 3306
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_PASSWORD: ${MYSQL_ROOT_PASSWORD}
REDIS_PASSWORD: ${REDIS_PASSWORD}
REDIS_SENTINEL_NODES: redis-sentinel:26379
SERVICE_AUTH_TOKEN: ${SERVICE_AUTH_TOKEN}
JWT_EXPIRATION: ${JWT_EXPIRATION:-86400}
SENTINEL_DASHBOARD_HOST: sentinel
SENTINEL_DASHBOARD_PORT: 8080
x-backend-build: &backend-build
context: .
dockerfile: Dockerfile.service.1panel
services:
mysql:
image: mysql:8.0
container_name: haovp-mysql
restart: unless-stopped
environment:
<<: *common-env
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: video_platform
MYSQL_USER: ${MYSQL_APP_USER:-video}
MYSQL_PASSWORD: ${MYSQL_APP_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
- ./sql/init.sql:/docker-entrypoint-initdb.d/01-init.sql:ro
- ./sql/nacos-schema.sql:/docker-entrypoint-initdb.d/02-nacos-schema.sql:ro
- ./sql/03-nacos-config-init.sh:/docker-entrypoint-initdb.d/03-nacos-config-init.sh:ro
- ./sql/nacos-config-init.sql:/init-sql/nacos-config-init.sql:ro
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --default-authentication-plugin=mysql_native_password
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p${MYSQL_ROOT_PASSWORD}"]
interval: 10s
timeout: 5s
retries: 15
networks:
- haovp-network
redis:
image: redis:7.0-alpine
container_name: haovp-redis
restart: unless-stopped
command: redis-server --requirepass ${REDIS_PASSWORD} --appendonly yes
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
interval: 10s
timeout: 5s
retries: 10
networks:
- haovp-network
redis-sentinel:
image: redis:7.0-alpine
container_name: haovp-redis-sentinel
restart: unless-stopped
volumes:
- redis_sentinel_data:/data
- ./config/redis/sentinel-single.conf:/usr/local/etc/redis/sentinel.conf:ro
command: sh -c "sed \"s/__REDIS_PASSWORD__/${REDIS_PASSWORD}/g\" /usr/local/etc/redis/sentinel.conf > /data/sentinel.conf && redis-sentinel /data/sentinel.conf"
depends_on:
redis:
condition: service_healthy
networks:
- haovp-network
nacos:
image: nacos/nacos-server:v2.3.2
container_name: haovp-nacos
restart: unless-stopped
environment:
<<: *common-env
MODE: standalone
SPRING_DATASOURCE_PLATFORM: mysql
MYSQL_SERVICE_HOST: mysql
MYSQL_SERVICE_PORT: 3306
MYSQL_SERVICE_DB_NAME: nacos_config
MYSQL_SERVICE_USER: root
MYSQL_SERVICE_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_SERVICE_DB_PARAM: characterEncoding=utf8&connectTimeout=10000&socketTimeout=30000&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
JVM_XMS: ${NACOS_JVM_XMS:-512m}
JVM_XMX: ${NACOS_JVM_XMX:-512m}
NACOS_AUTH_ENABLE: "true"
NACOS_AUTH_TOKEN: ${NACOS_AUTH_TOKEN}
NACOS_AUTH_IDENTITY_KEY: serverIdentity
NACOS_AUTH_IDENTITY_VALUE: security
PREFER_HOST_MODE: hostname
ports:
- "${LOCAL_BIND_ADDR:-127.0.0.1}:${NACOS_HTTP_PORT:-8848}:8848"
depends_on:
mysql:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8848/nacos/v1/console/health/liveness"]
interval: 10s
timeout: 5s
retries: 15
networks:
- haovp-network
rmqnamesrv:
image: apache/rocketmq:5.1.4
container_name: haovp-rmqnamesrv
restart: unless-stopped
command: sh mqnamesrv
healthcheck:
test: ["CMD-SHELL", "pgrep -f 'NamesrvStartup' || exit 1"]
interval: 10s
timeout: 5s
retries: 15
start_period: 30s
networks:
- haovp-network
rmqbroker:
image: apache/rocketmq:5.1.4
container_name: haovp-rmqbroker
user: root
restart: unless-stopped
environment:
NAMESRV_ADDR: rmqnamesrv:9876
JAVA_OPTS: -Duser.home=/opt
volumes:
- ./config/rocketmq/broker-1panel.conf:/home/rocketmq/rocketmq-5.1.4/conf/broker.conf:ro
- rmqbroker_logs:/home/rocketmq/logs
- rmqbroker_store:/home/rocketmq/store
command: sh mqbroker -c /home/rocketmq/rocketmq-5.1.4/conf/broker.conf
depends_on:
rmqnamesrv:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "pgrep -f 'BrokerStartup' || exit 1"]
interval: 10s
timeout: 5s
retries: 15
start_period: 30s
networks:
- haovp-network
minio:
image: quay.io/minio/minio
container_name: haovp-minio
restart: unless-stopped
environment:
<<: *common-env
MINIO_ROOT_USER: ${MINIO_ACCESS_KEY}
MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY}
volumes:
- minio_data:/data
command: server /data --console-address ":9001"
ports:
- "${LOCAL_BIND_ADDR:-127.0.0.1}:${MINIO_API_PORT:-9100}:9000"
- "${LOCAL_BIND_ADDR:-127.0.0.1}:${MINIO_CONSOLE_PORT:-9101}:9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 10s
timeout: 5s
retries: 10
networks:
- haovp-network
minio-init:
image: minio/mc
container_name: haovp-minio-init
restart: "no"
depends_on:
minio:
condition: service_healthy
entrypoint: >
/bin/sh -c "
mc alias set local http://minio:9000 '${MINIO_ACCESS_KEY}' '${MINIO_SECRET_KEY}' &&
mc mb --ignore-existing local/${MINIO_BUCKET:-video-platform} &&
mc anonymous set download local/${MINIO_BUCKET:-video-platform}
"
networks:
- haovp-network
sentinel:
build:
context: ./sentinel-dashboard
dockerfile: Dockerfile
image: haovp/sentinel-dashboard:1.8.6
container_name: haovp-sentinel
restart: unless-stopped
environment:
<<: *common-env
SERVER_PORT: 8080
ports:
- "${LOCAL_BIND_ADDR:-127.0.0.1}:${SENTINEL_HTTP_PORT:-8880}:8080"
networks:
- haovp-network
video-gateway:
build:
<<: *backend-build
args:
MODULE: video-gateway
JAR_PREFIX: video-gateway
image: haovp/video-gateway:1panel
container_name: haovp-video-gateway
restart: unless-stopped
environment:
<<: *service-env
JWT_SECRET: ${USER_JWT_SECRET}
USER_JWT_SECRET: ${USER_JWT_SECRET}
GATEWAY_IGNORE_URLS: /**/auth/login,/**/auth/register,/**/auth/captcha,/**/auth/refresh,/auth/username/**,/content/video/public/**,/content/category/tree,/content/category/list,/content/tag/list,/content/tag/page,/content/danmaku/all/**,/content/danmaku/time,/content/stat/**,/user/profile/public/**,/user/profile/search,/user/follow/following/**,/user/follow/followers/**,/comment/reply/public/**,/comment/public/**,/recommend/home,/recommend/hot/**,/recommend/similar/**,/recommend/tag/**,/admin/auth/captcha,/admin/auth/login
JAVA_OPTS: ${GATEWAY_JAVA_OPTS:--Xms128m -Xmx256m}
ports:
- "${LOCAL_BIND_ADDR:-127.0.0.1}:${GATEWAY_HTTP_PORT:-9000}:9000"
depends_on:
nacos:
condition: service_healthy
redis-sentinel:
condition: service_started
networks:
- haovp-network
video-auth:
build:
<<: *backend-build
args:
MODULE: video-auth
JAR_PREFIX: video-auth
image: haovp/video-auth:1panel
container_name: haovp-video-auth
restart: unless-stopped
environment:
<<: *service-env
JWT_SECRET: ${USER_JWT_SECRET}
USER_JWT_SECRET: ${USER_JWT_SECRET}
JAVA_OPTS: ${AUTH_JAVA_OPTS:--Xms128m -Xmx256m}
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis-sentinel:
condition: service_started
networks:
- haovp-network
video-user:
build:
<<: *backend-build
args:
MODULE: video-user
JAR_PREFIX: video-user
image: haovp/video-user:1panel
container_name: haovp-video-user
restart: unless-stopped
environment:
<<: *service-env
MINIO_HOST: minio
MINIO_PORT: 9000
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY}
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY}
MINIO_BUCKET: ${MINIO_BUCKET:-video-platform}
JWT_SECRET: ${USER_JWT_SECRET}
USER_JWT_SECRET: ${USER_JWT_SECRET}
JAVA_OPTS: ${USER_JAVA_OPTS:--Xms128m -Xmx256m}
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis-sentinel:
condition: service_started
minio:
condition: service_healthy
networks:
- haovp-network
video-content:
build:
<<: *backend-build
args:
MODULE: video-content
JAR_PREFIX: video-content
INSTALL_FFMPEG: "true"
image: haovp/video-content:1panel
container_name: haovp-video-content
restart: unless-stopped
environment:
<<: *service-env
NAMESRV_ADDR: rmqnamesrv:9876
ROCKETMQ_HOST: rmqnamesrv
ROCKETMQ_PORT: 9876
MINIO_HOST: minio
MINIO_PORT: 9000
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY}
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY}
MINIO_BUCKET: ${MINIO_BUCKET:-video-platform}
JWT_SECRET: ${USER_JWT_SECRET}
USER_JWT_SECRET: ${USER_JWT_SECRET}
JAVA_OPTS: ${CONTENT_JAVA_OPTS:--Xms256m -Xmx512m}
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis-sentinel:
condition: service_started
rmqbroker:
condition: service_healthy
minio:
condition: service_healthy
networks:
- haovp-network
video-comment:
build:
<<: *backend-build
args:
MODULE: video-comment
JAR_PREFIX: video-comment
image: haovp/video-comment:1panel
container_name: haovp-video-comment
restart: unless-stopped
environment:
<<: *service-env
JWT_SECRET: ${USER_JWT_SECRET}
USER_JWT_SECRET: ${USER_JWT_SECRET}
JAVA_OPTS: ${COMMENT_JAVA_OPTS:--Xms128m -Xmx256m}
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis-sentinel:
condition: service_started
networks:
- haovp-network
video-recommend:
build:
<<: *backend-build
args:
MODULE: video-recommend
JAR_PREFIX: video-recommend
image: haovp/video-recommend:1panel
container_name: haovp-video-recommend
restart: unless-stopped
environment:
<<: *service-env
JWT_SECRET: ${USER_JWT_SECRET}
USER_JWT_SECRET: ${USER_JWT_SECRET}
JAVA_OPTS: ${RECOMMEND_JAVA_OPTS:--Xms128m -Xmx256m}
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis-sentinel:
condition: service_started
networks:
- haovp-network
video-admin:
build:
<<: *backend-build
args:
MODULE: video-admin
JAR_PREFIX: video-admin
image: haovp/video-admin:1panel
container_name: haovp-video-admin
restart: unless-stopped
environment:
<<: *service-env
JWT_SECRET: ${ADMIN_JWT_SECRET}
ADMIN_JWT_SECRET: ${ADMIN_JWT_SECRET}
ADMIN_INIT_PASSWORD: ${ADMIN_INIT_PASSWORD}
APP_INIT_ADMIN_PASSWORD: ${ADMIN_INIT_PASSWORD}
JAVA_OPTS: ${ADMIN_JAVA_OPTS:--Xms128m -Xmx256m}
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis-sentinel:
condition: service_started
networks:
- haovp-network
frontend-web:
build:
context: ../frontend/video-frontend-web
dockerfile: Dockerfile.1panel
args:
VITE_API_BASE_URL: /api
VITE_MEDIA_BASE_URL: /media/video-platform
image: haovp/frontend-web:1panel
container_name: haovp-frontend-web
restart: unless-stopped
ports:
- "${FRONTEND_BIND_ADDR:-127.0.0.1}:${WEB_HTTP_PORT:-18080}:80"
depends_on:
- video-gateway
- minio
networks:
- haovp-network
frontend-admin:
build:
context: ../frontend/video-frontend-admin
dockerfile: Dockerfile.1panel
args:
VITE_API_BASE_URL: /api/admin
VITE_MEDIA_BASE_URL: /media/video-platform
image: haovp/frontend-admin:1panel
container_name: haovp-frontend-admin
restart: unless-stopped
ports:
- "${FRONTEND_BIND_ADDR:-127.0.0.1}:${ADMIN_HTTP_PORT:-18081}:80"
depends_on:
- video-gateway
- minio
networks:
- haovp-network
prometheus:
image: prom/prometheus:v2.54.1
container_name: haovp-prometheus
restart: unless-stopped
profiles:
- monitoring
ports:
- "${LOCAL_BIND_ADDR:-127.0.0.1}:${PROMETHEUS_HTTP_PORT:-9090}:9090"
volumes:
- ./monitoring/prometheus/prometheus.local.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/prometheus
command:
- --config.file=/etc/prometheus/prometheus.yml
- --storage.tsdb.path=/prometheus
- --storage.tsdb.retention.time=15d
networks:
- haovp-network
grafana:
image: grafana/grafana:11.2.0
container_name: haovp-grafana
restart: unless-stopped
profiles:
- monitoring
ports:
- "${LOCAL_BIND_ADDR:-127.0.0.1}:${GRAFANA_HTTP_PORT:-3000}:3000"
environment:
<<: *common-env
GF_SECURITY_ADMIN_USER: ${GRAFANA_ADMIN_USER:-admin}
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD}
GF_USERS_ALLOW_SIGN_UP: "false"
volumes:
- grafana_data:/var/lib/grafana
- ./monitoring/grafana/provisioning:/etc/grafana/provisioning:ro
- ./monitoring/grafana/dashboards:/var/lib/grafana/dashboards:ro
depends_on:
- prometheus
networks:
- haovp-network
mysqld-exporter:
image: prom/mysqld-exporter:v0.16.0
container_name: haovp-mysqld-exporter
restart: unless-stopped
profiles:
- monitoring
environment:
MYSQLD_EXPORTER_PASSWORD: ${MYSQL_ROOT_PASSWORD}
command:
- --mysqld.address=mysql:3306
- --mysqld.username=root
depends_on:
mysql:
condition: service_healthy
networks:
- haovp-network
redis-exporter:
image: oliver006/redis_exporter:v1.62.0
container_name: haovp-redis-exporter
restart: unless-stopped
profiles:
- monitoring
environment:
REDIS_ADDR: redis://redis:6379
REDIS_PASSWORD: ${REDIS_PASSWORD}
depends_on:
redis:
condition: service_healthy
networks:
- haovp-network
node-exporter:
image: prom/node-exporter:v1.8.2
container_name: haovp-node-exporter
restart: unless-stopped
profiles:
- monitoring
command:
- --path.procfs=/host/proc
- --path.sysfs=/host/sys
- --path.rootfs=/rootfs
- --collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
networks:
- haovp-network
networks:
haovp-network:
driver: bridge
volumes:
mysql_data:
redis_data:
redis_sentinel_data:
minio_data:
rmqbroker_logs:
rmqbroker_store:
prometheus_data:
grafana_data:
@@ -0,0 +1,22 @@
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci --prefer-offline --no-audit
COPY . .
ARG VITE_API_BASE_URL=/api/admin
ARG VITE_MEDIA_BASE_URL=/media/video-platform
ENV VITE_API_BASE_URL=${VITE_API_BASE_URL}
ENV VITE_MEDIA_BASE_URL=${VITE_MEDIA_BASE_URL}
RUN npm run build
FROM nginx:1.27-alpine
COPY deploy/nginx.1panel.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
@@ -0,0 +1,44 @@
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
client_max_body_size 1024m;
gzip on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript application/xml;
location / {
try_files $uri $uri/ /index.html;
}
location /api/admin/ {
proxy_pass http://video-gateway:9000/admin/;
proxy_http_version 1.1;
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;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_request_buffering off;
}
location /media/ {
proxy_pass http://minio:9000/;
proxy_http_version 1.1;
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;
proxy_buffering off;
}
location = /health {
access_log off;
return 200 "OK\n";
}
}
@@ -0,0 +1,22 @@
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci --prefer-offline --no-audit
COPY . .
ARG VITE_API_BASE_URL=/api
ARG VITE_MEDIA_BASE_URL=/media/video-platform
ENV VITE_API_BASE_URL=${VITE_API_BASE_URL}
ENV VITE_MEDIA_BASE_URL=${VITE_MEDIA_BASE_URL}
RUN npm run build
FROM nginx:1.27-alpine
COPY deploy/nginx.1panel.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
@@ -0,0 +1,44 @@
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
client_max_body_size 1024m;
gzip on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript application/xml;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://video-gateway:9000/;
proxy_http_version 1.1;
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;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_request_buffering off;
}
location /media/ {
proxy_pass http://minio:9000/;
proxy_http_version 1.1;
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;
proxy_buffering off;
}
location = /health {
access_log off;
return 200 "OK\n";
}
}