Files
asset_helper/prompt/v1.md
2026-03-28 18:01:45 +08:00

16 KiB
Raw Permalink Blame History

资产管理系统后端骨架 - 技术需求 V1Docker 全环境版)

执行目标:基于纯 Docker 环境构建可编译、可运行的最小化后端骨架,无宿主机依赖(无全局 Go/Protoc/Postgres/Redis 环境) 技术栈锁定golang:1.26.1-alpine3.23、postgres:18.3-alpine3.23、redis:8.6.2-alpine、Docker/Docker Compose

一、核心调整说明

  1. 基础镜像版本统一:所有 Go 构建/运行、数据库、缓存镜像均替换为指定版本
  2. 纯 Docker 环境闭环
    • 宿主机无依赖(无需安装 Go/Protoc/Make 等)
    • 所有构建/编译/运行操作均通过 Docker 容器完成
    • 新增 Protoc 构建容器(解决 proto 文件编译依赖)
  3. 路径与权限优化:适配 Alpine 3.23 镜像特性,调整文件权限和执行逻辑

二、完整目录结构(./backend/ 根)

./backend/
├── gateway/
│   ├── cmd/
│   │   └── main.go
│   ├── internal/
│   │   ├── config/
│   │   │   └── config.go
│   │   ├── ws/
│   │   │   ├── hub.go
│   │   │   ├── client.go
│   │   │   └── message.go
│   │   └── router/
│   │       └── router.go
│   ├── go.mod
│   └── Dockerfile
├── services/
│   └── user-svc/
│       ├── cmd/
│       │   └── main.go
│       ├── internal/
│       │   ├── config/
│       │   │   └── config.go
│       │   ├── domain/
│       │   │   └── user.go
│       │   ├── repository/
│       │   │   └── repo.go
│       │   ├── service/
│       │   │   └── service.go
│       │   └── grpcserver/
│       │       └── server.go
│       ├── proto/
│       │   └── user.proto
│       ├── migrations/
│       │   └── 001_init.sql
│       ├── go.mod
│       └── Dockerfile
├── shared/
│   ├── proto/
│   │   ├── common/
│   │   │   └── common.proto
│   │   └── generate.go
│   └── pkg/
│       ├── logger/
│       │   └── logger.go
│       ├── errors/
│       │   └── errors.go
│       ├── database/
│       │   └── postgres.go
│       └── cache/
│           └── redis.go
├── scripts/
│   ├── dev-start.sh          # 纯 Docker 启动脚本
│   ├── gen-proto.sh          # Docker 内编译 proto
│   └── docker-proto-builder/ # Protoc 编译容器配置
│       └── Dockerfile
├── docker-compose.yml        # 全服务编排(含 proto 编译、Go 构建)
├── docker-compose.dev.yml    # 开发模式编排(挂载源码、热更新)
├── Makefile                  # 封装 Docker 命令(兼容无宿主机 Make 环境)
└── README.md                 # 纯 Docker 环境使用说明

三、核心文件调整(适配指定技术栈 + 纯 Docker 环境)

3.1 基础镜像统一替换

所有 Dockerfile/Compose 文件中的基础镜像替换为指定版本:

  • Go 构建/运行:golang:1.26.1-alpine3.23
  • PostgreSQLpostgres:18.3-alpine3.23
  • Redisredis:8.6.2-alpine
  • 基础运行镜像:alpine:3.23

3.2 ./backend/gateway/Dockerfile

# 构建阶段:使用指定 Go 版本
FROM golang:1.26.1-alpine3.23 AS builder
WORKDIR /build

# 安装依赖Alpine 3.23 适配)
RUN apk add --no-cache git ca-certificates tzdata
ENV TZ=Asia/Shanghai

# 复制共享代码和网关代码
COPY ../shared /shared
COPY . /build

# 替换模块路径并构建(关闭 CGO 适配 Alpine
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o gateway ./cmd

# 运行阶段:轻量 Alpine
FROM alpine:3.23
RUN apk add --no-cache ca-certificates tzdata
ENV TZ=Asia/Shanghai
WORKDIR /app

# 复制构建产物
COPY --from=builder /build/gateway .
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

# 权限优化(非 root 运行)
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
RUN chown -R appuser:appgroup /app
USER appuser

