# ws_usernode 单二进制镜像(podman 多阶段构建) # # 构建(走代理时): # podman build -t ws-usernode:latest \ # --build-arg HTTP_PROXY=http://10.62.25.123:7897 \ # --build-arg HTTPS_PROXY=http://10.62.25.123:7897 \ # --build-arg ALL_PROXY=http://10.62.25.123:7897 \ # -f deploy/Containerfile . # 无代理环境可省略 --build-arg(Containerfile 内缺省为空,不影响)。 # 建议加 --network=host,规避容器网络插件缺失导致的拉包失败。 # ---------- 阶段 1:前端构建(node:20-alpine) ---------- FROM node:20-alpine AS web-build # proxychains 无法注入容器,代理环境变量须显式传入 ARG HTTP_PROXY= ARG HTTPS_PROXY= ARG ALL_PROXY= ARG NO_PROXY= ENV HTTP_PROXY=$HTTP_PROXY \ HTTPS_PROXY=$HTTPS_PROXY \ ALL_PROXY=$ALL_PROXY \ NO_PROXY=$NO_PROXY WORKDIR /web COPY web/package.json web/package-lock.json* ./ RUN npm install COPY web/ . RUN npm run build # 产物:/web/dist # ---------- 阶段 2:Go 构建(golang:1.22-alpine) ---------- FROM golang:1.22-alpine AS go-build ARG HTTP_PROXY= ARG HTTPS_PROXY= ARG ALL_PROXY= ARG NO_PROXY= ENV HTTP_PROXY=$HTTP_PROXY \ HTTPS_PROXY=$HTTPS_PROXY \ ALL_PROXY=$ALL_PROXY \ NO_PROXY=$NO_PROXY WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . # 用前端构建产物覆盖 internal/webui/dist(go:embed 入口) COPY --from=web-build /web/dist ./internal/webui/dist RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/usernode ./cmd/usernode # ---------- 阶段 3:运行镜像 ---------- FROM alpine:3.20 RUN apk add --no-cache ca-certificates tzdata \ && addgroup -S usernode && adduser -S -G usernode usernode COPY --from=go-build /out/usernode /usr/local/bin/usernode # 数据目录(SQLite 默认 data/usernode.db),运行时以专有用户运行 RUN mkdir -p /data && chown usernode:usernode /data VOLUME ["/data"] USER usernode WORKDIR /data EXPOSE 8080 ENTRYPOINT ["/usr/local/bin/usernode"] CMD ["serve", "--config", "/etc/usernode/config.toml"]