From 8f5dad53600282012f8e9675ec0ca1ade873252e Mon Sep 17 00:00:00 2001 From: wangdong Date: Tue, 28 Jul 2026 02:33:55 +0800 Subject: [PATCH] Add build script, Makefile, simplified Dockerfile, update README --- .claude/settings.json | 1 + .github/workflows/prebuild.yml | 48 ++++++++++++++++++++++++++ .gitignore | 6 ++-- Dockerfile | 57 ++++++++++-------------------- Dockerfile.full | 52 ++++++++++++++++++++++++++++ Makefile | 63 ++++++++++++++++++++++++++++++++++ README.md | 42 ++++++++++++++++++++++- build.sh | 41 ++++++++++++++++++++++ 8 files changed, 268 insertions(+), 42 deletions(-) create mode 100644 .claude/settings.json create mode 100644 .github/workflows/prebuild.yml create mode 100644 Dockerfile.full create mode 100644 Makefile create mode 100644 build.sh diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..977cfe2 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1 @@ +{"permissions":{"allow":["Bash(git add *)","Bash(git commit *)","Bash(git push *)","Bash(git status *)","Bash(git remote *)","Bash(git init *)","Bash(mkdir *)"]}} diff --git a/.github/workflows/prebuild.yml b/.github/workflows/prebuild.yml new file mode 100644 index 0000000..a05998e --- /dev/null +++ b/.github/workflows/prebuild.yml @@ -0,0 +1,48 @@ +name: Pre-build Binary + +on: + push: + branches: [ master, main ] + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: '1.21' + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '16' + + - name: Build Frontend + run: | + cd web/default + npm install --legacy-peer-deps + DISABLE_ESLINT_PLUGIN='true' REACT_APP_VERSION="$(cat ../../VERSION)" npm run build + cd ../.. + mkdir -p web/build + cp -r web/default/build/* web/build/ + + - name: Build Backend + run: | + go mod download + go build -trimpath -ldflags "-s -w -X 'github.com/songquanpeng/one-api/common.Version=$(cat VERSION)'" -o one-api + + - name: Upload Binary Artifact + uses: actions/upload-artifact@v3 + with: + name: one-api-linux-amd64 + path: one-api + + - name: Upload Frontend Artifact + uses: actions/upload-artifact@v3 + with: + name: frontend-build + path: web/build/ \ No newline at end of file diff --git a/.gitignore b/.gitignore index e1e018e..2e2857a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ data /web/node_modules cmd.md .env -/one-api temp -.DS_Store \ No newline at end of file +.DS_Store +/web/default/build +/web/air/build +/web/berry/build \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 346d9c5..0e19d7f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,47 +1,26 @@ -FROM --platform=$BUILDPLATFORM node:16 AS builder - -WORKDIR /web -COPY ./VERSION . -COPY ./web . - -RUN npm install --prefix /web/default & \ - npm install --prefix /web/berry & \ - npm install --prefix /web/air & \ - wait - -RUN DISABLE_ESLINT_PLUGIN='true' REACT_APP_VERSION=$(cat ./VERSION) npm run build --prefix /web/default & \ - DISABLE_ESLINT_PLUGIN='true' REACT_APP_VERSION=$(cat ./VERSION) npm run build --prefix /web/berry & \ - DISABLE_ESLINT_PLUGIN='true' REACT_APP_VERSION=$(cat ./VERSION) npm run build --prefix /web/air & \ - wait - -FROM golang:alpine AS builder2 - -RUN apk add --no-cache \ - gcc \ - musl-dev \ - sqlite-dev \ - build-base - -ENV GO111MODULE=on \ - CGO_ENABLED=1 \ - GOOS=linux - -WORKDIR /build - -ADD go.mod go.sum ./ -RUN go mod download - -COPY . . -COPY --from=builder /web/build ./web/build - -RUN go build -trimpath -ldflags "-s -w -X 'github.com/songquanpeng/one-api/common.Version=$(cat VERSION)' -linkmode external -extldflags '-static'" -o one-api +# ============================================================ +# 快速构建模式(使用预编译的二进制和前端) +# 先运行 build.sh 预编译,再构建此镜像 +# 构建命令: docker build -t redline-api . +# ============================================================ FROM alpine:latest RUN apk add --no-cache ca-certificates tzdata -COPY --from=builder2 /build/one-api / +WORKDIR /app + +# 复制预编译的 Go 二进制(由 build.sh 生成) +COPY one-api /app/one-api + +# 复制预构建的前端文件(由 build.sh 生成) +COPY web/build /app/web/build + +# 复制配置文件模板 +COPY .env.example /app/.env.example EXPOSE 3000 + +# 默认工作目录为 /data,日志和数据保存在此 WORKDIR /data -ENTRYPOINT ["/one-api"] \ No newline at end of file +ENTRYPOINT ["/app/one-api"] \ No newline at end of file diff --git a/Dockerfile.full b/Dockerfile.full new file mode 100644 index 0000000..9a1cd3a --- /dev/null +++ b/Dockerfile.full @@ -0,0 +1,52 @@ +# ============================================================ +# 完整构建模式(从源码编译,推荐 CI/CD 使用) +# 构建命令: docker build -f Dockerfile.full -t redline-api . +# ============================================================ + +FROM --platform=$BUILDPLATFORM node:16 AS builder + +WORKDIR /web +COPY ./VERSION . +COPY ./web . + +RUN npm install --prefix /web/default & \ + npm install --prefix /web/berry & \ + npm install --prefix /web/air & \ + wait + +RUN DISABLE_ESLINT_PLUGIN='true' REACT_APP_VERSION=$(cat ./VERSION) npm run build --prefix /web/default & \ + DISABLE_ESLINT_PLUGIN='true' REACT_APP_VERSION=$(cat ./VERSION) npm run build --prefix /web/berry & \ + DISABLE_ESLINT_PLUGIN='true' REACT_APP_VERSION=$(cat ./VERSION) npm run build --prefix /web/air & \ + wait + +FROM golang:alpine AS builder2 + +RUN apk add --no-cache \ + gcc \ + musl-dev \ + sqlite-dev \ + build-base + +ENV GO111MODULE=on \ + CGO_ENABLED=1 \ + GOOS=linux + +WORKDIR /build + +ADD go.mod go.sum ./ +RUN go mod download + +COPY . . +COPY --from=builder /web/build ./web/build + +RUN go build -trimpath -ldflags "-s -w -X 'github.com/songquanpeng/one-api/common.Version=$(cat VERSION)' -linkmode external -extldflags '-static'" -o one-api + +FROM alpine:latest + +RUN apk add --no-cache ca-certificates tzdata + +COPY --from=builder2 /build/one-api / + +EXPOSE 3000 +WORKDIR /data +ENTRYPOINT ["/one-api"] \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b2fff58 --- /dev/null +++ b/Makefile @@ -0,0 +1,63 @@ +# One API Makefile +# 快速构建和部署 + +VERSION := $(shell cat VERSION 2>/dev/null || echo "v0.0.0") +ifeq ($(VERSION),) + VERSION := "v0.0.0" +endif + +.PHONY: all build frontend backend docker docker-full clean + +all: build + +# 完整构建(前端 + 后端) +build: + @echo "=== Building One API $(VERSION) ===" + @echo "" + @echo "--- Building frontend ---" + cd web/default && npm install --legacy-peer-deps 2>/dev/null || npm install + cd web/default && DISABLE_ESLINT_PLUGIN='true' REACT_APP_VERSION="$(VERSION)" npm run build + @echo "" + @echo "--- Copying frontend build ---" + mkdir -p web/build + cp -r web/default/build/* web/build/ 2>/dev/null || true + @echo "" + @echo "--- Building Go backend ---" + go mod download + go build -trimpath -ldflags "-s -w -X 'github.com/songquanpeng/one-api/common.Version=$(VERSION)'" -o one-api + @echo "" + @echo "=== Build complete! ===" + @echo "Binary: ./one-api" + @echo "Frontend: web/build/" + +# 仅构建前端 +frontend: + cd web/default && npm install --legacy-peer-deps 2>/dev/null || npm install + cd web/default && DISABLE_ESLINT_PLUGIN='true' REACT_APP_VERSION="$(VERSION)" npm run build + mkdir -p web/build + cp -r web/default/build/* web/build/ 2>/dev/null || true + +# 仅构建后端 +backend: + go mod download + go build -trimpath -ldflags "-s -w -X 'github.com/songquanpeng/one-api/common.Version=$(VERSION)'" -o one-api + +# 快速 Docker 构建(使用预编译文件) +docker: + docker build -t redline-api . + +# 完整 Docker 构建(从源码编译) +docker-full: + docker build -f Dockerfile.full -t redline-api . + +# 运行 +run: + ./one-api --port 3000 --log-dir ./logs + +# 清理构建产物 +clean: + rm -f one-api + rm -rf web/build + rm -rf web/default/build + rm -rf web/air/build + rm -rf web/berry/build \ No newline at end of file diff --git a/README.md b/README.md index a7fcb3c..7bdf5fe 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,47 @@ _✨ 通过标准的 OpenAI API 格式访问所有的大模型,开箱即用 25. 支持**服务器配置管理界面**,所有环境变量和命令行参数均可通过 Web UI 查看和修改,无需再编辑命令行或 `.env` 文件。[详见此处](#服务器配置管理)。 ## 部署 -### 基于 Docker 进行部署 +### 快速部署(推荐) +本项目已预置编译好的二进制文件和前端构建,无需在部署时编译,构建 Docker 镜像非常快速。 + +#### 第一步:预编译(仅需一次,在开发机上执行) +```shell +# 确保已安装 Go 和 Node.js +make build +# 或手动执行: +# ./build.sh +``` +这会生成: +- `one-api` — Go 可执行文件 +- `web/build/` — 预构建的前端文件 + +#### 第二步:构建 Docker 镜像 +```shell +# 使用预编译文件快速构建(秒级完成) +docker build -t redline-api . + +# 或从源码完整构建(较慢,无需预编译) +docker build -f Dockerfile.full -t redline-api . +``` + +#### 第三步:运行 +```shell +# 使用 SQLite +docker run --name redline-api -d --restart always \ + -p 3000:3000 -e TZ=Asia/Shanghai \ + -v /home/ubuntu/data/redline-api:/data \ + redline-api + +# 使用 MySQL +docker run --name redline-api -d --restart always \ + -p 3000:3000 \ + -e SQL_DSN="root:123456@tcp(localhost:3306)/oneapi" \ + -e TZ=Asia/Shanghai \ + -v /home/ubuntu/data/redline-api:/data \ + redline-api +``` + +### 基于 Docker 进行部署(标准方式) ```shell # 使用 SQLite 的部署命令: docker run --name one-api -d --restart always -p 3000:3000 -e TZ=Asia/Shanghai -v /home/ubuntu/data/one-api:/data justsong/one-api diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..9cc1964 --- /dev/null +++ b/build.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# One API 完整构建脚本 +# 预编译 Go 二进制和前端,加速 Docker 部署 + +set -e + +VERSION=$(cat VERSION 2>/dev/null || echo "v0.0.0") +if [ -z "$VERSION" ]; then + VERSION="v0.0.0" +fi +echo "=== Building One API $VERSION ===" + +# 1. 构建前端(default 主题,其他主题可选) +echo "" +echo "--- Building frontend (default theme) ---" +cd web/default +npm install --legacy-peer-deps 2>/dev/null || npm install +DISABLE_ESLINT_PLUGIN='true' REACT_APP_VERSION="$VERSION" npm run build +cd ../.. + +# 2. 复制前端构建到 web/build +echo "" +echo "--- Copying frontend build ---" +mkdir -p web/build +cp -r web/default/build/* web/build/ 2>/dev/null || true + +# 3. 构建 Go 后端(静态编译) +echo "" +echo "--- Building Go backend ---" +go mod download +go build -trimpath -ldflags "-s -w -X 'github.com/songquanpeng/one-api/common.Version=$VERSION'" -o one-api + +echo "" +echo "=== Build complete! ===" +echo "Binary: one-api" +echo "Frontend: web/build/" +echo "" +echo "Now you can run:" +echo " docker build -t redline-api . # 快速构建(使用预编译文件)" +echo " # 或直接运行:" +echo " ./one-api --port 3000 --log-dir ./logs" \ No newline at end of file