EXPOSE 8080
# 优雅退出配置
STOPSIGNAL SIGTERM
CMD ["./gateway"]

3.3 ./backend/services/user-svc/Dockerfile

# 构建阶段
FROM golang:1.26.1-alpine3.23 AS builder
WORKDIR /build

RUN apk add --no-cache git ca-certificates tzdata
ENV TZ=Asia/Shanghai

# 复制共享代码和用户服务代码
COPY ../../shared /shared
COPY . /build

RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o user-svc ./cmd

# 运行阶段
FROM alpine:3.23
RUN apk add --no-cache ca-certificates tzdata
ENV TZ=Asia/Shanghai
WORKDIR /app

COPY --from=builder /build/user-svc .
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

# 非 root 运行
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
RUN chown -R appuser:appgroup /app
USER appuser

EXPOSE 50051
STOPSIGNAL SIGTERM
CMD ["./user-svc"]

3.4 ./backend/scripts/docker-proto-builder/Dockerfile

# Protoc 编译专用容器(解决宿主机无 Protoc 依赖)
FROM golang:1.26.1-alpine3.23

# 安装 Protoc 及 Go 插件
RUN apk add --no-cache protobuf git
RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.34.0
RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.5.1

# 配置环境变量
ENV PATH="$PATH:/go/bin"
ENV GOPATH="/go"

WORKDIR /proto
CMD ["protoc", "--version"]

3.5 ./backend/scripts/gen-proto.sh

#!/bin/sh
# 纯 Docker 环境编译 Proto 文件(无宿主机 Protoc 依赖)
set -e

# 进入项目根目录
SCRIPT_DIR=$(cd $(dirname $0)/.. && pwd)
cd $SCRIPT_DIR

# 构建 Protoc 编译容器并执行编译
docker build -t proto-builder:latest ./scripts/docker-proto-builder/

# 运行编译容器(挂载 proto 目录)
docker run --rm \
  -v $SCRIPT_DIR/shared/proto:/proto \
  -w /proto \
  proto-builder:latest \
  sh -c "for f in */*.proto; do \
           protoc --go_out=. --go_opt=paths=source_relative \
                  --go-grpc_out=. --go-grpc_opt=paths=source_relative \
                  \$f; \
         done"

echo "✅ Proto 文件编译完成Docker 环境)"

3.6 ./backend/docker-compose.yml

version: '3.8'
services:
  # Proto 编译服务(一次性执行)
  proto-builder:
    build: ./scripts/docker-proto-builder/
    volumes:
      - ./shared/proto:/proto
    command: sh -c "/proto/../scripts/gen-proto.sh"
    profiles: ["proto"]

  # 网关服务
  gateway:
    build: ./gateway
    ports:
      - "8080:8080"
    environment:
      - WS_ADDR=:8080
      - REDIS_ADDR=redis:6379
    depends_on:
      - redis
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    networks:
      - backend-network

  # 用户服务
  user-svc:
    build: ./services/user-svc
    ports:
      - "50051:50051"
    environment:
      - DB_HOST=user-db
      - DB_PORT=5432
      - DB_USER=postgres
      - DB_PASSWORD=postgres
      - DB_NAME=user_db
      - GRPC_ADDR=:50051
    depends_on:
      - user-db
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    networks:
      - backend-network

  # PostgreSQL 数据库(指定版本)
  user-db:
    image: postgres:18.3-alpine3.23
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_DB=user_db
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_INITDB_ARGS=--encoding=UTF8 --lc-collate=C --lc-ctype=C
    volumes:
      - user_data:/var/lib/postgresql/data
      - ./services/user-svc/migrations:/docker-entrypoint-initdb.d
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d user_db"]
      interval: 5s
      timeout: 3s
      retries: 5
    networks:
      - backend-network

  # Redis 缓存(指定版本)
  redis:
    image: redis:8.6.2-alpine
    ports:
      - "6379:6379"
    command: redis-server --appendonly yes --requirepass ""
    volumes:
      - redis_data:/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5
    networks:
      - backend-network

volumes:
  user_data:
  redis_data:

networks:
  backend-network:
    driver: bridge

3.7 ./backend/docker-compose.dev.yml开发模式挂载源码

