diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..d225ccc --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +node_modules +dist +build +coverage +.git +.vite +.env* +!.env.example +*.log +Dockerfile* +docker_compose_Nas.yaml +README.local.md diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4be56d4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM node:22-bookworm-slim + +WORKDIR /app + +RUN apt-get update \ + && apt-get install -y --no-install-recommends ca-certificates python3 make g++ \ + && rm -rf /var/lib/apt/lists/* + +COPY package.json package-lock.json ./ +RUN npm ci + +COPY . . + +EXPOSE 3000 3002 + +CMD ["sh", "-c", "npm run dev -- --host 0.0.0.0 --strictPort & npm run api"] diff --git a/README.md b/README.md index 4349edf..9a6198d 100644 --- a/README.md +++ b/README.md @@ -102,3 +102,29 @@ curl -X POST http://localhost:3002/api/analyze-document \ API auth is required by default. For local-only development, you can set `API_AUTH_DISABLED=true`, but do not use that on a LAN or server. For Agent-facing image editing instructions, see `API图片修改-Agent.md`. + +## Docker Compose Deploy + +Create `.env.local` first: + +```env +GEMINI_API_KEY="YOUR_GEMINI_API_KEY" +API_AUTH_TOKEN="YOUR_LONG_RANDOM_API_TOKEN" +API_AUTH_DISABLED="false" +API_PORT="3002" +APP_PASSWORD="123456" +APP_URL="http://YOUR_SERVER_IP:3000" +``` + +Then start: + +```bash +docker compose -f docker_compose.yaml up -d --build +``` + +Default ports: + +- UI: `http://YOUR_SERVER_IP:3000` +- API: `http://YOUR_SERVER_IP:3002` + +For migration steps and port changes, see `迁移部署说明.md`. diff --git a/docker_compose.yaml b/docker_compose.yaml new file mode 100644 index 0000000..7e55af5 --- /dev/null +++ b/docker_compose.yaml @@ -0,0 +1,22 @@ +services: + gemini-draw: + build: + context: . + dockerfile: Dockerfile + container_name: gemini-draw + init: true + restart: unless-stopped + env_file: + - .env.local + environment: + API_PORT: "3002" + API_AUTH_DISABLED: "false" + ports: + - "3000:3000" + - "3002:3002" + healthcheck: + test: ["CMD-SHELL", "node -e \"fetch('http://127.0.0.1:3002/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\""] + interval: 30s + timeout: 10s + retries: 3 + start_period: 20s diff --git a/迁移部署说明.md b/迁移部署说明.md new file mode 100644 index 0000000..7af30c0 --- /dev/null +++ b/迁移部署说明.md @@ -0,0 +1,236 @@ +# 迁移部署说明 + +本文档用于把 Gemini Draw 迁移到 NAS、Linux 服务器或另一台电脑,并使用 Docker Compose 部署。 + +## 需要准备 + +- Docker +- Docker Compose v2 +- 当前项目源码 +- Gemini API Key +- 一串你自己生成的 API 访问密钥 `API_AUTH_TOKEN` + +## 必须修改的配置 + +在目标机器项目根目录创建 `.env.local`: + +```env +GEMINI_API_KEY="你的_Gemini_API_Key" +API_AUTH_TOKEN="一串足够长的随机访问密钥" +API_AUTH_DISABLED="false" +API_PORT="3002" +APP_PASSWORD="123456" +APP_URL="http://目标机器IP:3000" +``` + +字段说明: + +- `GEMINI_API_KEY`:调用 Gemini 模型的密钥。 +- `API_AUTH_TOKEN`:调用本项目 API 的访问密钥,别人调用接口时必须带上。 +- `API_AUTH_DISABLED`:必须保持 `false`,只有本机临时调试才可以设为 `true`。 +- `API_PORT`:容器内 API 端口,默认 `3002`。 +- `APP_PASSWORD`:网页登录密码,默认用户名是 `admin`。 +- `APP_URL`:前端访问地址,迁移到 NAS 时建议写成 `http://NAS_IP:3000`。 + +生成随机 `API_AUTH_TOKEN` 的示例: + +```bash +openssl rand -hex 32 +``` + +Windows PowerShell: + +```powershell +-join ((1..32) | ForEach-Object { '{0:x2}' -f (Get-Random -Minimum 0 -Maximum 256) }) +``` + +## Docker Compose 部署 + +在项目根目录执行: + +```bash +docker compose -f docker_compose.yaml up -d --build +``` + +查看日志: + +```bash +docker logs -f gemini-draw +``` + +停止服务: + +```bash +docker compose -f docker_compose.yaml down +``` + +重新部署: + +```bash +git pull +docker compose -f docker_compose.yaml up -d --build --force-recreate +``` + +## 访问地址 + +默认端口: + +- 前端页面:`http://目标机器IP:3000` +- API 健康检查:`http://目标机器IP:3002/api/health` + +如果要修改宿主机端口,编辑 `docker_compose.yaml`: + +```yaml +ports: + - "4001:3000" + - "4002:3002" +``` + +修改后访问地址变为: + +- 前端页面:`http://目标机器IP:4001` +- API:`http://目标机器IP:4002` + +如果修改了前端宿主机端口,也建议同步修改 `.env.local`: + +```env +APP_URL="http://目标机器IP:4001" +``` + +## API 调用必须带访问密钥 + +受保护 API 必须带 `API_AUTH_TOKEN`: + +```bash +curl http://目标机器IP:3002/api/config \ + -H "Authorization: Bearer 你的_API_AUTH_TOKEN" +``` + +也可以使用: + +```bash +curl http://目标机器IP:3002/api/config \ + -H "x-api-key: 你的_API_AUTH_TOKEN" +``` + +图片修改示例: + +```bash +curl -X POST http://目标机器IP:3002/api/edit-image \ + -H "Authorization: Bearer 你的_API_AUTH_TOKEN" \ + -F "prompt=保留主体不变,把背景改成白色摄影棚风格" \ + -F "imageSize=1K" \ + -F "aspectRatio=1:1" \ + -F "files=@input.png" +``` + +## 迁移到另一台机器的方案 + +### 方案 A:通过 Git 迁移 + +1. 在目标机器安装 Docker 和 Docker Compose。 +2. 拉取仓库: + +```bash +git clone http://192.168.31.5:5002/admin/Gemini_Draw.git +cd Gemini_Draw +``` + +3. 创建 `.env.local`,填入目标机器自己的密钥和地址。 +4. 启动: + +```bash +docker compose -f docker_compose.yaml up -d --build +``` + +### 方案 B:直接复制目录 + +1. 复制项目目录到目标机器。 +2. 不需要复制这些目录或文件: + +```txt +node_modules +dist +.git +.env.local +*.log +``` + +3. 在目标机器重新创建 `.env.local`。 +4. 执行 Docker Compose 启动命令。 + +## NAS 部署建议 + +如果部署到 NAS,例如路径 `/share/Container/Gemini_Draw`: + +```bash +cd /share/Container/Gemini_Draw +docker compose -f docker_compose.yaml up -d --build +``` + +`.env.local` 示例: + +```env +GEMINI_API_KEY="你的_Gemini_API_Key" +API_AUTH_TOKEN="你的_API_访问密钥" +API_AUTH_DISABLED="false" +API_PORT="3002" +APP_PASSWORD="你的网页登录密码" +APP_URL="http://192.168.31.5:3000" +``` + +如果 NAS 上 `3000` 或 `3002` 已被占用,就只改 `docker_compose.yaml` 左侧宿主机端口: + +```yaml +ports: + - "4001:3000" + - "4002:3002" +``` + +容器内端口右侧保持不变。 + +## 常见问题 + +### 前端能打开,API 不能用 + +检查容器日志: + +```bash +docker logs -f gemini-draw +``` + +检查健康接口: + +```bash +curl http://目标机器IP:3002/api/health +``` + +### API 返回 Unauthorized + +请求缺少 `API_AUTH_TOKEN`。补上: + +```txt +Authorization: Bearer 你的_API_AUTH_TOKEN +``` + +### API 返回 Gemini API key is required + +说明没有配置 Gemini Key。检查 `.env.local`: + +```env +GEMINI_API_KEY="你的_Gemini_API_Key" +``` + +也可以单次请求传入: + +```txt +x-gemini-api-key: 你的_Gemini_API_Key +``` + +### 修改 `.env.local` 后没有生效 + +重启容器: + +```bash +docker compose -f docker_compose.yaml up -d --force-recreate +```