mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-29 05:56:38 +08:00
更新项目
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
.git
|
||||
.idea
|
||||
.vscode
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
config.yaml
|
||||
.env
|
||||
.env.*
|
||||
|
||||
bin/
|
||||
build/
|
||||
dist/
|
||||
data/
|
||||
logs/
|
||||
uploads/
|
||||
s3_cache/
|
||||
|
||||
frontend/node_modules/
|
||||
frontend/.next/
|
||||
frontend/out/
|
||||
frontend/build/
|
||||
frontend/disk/
|
||||
frontend/.env
|
||||
frontend/next-env.d.ts
|
||||
frontend/*.tsbuildinfo
|
||||
frontend/package-lock.json
|
||||
|
||||
internal/router/dist/
|
||||
@@ -39,14 +39,17 @@
|
||||
以下是项目的顶层目录结构及其职责, 如果有新增目录或文件,请务必在此处同步更新:
|
||||
|
||||
```
|
||||
Refreshing/ # 项目根目录(模块名: github.com/linux-do/credit)
|
||||
wavelet/ # 项目根目录(模块名: github.com/linux-do/credit)
|
||||
├── main.go # 程序入口,调用 internal/cmd
|
||||
├── go.mod / go.sum # Go 模块依赖
|
||||
├── config.yaml # 运行时配置(不提交到 Git)
|
||||
├── config.example.yaml # 配置模板(需提交)
|
||||
├── DEPLOYMENT_zh.md # 部署说明文档(中文版)
|
||||
├── Makefile # 常用命令(swagger/tidy/license)
|
||||
├── Dockerfile # 后端容器镜像构建
|
||||
├── docker/ # Docker 镜像构建文件(集成/前端/后端)
|
||||
│ ├── Dockerfile # 标准集成镜像(前端静态导出嵌入后端)
|
||||
│ ├── Dockerfile.frontend # 仅前端镜像(Next.js)
|
||||
│ └── Dockerfile.backend # 仅后端镜像(Go API/Worker/Scheduler)
|
||||
├── docker-compose.yml # 本地依赖服务(PostgreSQL / Redis / ClickHouse)
|
||||
├── .editorconfig # 编辑器格式规范
|
||||
├── .gitignore
|
||||
|
||||
@@ -39,14 +39,17 @@
|
||||
以下是项目的顶层目录结构及其职责, 如果有新增目录或文件,请务必在此处同步更新:
|
||||
|
||||
```
|
||||
Refreshing/ # 项目根目录(模块名: github.com/linux-do/credit)
|
||||
wavelet/ # 项目根目录(模块名: github.com/linux-do/credit)
|
||||
├── main.go # 程序入口,调用 internal/cmd
|
||||
├── go.mod / go.sum # Go 模块依赖
|
||||
├── config.yaml # 运行时配置(不提交到 Git)
|
||||
├── config.example.yaml # 配置模板(需提交)
|
||||
├── DEPLOYMENT_zh.md # 部署说明文档(中文版)
|
||||
├── Makefile # 常用命令(swagger/tidy/license)
|
||||
├── Dockerfile # 后端容器镜像构建
|
||||
├── docker/ # Docker 镜像构建文件(集成/前端/后端)
|
||||
│ ├── Dockerfile # 标准集成镜像(前端静态导出嵌入后端)
|
||||
│ ├── Dockerfile.frontend # 仅前端镜像(Next.js)
|
||||
│ └── Dockerfile.backend # 仅后端镜像(Go API/Worker/Scheduler)
|
||||
├── docker-compose.yml # 本地依赖服务(PostgreSQL / Redis / ClickHouse)
|
||||
├── .editorconfig # 编辑器格式规范
|
||||
├── .gitignore
|
||||
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
FROM alpine:3.23
|
||||
|
||||
# set the time zone to Beijing Time in the Eastern 8th Time Zone
|
||||
ARG TZ=Asia/Shanghai
|
||||
RUN apk add --no-cache tzdata && \
|
||||
cp /usr/share/zoneinfo/${TZ} /etc/localtime && \
|
||||
echo "${TZ}" > /etc/timezone
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# set build arg for platform
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
# copy the appropriate binary based on platform
|
||||
COPY credit-server-${TARGETPLATFORM#linux/} ./credit-server
|
||||
|
||||
# copy docs
|
||||
COPY docs ./docs
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
# set entrypoint
|
||||
ENTRYPOINT ["./credit-server"]
|
||||
@@ -5,4 +5,4 @@ build-embedded:
|
||||
cd frontend && pnpm build:embed
|
||||
rm -rf internal/router/dist
|
||||
cp -R frontend/out internal/router/dist
|
||||
go build -tags embed_frontend -o bin/credit main.go
|
||||
go build -tags embed_frontend -o bin/wavelet main.go
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Wavelet
|
||||
# wavelet
|
||||
|
||||
🚀 A modern, production-ready full-stack boilerplate for building scalable web applications
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
## 📖 Introduction
|
||||
|
||||
**Wavelet** is a generic, production-ready full-stack boilerplate built with **Go (Gin + GORM)** on the backend and **Next.js (App Router + Shadcn UI)** on the frontend. It ships with everything you need to bootstrap a modern SaaS, internal tool, or developer platform — without the boilerplate headaches.
|
||||
**wavelet** is a generic, production-ready full-stack boilerplate built with **Go (Gin + GORM)** on the backend and **Next.js (App Router + Shadcn UI)** on the frontend. It ships with everything you need to bootstrap a modern SaaS, internal tool, or developer platform — without the boilerplate headaches.
|
||||
|
||||
The project was designed from the ground up to be **framework-first and business-agnostic**: plug in your own domain logic while reusing the battle-tested infrastructure that comes out of the box.
|
||||
|
||||
@@ -209,11 +209,11 @@ pnpm format
|
||||
## 📁 Project Structure
|
||||
|
||||
```
|
||||
Refreshing/
|
||||
wavelet/
|
||||
├── main.go # Entry point (delegates to internal/cmd)
|
||||
├── config.example.yaml # Configuration template
|
||||
├── Makefile # Common commands (swagger, tidy, license)
|
||||
├── Dockerfile # Container image build
|
||||
├── docker/ # Docker image build files (integrated/frontend/backend)
|
||||
├── docs/ # Swagger auto-generated docs
|
||||
├── frontend/ # Next.js frontend application
|
||||
│ ├── app/ # App Router pages
|
||||
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
# Wavelet
|
||||
# wavelet
|
||||
|
||||
🚀 现代化、生产就绪的全栈应用脚手架
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
## 📖 项目简介
|
||||
|
||||
**Wavelet** 是一个通用型、生产就绪的现代全栈脚手架,后端采用 **Go(Gin + GORM)**,前端采用 **Next.js(App Router + Shadcn UI)**。项目开箱即用,内置构建现代 SaaS、内部工具或开发者平台所需的核心基础设施。
|
||||
**wavelet** 是一个通用型、生产就绪的现代全栈脚手架,后端采用 **Go(Gin + GORM)**,前端采用 **Next.js(App Router + Shadcn UI)**。项目开箱即用,内置构建现代 SaaS、内部工具或开发者平台所需的核心基础设施。
|
||||
|
||||
项目设计理念是 **框架优先、业务中立**:您可以在沿用经过实战检验的底层基础设施的同时,自由接入自己的业务逻辑。
|
||||
|
||||
@@ -209,11 +209,11 @@ pnpm format
|
||||
## 📁 项目结构
|
||||
|
||||
```
|
||||
Refreshing/
|
||||
wavelet/
|
||||
├── main.go # 程序入口(委托给 internal/cmd)
|
||||
├── config.example.yaml # 配置模板
|
||||
├── Makefile # 常用命令(swagger、tidy、license)
|
||||
├── Dockerfile # 容器镜像构建
|
||||
├── docker/ # Docker 镜像构建文件(集成/前端/后端)
|
||||
├── docs/ # Swagger 自动生成文档
|
||||
├── frontend/ # Next.js 前端应用
|
||||
│ ├── app/ # App Router 页面
|
||||
|
||||
+3
-4
@@ -1,15 +1,15 @@
|
||||
# Wavelet — Full-Stack Boilerplate Config
|
||||
# wavelet — Full-Stack Boilerplate Config
|
||||
# Copy this file to config.yaml and fill in your values.
|
||||
# Fields marked with <...> are required; others have sensible defaults.
|
||||
|
||||
# ─── Application ────────────────────────────────────────────────────────────────
|
||||
app:
|
||||
app_name: "Wavelet"
|
||||
app_name: "wavelet"
|
||||
env: "development" # development | testing | production
|
||||
addr: ":8000"
|
||||
node_id: 1 # Snowflake node ID (0-1023). Must be unique per instance.
|
||||
graceful_shutdown_timeout: 30
|
||||
session_cookie_name: "Wavelet_session_id" # Change to something unique before deploy
|
||||
session_cookie_name: "wavelet_session_id" # Change to something unique before deploy
|
||||
session_secret: "<uniq-random-string>" # Cannot be changed after first start
|
||||
session_domain: "" # e.g. ".yourdomain.com"
|
||||
session_age: 86400 # Session lifetime in seconds (default: 24h)
|
||||
@@ -127,4 +127,3 @@ s3:
|
||||
local_cache:
|
||||
enabled: false
|
||||
cache_dir: "./s3_cache"
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:17-alpine
|
||||
container_name: Wavelet-postgres
|
||||
container_name: wavelet-postgres
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: ${POSTGRES_DB:-wavelet}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
# 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
|
||||
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
ENV NODE_ENV=production
|
||||
ENV NEXT_STANDALONE_EXPORT=true
|
||||
|
||||
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
|
||||
|
||||
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/dist
|
||||
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build \
|
||||
-tags embed_frontend \
|
||||
-trimpath \
|
||||
-ldflags="-s -w" \
|
||||
-o /out/wavelet \
|
||||
./main.go
|
||||
|
||||
FROM alpine:${ALPINE_VERSION}
|
||||
|
||||
ARG TZ=Asia/Shanghai
|
||||
|
||||
RUN apk add --no-cache ca-certificates tzdata && \
|
||||
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 ["api"]
|
||||
@@ -0,0 +1,39 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
|
||||
ARG GO_VERSION=1.25
|
||||
ARG ALPINE_VERSION=3.23
|
||||
|
||||
FROM golang:${GO_VERSION}-alpine AS builder
|
||||
|
||||
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" \
|
||||
-o /out/wavelet \
|
||||
./main.go
|
||||
|
||||
FROM alpine:${ALPINE_VERSION}
|
||||
|
||||
ARG TZ=Asia/Shanghai
|
||||
|
||||
RUN apk add --no-cache ca-certificates tzdata && \
|
||||
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"]
|
||||
@@ -0,0 +1,54 @@
|
||||
# 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_LINUX_DO_CREDIT_BACKEND_URL=https://build-placeholder.invalid
|
||||
ENV LINUX_DO_CREDIT_SESSION_COOKIE_NAME=__LINUX_DO_CREDIT_SESSION_COOKIE_NAME__
|
||||
ENV LINUX_DO_CREDIT_RATE_LIMIT_ENABLED=__LINUX_DO_CREDIT_RATE_LIMIT_ENABLED__
|
||||
ENV LINUX_DO_CREDIT_BACKEND_URL=https://build-placeholder-2.invalid
|
||||
|
||||
ARG VERSION=""
|
||||
ARG BUILD_DATE=""
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY frontend/package.json frontend/pnpm-lock.yaml ./
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
COPY frontend/ ./
|
||||
|
||||
RUN if [ -n "$VERSION" ] || [ -n "$BUILD_DATE" ]; then \
|
||||
VERSION="$VERSION" BUILD_DATE="$BUILD_DATE" node -e "const fs = require('fs'); const pkg = require('./package.json'); const version = process.env.VERSION; const buildDate = process.env.BUILD_DATE; if (version) pkg.version = version; if (buildDate) pkg.buildDate = buildDate; fs.writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\\n')"; \
|
||||
fi
|
||||
|
||||
RUN pnpm build
|
||||
|
||||
RUN grep -rl \
|
||||
-e "https://build-placeholder.invalid" \
|
||||
-e "https://build-placeholder-2.invalid" \
|
||||
-e "__LINUX_DO_CREDIT_SESSION_COOKIE_NAME__" \
|
||||
-e "__LINUX_DO_CREDIT_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"]
|
||||
+15
-15
@@ -1,6 +1,6 @@
|
||||
# Wavelet 部署指南
|
||||
# wavelet 部署指南
|
||||
|
||||
本文档详细介绍了 **Wavelet** 脚手架系统在不同业务阶段的部署方案,涵盖从**最小化单机部署**到**最大化高可用分布式部署**的全生命周期架构。
|
||||
本文档详细介绍了 **wavelet** 脚手架系统在不同业务阶段的部署方案,涵盖从**最小化单机部署**到**最大化高可用分布式部署**的全生命周期架构。
|
||||
|
||||
---
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
| 组件名称 | 运行命令/形式 | 职责说明 | 必选/可选 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **HTTP API 服务** | `bin/credit api` | 接收并处理前端及第三方的 RESTful API 请求 | **必选** |
|
||||
| **异步任务工作进程** | `bin/credit worker` | 消费并处理异步队列任务(如邮件发送、清理上传文件等) | **必选** |
|
||||
| **定时任务调度器** | `bin/credit scheduler` | 定时向 Redis 队列下发 Cron 任务(仅负责触发,不负责执行) | **必选** |
|
||||
| **HTTP API 服务** | `bin/wavelet api` | 接收并处理前端及第三方的 RESTful API 请求 | **必选** |
|
||||
| **异步任务工作进程** | `bin/wavelet worker` | 消费并处理异步队列任务(如邮件发送、清理上传文件等) | **必选** |
|
||||
| **定时任务调度器** | `bin/wavelet scheduler` | 定时向 Redis 队列下发 Cron 任务(仅负责触发,不负责执行) | **必选** |
|
||||
| **前端服务 (Node.js)** | `pnpm start` | 提供 React/Next.js 页面服务(在分离部署时使用) | 分离模式必选 |
|
||||
| **PostgreSQL** | 关系型主数据库 | 存储用户、系统配置、认证源、任务执行记录等核心数据 | **必选** |
|
||||
| **Redis** | 缓存与消息队列中间件 | 存储 Session 会话、临时缓存以及 Asynq 异步任务队列数据 | **必选** |
|
||||
@@ -99,12 +99,12 @@ docker compose up -d
|
||||
make build-embedded
|
||||
```
|
||||
该命令会自动完成前端的静态编译导出 (`frontend/out`)、复制到 Go 后端目录,最后使用 `-tags embed_frontend` 生成后端单文件:
|
||||
- 产物路径:`bin/credit`
|
||||
- 产物路径:`bin/wavelet`
|
||||
|
||||
#### 3. 进程管理 (使用 Systemd)
|
||||
将 `bin/credit` 拷贝到生产服务器 `/usr/local/bin/credit`,并为 `api`、`worker` 和 `scheduler` 配置 Systemd 管理服务。
|
||||
将 `bin/wavelet` 拷贝到生产服务器 `/usr/local/bin/wavelet`,并为 `api`、`worker` 和 `scheduler` 配置 Systemd 管理服务。
|
||||
|
||||
新建 API 进程服务文件 `/etc/systemd/system/refreshing-api.service`:
|
||||
新建 API 进程服务文件 `/etc/systemd/system/wavelet-api.service`:
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Refreshing API Service
|
||||
@@ -114,14 +114,14 @@ After=network.target
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/app
|
||||
ExecStart=/usr/local/bin/credit api
|
||||
ExecStart=/usr/local/bin/wavelet api
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
同理,新建 Worker 服务 `/etc/systemd/system/refreshing-worker.service`(将命令改为 `credit worker`),以及 Scheduler 服务 `/etc/systemd/system/refreshing-scheduler.service`(将命令改为 `credit scheduler`)。
|
||||
同理,新建 Worker 服务 `/etc/systemd/system/wavelet-worker.service`(将命令改为 `wavelet worker`),以及 Scheduler 服务 `/etc/systemd/system/wavelet-scheduler.service`(将命令改为 `wavelet scheduler`)。
|
||||
|
||||
启动并启用所有服务:
|
||||
```bash
|
||||
@@ -171,9 +171,9 @@ server {
|
||||
#### 1. 部署后端 Go 服务
|
||||
1. 编译后端:
|
||||
```bash
|
||||
go build -o bin/credit main.go
|
||||
go build -o bin/wavelet main.go
|
||||
```
|
||||
2. 在后端服务器上,同样使用 Systemd 或 Docker 守护启动 `credit api`、`credit worker` 和 `credit scheduler`。
|
||||
2. 在后端服务器上,同样使用 Systemd 或 Docker 守护启动 `wavelet api`、`wavelet worker` 和 `wavelet scheduler`。
|
||||
3. 配置后端 Nginx 将客户端 API 请求(如 `/api/...`)反向代理至后端绑定的端口(如 `:8000`)。
|
||||
|
||||
#### 2. 部署前端 Next.js 服务
|
||||
@@ -301,9 +301,9 @@ s3:
|
||||
```
|
||||
|
||||
#### 4. 后端进程横向拆分部署
|
||||
- **API 集群**:启动数十个甚至上百个 `credit api` 无状态容器。它们可以通过负载均衡器直接挂载,支持随时弹性缩容扩容。
|
||||
- **Worker 集群**:启动多个 `credit worker` 容器。因为 `Asynq` 基于 Redis 分布式处理,多个 Worker 进程可以安全地同时运行并竞抢同一队列的异步任务,自动保障任务的并发吞吐能力。
|
||||
- **Scheduler 独占**:**【注意】** 为避免重复触发定时 Cron 任务,`credit scheduler` 定时调度器进程**同一时间应仅运行单个活跃实例**(主备高可用可以通过容器平台的单实例保障或 K8s Job 机制来限制实例数为 1)。
|
||||
- **API 集群**:启动数十个甚至上百个 `wavelet api` 无状态容器。它们可以通过负载均衡器直接挂载,支持随时弹性缩容扩容。
|
||||
- **Worker 集群**:启动多个 `wavelet worker` 容器。因为 `Asynq` 基于 Redis 分布式处理,多个 Worker 进程可以安全地同时运行并竞抢同一队列的异步任务,自动保障任务的并发吞吐能力。
|
||||
- **Scheduler 独占**:**【注意】** 为避免重复触发定时 Cron 任务,`wavelet scheduler` 定时调度器进程**同一时间应仅运行单个活跃实例**(主备高可用可以通过容器平台的单实例保障或 K8s Job 机制来限制实例数为 1)。
|
||||
|
||||
#### 5. ClickHouse 高并发同步
|
||||
在大数据量、高频支付结算场景下,开启 ClickHouse 以接收系统的历史数据同步(如订单流水和任务大宽表),通过定时器把 PostgreSQL 的压力转移到 ClickHouse 列式存储中。
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
# ---- base stage ----
|
||||
FROM node:22-alpine AS base
|
||||
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
|
||||
RUN corepack enable && corepack prepare pnpm@10.10.0 --activate
|
||||
|
||||
# ---- build stage ----
|
||||
FROM base AS builder
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV NEXT_PUBLIC_LINUX_DO_CREDIT_BACKEND_URL=https://build-placeholder.invalid
|
||||
ENV LINUX_DO_CREDIT_SESSION_COOKIE_NAME=__LINUX_DO_CREDIT_SESSION_COOKIE_NAME__
|
||||
ENV LINUX_DO_CREDIT_RATE_LIMIT_ENABLED=__LINUX_DO_CREDIT_RATE_LIMIT_ENABLED__
|
||||
ENV LINUX_DO_CREDIT_BACKEND_URL=https://build-placeholder-2.invalid
|
||||
|
||||
ARG VERSION=""
|
||||
ARG BUILD_DATE=""
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json pnpm-lock.yaml ./
|
||||
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN if [ -n "$VERSION" ] || [ -n "$BUILD_DATE" ]; then \
|
||||
VERSION="$VERSION" BUILD_DATE="$BUILD_DATE" node -e "const fs = require('fs'); const pkg = require('./package.json'); const version = process.env.VERSION; const buildDate = process.env.BUILD_DATE; if (version) pkg.version = version; if (buildDate) pkg.buildDate = buildDate; fs.writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\\n')"; \
|
||||
fi
|
||||
|
||||
RUN pnpm build
|
||||
|
||||
RUN grep -rl \
|
||||
-e "https://build-placeholder.invalid" \
|
||||
-e "https://build-placeholder-2.invalid" \
|
||||
-e "__LINUX_DO_CREDIT_SESSION_COOKIE_NAME__" \
|
||||
-e "__LINUX_DO_CREDIT_RATE_LIMIT_ENABLED__" \
|
||||
/app/.next > /app/.replace.files
|
||||
|
||||
# ---- runner stage ----
|
||||
FROM base AS runner
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /app .
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
ENTRYPOINT ["./entrypoint.sh"]
|
||||
CMD ["pnpm", "start"]
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "Wavelet",
|
||||
"name": "wavelet",
|
||||
"version": "1.3.9",
|
||||
"buildDate": "2026-04-22 16:00:00",
|
||||
"private": true,
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ import (
|
||||
|
||||
var apiCmd = &cobra.Command{
|
||||
Use: "api",
|
||||
Short: "credit API",
|
||||
Short: "wavelet API",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
router.Serve()
|
||||
},
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
)
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "linux-do-credit",
|
||||
Use: "wavelet",
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
migrator.Migrate()
|
||||
},
|
||||
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
|
||||
var schedulerCmd = &cobra.Command{
|
||||
Use: "scheduler",
|
||||
Short: "credit Scheduler",
|
||||
Short: "wavelet Scheduler",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
log.Println("[Scheduler] 启动定时任务调度服务")
|
||||
if err := scheduler.StartScheduler(); err != nil {
|
||||
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
|
||||
var workerCmd = &cobra.Command{
|
||||
Use: "worker",
|
||||
Short: "credit Worker",
|
||||
Short: "wavelet Worker",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
log.Println("[Worker] 启动任务处理服务")
|
||||
if err := worker.StartWorker(); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user