version: '3.8'
services:
  gateway:
    build: ./gateway
    ports:
      - "8080:8080"
    environment:
      - WS_ADDR=:8080
      - REDIS_ADDR=redis:6379
    depends_on:
      - redis
    volumes:
      - ./gateway:/build
      - ./shared:/shared
    command: sh -c "go run cmd/main.go"
    restart: on-failure
    networks:
      - backend-network

  user-svc:
    build: ./services/user-svc
    ports:
      - "50051:50051"
    environment:
      - DB_HOST=user-db
      - DB_PORT=5432
      - DB_USER=postgres
      - DB_PASSWORD=postgres
      - DB_NAME=user_db
      - GRPC_ADDR=:50051
    depends_on:
      - user-db
    volumes:
      - ./services/user-svc:/build
      - ./shared:/shared
    command: sh -c "go run cmd/main.go"
    restart: on-failure
    networks:
      - backend-network

  # 复用主 Compose 的数据库/缓存服务
  user-db:
    extends:
      file: docker-compose.yml
      service: user-db

  redis:
    extends:
      file: docker-compose.yml
      service: redis

volumes:
  user_data:
  redis_data:

networks:
  backend-network:
    driver: bridge

3.8 ./backend/scripts/dev-start.sh

#!/bin/sh
set -e

# 纯 Docker 环境启动脚本(无宿主机依赖)
SCRIPT_DIR=$(cd $(dirname $0)/.. && pwd)
cd $SCRIPT_DIR

echo "======================================"
echo "  Asset Helper Backend (Docker 环境)  "
echo "======================================"

# 停止旧容器
echo "🔄 停止旧容器..."
docker-compose -f docker-compose.yml down -v 2>/dev/null || true

# 编译 Proto 文件Docker 内执行)
echo "📝 编译 Proto 文件..."
./scripts/gen-proto.sh

# 启动开发环境
echo "🚀 启动开发容器..."
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up --build -d

# 等待服务就绪
echo "⌛ 等待服务初始化..."
sleep 10

# 检查服务状态
echo "✅ 服务状态检查:"
docker-compose -f docker-compose.yml ps

# 健康检查
echo "\n📊 健康检查:"
docker run --rm --network backend_backend-network curlimages/curl:8.7.1 -s http://gateway:8080/health || echo "⚠️ Gateway 服务未就绪"

# 输出访问信息
echo "\n📌 访问信息:"
echo "Gateway WebSocket: ws://localhost:8080/ws"
echo "Health Check: http://localhost:8080/health"
echo "User gRPC: localhost:50051"
echo "PostgreSQL: localhost:5432 (user: postgres, pass: postgres, db: user_db)"
echo "Redis: localhost:6379"

echo "\n💡 查看日志docker-compose -f docker-compose.yml logs -f"
echo "💡 停止服务docker-compose -f docker-compose.yml down -v"

3.9 ./backend/Makefile兼容无宿主机 Make 环境)

.PHONY: dev build proto test down logs clean

# 兼容无宿主机 Make 环境:通过 Docker 执行核心操作
dev:
  @echo "启动开发环境(纯 Docker..."
  @./scripts/dev-start.sh

build:
  @echo "构建生产镜像..."
  @docker-compose -f docker-compose.yml build

proto:
  @echo "编译 Proto 文件Docker 内)..."
  @./scripts/gen-proto.sh

test:
  @echo "执行健康检查..."
  @docker run --rm --network backend_backend-network curlimages/curl:8.7.1 -s http://gateway:8080/health || echo "Gateway 服务未运行"

down:
  @echo "停止并清理容器..."
  @docker-compose -f docker-compose.yml -f docker-compose.dev.yml down -v

logs:
  @echo "实时查看日志..."
  @docker-compose -f docker-compose.yml -f docker-compose.dev.yml logs -f

clean: down
  @echo "清理镜像和数据卷..."
  @docker system prune -f
  @docker volume rm backend_user_data backend_redis_data 2>/dev/null || true

3.10 ./backend/README.md纯 Docker 环境说明)

# Asset Helper Backend
资产管理系统后端服务(纯 Docker 环境版)

