# 构建阶段 1:构建前端 FROM node:20-alpine AS web-builder WORKDIR /app/web # 复制前端依赖文件 COPY web/package*.json ./ RUN npm ci # 复制前端源码并构建 COPY web/ ./ RUN npm run build # 构建阶段 2:构建 Go 后端 FROM golang:1.26-alpine AS server-builder WORKDIR /app/server # 安装构建依赖 RUN apk add --no-cache git gcc musl-dev # 复制 Go 模块文件 COPY go.mod go.sum ./ RUN go mod download # 复制后端源码 COPY server/ ./ # 复制前端构建产物到 static 目录 COPY --from=web-builder /app/web/dist ./static/ # 构建 Go 二进制(静态链接,无 CGO) RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /app/lan-manager . # 运行阶段:最小化镜像 FROM alpine:3.21 LABEL maintainer="LAN Manager" LABEL description="局域网机器管理后台" WORKDIR /app # 安装必要的运行时依赖 # iputils 提供 ping 命令(用于网络检测) # ca-certificates 用于 HTTPS 请求 RUN apk add --no-cache \ ca-certificates \ iputils \ libcap \ && rm -rf /var/cache/apk/* # 从构建阶段复制二进制文件 COPY --from=server-builder /app/lan-manager /app/lan-manager # 赋予 ping 权限(不需要 root 也能执行 ICMP ping) RUN setcap cap_net_raw+ep /bin/ping || true # 创建非 root 用户运行服务 RUN adduser -D -s /bin/sh lanmgr && \ mkdir -p /app/data && \ chown -R lanmgr:lanmgr /app # 切换到非 root 用户 USER lanmgr # 暴露端口 EXPOSE 8080 # 健康检查 HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:8080/api/health || exit 1 # 设置数据目录环境变量 ENV DATA_DIR=/app/data ENV DB_PATH=/app/data/lan-manager.db ENV HOST=0.0.0.0 ENV PORT=8080 # 数据卷(持久化 SQLite 数据库) VOLUME ["/app/data"] # 启动命令 ENTRYPOINT ["/app/lan-manager"]