# JNPF 全栈 docker-compose 操作入口(详见 docs/docker-compose-guide.md)
|
.PHONY: help jars jars-microservice flow-engine prepare web-dist check-web-dist pull-infra images preflight up up-no-pull images-offline down restart ps logs smoke
|
|
# ── 第三方基础设施镜像:SWR 长名 → 本地短名 ──────────────────────────────────
|
# compose 里写的是短名(cx-redis / cx-onlyoffice / cx-nginx),由下面的 pull-infra retag 而来。
|
# `docker tag` 只是给同一个 image ID 挂别名,不复制数据(0 字节开销)。
|
SWR := swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io
|
|
help: ## 显示本帮助
|
@grep -E '^[a-z-]+:.*##' $(MAKEFILE_LIST) | awk -F':.*## ' '{printf " make %-10s %s\n", $$1, $$2}'
|
|
jars: ## Maven 打包全部业务 jar(业务镜像构建的前置)
|
mvn clean package -DskipTests
|
|
# 2026-08-11 平台聚合:默认(monolith)产出 jnpf-platform 一个 fat jar,取代原来
|
# oauth/system/visualdev/flowable/file/message/permission/visualdata/app 九个。
|
# 九个 *-server 模块的源码**保留未删**,由各自父 pom 的 microservice profile 门控。
|
# 回滚到微服务形态 = 本目标 + 还原 config/*/discovery.yaml 的九个服务名端口
|
# + 放回 docker-compose.yml / start-all.sh 里被注释的九段。不需要 git revert。
|
jars-microservice: ## 回滚用:按微服务形态打包(额外产出九个平台服务 fat jar)
|
mvn -P microservice clean package -DskipTests
|
|
flow-engine: ## 构建自有流程引擎 jar(独立工程,不在父 POM,故单独构建)
|
mvn -f jnpf-flow-engine/pom.xml clean package -DskipTests
|
|
# 业务镜像 COPY 宿主 target/*.jar(非多阶段构建),故 images 前必须先有业务 jar。
|
# 用哨兵校验避免"干净机器忘了 make jars → docker COPY 阶段晦涩失败":缺失即报错提示。
|
# 不直接让 images 依赖 jars,是为保留本地"编一次、反复起"的迭代速度(全量 mvn 约 10min)。
|
check-jars:
|
@test -f jnpf-gateway/target/jnpf-gateway-*.jar || { \
|
echo "错误:未找到业务 jar(jnpf-gateway/target/*.jar)"; \
|
echo " 请先构建全部业务 jar:make jars"; exit 1; }
|
|
prepare: flow-engine ## 构建并暂存自建流程引擎 jar 到镜像上下文(不入 git)
|
./docker/flow-engine/prepare-context.sh
|
|
web-dist: ## 构建前端并快照 dist 到镜像上下文(前端仓库路径可 FRONTEND_REPO= 覆盖;只拷不构建 SKIP_BUILD=1)
|
./docker/frontend/sync-dist.sh
|
|
# 与 check-jars 同理:不让 images 直接依赖 web-dist(前端构建数分钟级),
|
# 只做存在性哨兵;dist 是否新鲜看 docker/frontend/dist/.build-info
|
check-web-dist:
|
@test -f docker/frontend/dist/index.html || { \
|
echo "错误:未找到前端产物(docker/frontend/dist/index.html)"; \
|
echo " 请先构建前端:make web-dist"; exit 1; }
|
|
pull-infra: ## 拉取第三方基础设施镜像并 retag 成短名(cx-redis / cx-onlyoffice / cx-nginx)
|
docker pull --platform linux/amd64 $(SWR)/redis:8.4.0-alpine
|
docker tag $(SWR)/redis:8.4.0-alpine cx-redis:8.4.0-alpine
|
# OnlyOffice DS 同样走 SWR(2026-08-19):Hub 直连在国内网络稳定超时。
|
# 镜像 ~2GB,首次拉取偏慢;compose 里对应短名 cx-onlyoffice:9.4.0.1。
|
docker pull --platform linux/amd64 $(SWR)/onlyoffice/documentserver:9.4.0.1
|
docker tag $(SWR)/onlyoffice/documentserver:9.4.0.1 cx-onlyoffice:9.4.0.1
|
# cx-nginx 是 cx-web 的**构建基底**(Dockerfile FROM),不是 compose 的 image 字段——
|
# 故它只在 .env 设了 NGINX_BASE_IMAGE=cx-nginx:1.27-alpine 时被消费;未设则走
|
# compose 默认的 Docker Hub 多架构 nginx:1.27-alpine(arm64 原生,但需 Hub 可达)。
|
docker pull --platform linux/amd64 $(SWR)/nginx:1.27-alpine
|
docker tag $(SWR)/nginx:1.27-alpine cx-nginx:1.27-alpine
|
@echo "基础设施镜像已就绪(短名 → 架构):"
|
@for i in cx-redis:8.4.0-alpine cx-onlyoffice:9.4.0.1 cx-nginx:1.27-alpine; do \
|
printf ' %-24s %s\n' "$$i" "$$(docker image inspect --format '{{.Architecture}}' $$i 2>/dev/null || echo '缺失')"; \
|
done
|
|
# 取代原先的 `docker compose pull --ignore-buildable`:compose 里没有 build 段的服务
|
# 恰好就是那三个第三方基础设施服务(redis/namesrv/broker),它们现在用短名,
|
# 裸 pull 会去 docker.io 找不存在的仓库。pull-infra 覆盖同一批镜像且带 retag。
|
# --profile localdb 是构建期必须的:cx-postgres 在该 profile 内(默认不启动,见 compose 服务块),
|
# 不带它 `compose build` 会跳过 PG 镜像,交付/正式环境起栈时才发现没镜像。
|
# 构建全集 ≠ 启动集合:这里只保证镜像齐,起哪些服务仍由 .env 的 COMPOSE_PROFILES 决定。
|
images: check-jars check-web-dist prepare pull-infra ## 确保全部镜像就绪:自建的构建(cx/postgres、cx/flow-engine、业务、前端),第三方的拉取+retag
|
docker compose --profile localdb build
|
|
# up/up-no-pull 强制前置 preflight(Backlog C1):空卷/空库/缺 .env 键在 compose up 前拦下,
|
# 消灭"空库 PG 却 healthy、业务全线连不上"的静默失败;确要跳过 SKIP_PREFLIGHT=1
|
preflight: ## 部署自举校验:docker/内存/.env 必填键/数据卷/三库 schema/种子数据/共享配置文件/业务角色
|
@if [ "$(SKIP_PREFLIGHT)" = "1" ]; then echo "跳过 preflight(SKIP_PREFLIGHT=1)"; \
|
else ./docker/preflight.sh; fi
|
|
up: images preflight ## 镜像就绪后一键启动全栈(冷启动约 5-8 分钟:PG→业务自动排队)
|
docker compose up -d
|
docker compose ps
|
|
up-no-pull: preflight ## 跳过构建与拉取,用本地已有镜像起全栈(离线/快速迭代;镜像缺失直接报错)
|
docker compose up -d --no-build --pull never
|
docker compose ps
|
|
images-offline: check-jars check-web-dist prepare ## 组装整栈 amd64 离线交付包到 dist/(详见 docs/docker-compose-guide.md §14)
|
./docker/delivery/assemble-offline-package.sh
|
|
# --profile localdb 不能省:compose 的 down 只覆盖当前启用 profile 内的服务(实测:profile 关闭时
|
# 该容器会被原样留着跑)。带上它,无论本环境用不用栈内 PG,停栈都是干净的(没起过则是空操作)。
|
down: ## 全部停止并移除容器(数据安全:pgdata 是 external 卷,永不删除)
|
docker compose --profile localdb down
|
|
restart: ## 重启全栈容器(原地重启,不重建容器/不丢 MQ 无持久化消息)
|
docker compose restart
|
|
ps: ## 查看容器状态与健康
|
docker compose ps
|
|
logs: ## 跟踪某服务日志:make logs s=cx-lims
|
docker compose logs -f $(s)
|
|
smoke: ## 冒烟三段:gateway 登录 + 前端静态 200 + 经 80 反代登录(L017 脚本;与 site.Makefile 同步维护)
|
@set -o pipefail; \
|
MD5=$$(command -v md5 >/dev/null 2>&1 && echo md5 || echo md5sum); \
|
hash5() { if [ "$$MD5" = md5 ]; then md5; else md5sum | cut -d' ' -f1; fi; }; \
|
KEYHEX=$$(printf '%s' "$$(printf '%s' 'EY8WePvjM5GGwQzn' | hash5)" | xxd -p | tr -d '\n'); \
|
ENC=$$(printf '%s' "$$(printf '%s' '123456' | hash5)" | openssl enc -aes-256-ecb -K "$$KEYHEX" -nosalt | xxd -p | tr -d '\n'); \
|
RESP=$$(curl -fsS -X POST http://127.0.0.1:30000/api/oauth/Login -H 'Content-Type: application/x-www-form-urlencoded' \
|
--data-urlencode account=admin --data-urlencode "password=$$ENC" \
|
--data-urlencode grant_type=password --data-urlencode origin=password); \
|
echo "$$RESP" | head -c 200; echo; \
|
echo "$$RESP" | grep -q '"code":200' || { echo "冒烟失败:登录未返回 code 200(gateway 30000 直连)"; exit 1; }; \
|
curl -fsS -o /dev/null http://127.0.0.1:80/ || { echo "冒烟失败:前端静态入口 http://127.0.0.1:80/ 不通"; exit 1; }; \
|
RESP2=$$(curl -fsS -X POST http://127.0.0.1:80/api/oauth/Login -H 'Content-Type: application/x-www-form-urlencoded' \
|
--data-urlencode account=admin --data-urlencode "password=$$ENC" \
|
--data-urlencode grant_type=password --data-urlencode origin=password); \
|
echo "$$RESP2" | grep -q '"code":200' || { echo "冒烟失败:经前端 80 反代登录未返回 code 200"; exit 1; }; \
|
echo "冒烟通过 ✓(gateway 直连 + 前端静态 + 80 反代登录)"
|