從 edge-ai-platform POC 轉為正式產品的雲端後端,含以下整合階段:
- Phase 0:雛形骨架 — `cmd/api-server` (REST :3721) + `cmd/remote-proxy`
(tunnel :3800 / internal :3801) 雙 binary 共用 internal/,沿用 POC 的
WebSocket+yamux tunnel 協定但解耦 relay 與 API
- Phase 0.6:OIDC BFF 接 Innovedus Member Center
- internal/oidc package(coreos/go-oidc + PKCE S256 + state + nonce)
- internal/usersession package(HMAC-SHA256 cookie + RotateSessionID
防 session fixation, OWASP ASVS V3.2.1)
- 4 個 OIDC handler(/api/auth/login|callback|me|logout)+ AuthMiddleware
- 完全拔除 StaticAuthProvider,OIDC 是唯一認證路徑
- 9 個 ADR(含 ADR-010 BFF / ADR-011 取代 static auth /
ADR-012 pending session shared cookie / ADR-013 PKCE-only public client)
- Phase 0.7:A1 改造 + security audit 修復
- OIDC ClientSecret 變選填,支援 stage MC 的 public PKCE-only client
(AuthStyleInParams 強制 token endpoint 不送 client_secret)
- 預留 ServiceClient* 欄位給未來 client_credentials grant
- 移除 13+ 處 resolveUserID(uc, StaticUserID) fallback 改 strict mode
(Audit C1:multi-tenant 隔離破口)
- Pairing exchange MarkUsed 失敗 abort + revoke session token(Audit M3)
- 新增 all_endpoints_require_auth_test 整合測試(51 endpoint × 401)
驗證:go test -race -count=3 ./... 17 packages 全綠 / go vet 0 warning
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
73 lines
2.7 KiB
Docker
73 lines
2.7 KiB
Docker
# syntax=docker/dockerfile:1.6
|
||
#
|
||
# visionA-backend / api-server — multi-stage Docker image
|
||
#
|
||
# 設計原則(對齊 build-deploy.md §2 與 backend CLAUDE.md §9):
|
||
# - Multi-stage:builder 階段負責編譯,runtime 階段只帶 binary(image 最小化)
|
||
# - CGO_ENABLED=0:產出 static binary,可直接放進 alpine/distroless
|
||
# - Non-root user:降低 container escape 風險
|
||
# - HEALTHCHECK:container 層級健康檢查(K8s / docker-compose 會用到)
|
||
#
|
||
# Build:
|
||
# docker build -f docker/Dockerfile.api-server -t visiona/api-server:dev .
|
||
# 執行目錄為 visionA-backend/,因此 COPY . . 會把整個 backend 帶進 builder。
|
||
|
||
# ---- Stage 1: builder ----------------------------------------------------
|
||
FROM golang:1.26-alpine AS builder
|
||
|
||
# git 給 go mod download 用(部分 module path 會需要)
|
||
RUN apk add --no-cache git ca-certificates
|
||
|
||
WORKDIR /src
|
||
|
||
# 先 COPY go.mod / go.sum,讓 dependency layer 可以被 cache(只有改依賴才重跑)
|
||
COPY go.mod go.sum ./
|
||
RUN go mod download
|
||
|
||
# 複製其餘原始碼
|
||
COPY . .
|
||
|
||
# 編譯 api-server:
|
||
# - CGO_ENABLED=0:pure Go static binary(alpine 可以直接跑)
|
||
# - -ldflags="-s -w":strip debug info,縮小 binary 大小
|
||
# - -trimpath:去掉原始碼路徑,避免洩漏 builder 主機資訊
|
||
ENV CGO_ENABLED=0 GOOS=linux
|
||
RUN go build -trimpath -ldflags="-s -w" -o /out/api-server ./cmd/api-server
|
||
|
||
# ---- Stage 2: runtime ----------------------------------------------------
|
||
FROM alpine:3.19
|
||
|
||
# 安裝 curl 給 HEALTHCHECK 用 + ca-certificates 給未來 HTTPS out-bound 用
|
||
# (Phase 0 雛形沒 outbound HTTPS,但預裝不增加太多體積,避免日後踩雷)
|
||
RUN apk add --no-cache ca-certificates curl tzdata && \
|
||
addgroup -S -g 1001 visiona && \
|
||
adduser -S -u 1001 -G visiona visiona
|
||
|
||
WORKDIR /app
|
||
|
||
# 建立 storage 目錄(讓 LocalFS backend 預設路徑可寫)
|
||
RUN mkdir -p /app/data/storage && chown -R visiona:visiona /app
|
||
|
||
# 複製 binary
|
||
COPY --from=builder --chown=visiona:visiona /out/api-server /app/api-server
|
||
|
||
# 切到非 root
|
||
USER visiona:visiona
|
||
|
||
# api-server 預設 listen 3721(對齊 local-tool,見 config/config.go ServerConfig.Port)
|
||
EXPOSE 3721
|
||
|
||
# 預設環境變數:容器內的儲存路徑。
|
||
# 實際部署時由 docker-compose 或 K8s ConfigMap / Secret 覆蓋。
|
||
ENV VISIONA_HOST=0.0.0.0 \
|
||
VISIONA_API_PORT=3721 \
|
||
VISIONA_STORAGE_LOCALFS_ROOT=/app/data/storage \
|
||
VISIONA_LOG_LEVEL=info
|
||
|
||
# Container 層級 healthcheck — docker / compose 會用。
|
||
# 30s 週期、3s timeout、連續 3 次失敗視為 unhealthy。
|
||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||
CMD curl -fsS http://localhost:3721/healthz || exit 1
|
||
|
||
ENTRYPOINT ["/app/api-server"]
|