Merge remote-tracking branch 'origin/main'
# Conflicts: # web/pnpm-workspace.yaml
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
name: Deploy im-manager (Blue-Green)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
image_tag:
|
||||
description: '镜像tag,留空则使用commit短哈希'
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: deploy-host
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: 确定镜像tag
|
||||
id: vars
|
||||
run: |
|
||||
TAG="${{ github.event.inputs.image_tag }}"
|
||||
[ -z "$TAG" ] && TAG=$(git rev-parse --short HEAD)
|
||||
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: 构建镜像(前端+后端一体,自包含多阶段构建)
|
||||
run: docker build -t im-manager:${{ steps.vars.outputs.tag }} .
|
||||
|
||||
- name: 蓝绿部署
|
||||
env:
|
||||
MYSQL_DSN: ${{ secrets.MYSQL_DSN }}
|
||||
REDIS_ADDR: ${{ secrets.REDIS_ADDR }}
|
||||
REDIS_DB: ${{ secrets.REDIS_DB }}
|
||||
REDIS_PASSWORD: ${{ secrets.REDIS_PASSWORD }}
|
||||
TOKEN_SECRET_KEY: ${{ secrets.TOKEN_SECRET_KEY }}
|
||||
run: |
|
||||
IMAGE=im-manager:${{ steps.vars.outputs.tag }} /opt/apps/im-manager/deploy.sh
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
# ---- Stage 1: build the Vue frontend ----
|
||||
FROM node:22-alpine AS web-build
|
||||
WORKDIR /web
|
||||
RUN npm install -g pnpm
|
||||
COPY web/package.json web/pnpm-lock.yaml web/pnpm-workspace.yaml ./
|
||||
RUN pnpm install --frozen-lockfile
|
||||
COPY web/ .
|
||||
RUN pnpm run build
|
||||
|
||||
# ---- Stage 2: build the Go backend, embedding the frontend build ----
|
||||
FROM golang:1.24-alpine AS server-build
|
||||
RUN apk add --no-cache git
|
||||
WORKDIR /src
|
||||
COPY server/go.mod server/go.sum ./
|
||||
RUN go mod download
|
||||
COPY server/ .
|
||||
|
||||
# Same layout the project's own Makefile produces: built frontend goes into
|
||||
# resource/public/admin/ before packing/building the backend.
|
||||
RUN rm -rf resource/public/admin && mkdir -p resource/public/admin
|
||||
COPY --from=web-build /web/dist/ ./resource/public/admin/
|
||||
|
||||
# main.go does `import _ "hotgo/internal/packed"`, a file normally generated by
|
||||
# `gf build` (see server/hack/config.yaml: packSrc/packDst) and gitignored —
|
||||
# generate it explicitly with the same gf CLI version pinned in go.mod.
|
||||
RUN go install github.com/gogf/gf/cmd/gf/v2@v2.10.0
|
||||
RUN gf pack resource internal/packed/packed.go
|
||||
|
||||
RUN CGO_ENABLED=0 go build -o /out/hotgo main.go
|
||||
|
||||
# ---- Stage 3: runtime ----
|
||||
FROM alpine:3.22
|
||||
|
||||
RUN apk add --no-cache ca-certificates gettext bash tzdata
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=server-build /src/manifest ./manifest
|
||||
COPY --from=server-build /src/hack ./hack
|
||||
COPY --from=server-build /out/hotgo .
|
||||
COPY server/manifest/docker/entrypoint.sh .
|
||||
|
||||
RUN mkdir -p storage/logs storage/data storage/cache storage/diskqueue \
|
||||
&& chmod +x entrypoint.sh hotgo
|
||||
|
||||
HEALTHCHECK --interval=1m --timeout=3s --start-period=20s \
|
||||
CMD nc -z localhost 8000 || exit 1
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
ENTRYPOINT ["./entrypoint.sh"]
|
||||
@@ -0,0 +1,303 @@
|
||||
# hotgo系统配置
|
||||
system:
|
||||
# 应用名称
|
||||
appName: "hotgo"
|
||||
# debug开关,开启后接口出现错误时会向前端输出堆栈信息,可选:false|true,默认为true
|
||||
debug: true
|
||||
# gf运行模式,可选:not-set|develop|testing|staging|product。product模式下后台【开发工具】菜单自动隐藏
|
||||
mode: "develop"
|
||||
# IP归属地解析方法,可选:cz88|whois,默认为whois
|
||||
ipMethod: "whois"
|
||||
# 是否为演示系统,可选:false|true
|
||||
isDemo: false
|
||||
# 是否为集群部署,可选:false|true 默认为false。开启集群必须配置redis,通过redis发布订阅进行集群之间的数据同步
|
||||
isCluster: false
|
||||
# 全局请求日志
|
||||
log:
|
||||
switch: true # 日志开关,可选:false|true,默认为true
|
||||
queue: true # 是否启用队列,启用时需要配置队列信息,可选:false|true,默认为true
|
||||
module: [ "admin", "api", "default" ] # 需要记录的模块
|
||||
skipCode: [ ] # 不记录的状态码,如: ["0", "-1"]
|
||||
# 系统日志,用于在后台统计异常日志
|
||||
serveLog:
|
||||
switch: true # 日志开关,可选:false|true,默认为true
|
||||
queue: true # 是否启用队列,启用时需要配置队列信息,可选:false|true,默认为true
|
||||
levelFormat: [ "WARN", "ERRO", "FATA", "PANI" ] # 需要记录的等级
|
||||
# 国际化
|
||||
i18n:
|
||||
switch: true # 国际化开关,可选:false|true,默认为true
|
||||
defaultLanguage: "zh-CN" # 默认使用语言,可选:zh-CN|zh-TW|en,默认为zh-CN
|
||||
# 插件资源目录,用于静态文件和模版文件的路径,默认为resource
|
||||
addonsResourcePath: "resource"
|
||||
|
||||
|
||||
# 统一默认日志配置
|
||||
defaultLogger: &defaultLogger
|
||||
level: "all"
|
||||
flags: 42
|
||||
file: "{Y-m-d}.log" # 日志文件格式。默认为"{Y-m-d}.log"
|
||||
stdoutColorDisabled: false # 关闭终端的颜色打印。可选:false|true,默认false
|
||||
writerColorEnable: false # 日志文件是否带上颜色。可选:false|true,默认false,表示不带颜色
|
||||
rotateExpire: "7d" # 日志保留天数
|
||||
rotateBackupLimit: 2 # 最大备份数量
|
||||
rotateBackupCompress: 2 # 日志文件压缩级别,0-9,9最高
|
||||
|
||||
|
||||
# gf配置,配置参考:https://goframe.org/pages/viewpage.action?pageId=44449486
|
||||
server:
|
||||
address: ":8000" # 本地监听地址。默认":8000",多个地址以","号分隔。例如:"192.168.2.3:8000,10.0.3.10:8001"
|
||||
openapiPath: "/api.json" # OpenAPI接口文档地址
|
||||
swaggerPath: "/swagger" # 内置SwaggerUI展示地址
|
||||
serverRoot: "resource/public" # 静态文件服务的目录根路径,配置时自动开启静态文件服务。
|
||||
DumpRouterMap: false # 是否在Server启动时打印所有的路由列表。
|
||||
logPath: "logs/server" # 服务日志保存路径
|
||||
ErrorStack: true # 当Server捕获到异常时是否记录堆栈信息到日志中。默认为true
|
||||
ErrorLogEnabled: true # 是否记录异常日志信息到日志中。默认为true
|
||||
errorLogPattern: "error/{Y-m-d}.log" # 异常错误日志文件格式。默认为"error-{Ymd}.log"
|
||||
accessLogEnabled: true # 是否记录访问日志。默认为false
|
||||
accessLogPattern: "access/{Y-m-d}.log" # 访问日志文件格式。默认为"access-{Ymd}.log"
|
||||
maxHeaderBytes: "100KB" # 请求头大小限制,请求头包括客户端提交的Cookie数据,默认设置为100KB
|
||||
clientMaxBodySize: "200MB" # 客户端提交的Body大小限制,同时也影响文件上传大小,默认设置为200MB
|
||||
serverAgent: "HG HTTP Server" # 服务端Agent信息。默认为"HG HTTP Server"
|
||||
# PProf配置
|
||||
pprofEnabled: true # 是否开启PProf性能调试特性。默认为false
|
||||
pprofPattern: "/pprof" # 开启PProf时有效,表示PProf特性的页面访问路径,对当前Server绑定的所有域名有效。
|
||||
# 服务日志配置
|
||||
logger:
|
||||
path: "logs/server" # 日志文件路径。默认为空,表示关闭,仅输出到终端
|
||||
<<: *defaultLogger
|
||||
|
||||
|
||||
# tcp服务
|
||||
tcp:
|
||||
# 服务器
|
||||
server:
|
||||
address: ":8099"
|
||||
# 客户端
|
||||
client:
|
||||
# 定时任务
|
||||
cron:
|
||||
group: "cron" # 分组名称
|
||||
name: "cron1" # 客户端名称
|
||||
address: "127.0.0.1:8099" # 服务器地址
|
||||
appId: "1002" # 应用名称
|
||||
secretKey: "hotgo" # 密钥
|
||||
# 系统授权
|
||||
auth:
|
||||
group: "auth" # 分组名称
|
||||
name: "auth1" # 客户端名称
|
||||
address: "127.0.0.1:8099" # 服务器地址
|
||||
appId: "mengshuai" # 应用名称
|
||||
secretKey: "123456" # 密钥
|
||||
|
||||
|
||||
# 日志配置
|
||||
logger:
|
||||
# 全局日志:g.Log()
|
||||
path: "logs/logger" # 日志文件路径。默认为空,表示关闭,仅输出到终端
|
||||
<<: *defaultLogger
|
||||
# 定时任务:g.Log("cron")
|
||||
cron:
|
||||
path: "logs/cron" # 日志文件路径。默认为空,表示关闭,仅输出到终端
|
||||
<<: *defaultLogger
|
||||
# 消息队列:g.Log("cron")
|
||||
queue:
|
||||
path: "logs/queue" # 日志文件路径。默认为空,表示关闭,仅输出到终端
|
||||
<<: *defaultLogger
|
||||
# tcp服务器:g.Log("tcpServer")
|
||||
tcpServer:
|
||||
path: "logs/tcpServer" # 日志文件路径。默认为空,表示关闭,仅输出到终端
|
||||
<<: *defaultLogger
|
||||
# tcp客户端:g.Log("tcpClient")
|
||||
tcpClient:
|
||||
path: "logs/tcpClient" # 日志文件路径。默认为空,表示关闭,仅输出到终端
|
||||
<<: *defaultLogger
|
||||
|
||||
|
||||
# Viewer. 配置参考:https://goframe.org/pages/viewpage.action?pageId=1114335
|
||||
viewer:
|
||||
paths: "resource/template"
|
||||
defaultFile: "index.html"
|
||||
delimiters: [ "@{", "}" ]
|
||||
homeLayout: "home/index.html"
|
||||
|
||||
|
||||
# 内容设置
|
||||
setting:
|
||||
title: "HotGo"
|
||||
keywords: "中后台解决方案,gf框架,vue3"
|
||||
description: "hotgo 是一个基于 goframe2,vue3,vite2,TypeScript,uniapp 的中后台解决方案,它可以帮助你快速搭建企业级中后台项目,相信不管是从新技术使用还是其他方面,都能帮助到你,持续更新中。"
|
||||
|
||||
|
||||
# 路由配置
|
||||
router:
|
||||
# 后台
|
||||
admin:
|
||||
# 前缀
|
||||
prefix: "/admin"
|
||||
# 不需要验证登录的路由地址
|
||||
exceptLogin: [
|
||||
"/sms/send", # 短信验证码
|
||||
"/wechat/authorizeCall", # 微信用户授权回调
|
||||
]
|
||||
# 不需要验证权限的路由地址
|
||||
exceptAuth: [
|
||||
"/member/info", # 登录用户信息
|
||||
"/role/dynamic", # 获取动态路由
|
||||
"/notice/pullMessages", # 拉取我的消息
|
||||
"/notice/readAll", # 设置全部已读公告
|
||||
"/notice/upRead", # 已读指定公告
|
||||
"/dictData/option", # 单个数据字典
|
||||
"/dictData/options", # 多个数据字典
|
||||
"/provinces/select", # 动态省市区选项
|
||||
"/provinces/cityLabel", # 动态解析省市区名称
|
||||
"/member/option", # 用户选项
|
||||
]
|
||||
# 接口
|
||||
api:
|
||||
# 前缀
|
||||
prefix: "/api"
|
||||
# 不需要验证登录的路由地址
|
||||
exceptLogin: [ ]
|
||||
# websocket
|
||||
websocket:
|
||||
# 前缀
|
||||
prefix: "/socket"
|
||||
# 不需要验证登录的路由地址
|
||||
exceptLogin: [ ]
|
||||
# 前台页面
|
||||
home:
|
||||
# 前缀
|
||||
prefix: "/home"
|
||||
# 不需要验证登录的路由地址
|
||||
exceptLogin: [ ]
|
||||
|
||||
|
||||
# 缓存驱动
|
||||
cache:
|
||||
adapter: "redis" # 缓存驱动方式,支持:memory|redis|file,不填默认memory
|
||||
fileDir: "./storage/cache" # 文件缓存路径,adapter=file时必填
|
||||
|
||||
|
||||
# 登录令牌
|
||||
token:
|
||||
secretKey: "$TOKEN_SECRET_KEY" # 令牌加密秘钥,考虑安全问题生产环境中请修改默认值
|
||||
expires: 604800 # 令牌有效期,单位:秒。默认7天
|
||||
autoRefresh: true # 是否开启自动刷新过期时间, false|true 默认为true
|
||||
refreshInterval: 86400 # 刷新间隔,单位:秒。必须小于expires,否则无法触发。默认1天内只允许刷新一次
|
||||
maxRefreshTimes: 30 # 最大允许刷新次数,-1不限制。默认30次
|
||||
multiLogin: true # 是否允许多端登录, false|true 默认为true
|
||||
|
||||
|
||||
# 消息队列
|
||||
queue:
|
||||
switch: true # 队列开关,可选:true|false,默认为true
|
||||
driver: "redis" # 队列驱动,可选:disk|redis|rocketmq|kafka,默认为disk
|
||||
groupName: "hotgo" # mq群组名称
|
||||
# 磁盘队列
|
||||
disk:
|
||||
path: "./storage/diskqueue" # 数据存放路径
|
||||
batchSize: 100 # 每100条消息同步一次,batchSize和batchTime满足其一就会同步一次
|
||||
batchTime: 1 # 每1秒消息同步一次
|
||||
segmentSize: 10485760 # 每个topic分片数据文件最大字节,默认10M
|
||||
segmentLimit: 3000 # 每个topic最大分片数据文件数量,超出部分将会丢弃
|
||||
# redis,默认使用全局redis运行队列
|
||||
redis:
|
||||
timeout: 0 # 队列超时时间以秒为单位,0表示永不超时。如果队列在设定的超时时间内没有被消费,则会被销毁
|
||||
rocketmq:
|
||||
nameSrvAdders: ["127.0.0.1:9876"] # nameSrvAdder+端口,支持多个
|
||||
accessKey: "" # 选填。如果开启了acl控制就必填
|
||||
secretKey: "" # 选填。如果开启了acl控制就必填
|
||||
brokerAddr: "127.0.0.1:10911" # brokerAddr+端口,选填。用于消费者订阅主题前会检查主题是否存在,不存在会自动创建。你也可以在rocketmq控制台手动创建主题
|
||||
retry: 0 # 重试次数
|
||||
logLevel: "info" # rocketmq日志输出级别,可选:all|close|debug|info|warn|error|fatal
|
||||
kafka:
|
||||
address: "127.0.0.1:9092" # kafka地址+端口
|
||||
version: "2.0.0.0" # kafka专属配置,默认2.0.0.0
|
||||
randClient: true # 开启随机生成clientID,可以实现启动多实例同时一起消费相同topic,加速消费能力的特性,默认为true
|
||||
multiConsumer: true # 是否支持创建多个消费者
|
||||
|
||||
|
||||
# Redis. 配置参考:https://goframe.org/pages/viewpage.action?pageId=1114217
|
||||
redis:
|
||||
default:
|
||||
address: "$REDIS_ADDR"
|
||||
db: "$REDIS_DB"
|
||||
pass: "$REDIS_PASSWORD"
|
||||
idleTimeout: "20"
|
||||
|
||||
|
||||
# Database. 配置参考:https://goframe.org/pages/viewpage.action?pageId=1114245
|
||||
database:
|
||||
logger:
|
||||
path: "logs/database" # 日志文件路径。默认为空,表示关闭,仅输出到终端
|
||||
<<: *defaultLogger
|
||||
stdout: true
|
||||
default:
|
||||
link: "$MYSQL_DSN"
|
||||
debug: true
|
||||
Prefix: "hg_"
|
||||
|
||||
|
||||
# 链路追踪
|
||||
jaeger:
|
||||
switch: false # 链路追踪开关,可选:true|false,默认为false
|
||||
endpoint: "127.0.0.1:6831" # jaeger-agent上报地址
|
||||
|
||||
|
||||
# 生成代码
|
||||
hggen:
|
||||
allowedIPs: [ "127.0.0.1", "*" ] # 白名单,*代表所有,只有允许的IP后台才能使用生成代码功能
|
||||
selectDbs: [ "default" ] # 可选生成表的数据库配置名称,支持多库
|
||||
disableTables: [ "hg_sys_gen_codes","hg_admin_role_casbin" ] # 禁用的表,禁用以后将不会在选择表中看到
|
||||
delimiters: [ "@{", "}" ] # 模板引擎变量分隔符号
|
||||
# 生成应用模型,所有生成模板允许自定义,可以参考default模板进行改造
|
||||
application:
|
||||
# CRUD和关系树列表模板
|
||||
crud:
|
||||
templates:
|
||||
# 默认的主包模板
|
||||
- group: "default" # 分组名称
|
||||
isAddon: false # 是否为插件模板 false|true
|
||||
masterPackage: "sys" # 主包名称,需和controllerPath、logicPath、inputPath保持关联
|
||||
templatePath: "./resource/generate/default/curd" # 模板路径
|
||||
apiPath: "./api/admin" # goApi生成路径
|
||||
controllerPath: "./internal/controller/admin/sys" # 控制器生成路径
|
||||
logicPath: "./internal/logic/sys" # 主要业务生成路径
|
||||
inputPath: "./internal/model/input/sysin" # 表单过滤器生成路径
|
||||
routerPath: "./internal/router/genrouter" # 生成路由表路径
|
||||
sqlPath: "./storage/data/generate" # 生成sql语句路径
|
||||
webApiPath: "../web/src/api" # webApi生成路径
|
||||
webViewsPath: "../web/src/views" # web页面生成路径
|
||||
|
||||
# 默认的插件包模板,{$name}会自动替换成实际的插件名称
|
||||
- group: "addon" # 分组名称
|
||||
isAddon: true # 是否为插件模板 false|true
|
||||
masterPackage: "sys" # 主包名称,需和controllerPath、logicPath、inputPath保持关联
|
||||
templatePath: "./resource/generate/default/curd" # 模板路径
|
||||
apiPath: "./addons/{$name}/api/admin" # goApi生成路径
|
||||
controllerPath: "./addons/{$name}/controller/admin/sys" # 控制器生成路径
|
||||
logicPath: "./addons/{$name}/logic/sys" # 主要业务生成路径
|
||||
inputPath: "./addons/{$name}/model/input/sysin" # 表单过滤器生成路径
|
||||
routerPath: "./addons/{$name}/router/genrouter" # 生成路由表路径
|
||||
sqlPath: "./storage/data/generate/addons" # 生成sql语句路径
|
||||
webApiPath: "../web/src/api/addons/{$name}" # webApi生成路径
|
||||
webViewsPath: "../web/src/views/addons/{$name}" # web页面生成路径
|
||||
|
||||
# 消息队列模板
|
||||
queue:
|
||||
templates:
|
||||
- group: "default"
|
||||
templatePath: "./resource/generate/default/queue"
|
||||
|
||||
# 定时任务模板
|
||||
cron:
|
||||
templates:
|
||||
- group: "default"
|
||||
templatePath: "./resource/generate/default/cron"
|
||||
|
||||
# 生成插件模块,通过后台创建新插件时使用的模板,允许自定义,可以参考default模板进行改造
|
||||
addon:
|
||||
srcPath: "./resource/generate/default/addon" # 生成模板路径
|
||||
webApiPath: "../web/src/api/addons/{$name}" # webApi生成路径
|
||||
webViewsPath: "../web/src/views/addons/{$name}" # web页面生成路径
|
||||
@@ -1,5 +1,12 @@
|
||||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
cd /app && ./hotgo &
|
||||
echo "hotgo start all server.."
|
||||
tail -f /dev/null
|
||||
cd /app
|
||||
|
||||
# Render the real config from the template using only the specific env vars we
|
||||
# expect — avoids accidentally substituting anything else that might contain a
|
||||
# literal '$' in the YAML.
|
||||
envsubst '$MYSQL_DSN $REDIS_ADDR $REDIS_DB $REDIS_PASSWORD $TOKEN_SECRET_KEY' \
|
||||
< manifest/config/config.template > manifest/config/config.yaml
|
||||
|
||||
exec ./hotgo
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
allowBuilds:
|
||||
'@swc/core': set this to true or false
|
||||
core-js: set this to true or false
|
||||
esbuild: set this to true or false
|
||||
vue-demi: set this to true or false
|
||||
'@swc/core': true
|
||||
core-js: true
|
||||
esbuild: true
|
||||
vue-demi: true
|
||||
|
||||
Reference in New Issue
Block a user