# ============================================================
# opsxsql - 单镜像多阶段构建(参照 opsx-loki)
#   前端 dist + Go 后端 + gh-ost 合并为一个 alpine 运行时镜像
#   非 root 用户运行;/health 健康检查;数据落 /app/data 卷
# ============================================================

# ---------------------------------------------------------------
# Stage 1: 前端构建(Node)
# ---------------------------------------------------------------
FROM node:20-alpine AS frontend-builder
WORKDIR /app/frontend
COPY frontend/package*.json ./
RUN npm ci --ignore-scripts && npm cache clean --force
COPY frontend/ ./
RUN npm run build

# ---------------------------------------------------------------
# Stage 2: 后端构建(Go,CGO 因 mattn/go-sqlite3 必开)
# ---------------------------------------------------------------
FROM golang:1.26-alpine AS backend-builder
RUN apk add --no-cache git gcc musl-dev
ENV GOTOOLCHAIN=local
WORKDIR /app/backend
COPY backend/go.* ./
RUN go mod download
COPY backend/ ./
RUN CGO_ENABLED=1 GOOS=linux go build -trimpath -ldflags="-s -w" -o /out/opsxsql ./cmd/server/

# ---------------------------------------------------------------
# Stage 3: gh-ost 在线变更工具(静态二进制,按架构取包)
#
# 注意：GitHub release 的实际 asset 名不是 gh-ost-linux-<arch>，而是：
#   amd64: gh-ost                              （裸二进制，18MB）
#   arm64: gh-ost-binary-linux-arm64-<ts>.tar.gz（tar 包）
# ---------------------------------------------------------------
FROM alpine:3.20 AS ghost
ARG TARGETARCH
ARG GH_OST_VER=v1.1.9
ARG GH_OST_ARM64_ASSET=gh-ost-binary-linux-arm64-20260501022029.tar.gz
RUN mkdir -p /out && \
    apk add --no-cache curl tar && \
    case "${TARGETARCH}" in \
      arm64) \
        curl -fsSL -o /tmp/gh.tgz \
          "https://github.com/github/gh-ost/releases/download/${GH_OST_VER}/${GH_OST_ARM64_ASSET}" && \
        tar -xzf /tmp/gh.tgz -C /tmp && \
        mv /tmp/gh-ost-binary-linux-arm64-* /out/gh-ost ;; \
      *) \
        curl -fsSL -o /out/gh-ost \
          "https://github.com/github/gh-ost/releases/download/${GH_OST_VER}/gh-ost" ;; \
    esac && \
    chmod +x /out/gh-ost && \
    ls -lh /out/gh-ost

# ---------------------------------------------------------------
# Stage 4: 运行时镜像
# ---------------------------------------------------------------
FROM alpine:3.20
RUN apk --no-cache add ca-certificates tzdata wget sqlite && \
    rm -rf /tmp/* /var/cache/apk/*

# 非 root 用户
RUN addgroup -g 1000 opsxsql && \
    adduser -u 1000 -G opsxsql -s /bin/sh -D opsxsql

WORKDIR /app
COPY --from=backend-builder --chown=opsxsql:opsxsql /out/opsxsql ./opsxsql
COPY --from=ghost --chown=opsxsql:opsxsql /out/gh-ost /usr/local/bin/gh-ost
COPY --from=frontend-builder --chown=opsxsql:opsxsql /app/frontend/dist ./dist

RUN mkdir -p /app/data && chown -R opsxsql:opsxsql /app/data && \
    chmod +x ./opsxsql

ENV DIST_DIR=/app/dist \
    DB_PATH=/app/data/sqlite3.db \
    PORT=9000 \
    DEBUG=false \
    GH_OST_PATH=/usr/local/bin/gh-ost \
    HOME=/home/opsxsql

COPY --chown=opsxsql:opsxsql docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh

USER opsxsql
EXPOSE 9000
VOLUME ["/app/data"]

HEALTHCHECK --interval=30s --timeout=5s --retries=3 --start-period=15s \
  CMD wget --no-verbose --tries=1 --spider http://localhost:9000/health || exit 1

ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
