wavelet init

This commit is contained in:
ryan
2026-06-18 15:24:48 +08:00
parent d6a7011885
commit 99738bbc17
714 changed files with 139987 additions and 0 deletions
+68
View File
@@ -0,0 +1,68 @@
# syntax=docker/dockerfile:1.7
ARG GO_VERSION=1.25
ARG NODE_VERSION=22
ARG ALPINE_VERSION=3.23
FROM node:${NODE_VERSION}-alpine AS frontend-builder
ARG VERSION=dev
ARG BUILD_DATE=""
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
ENV NODE_ENV=production
ENV NEXT_STANDALONE_EXPORT=true
ENV NEXT_PUBLIC_APP_VERSION=${VERSION}
ENV NEXT_PUBLIC_APP_BUILD_DATE=${BUILD_DATE}
RUN corepack enable && corepack prepare pnpm@10.10.0 --activate
WORKDIR /workspace/frontend
COPY frontend/package.json frontend/pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY frontend/ ./
RUN pnpm build:embed
FROM golang:${GO_VERSION}-alpine AS backend-builder
ARG VERSION=dev
ARG BUILD_DATE=""
RUN apk add --no-cache ca-certificates git
WORKDIR /workspace
COPY go.mod go.sum ./
RUN go mod download
COPY . .
COPY --from=frontend-builder /workspace/frontend/out ./internal/router/root/dist
RUN CGO_ENABLED=0 GOOS=linux go build \
-tags embed_frontend \
-trimpath \
-ldflags="-s -w -X github.com/Rain-kl/Wavelet/internal/buildinfo.Version=${VERSION} -X github.com/Rain-kl/Wavelet/internal/buildinfo.BuildTime=${BUILD_DATE}" \
-o /out/wavelet \
./main.go
FROM alpine:${ALPINE_VERSION}
ARG TZ=Asia/Shanghai
RUN apk add --no-cache ca-certificates tzdata postgresql-client && \
cp /usr/share/zoneinfo/${TZ} /etc/localtime && \
echo "${TZ}" > /etc/timezone
WORKDIR /app
COPY --from=backend-builder /out/wavelet ./wavelet
COPY docs ./docs
EXPOSE 8000
ENTRYPOINT ["./wavelet"]
CMD ["all"]
+42
View File
@@ -0,0 +1,42 @@
# syntax=docker/dockerfile:1.7
ARG GO_VERSION=1.25
ARG ALPINE_VERSION=3.23
FROM golang:${GO_VERSION}-alpine AS builder
ARG VERSION=dev
ARG BUILD_DATE=""
RUN apk add --no-cache ca-certificates git
WORKDIR /workspace
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build \
-trimpath \
-ldflags="-s -w -X github.com/Rain-kl/Wavelet/internal/buildinfo.Version=${VERSION} -X github.com/Rain-kl/Wavelet/internal/buildinfo.BuildTime=${BUILD_DATE}" \
-o /out/wavelet \
./main.go
FROM alpine:${ALPINE_VERSION}
ARG TZ=Asia/Shanghai
RUN apk add --no-cache ca-certificates tzdata postgresql-client && \
cp /usr/share/zoneinfo/${TZ} /etc/localtime && \
echo "${TZ}" > /etc/timezone
WORKDIR /app
COPY --from=builder /out/wavelet ./wavelet
COPY docs ./docs
EXPOSE 8000
ENTRYPOINT ["./wavelet"]
CMD ["api"]
+108
View File
@@ -0,0 +1,108 @@
# syntax=docker/dockerfile:1.7
# Cross-platform build workflow — produces up to 6 static binaries under ./bin/
# Each binary embeds the compiled frontend and is stamped with VERSION.
#
# Build args:
# VERSION — version string injected at link time (default: dev)
# TARGET_OS — restrict to one OS: linux | darwin | windows (default: all)
# TARGET_ARCH — restrict to one arch: amd64 | arm64 (default: all)
#
# Usage:
# docker build -f docker/Dockerfile.cross --output ./bin .
# docker build -f docker/Dockerfile.cross \
# --build-arg VERSION=v1.2.3 --output ./bin .
# docker build -f docker/Dockerfile.cross \
# --build-arg TARGET_OS=linux --build-arg TARGET_ARCH=arm64 \
# --output ./bin .
#
# Or via Makefile:
# make cross-build
# make cross-build VERSION=v1.2.3
# make cross-build GOOS=linux GOARCH=arm64
# make cross-build GOOS=darwin
ARG GO_VERSION=1.25
ARG NODE_VERSION=22
ARG ALPINE_VERSION=3.23
# ── Stage 1: Build frontend (static export for embedding) ────────────────────
FROM node:${NODE_VERSION}-alpine AS frontend-builder
ARG VERSION=dev
ARG BUILD_DATE=""
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
ENV NODE_ENV=production
ENV NEXT_STANDALONE_EXPORT=true
ENV NEXT_PUBLIC_APP_VERSION=${VERSION}
ENV NEXT_PUBLIC_APP_BUILD_DATE=${BUILD_DATE}
RUN corepack enable && corepack prepare pnpm@10.10.0 --activate
WORKDIR /workspace/frontend
# Cache dependency layer
COPY frontend/package.json frontend/pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY frontend/ ./
RUN pnpm build:embed
# ── Stage 2: Cross-compile Go backend ──────────────────────────────────────
FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS builder
ARG VERSION=dev
ARG BUILD_DATE=""
# Empty string means "build all"; set to a specific value to filter.
ARG TARGET_OS=
ARG TARGET_ARCH=
# git — needed by go mod download for VCS-stamped modules
# ca-certificates — needed for HTTPS during module download
RUN apk add --no-cache ca-certificates git
WORKDIR /workspace
# Cache dependency layer
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# Overlay the compiled frontend into the embed path
COPY --from=frontend-builder /workspace/frontend/out ./internal/router/root/dist
# Build matrix: GOOS × GOARCH
# CGO_ENABLED=0 — fully static, no libc dependency, required for cross-compilation.
# -trimpath — strip local filesystem paths from the binary.
# -s -w — omit symbol table and DWARF debug info (smaller output).
# -X — stamp version string at link time.
# TARGET_OS / TARGET_ARCH — when non-empty, skip non-matching combinations.
RUN set -e; \
mkdir -p /out; \
FILTER_OS="${TARGET_OS}"; \
FILTER_ARCH="${TARGET_ARCH}"; \
for GOOS in linux darwin windows; do \
[ -n "$FILTER_OS" ] && [ "$GOOS" != "$FILTER_OS" ] && continue; \
for GOARCH in amd64 arm64; do \
[ -n "$FILTER_ARCH" ] && [ "$GOARCH" != "$FILTER_ARCH" ] && continue; \
EXT=""; \
[ "$GOOS" = "windows" ] && EXT=".exe"; \
OUTPUT="/out/wavelet_${GOOS}_${GOARCH}${EXT}"; \
echo "==> Building ${OUTPUT} (version=${VERSION})..."; \
CGO_ENABLED=0 GOOS=${GOOS} GOARCH=${GOARCH} \
go build \
-tags embed_frontend \
-trimpath \
-ldflags="-s -w -X github.com/Rain-kl/Wavelet/internal/buildinfo.Version=${VERSION} -X github.com/Rain-kl/Wavelet/internal/buildinfo.BuildTime=${BUILD_DATE}" \
-o "${OUTPUT}" \
./main.go; \
done; \
done
# ── Export stage ─────────────────────────────────────────────────────────────
# `docker build --output ./bin .` copies everything from /out to the host.
FROM scratch AS export
COPY --from=builder /out/ /
+53
View File
@@ -0,0 +1,53 @@
# syntax=docker/dockerfile:1.7
ARG NODE_VERSION=22
FROM node:${NODE_VERSION}-alpine AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable && corepack prepare pnpm@10.10.0 --activate
FROM base AS builder
ENV NODE_ENV=production
ENV NEXT_PUBLIC_WAVELET_BACKEND_URL=https://build-placeholder.invalid
ENV WAVELET_SESSION_COOKIE_NAME=__WAVELET_SESSION_COOKIE_NAME__
ENV WAVELET_RATE_LIMIT_ENABLED=__WAVELET_RATE_LIMIT_ENABLED__
ENV WAVELET_BACKEND_URL=https://build-placeholder-2.invalid
ARG VERSION=""
ARG BUILD_DATE=""
ENV NEXT_PUBLIC_APP_VERSION=${VERSION}
ENV NEXT_PUBLIC_APP_BUILD_DATE=${BUILD_DATE}
WORKDIR /app
COPY frontend/package.json frontend/pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY frontend/ ./
RUN pnpm build
RUN grep -rl \
-e "https://build-placeholder.invalid" \
-e "https://build-placeholder-2.invalid" \
-e "__WAVELET_SESSION_COOKIE_NAME__" \
-e "__WAVELET_RATE_LIMIT_ENABLED__" \
/app/.next > /app/.replace.files
FROM base AS runner
ENV NODE_ENV=production
WORKDIR /app
COPY --from=builder /app ./
EXPOSE 3010
ENTRYPOINT ["./entrypoint.sh"]
CMD ["pnpm", "start"]