## 核心特性
- 📦 全 Docker 环境:无需宿主机安装 Go/Protoc/Postgres/Redis 等依赖
- 🔒 安全配置:非 root 用户运行容器、权限最小化
- 🚀 开发/生产双模式:开发模式挂载源码,生产模式构建镜像
- 🛡️ 健康检查:自动检测服务状态,快速定位问题

## 环境要求
- Docker 20.10+
- Docker Compose 2.0+
- 无其他宿主机依赖(无需 Go/Protoc/Make/Postgres/Redis

## 快速开始
```bash
# 进入后端目录
cd ./backend

# 启动开发环境(自动编译 Proto + 启动所有服务)
make dev

# 检查服务状态
make test

# 查看实时日志
make logs

# 停止并清理环境
make down

# 清理所有镜像/数据卷(彻底重置)
make clean

服务端口

服务 端口 说明
gateway 8080 WebSocket + HTTP 入口
user-svc 50051 gRPC 用户服务
user-db 5432 PostgreSQL 数据库
redis 6379 Redis 缓存

开发模式 vs 生产模式

开发模式(默认)

  • 挂载本地源码到容器,支持实时修改
  • 使用 docker-compose.dev.yml 扩展配置
  • 自动重启 Go 服务(代码修改后需手动重启)

生产模式

# 构建生产镜像
make build

# 启动生产环境(无源码挂载)
docker-compose -f docker-compose.yml up -d

关键操作

编译 Proto 文件

make proto

健康检查

make test
# 或直接执行
curl http://localhost:8080/health

测试 WebSocket

# 安装 wscat或使用 Docker 版)
docker run --rm -it --network backend_backend-network jmalloc/websocket-client wss://gateway:8080/ws
> {"id":"1","type":"test","service":"user","action":"health"}

目录结构

./backend/          # 后端服务根目录
├── gateway/        # 网关服务WebSocket + HTTP
├── services/       # 微服务目录user-svc 示例)
├── shared/         # 共享代码/Proto/工具包
├── scripts/        # 自动化脚本Docker 环境适配)
├── docker-compose.yml       # 生产环境编排
├── docker-compose.dev.yml   # 开发环境编排
└── Makefile                # 快捷命令封装

技术栈版本

  • Go: 1.26.1-alpine3.23
  • PostgreSQL: 18.3-alpine3.23
  • Redis: 8.6.2-alpine
  • Docker: 20.10+
  • Docker Compose: 2.0+

## 四、验证标准(纯 Docker 环境)
### 4.1 执行命令
```bash
cd ./backend
make dev

4.2 预期结果

  1. 容器启动:gateway/user-svc/user-db/redis 4 个容器状态为 Up
  2. Proto 编译:无报错,shared/proto/common/ 生成 common.pb.gocommon_grpc.pb.go
  3. 健康检查:make test 返回 {"status":"ok"}
  4. 端口可访问:
    • ws://localhost:8080/ws 可建立 WebSocket 连接
    • localhost:5432 可连接 PostgreSQL
    • localhost:6379 可连接 Redis

4.3 生产环境验证

# 构建生产镜像
make build

# 启动生产环境
docker-compose up -d

# 验证无源码挂载,服务正常运行
docker-compose ps
curl http://localhost:8080/health

五、关键优化点(适配纯 Docker 环境)

  1. Protoc 编译容器化:无需宿主机安装 Protoc通过专用容器完成 proto 编译
  2. 依赖全内置:所有 Go 模块、系统依赖均在 Docker 内安装,无宿主机依赖
  3. 权限安全:容器内使用非 root 用户运行服务,降低安全风险
  4. 健康检查PostgreSQL/Redis 增加健康检查,确保服务就绪后启动应用
  5. 日志与重启策略:配置合理的重启策略和日志输出,便于问题排查
  6. 网络隔离:使用自定义网络,避免端口冲突和网络安全问题

六、执行说明(给 Trae 的指令)

  1. 确保目标机器已安装 Docker 和 Docker Compose
  2. 将上述目录结构和文件完整生成到 ./backend/ 目录
  3. 执行 cd ./backend && make dev 启动环境
  4. 验证 make test 返回 {"status":"ok"} 即完成基础架构搭建
  5. 后续业务逻辑开发可基于此骨架,通过挂载源码的开发模式迭代