# server/Dockerfile — onesvm-browser-server 多阶段构建（Contract §5-A5）。
#
# 架构说明（docker-image-transfer 规则）：生产 amd64；Mac（arm64）构建时
# Makefile/部署脚本传 --platform linux/amd64；本机冒烟可 --platform linux/arm64。
#
# 运行镜像二选一（默认 distroless；若生产节点拉取失败转 alpine）：
#   ① gcr.io/distroless/base-debian12:nonroot —— 无 shell，~20MB，符合 ≤60MB 目标；
#   ② alpine:3.20 —— 有 shell，healthcheck 更方便，体积 ~13MB + 二进制。
# 本仓选 ①（distroless）：镜像最小、攻击面最小；healthcheck 走二进制内建探针
# （-healthz-probe，见 cmd/browser-server main.go 同包说明）。
#
# 构建示例：
#   docker build --platform linux/amd64 -t onesvm/browser-server:dev -f server/Dockerfile .

# ---- 阶段一：构建（goproxy.cn 镜像加速；CGO 关闭纯静态）----
FROM golang:1.27-alpine AS builder

ENV GOPROXY=https://goproxy.cn,direct \
    CGO_ENABLED=0 \
    GOOS=linux

WORKDIR /src

# 先拷依赖清单做层缓存（go.mod/go.sum 变动才重新 download）。
COPY server/go.mod server/go.sum ./
RUN go mod download

COPY server/ ./
# -trimpath 去路径、-s -w 去符号表（镜像 ≤60MB 目标）；产出单二进制多角色。
RUN go build -trimpath -ldflags "-s -w" -o /out/browser-server ./cmd/browser-server \
    && touch /out/.keep   # 供 stage-2 借道 copy 一个属主为 nonroot 的文件以建 /data 目录

# ---- 阶段二：运行（distroless / nonroot）----
# 备选（若生产节点 distroless 拉不动）：把下行换为
#   FROM docker.m.daocloud.io/library/alpine:3.20
# 并补 entrypoint ["/browser-server"]（alpine 下 CMD 形式不变）。
FROM gcr.io/distroless/base-debian12:nonroot

COPY --from=builder /out/browser-server /browser-server

# 数据卷属主预置：named volume 首挂时 Docker 以镜像目录属主初始化（copy-up），
# 默认 root 属主会挡住 nonroot(65532) 写库；这里预建 /data 并授予 nonroot 属主，
# 卷挂载后 65532 可建库文件与 mihomo provider 子目录（swarm/compose 同理）。
COPY --from=builder --chown=65532:65532 /out/.keep /data/.keep

# 无 EXPOSE 需要（8640 由 stack ports/ingress 声明）；entrypoint 直指二进制，
# role 由 stack command 追加参数（-role=gateway|scheduler|proxymanager）。
ENTRYPOINT ["/browser-server"]