Repository: dreamhartley/gemini-proxy-panel Branch: main Commit: 8eeab2968b18 Files: 50 Total size: 547.7 KB Directory structure: gitextract_h9d7l8di/ ├── .dockerignore ├── .github/ │ └── workflows/ │ └── docker-publish.yml ├── .gitignore ├── Dockerfile ├── Dockerfile.huggingface ├── LICENSE ├── README.md ├── README_zh.md ├── doc/ │ ├── Deploy/ │ │ ├── Colab/ │ │ │ ├── Colab部署.md │ │ │ └── colab启动.ipynb │ │ ├── GitHub/ │ │ │ └── GitHub同步.md │ │ ├── HuggingFace/ │ │ │ ├── Hugging Face Space部署-fork说明.md │ │ │ └── Hugging Face Space部署.md │ │ ├── Koyeb/ │ │ │ └── Koyeb部署.md │ │ ├── Local/ │ │ │ └── 本地部署.md │ │ ├── Render/ │ │ │ └── Render部署.md │ │ └── Uptimerobot/ │ │ └── 配置Uptimerrobot.md │ ├── Usage/ │ │ ├── KEEPALIVE.md │ │ ├── Vertex/ │ │ │ └── Vertex代理配置.md │ │ ├── 在客户端中使用.md │ │ └── 配置API连接.md │ └── 项目介绍.md ├── docker-compose.yml ├── get-jimihub.sh ├── package.json ├── public/ │ ├── admin/ │ │ ├── index.html │ │ ├── script.js │ │ ├── style.css │ │ └── version.txt │ ├── i18n.js │ ├── login.html │ └── login.script.js └── src/ ├── db/ │ └── index.js ├── index.js ├── middleware/ │ ├── adminAuth.js │ └── workerAuth.js ├── routes/ │ ├── adminApi.js │ ├── apiV1.js │ └── auth.js ├── services/ │ ├── batchTestService.js │ ├── configService.js │ ├── geminiKeyService.js │ ├── geminiProxyService.js │ ├── schedulerService.js │ └── vertexProxyService.js └── utils/ ├── githubSync.js ├── helpers.js ├── proxyPool.js ├── session.js └── transform.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .dockerignore ================================================ # Git files .git .gitignore # Docker files Dockerfile .dockerignore docker-compose.yml Dockerfile.huggingface # Node dependencies (install these inside the container) node_modules # Environment variables .env .env.* .dev.vars # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* lerna-debug.log* .pnpm-debug.log* # Runtime data pids *.pid *.seed *.pid.lock # Coverage directory coverage *.lcov .nyc_output # Build artifacts and caches build/ dist/ .cache/ .parcel-cache/ *.tsbuildinfo .npm/ .eslintcache .stylelintcache .rpt2_cache/ .rts2_cache_cjs/ .rts2_cache_es/ .rts2_cache_umd/ .node_repl_history *.tgz .yarn-integrity .next/ out/ .nuxt/ .vuepress/dist .temp/ .docusaurus/ .serverless/ .fusebox/ .dynamodb/ .tern-port .vscode-test/ # Yarn PnP files .yarn/ .pnp.* # Wrangler project files (assuming they are not needed in this specific image) wrangler.toml .wrangler/ worker/ # Documentation and License (optional, remove if needed in image) README.md README_zh.md LICENSE get-gemhub.sh doc/ data/ ================================================ FILE: .github/workflows/docker-publish.yml ================================================ name: Docker Image CI for Hugging Face on: push: branches: [ "main" ] workflow_dispatch: jobs: build_and_push: runs-on: ubuntu-latest permissions: contents: read packages: write steps: - name: Checkout repository uses: actions/checkout@v4 - name: Log in to the Container registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Convert owner to lowercase id: string run: echo "REPO_OWNER_LC=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV - name: Convert repo name to lowercase id: repo_name run: echo "REPO_NAME_LC=$(echo ${{ github.event.repository.name }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v5 with: images: ghcr.io/${{ env.REPO_OWNER_LC }}/${{ env.REPO_NAME_LC }} - name: Build and push Docker image uses: docker/build-push-action@v5 with: context: . file: ./Dockerfile.huggingface push: true tags: ghcr.io/${{ env.REPO_OWNER_LC }}/${{ env.REPO_NAME_LC }}:latest labels: ${{ steps.meta.outputs.labels }} ================================================ FILE: .gitignore ================================================ # Logs logs _.log npm-debug.log_ yarn-debug.log* yarn-error.log* lerna-debug.log* .pnpm-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json # Runtime data pids _.pid _.seed \*.pid.lock # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage \*.lcov # nyc test coverage .nyc_output # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) .grunt # Bower dependency directory (https://bower.io/) bower_components # node-waf configuration .lock-wscript # Compiled binary addons (https://nodejs.org/api/addons.html) build/Release # Dependency directories node_modules/ jspm_packages/ # Snowpack dependency directory (https://snowpack.dev/) web_modules/ # TypeScript cache \*.tsbuildinfo # Optional npm cache directory .npm # Optional eslint cache .eslintcache # Optional stylelint cache .stylelintcache # Microbundle cache .rpt2_cache/ .rts2_cache_cjs/ .rts2_cache_es/ .rts2_cache_umd/ # Optional REPL history .node_repl_history # Output of 'npm pack' \*.tgz # Yarn Integrity file .yarn-integrity # dotenv environment variable files .env .env.development.local .env.test.local .env.production.local .env.local # parcel-bundler cache (https://parceljs.org/) .cache .parcel-cache # Next.js build output .next out # Nuxt.js build / generate output .nuxt dist # Gatsby files .cache/ # Comment in the public line in if your project uses Gatsby and not Next.js # https://nextjs.org/blog/next-9-1#public-directory-support # public # vuepress build output .vuepress/dist # vuepress v2.x temp and cache directory .temp .cache # Docusaurus cache and generated files .docusaurus # Serverless directories .serverless/ # FuseBox cache .fusebox/ # DynamoDB Local files .dynamodb/ # TernJS port file .tern-port # Stores VSCode versions used for testing VSCode extensions .vscode-test # yarn v2 .yarn/cache .yarn/unplugged .yarn/build-state.yml .yarn/install-state.gz .pnp.\* # wrangler project .dev.vars .wrangler/ ================================================ FILE: Dockerfile ================================================ FROM node:lts-slim WORKDIR /app COPY package*.json ./ RUN npm install --only=production COPY . . EXPOSE 3000 CMD [ "npm", "start" ] ================================================ FILE: Dockerfile.huggingface ================================================ FROM dreamhartley705/jimihub:latest ENV HUGGING_FACE=1 ENV PORT=7860 USER root RUN mkdir -p /home/user/data && \ chmod 777 /home/user/data && \ chown -R node:node /home/user/data USER node EXPOSE 7860 CMD [ "npm", "start" ] ================================================ FILE: LICENSE ================================================ Creative Commons Attribution-NonCommercial 4.0 International Public License By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. Section 1 – Definitions. a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. b. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. c. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. d. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. e. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License. f. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. g. Licensor means the individual(s) or entity(ies) granting rights under this Public License. h. NonCommercial means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this Public License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange. i. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. j. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. k. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. Section 2 – Scope. a. License grant. 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: A. reproduce and Share the Licensed Material, in whole or in part; and B. produce, reproduce, and Share Adapted Material. 2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. 3. Term. The term of this Public License is specified in Section 6(a). 4. Media and formats; technical modifications. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Public License does not violate this Section 2(a)(4). 5. Downstream recipients. A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. B. Additional terms – Licensed Material. No downstream recipient of the Licensed Material may have any terms imposed on their use of the Licensed Material that restrict the terms of this Public License or the exercise of the Licensed Rights granted under this Public License. C. Offer from the Licensor – Adapted Material. Every recipient of Adapted Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License on the Adapted Material. D. Additional terms – Adapted Material. No downstream recipient of Adapted Material may have any terms imposed on their use of the Adapted Material that restrict the terms of this Public License or the exercise of the Licensed Rights granted under this Public License. b. Other rights. 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. 2. Patent and trademark rights are not licensed under this Public License. 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. Section 3 – License Conditions. Your exercise of the Licensed Rights is expressly made subject to the following conditions. a. Attribution. 1. If You Share the Licensed Material (including in modified form), You must: A. retain the following if it is supplied by the Licensor with the Licensed Material: i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor; ii. a copyright notice; iii. a notice that refers to this Public License; iv. a notice that refers to the disclaimer of warranties; v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. b. NonCommercial. You may not exercise any of the Licensed Rights for commercial purposes. c. No additional restrictions. You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. Section 4 – Sui Generis Database Rights. Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material, the Licensor waives to the fullest extent permitted by law the Licensed Rights, to the extent necessary to allow You to use, reproduce, and Share the Licensed Material including by including in Your adaptations any contents of the database. Section 5 – Disclaimer of Warranties and Limitation of Liability. a. Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, either express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. b. To the extent possible, in no event will the Licensor be liable to You on any legal theory for any damages arising out of or in connection with the Licensed Material or the use or other dealings with the Licensed Material, including any direct, indirect, special, incidental, consequential, punitive, exemplary, or other damages, including loss of profits, data, use, goodwill, or other intangible losses, even if the Licensor has been advised of the possibility of such damages. Section 6 – Term and Termination. a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. b. Where Your rights under this Public License terminate, they will not be reinstated. c. Subject to the above, the license is perpetual (for the duration of the applicable rights). d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. Section 7 – Other Terms and Conditions. a. The Licensor and You agree that this Public License constitutes the entire agreement regarding the Licensed Material and supersedes all prior agreements and understandings, whether oral or written. b. The Licensor waives any right to collect royalties from You for the Licensed Rights licensed under this Public License. c. If any provision of this Public License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remaining provisions of this Public License, and such provision shall be reformed to the minimum extent necessary to make it valid and enforceable. d. No warranties are given. The license may not give You all of the permissions necessary for Your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how You use the Licensed Material. e. No trademark rights are granted. Section 8 – Interpretation. a. For the avoidance of doubt, this Public License is not intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in applicable copyright law. b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to be enforceable. c. No warranties or conditions shall be construed to limit the scope of rights granted under this Public License. d. No interpretation of this Public License shall be used to justify any infringement of copyright or rights under this Public License. For more information, please visit https://creativecommons.org/licenses/by-nc/4.0/legalcode ================================================ FILE: README.md ================================================ # JimiHub > **本项目遵循CC BY-NC 4.0协议,禁止任何形式的商业倒卖行为。** This project is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License (CC BY-NC 4.0). Commercial resale or any form of commercial use is prohibited. [**中文介绍**](./README_zh.md "Chinese Readme")

[***详细部署与使用文档(新手看这里)***](./doc/项目介绍.md "项目介绍")

## Introduction `JimiHub` is a proxy service. It forwards requests formatted for the OpenAI API to the Google Gemini Pro API, allowing applications developed for OpenAI to seamlessly switch to or leverage the capabilities of Gemini models. ## Features * **OpenAI to Gemini Proxy**: Seamlessly translates OpenAI Chat API requests into Gemini Pro API requests. * **Multi-API Key Rotation**: Supports configuring multiple Gemini API keys and automatically rotates through them to distribute request load and circumvent rate limits. * **Quota and Usage Management**: Monitor the usage of each Gemini API key through an intuitive management interface. * **Key Management**: Centrally manage multiple Gemini API keys and Worker API keys (used to access this proxy service) within the management panel. * **Model Configuration**: Define and manage the Gemini models supported by this proxy in the management panel. * **Intuitive Management Interface**: Provides a Web UI (`/login` or `/admin`) to view API usage statistics and configure settings. * **One-Click Deployment**: Supports quick deployment to the Cloudflare Workers platform via the "Deploy to Cloudflare" button. * **GitHub Actions Automatic Deployment**: After forking the repository, enables automatic deployment via GitHub Actions upon code push. * **GitHub Database Sync**: Leverages GitHub repositories for automatic database synchronization. ## Hugging Face Space Deployment This deployment method utilizes Hugging Face Space's Docker environment and **requires enabling GitHub sync** for data persistence. 1. **Prepare GitHub Repository and PAT**: * You need **your own** GitHub repository to store synchronized data. A private repository is recommended. * Create a GitHub Personal Access Token (PAT) with the `repo` permission scope. **Keep this token secure**. 2. **Create a Hugging Face Space**: * Visit Hugging Face and create a new Space. * Select "Docker" as the Space SDK. * Choose "Use existing Dockerfile from repository". 3. **Configure Space Secrets**: * Go to your Space's "Settings" -> "Repository secrets". * Add the following Secrets: * `ADMIN_PASSWORD`: Set a login password for the admin panel. * `SESSION_SECRET_KEY`: Set a long, random session key. * `GITHUB_PROJECT`: Enter **your own** GitHub repository path in the format `your-username/your-repo-name`. * `GITHUB_PROJECT_PAT`: Enter your GitHub PAT created earlier. * `GITHUB_ENCRYPT_KEY`: Set an encryption key for synced data, **must be at least 32 characters long**. 4. **Create Dockerfile**: * In your Hugging Face Space's "Files" tab, click "Add file" -> "Create new file". * Set the filename to `Dockerfile`. * Paste the following content into the file: ```dockerfile FROM dreamhartley705/jimihub:huggingface ``` * Click "Commit new file". 5. **Launch and Access**: * Hugging Face Space will automatically build and start the application using this `Dockerfile`. * Once launched, the app will connect to your GitHub repository for data syncing using your configured Secrets. * You can access the admin panel (`/login` or `/admin`) and API (`/v1`) via the URL provided by the Space. ## Local Node.js Deployment This method is suitable for local development and testing. 1. **Clone the Repository**: ```bash git clone https://github.com/dreamhartley/gemini-proxy-panel.git cd gemini-proxy-panel ``` 2. **Install Dependencies**: ```bash npm install ``` 3. **Configure Environment Variables**: * Copy the `.env.example` file to `.env`: ```bash cp .env.example .env ``` * Edit the `.env` file, setting at minimum: * `ADMIN_PASSWORD`: Set the admin panel login password. * `SESSION_SECRET_KEY`: Set a long, random string for session security (e.g., generate with `openssl rand -base64 32`). * `PORT` (optional): Default is 3000, change as needed. * **(Optional) Configure GitHub Sync**: To sync data to a GitHub repository, set: * `GITHUB_PROJECT`: Your GitHub repository path in format `username/repo-name`. **Note: This is your own repository for data backup, not this project's repository.** * `GITHUB_PROJECT_PAT`: Your GitHub Personal Access Token with `repo` permission. * `GITHUB_ENCRYPT_KEY`: An encryption key for syncing data, must be at least 32 characters long. 4. **Start the Service**: ```bash npm start ``` The service will run at `http://localhost:3000` (or your configured port). ## Docker Deployment You can quickly deploy using Docker or Docker Compose. ### Method 1: Using `docker build` and `docker run` 1. **Clone the Repository**: ```bash git clone https://github.com/dreamhartley/JimiHub.git cd JimiHub ``` 2. **Configure Environment Variables**: * Copy the `.env.example` file to `.env`: ```bash cp .env.example .env ``` * Edit the `.env` file, setting the necessary variables (`ADMIN_PASSWORD`, `SESSION_SECRET_KEY`) and optional GitHub sync variables (`GITHUB_PROJECT`, `GITHUB_PROJECT_PAT`, `GITHUB_ENCRYPT_KEY`). **Note: The `PORT` variable typically doesn't need to be set in the `.env` file for Docker deployments, as port mapping is done in the `docker run` command.** 3. **Build the Docker Image**: ```bash docker build -t gemhub . ``` 4. **Run the Docker Container**: ```bash docker run -d --name gemhub \ -p 3000:3000 \ --env-file .env \ -v ./data:/usr/src/app/data \ gemhub ``` * `-d`: Run the container in the background. * `--name gemhub`: Name for the container. * `-p 3000:3000`: Map host port 3000 to container port 3000. * `--env-file .env`: Load environment variables from the `.env` file. * `-v ./data:/usr/src/app/data`: Mount the local `data` directory to the container for SQLite database persistence. Ensure the `data` directory exists locally. ### Method 2: Using `docker-compose` (Recommended) 1. **Clone the Repository**: ```bash git clone https://github.com/dreamhartley/JimiHub.git cd JimiHub ``` 2. **Configure Environment Variables**: * Copy the `.env.example` file to `.env`: ```bash cp .env.example .env ``` * Edit the `.env` file, setting the necessary variables (`ADMIN_PASSWORD`, `SESSION_SECRET_KEY`) and optional GitHub sync variables (`GITHUB_PROJECT`, `GITHUB_PROJECT_PAT`, `GITHUB_ENCRYPT_KEY`). 3. **Start the Service**: ```bash docker-compose up -d ``` Docker Compose will automatically build the image (if needed), create and start the container, and handle port mapping, environment variables, and data volumes according to the `docker-compose.yml` file. ## Usage ### Management Panel 1. Access the `/login` or `/admin` path of your Worker URL (e.g., `https://your-worker-name.your-subdomain.workers.dev/login`). 2. Log in using the `ADMIN_PASSWORD` you set. 3. In the management panel, you can: * Add and manage your Gemini API keys. * Add and manage API keys used to access this Worker proxy (Worker API Keys). * Set global quotas for Pro and Flash series models. * View usage statistics for each Gemini API key. * Configure supported Gemini models. ### API Proxy 1. Point the API endpoint of your application (originally configured to call the OpenAI API) to your deployed Worker URL (e.g., `https://your-worker-name.your-subdomain.workers.dev/v1`). 2. Ensure that your application includes valid authentication information when sending requests. This is usually done by carrying the "Worker API Key" configured in the management panel in the `Authorization` request header: ``` Authorization: Bearer ``` 3. Send requests compatible with the OpenAI Chat Completions API. The Worker will convert them into Gemini API requests and return the formatted response. ## Configuration Overview ## Configuration Overview ### Local Node.js / Docker / Hugging Face Deployments These deployment methods configure environment variables through the `.env` file or Secrets (Hugging Face). * **Core Environment Variables (Required)**: * `ADMIN_PASSWORD`: Login password for the admin panel. * `SESSION_SECRET_KEY`: Key for securing user sessions (use a long, random string). * **Optional Environment Variables**: * `PORT`: (Local Node.js/Docker only) Port for the service to listen on, default is 3000. Hugging Face handles the port automatically. * **GitHub Sync Environment Variables (Optional, Required for Hugging Face)**: * `GITHUB_PROJECT`: Path to **your own** GitHub repository for data syncing (format: `username/repo-name`). * `GITHUB_PROJECT_PAT`: GitHub Personal Access Token with `repo` permission. * `GITHUB_ENCRYPT_KEY`: Key for encrypting synced data (at least 32 characters). ================================================ FILE: README_zh.md ================================================ # JimiHub ## 简介 `JimiHub` 是一个代理服务。它可以将 OpenAI API 格式的请求转发给 Google Gemini Pro API,使得为 OpenAI 开发的应用能够无缝切换或利用 Gemini 模型的能力。 ## 功能 * **OpenAI 到 Gemini 代理**: 无缝将 OpenAI Chat API 请求转换为 Gemini Pro API 请求。 * **多 API Key 轮询**: 支持配置多个 Gemini API Key,并自动轮询使用,以分摊请求负载和规避速率限制。 * **配额与用量管理**: 通过直观的管理界面监控每个 Gemini API Key 的使用情况。 * **密钥管理**: 在管理面板中集中管理多个 Gemini API Key 和 Worker API Key(用于访问此代理服务)。 * **模型配置**: 在管理面板中定义和管理此代理支持的 Gemini 模型。 * **直观的管理界面**: 提供 Web UI (`/login` 或 `/admin`) 查看 API 使用统计和配置设置。 * **一键部署**: 支持通过 "Deploy to Cloudflare" 按钮快速部署到 Cloudflare Workers 平台。 * **GitHub Actions 自动部署**: Fork 仓库后,可通过 GitHub Actions 实现推送代码时自动部署。 * **GitHub 同步数据库**: 利用GitHub仓库自动同步数据库 ## Hugging Face Space 部署 此部署方式利用 Hugging Face Space 的 Docker 环境运行,并**强制要求启用 GitHub 同步**功能以实现数据持久化。 1. **准备 GitHub 仓库和 PAT**: * 你需要一个**自己的** GitHub 仓库来存储同步的数据。建议使用私有仓库。 * 创建一个 GitHub Personal Access Token (PAT),并确保勾选了 `repo` 权限范围。**请妥善保管此 Token**。 2. **创建 Hugging Face Space**: * 访问 Hugging Face 并创建一个新的 Space。 * 选择 "Docker" 作为 Space SDK。 * 选择 "Use existing Dockerfile from repository"。 3. **配置 Space Secrets**: * 进入你创建的 Space 的 "Settings" -> "Repository secrets"。 * 添加以下 Secrets: * `ADMIN_PASSWORD`: 设置管理面板的登录密码。 * `SESSION_SECRET_KEY`: 设置一个长且随机的会话密钥。 * `GITHUB_PROJECT`: 填入你**自己的** GitHub 仓库路径,格式为 `your-username/your-repo-name`。 * `GITHUB_PROJECT_PAT`: 填入你创建的 GitHub PAT。 * `GITHUB_ENCRYPT_KEY`: 设置一个用于加密同步数据的密钥,**必须是 32 位或更长的字符串**。 4. **创建 Dockerfile**: * 在你的 Hugging Face Space 的 "Files" 标签页中,点击 "Add file" -> "Create new file"。 * 将文件名设置为 `Dockerfile`。 * 将以下内容粘贴到文件中: ```dockerfile FROM dreamhartley705/jimihub:huggingface ``` * 点击 "Commit new file"。 5. **启动和访问**: * Hugging Face Space 会自动使用此 `Dockerfile` 构建并启动应用。 * 应用启动后,会使用你配置的 Secrets 连接到你的 GitHub 仓库进行数据同步。 * 你可以通过 Space 提供的 URL 访问管理面板 (`/login` 或 `/admin`) 和 API (`/v1`)。 ## 本地 Node.js 部署 此方式适合本地开发和测试。 1. **克隆仓库**: ```bash git clone https://github.com/dreamhartley/JimiHub.git cd JimiHub ``` 2. **安装依赖**: ```bash npm install ``` 3. **配置环境变量**: * 复制 `.env.example` 文件为 `.env`: ```bash cp .env.example .env ``` * 编辑 `.env` 文件,至少设置以下变量: * `ADMIN_PASSWORD`: 设置管理面板的登录密码。 * `SESSION_SECRET_KEY`: 设置一个长且随机的字符串用于会话安全(例如,使用 `openssl rand -base64 32` 生成)。 * `PORT` (可选): 默认是 3000,可以根据需要修改。 * **(可选) 配置 GitHub 同步**: 如果需要将数据同步到 GitHub 仓库,请配置以下变量: * `GITHUB_PROJECT`: 你的 GitHub 仓库路径,格式为 `username/repo-name`。**注意:这是你自己的仓库,用于存储数据备份,并非本项目仓库。** * `GITHUB_PROJECT_PAT`: 你的 GitHub Personal Access Token,需要 `repo` 权限。 * `GITHUB_ENCRYPT_KEY`: 用于加密同步数据的密钥,必须是 32 位或更长的字符串。 4. **启动服务**: ```bash npm start ``` 服务将在 `http://localhost:3000` (或你配置的端口) 运行。 ## Docker 部署 你可以使用 Docker 或 Docker Compose 快速部署。 ### 方式一:使用 `docker build` 和 `docker run` 1. **克隆仓库**: ```bash git clone https://github.com/dreamhartley/JimiHub.git cd JimiHub ``` 2. **配置环境变量**: * 复制 `.env.example` 文件为 `.env`: ```bash cp .env.example .env ``` * 编辑 `.env` 文件,设置必要的变量(`ADMIN_PASSWORD`, `SESSION_SECRET_KEY`)以及可选的 GitHub 同步变量(`GITHUB_PROJECT`, `GITHUB_PROJECT_PAT`, `GITHUB_ENCRYPT_KEY`)。**注意:`PORT` 变量在 Docker 部署中通常不需要在 `.env` 文件中设置,端口映射在 `docker run` 命令中完成。** 3. **构建 Docker 镜像**: ```bash docker build -t gemhub . ``` 4. **运行 Docker 容器**: ```bash docker run -d --name gemhub \ -p 3000:3000 \ --env-file .env \ -v ./data:/usr/src/app/data \ gemhub ``` * `-d`: 后台运行容器。 * `--name gemhub`: 给容器命名。 * `-p 3000:3000`: 将主机的 3000 端口映射到容器的 3000 端口。 * `--env-file .env`: 从 `.env` 文件加载环境变量。 * `-v ./data:/usr/src/app/data`: 将本地的 `data` 目录挂载到容器内,用于持久化 SQLite 数据库。请确保本地存在 `data` 目录。 ### 方式二:使用 `docker-compose` (推荐) 1. **克隆仓库**: ```bash git clone https://github.com/dreamhartley/JimiHub.git cd JimiHub ``` 2. **配置环境变量**: * 复制 `.env.example` 文件为 `.env`: ```bash cp .env.example .env ``` * 编辑 `.env` 文件,设置必要的变量(`ADMIN_PASSWORD`, `SESSION_SECRET_KEY`)以及可选的 GitHub 同步变量(`GITHUB_PROJECT`, `GITHUB_PROJECT_PAT`, `GITHUB_ENCRYPT_KEY`)。 3. **启动服务**: ```bash docker-compose up -d ``` Docker Compose 会自动构建镜像(如果需要)、创建并启动容器,并根据 `docker-compose.yml` 文件处理端口映射、环境变量和数据卷。 ## 使用 ### 管理面板 1. 访问你的 URL 的 `/login` 或 `/admin` 路径 (例如: `https://your-worker-name.your-subdomain.workers.dev/login`)。 2. 使用你设置的 `ADMIN_PASSWORD` 登录。 3. 在管理面板中,你可以: * 添加和管理你的 Gemini API Key。 * 添加和管理用于访问此 Worker 代理的 API Key (Worker API Keys)。 * 为 Pro 和 Flash 系列模型设置全局配额。 * 查看每个 Gemini API Key 的使用统计。 * 配置支持的 Gemini 模型。 ### API 代理 1. 将你的应用程序的 API 端点(原本配置为调用 OpenAI API 的地址)指向你部署的 Worker URL (例如: `https://your-worker-name.your-subdomain.workers.dev/v1`)。 2. 确保你的应用在发送请求时包含有效的身份验证信息。这通常通过在 `Authorization` 请求头中携带在管理面板配置的 "Worker API Key" 来完成: ``` Authorization: Bearer ``` 3. 发送与 OpenAI Chat Completions API 兼容的请求。Worker 会将其转换为 Gemini API 请求,并返回格式化的响应。 ## 配置概览 ### 本地 Node.js / Docker / Hugging Face 部署 这些部署方式通过 `.env` 文件或 Secrets (Hugging Face) 配置环境变量。 * **核心环境变量 (必须)**: * `ADMIN_PASSWORD`: 管理面板的登录密码。 * `SESSION_SECRET_KEY`: 用于保护用户会话安全的密钥 (建议使用长随机字符串)。 * **可选环境变量**: * `PORT`: (仅本地 Node.js/Docker) 服务监听的端口,默认为 3000。Hugging Face 会自动处理端口。 * **GitHub 同步环境变量 (可选, Hugging Face 必需)**: * `GITHUB_PROJECT`: 用于数据同步的**你自己的** GitHub 仓库路径 (格式: `username/repo-name`)。 * `GITHUB_PROJECT_PAT`: 具有 `repo` 权限的 GitHub Personal Access Token。 * `GITHUB_ENCRYPT_KEY`: 用于加密同步数据的密钥 (至少 32 位)。 ================================================ FILE: doc/Deploy/Colab/Colab部署.md ================================================ # Colab 部署 此部署方式利用 Colab 的 Notebook 环境运行,并**强制要求启用 GitHub 同步**功能以实现数据持久化。 注意,由于 Colab 的特性,此部署方式无法做到持续运行,每次运行后退出网页,实例最长运行90分钟。但此方法拥有以下显著优点: * 无门槛,只要有 Google 帐号即可使用 * 部署简单,通过笔记本一键部署运行 * 最大化利用 GitHub 同步功能,实现数据的持久保存 1. **准备 GitHub 仓库和 PAT (必须)**: * 你需要一个**自己的** GitHub 仓库来存储同步的数据。建议使用私有仓库。 * 创建一个 GitHub Personal Access Token (PAT),并确保勾选了 `repo` 权限范围。**请妥善保管此 Token**。 * 具体操作步骤详见[GitHub配置同步教程](../GitHub/GitHub同步.md) 2. **保存 Colab 笔记本**: * 点击[![Open In Colab](202507131855.svg)](https://colab.research.google.com/github/dreamhartley/JimiHub/blob/main/doc/Deploy/Colab/colab启动.ipynb)打开笔记本。 * 点击左上角的`复制到云端硬盘`,这将在您自己的 Google Drive 中创建一个副本。 ![](image/1.0.jpg) * 页面将进行跳转,确认新的笔记本名称为`“colab启动.ipynb”的副本`,您可以自行修改名称。 ![](image/1.1.jpg) 3. **填写环境变量**: * 在您自己的笔记本中,来到`配置环境变量`代码单元,在表单中根据说明填写您的配置信息。 ![](image/2.0.jpg) * 在表单中填写必填项,包括管理员密码、GitHub 项目路径和 PAT。 * 如果需要,可以填写可选项,包括加密密钥。 * 填写的配置信息会自动保存,下次启动时无需再次填写。 4. **运行笔记本**: * 确认所有配置无误后,点击`全部运行`按钮,即可启动面板。 ![](image/2.1.jpg) * 在`启动面板`代码单元的输出中可以找到Cloudflare Tunnel的临时地址,点击即可访问后台UI。 ![](image/2.2.jpg) 5. **持续运行与结束**: * Colab 实例在未操作的情况下最长运行90分钟,您可以关闭网页(不要结束运行),实例会继续运行。 * 如果需要保持运行,可以在保持网页开启的情况下最长运行12小时。 * 当需要结束运行时,点击右上角的`断开连接并删除运行时`。 ![](image/3.0.jpg) * 填写的信息会自动保存,下次使用时访问[Google Colab](https://colab.research.google.com/)选择之前保存的笔记本,无须输入即可直接`全部运行`,每次连接时仅需要替换新的临时地址即可。 6. **在后台中进行设置** * 在后台UI中进行配置 Api 连接,详细请参考[配置API连接教程](../../Usage/配置API连接.md)。 ================================================ FILE: doc/Deploy/Colab/colab启动.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "cellView": "form", "id": "Y3W1uluay548" }, "outputs": [], "source": [ "# @title 🔨 1. 安装依赖\n", "import subprocess\n", "import sys\n", "import os\n", "\n", "def run_cmd(cmd, cwd=None):\n", " result = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd)\n", " if result.returncode != 0:\n", " print(f\"❌ 命令执行出错: {cmd}\")\n", " print(result.stderr.decode('utf-8'))\n", " sys.exit(1)\n", "\n", "print('⏳ 正在安装依赖...')\n", "\n", "try:\n", " # 安装 Node.js 20\n", " run_cmd('curl -fsSL https://deb.nodesource.com/setup_20.x | bash -')\n", " run_cmd('apt-get install -y nodejs')\n", "\n", " # 克隆 GitHub 项目\n", " run_cmd('git clone https://github.com/dreamhartley/JimiHub.git')\n", "\n", " # 进入项目目录\n", " os.chdir('JimiHub')\n", "\n", " # 使用 npm 安装项目依赖\n", " run_cmd('npm install')\n", "\n", " print('✅ 依赖安装完成!')\n", "except Exception as e:\n", " print('❌ 安装过程中出现了错误:', e)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "cellView": "form", "id": "FxGtbacnzSZn" }, "outputs": [], "source": [ "# @title ⚙️ 2. 配置环境变量\n", "%cd /content/JimiHub\n", "# @markdown 请在下面的表单中填入您的配置信息。\n", "# @markdown ---\n", "\n", "# @markdown ### **必填项**\n", "# @markdown **1. 管理员密码 (`ADMIN_PASSWORD`)**\n", "# @markdown 后台管理面板的登录密码。\n", "admin_password = \"\" #@param {type:\"string\"}\n", "\n", "# @markdown **2. GitHub 项目 (`GITHUB_PROJECT`)**\n", "# @markdown 您的 GitHub 项目路径,格式为 `用户名/仓库名`。\n", "github_project = \"\" #@param {type:\"string\"}\n", "\n", "# @markdown **3. GitHub PAT (`GITHUB_PROJECT_PAT`)**\n", "# @markdown 用于访问 GitHub 仓库的个人访问令牌 (Personal Access Token)。请确保它具有读写仓库内容的权限。\n", "github_pat = \"\" #@param {type:\"string\"}\n", "\n", "# @markdown ---\n", "# @markdown ### **可选项**\n", "# @markdown **4. 加密密钥 (`GITHUB_ENCRYPT_KEY`)**\n", "# @markdown (可选)一个32位长度的字符串,用于加密敏感数据,对于已加密的数据库必须使用和之前相同的密钥。如果留空,则不启用加密。\n", "github_encrypt_key = \"\" #@param {type:\"string\"}\n", "\n", "\n", "# --- 后续逻辑 (无需修改) ---\n", "# 检查必填项是否已填写\n", "if not all([admin_password, github_project, github_pat]):\n", " print(\"❌ 错误:管理员密码、GitHub 项目和 PAT 均为必填项,请填写后再运行!\")\n", "else:\n", " # 使用从表单获取的变量创建 .env 文件内容\n", " # .strip() 用于移除开头和结尾可能存在的空白\n", " env_content = f\"\"\"\n", "ADMIN_PASSWORD={admin_password}\n", "GITHUB_PROJECT={github_project}\n", "GITHUB_PROJECT_PAT={github_pat}\n", "GITHUB_ENCRYPT_KEY={github_encrypt_key}\n", "\"\"\".strip()\n", "\n", " # 将内容写入 .env 文件\n", " with open(\".env\", \"w\") as f:\n", " f.write(env_content)\n", "\n", " print(\"✅ .env 文件已成功创建并写入以下内容:\")\n", " # 打印文件内容以供核对\n", " !cat .env\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "cellView": "form", "id": "T3Wzz133zWEx" }, "outputs": [], "source": [ "# @title 🚀 3. 启动面板\n", "# 下载 Cloudflare Tunnel\n", "!wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -O cloudflared\n", "!chmod +x cloudflared\n", "\n", "import subprocess\n", "import time\n", "from IPython.display import display, HTML\n", "import re\n", "\n", "def start_cloudflare_tunnel(log_path='tunnel.log', retries=5, wait_sec=5):\n", " \"\"\"启动 Cloudflare Tunnel 并返回访问 URL,失败时自动重试。\"\"\"\n", " tunnel_cmd = './cloudflared tunnel --url http://127.0.0.1:3000 > {} 2>&1 &'.format(log_path)\n", " for attempt in range(1, retries + 1):\n", " # 启动隧道\n", " subprocess.Popen(tunnel_cmd, shell=True)\n", " print(f\"第 {attempt} 次尝试启动 Cloudflare Tunnel...\")\n", " time.sleep(wait_sec)\n", " # 提取 URL\n", " tunnel_url = None\n", " try:\n", " with open(log_path, 'r', encoding='utf-8', errors='ignore') as f:\n", " for line in f:\n", " match = re.search(r'https://[a-zA-Z0-9-]+\\.trycloudflare\\.com', line)\n", " if match:\n", " tunnel_url = match.group(0)\n", " break\n", " except Exception as e:\n", " print(f\"读取日志文件异常: {e}\")\n", " if tunnel_url:\n", " return tunnel_url\n", " else:\n", " print(\"未获取到 URL,准备重试...\")\n", " # 杀掉可能遗留的 cloudflared 进程\n", " subprocess.run(\"pkill -f cloudflared\", shell=True)\n", " time.sleep(1)\n", " return None\n", "\n", "tunnel_url = start_cloudflare_tunnel()\n", "\n", "if tunnel_url:\n", " # 美化的 HTML 面板\n", " panel_html = f\"\"\"\n", "
\n", "
\n", " ✅ Cloudflare Tunnel 已启动\n", "
\n", "
\n", " 访问地址:\n", " {tunnel_url}\n", "
\n", "
\n", " API端点:\n", " {tunnel_url}/v1\n", "
\n", "
\n", " \"\"\"\n", " display(HTML(panel_html))\n", "else:\n", " error_html = \"\"\"\n", "
\n", " ❌ 未能获取 Cloudflare Tunnel 的临时 URL,请检查 tunnel.log 或稍后重试。\n", "
\n", " \"\"\"\n", " display(HTML(error_html))\n", "\n", "# 启动 Node.js 项目\n", "print(\"\\n正在后台启动 Node.js 项目 (npm start)...\")\n", "!npm start\n" ] } ], "metadata": { "colab": { "provenance": [] }, "kernelspec": { "display_name": "Python 3", "name": "python3" }, "language_info": { "name": "python" } }, "nbformat": 4, "nbformat_minor": 0 } ================================================ FILE: doc/Deploy/GitHub/GitHub同步.md ================================================ # GitHub 同步功能 gemini proxy panel 支持 GitHub 同步数据库功能,这个功能可以自动将数据库上传至您的私人 GitHub 仓库,并且在每次启动时自动下载最新的数据库,以保证数据的持久化存储。 **注意:** 在不支持持久化数据的平台(例如 Hugging Face Space)部署时,必须启用此功能。 ## 创建数据库仓库 1. 首先,来到 GitHub 后台,点击右上角的头像打开右侧边栏。 ![GitHub 后台界面](image/1.0.jpg) 2. 点击 `Your repositories` 打开 repo 界面。 ![Your repositories 界面](image/1.1.jpg) 3. 点击 `New` 新建一个仓库。 ![新建仓库按钮](image/1.2.jpg) 4. 在 `Repository name` 处填写一个自定义名称,并且选择 `Private` 创建一个私人仓库,最后点击 `Create repository` 完成创建。 ![创建仓库表单](image/1.3.jpg) 5. 在 repo 界面找到刚刚创建的仓库,点击打开,在 URL 栏复制后缀 `用户名/仓库名`,这将作为环境变量 `GITHUB_PROJECT` 使用。 ![仓库 URL 位置](image/1.4.jpg) ## 创建 PAT 密钥 1. 在 GitHub 后台,点击右上角的头像打开的右侧边栏中点击 `Settings`。 ![Settings 菜单](image/2.0.jpg) 2. 在新打开的左侧边栏中的最下方点击 `Developer settings`。 ![Developer settings 选项](image/3.0.jpg) 3. 选择 `Personal access tokens` 中的 `Tokens (classic)` 选项,并在右侧的页面中选择 `Generate new token` 并点击 `Generate new token (classic)`。 ![Personal access tokens 页面](image/4.0.jpg) 4. 在新打开的页面中随意填写一个 `Note` 为 PAT 命名,并且在下方的权限选择区域中确保选中 `repo` 权限。可以设置让 PAT 不会过期。 ![PAT 权限设置](image/5.0.jpg) 5. 点击 `Generate token` 创建 PAT 密钥。 ![Generate token 按钮](image/5.1.jpg) 6. 在弹出的页面中记录 PAT 密钥,这将作为环境变量 `GITHUB_PROJECT_PAT` 使用。 ![生成的 PAT 密钥](image/5.2.jpg) ## 启用 GitHub 同步功能 在环境变量中正确配置上面步骤中获取的 `GITHUB_PROJECT`、`GITHUB_PROJECT_PAT` 即可启用 GitHub 同步功能。 ### 启用加密功能(可选) 数据库加密功能将使用 AES-256-CBC 加密算法实现对上传的数据库进行加密,在不泄露密钥的情况下基本可保证数据的安全不被破解。 在环境变量中添加变量 `GITHUB_ENCRYPT_KEY`,并配置一个最少 32 位的密钥以启用加密功能,建议使用[密码生成工具](https://1password.com/zh-cn/password-generator)生成。 > **注意:** 如果您希望后续重置部署,或使用其他的部署时保持现有的数据,请在本地妥善保存以上使用到的环境变量。 ================================================ FILE: doc/Deploy/HuggingFace/Hugging Face Space部署-fork说明.md ================================================ # Hugging Face Space部署出现问题的应对 由于本项目在Hugging Face Space中部署较多,疑似被官方封禁,直接拉取项目镜像可能会导致部署失败或Space被停用,如果您在使用中遇到类似的问题,请参考以下的步骤Fork项目并创建自己的镜像: 1. **创建GitHub仓库Fork** - 创建Fork [dreamhartley/JimiHub](https://github.com/dreamhartley/JimiHub/fork) - 确保使用自定义的仓库名称,**不要包含** `JimiHub`或`hajimi`等关键词 2. **启用工作流** - 在上方Actions标签栏,点击`I understand my workflows, go ahead and enable them`按钮 ![](image/8.0.jpg) 3. **运行Docker镜像构建工作流** - 在左侧边栏选择`Docker Image CI for Hugging Face` - 在右侧点击`Run workflow` ![](image/8.1.jpg) 4. **获取镜像地址** - 等待运行完成 - 在Fork的仓库页面,点击Packages中创建的镜像 ![](image/8.2.jpg) - 复制镜像地址 5. **创建Huggingface Space** - 在Huggingface Space创建Dockerfile - 内容填写:`FROM ghcr.io/GitHub用户名/Fork仓库名:latest` - 替代原本教程中提供的镜像地址,其余步骤不变 ## 更新部署 如果通过fork仓库创建镜像后部署在Huggingface Space的用户需要更新: 1. 在fork的仓库页面点击`Sync fork`-->`Update branch` ![](image/8.3.jpg) 2. 等待Actions自动运行完成后会创建新的镜像 3. 在Space页面点击`Settings`-->`Factory rebuild`即可 ================================================ FILE: doc/Deploy/HuggingFace/Hugging Face Space部署.md ================================================ # Hugging Face Space 部署 此部署方式利用 Hugging Face Space 的 Docker 环境运行,并**强制要求启用 GitHub 同步**功能以实现数据持久化。 > 本项目被Hugging Face标记,如果您在使用中存在问题,例如卡Building或者停止运行,请参考[Hugging Face部署出现问题的应对](Hugging%20Face%20Space部署-fork说明.md) 1. **准备 GitHub 仓库和 PAT**: * 你需要一个**自己的** GitHub 仓库来存储同步的数据。建议使用私有仓库。 * 创建一个 GitHub Personal Access Token (PAT),并确保勾选了 `repo` 权限范围。**请妥善保管此 Token**。 * 具体操作步骤详见[GitHub配置同步教程](../GitHub/GitHub同步.md) 2. **创建 Hugging Face Space**: * 访问 Hugging Face Space 页面,点击新建一个 Space。\ ![](image/1.0.jpg) * 在`Space name`处随意填写一个自定义名称,请不要包含`gemini proxy panel`或`hajimi`等关键词\ ![](image/2.0.jpg) * 选择 "Docker" 作为 Space SDK。\ ![](image/2.1.jpg) * 确保选择的免费的配置类型,并且设置空间为公开。最后点击`Create Space`。\ ![](image/2.2.jpg) 3. **配置 Space Secrets**: * 进入你创建的 Space 的 "Settings" -> "Repository secrets"。\ ![](image/3.0.jpg) ![](image/4.0.jpg) * 添加以下 Secrets: * `ADMIN_PASSWORD`: 设置管理面板的登录密码。\ ![](image/4.4.jpg) * `GITHUB_PROJECT`: 填入你**自己的** GitHub 仓库路径,格式为 `your-username/your-repo-name`。\ ![](image/4.1.jpg) * `GITHUB_PROJECT_PAT`: 填入你创建的 GitHub PAT。\ ![](image/4.2.jpg) * Secrets配置完成。 ![](image/5.0.jpg) 4. **创建 Dockerfile**: > 本项目被Hugging Face标记,如果您在使用中存在问题,例如卡Building或者停止运行,请参考[Hugging Face部署出现问题的应对](Hugging%20Face%20Space部署-fork说明.md) * 在 Hugging Face Space 的 "Files" 标签页中,点击 "Add file" -> "Create new file"。\ ![](image/6.0.jpg) * 将文件名设置为 `Dockerfile`。 * 将以下内容粘贴到文件中: ```dockerfile FROM dreamhartley705/jimihub:huggingface ``` 或Fork仓库创建的镜像地址 ```dockerfile FROM ghcr.io/GitHub用户名/Fork仓库名:latest ``` * 点击 "Commit new file"。 ![](image/6.1.jpg) 5. **启动和访问**: * Hugging Face Space 会自动使用此 `Dockerfile` 构建并启动应用。 * 应用启动后,会使用你配置的 Secrets 连接到你的 GitHub 仓库进行数据同步。 * 点击查看 Log 会自动显示后台UI地址。\ ![](image/7.jpg) 6. **在后台中进行设置** * 在后台UI中进行配置 Api 连接,详细请参考[配置API连接教程](../../Usage/配置API连接.md) ================================================ FILE: doc/Deploy/Koyeb/Koyeb部署.md ================================================ # Koyeb 部署 此部署方式利用 Koyeb 的 Docker 环境运行,并**强制要求启用 GitHub 同步**功能以实现数据持久化。 1. **准备 GitHub 仓库和 PAT**(不可跳过): * 你需要一个**自己的** GitHub 仓库来存储同步的数据。建议使用私有仓库。 * 创建一个 GitHub Personal Access Token (PAT),并确保勾选了 `repo` 权限范围。**请妥善保管此 Token**。 * 具体操作步骤详见[GitHub配置同步教程](../GitHub/GitHub同步.md) 2. **在 Koyeb 创建并部署容器**: * 访问 [Koyeb注册页面](https://app.koyeb.com/auth/signup)。 * 选择一个方式创建账户,可以使用GitHub账号,或邮箱进行注册。 ![](image/1.0.jpg) * 注册并验证账号后,在页面中输入一个自定义的组织名称,后续选项可以随意选择或跳过。 ![](image/1.1.jpg) * 进入主界面后,在右侧选择Docker容器部署。 ![](image/2.0.jpg) * 在Image选项填写`dreamhartley705/jimihub:latest`,点击下一步。 ![](image/2.1.jpg) * 在配置选择界面,选择`CPU Eco`,并选择一个免费的容器类型,点击下一步。 ![](image/2.2.jpg) * 来到详细配置页面,在`Edit variables and files`中配置环境变量,请确保填写`ADMIN_PASSWORD`,`GITHUB_PROJECT`,`GITHUB_PROJECT_PAT`这三个变量。`GITHUB_ENCRYPT_KEY`为可选的数据库加密选项,如果需要请自行填写。 ![](image/3.0.jpg) * 选择`Exposed ports`选项,将端口修改为`3000`。 ![](image/3.1.jpg) * 选择`Service name`选项,设置一个自定义的容器名称,请不要使用默认的名称。 ![](image/3.2.jpg) * 配置完成后,点击`Deploy`即可创建容器。 ![](image/3.3.jpg) * 在新页面中,等待容器创建完成,上方的`Public URL`为访问地址。 ![](image/4.0.jpg) 3. **在后台中进行设置** * 在后台UI中进行配置 Api 连接,详细请参考[配置API连接教程](../../Usage/配置API连接.md)。 4. **Koyeb 容器保活(可选)** * Koyeb 容器将在未使用时自动关闭,并且再次请求时自动启动,这会导致容器重启后第一次的请求时间大幅度延迟,如果您希望让容器保持运行,可以参考[配置Uptimerrobot](../Uptimerobot/配置Uptimerrobot.md)中的内容。 ================================================ FILE: doc/Deploy/Local/本地部署.md ================================================ # 本地部署指南 ## Node.js 部署 此方式适合本地开发和测试。 1. **克隆仓库**: ```bash git clone https://github.com/dreamhartley/JimiHub.git cd JimiHub ``` 2. **安装依赖**: ```bash npm install ``` 3. **配置环境变量**: * 复制 `.env.example` 文件为 `.env`: ```bash cp .env.example .env ``` * 编辑 `.env` 文件,至少设置以下变量: * `ADMIN_PASSWORD`: 设置管理面板的登录密码。 * `SESSION_SECRET_KEY`: 设置一个长且随机的字符串用于会话安全(例如,使用 `openssl rand -base64 32` 生成)。 * `PORT` (可选): 默认是 3000,可以根据需要修改。 * **(可选) 配置 GitHub 同步**: 如果需要将数据同步到 GitHub 仓库,请配置以下变量: * `GITHUB_PROJECT`: 你的 GitHub 仓库路径,格式为 `username/repo-name`。**注意:这是你自己的仓库,用于存储数据备份,并非本项目仓库。** * `GITHUB_PROJECT_PAT`: 你的 GitHub Personal Access Token,需要 `repo` 权限。 * `GITHUB_ENCRYPT_KEY`: 用于加密同步数据的密钥,必须是 32 位或更长的字符串。 4. **启动服务**: ```bash npm start ``` 服务将在 `http://localhost:3000` (或你配置的端口) 运行。 ## Docker 部署 你可以使用 Docker 或 Docker Compose 快速部署。 ### 方式一:使用 `docker build` 和 `docker run` 1. **克隆仓库**: ```bash git clone https://github.com/dreamhartley/JimiHub.git cd JimiHub ``` 2. **配置环境变量**: * 复制 `.env.example` 文件为 `.env`: ```bash cp .env.example .env ``` * 编辑 `.env` 文件,设置必要的变量(`ADMIN_PASSWORD`, `SESSION_SECRET_KEY`)以及可选的 GitHub 同步变量(`GITHUB_PROJECT`, `GITHUB_PROJECT_PAT`, `GITHUB_ENCRYPT_KEY`)。**注意:`PORT` 变量在 Docker 部署中通常不需要在 `.env` 文件中设置,端口映射在 `docker run` 命令中完成。** 3. **构建 Docker 镜像**: ```bash docker build -t jimihub . ``` 4. **运行 Docker 容器**: ```bash docker run -d --name jimihub \ -p 3000:3000 \ --env-file .env \ -v ./data:/usr/src/app/data \ jimihub ``` * `-d`: 后台运行容器。 * `--name gemini-proxy-panel`: 给容器命名。 * `-p 3000:3000`: 将主机的 3000 端口映射到容器的 3000 端口。 * `--env-file .env`: 从 `.env` 文件加载环境变量。 * `-v ./data:/usr/src/app/data`: 将本地的 `data` 目录挂载到容器内,用于持久化 SQLite 数据库。请确保本地存在 `data` 目录。 ### 方式二:使用 `docker-compose` (推荐) 1. **克隆仓库**: ```bash git clone https://github.com/dreamhartley/JimiHub.git cd JimiHub ``` 2. **配置环境变量**: * 复制 `.env.example` 文件为 `.env`: ```bash cp .env.example .env ``` * 编辑 `.env` 文件,设置必要的变量(`ADMIN_PASSWORD`, `SESSION_SECRET_KEY`)以及可选的 GitHub 同步变量(`GITHUB_PROJECT`, `GITHUB_PROJECT_PAT`, `GITHUB_ENCRYPT_KEY`)。 3. **启动服务**: ```bash docker-compose up -d ``` Docker Compose 会自动构建镜像(如果需要)、创建并启动容器,并根据 `docker-compose.yml` 文件处理端口映射、环境变量和数据卷。 ================================================ FILE: doc/Deploy/Render/Render部署.md ================================================ # Render 部署 此部署方式利用 Render 的 Docker 环境运行,并**强制要求启用 GitHub 同步**功能以实现数据持久化。 1. **准备 GitHub 仓库和 PAT**: * 你需要一个**自己的** GitHub 仓库来存储同步的数据。建议使用私有仓库。 * 创建一个 GitHub Personal Access Token (PAT),并确保勾选了 `repo` 权限范围。**请妥善保管此 Token**。 * 具体操作步骤详见[GitHub配置同步教程](../GitHub/GitHub同步.md) 2. **在 Render 创建并部署容器** * 访问 [Render](https://render.com/),点击右上角的`Get Started`按钮。 ![](image/1.0.jpg) * 选择一个方式创建账户,可以使用邮箱或第三方账号,例如谷歌账号登陆。 ![](image/2.0.jpg) * 在开始界面选择创建一个`Web Services`。 ![](image/3.0.jpg) * 选择`Existing Image`,在`Image URL`中填写项目的镜像。 ``` dreamhartley705/jimihub:latest ``` ![](image/4.0.jpg) * 点击`Connect`,在`Name`中填写一个自定义容器的名称,这个名称将会是访问URL的一部分,**不建议使用默认**,请自行填写。在下方选择容器的区域,推荐使用美国(US)区域。 ![](image/4.1.jpg) * 选择免费容器类型。 ![](image/4.2.jpg) * 配置环境变量,请确保填写`ADMIN_PASSWORD`,`GITHUB_PROJECT`,`GITHUB_PROJECT_PAT`这三个变量。`GITHUB_ENCRYPT_KEY`为可选的数据库加密选项,如果需要请自行填写。 ![](image/4.3.jpg)配置完成的示例 * 点击`Deploy web service`即可创建容器。 * 在新页面中出现`Your service is live 🎉`表示部署成功,点击Log上方的URL即可访问容器地址。
注意,如果在创建容器时未修改镜像名称,URL将会为默认名称后添加随机字符,建议修改为自定义名称。 ![](image/5.0.jpg) * 后台地址为`https://xxx.onrender.com/admin` 3. **在后台中进行设置** * 在后台UI中进行配置 Api 连接,详细请参考[配置API连接教程](../../Usage/配置API连接.md)。 4. **Render 容器保活(可选)** * Render 容器将在未使用的15分钟后自动关闭,并且再次请求时自动启动,这会导致容器重启后第一次的请求时间大幅度延迟,如果您希望让容器保持运行,可以参考[配置Uptimerrobot](../Uptimerobot/配置Uptimerrobot.md)中的内容。 > ⚠️ 注意: Render 免费容器每月有750小时的免费额度,这意味着您在同一个 Render 账号中仅可部署一个持续运行的容器。超出免费额度的使用可能会被关停容器或要求付费。 ================================================ FILE: doc/Deploy/Uptimerobot/配置Uptimerrobot.md ================================================ # 使用 Uptimerrobot 保活容器 1. **注册 Uptimerrobot** * 访问 [Uptimerrobot](https://uptimerobot.com/),选择登陆或创建一个账号,创建账号时使用邮箱进行创建。 ![](image/1.0.jpg) ![](image/1.1.jpg) 2. **登陆并配置 Uptimerrobot** * 注册并验证邮箱后可以登陆到 Uptimerrobot,如果是第一次登陆会直接提示配置监控。 * 在`Create your first monitor`中的`URL to monitor`处填写您的容器地址(主页即可)。点击`Create monitor`。 ![](image/2.0.jpg) * 后续的步骤可以点击跳过(Skip),最后点击`Nah, get me to dashboard already!`完成创建。 ![](image/2.1.jpg) ## 您已经成功配置 Uptimerrobot 免费套餐下 Uptimerrobot 会每 5 分钟访问一次配置的URL,您的容器已经实现了24小时在线运行。 ================================================ FILE: doc/Usage/KEEPALIVE.md ================================================ # 功能介绍: KEEPALIVE模式 ## Docker/Hugging Face Space/Node.js 在网页设置中开启`KEEPALIVE`开关,可以启用KEEPALIVE响应模式。 启用KEEPALIVE模式后,使用流式请求到脚本,脚本会持续向客户端发送心跳响应以保持客户端的持续连接,防止客户端发生异常断开的情况。 注意,当使用`KEEPALIVE`功能时,请确保使用的请求密钥(Worker Api Key)的安全设定为关闭(Disabled),且在请求时使用流式响应。 `KEEPALIVE`功能不会影响到非流式响应或启用了安全设定的流式响应。 ================================================ FILE: doc/Usage/Vertex/Vertex代理配置.md ================================================ # Vertex 代理配置 通过配置 `VERTEX` 环境变量,启用 Vertex 代理功能,添加使用 Vertex AI 平台的 Gemini 模型。 --- ## 启用 Generative Language API * 如果您的项目还未启用 Generative Language API,需要先设置启用,已经启用可以跳过。 * 在左侧边栏中选择`API 和服务`中的`已启用的API 和服务`。 ![](image/5.0.jpg) * 在打开的页面中点击`+ 启用API 和服务`。 ![](image/5.1.jpg) * 在搜索栏中输入搜索`Generative Language API`。 ![](image/5.2.jpg) * 选择启用 Generative Language API ![](image/5.3.jpg) --- ## 创建服务账号 * 在 [Google Cloud Platform](https://cloud.google.com/) 中登陆并激活账户。 * 在左侧边栏中选择`IAM和管理`并点击`服务账号`。 ![](image/1.0.jpg) * 点击`创建服务账号`。 ![](image/2.0.jpg) * 在`服务账号详情`中随意填写一个`服务账号ID`。选择`创建并继续`。 ![](image/3.0.jpg) * 在角色中选择`Vertex Al Service Agent`。 ![](image/3.1.jpg) ![](image/3.2.jpg) * 点击`完成`创建服务账号。 ![](image/3.3.jpg) --- ## 创建API凭证 * 点击服务账号右侧的三点图标并选择`管理密钥`。 ![](image/4.0.jpg) ![](image/4.1.jpg) * 在页面中点击`添加键`并选择`创建新密钥`。 ![](image/4.2.jpg) * 选择JSON格式并点击创建。 ![](image/4.3.jpg) --- ## 添加 API 凭证到环境变量 在变量文件中添加一个`VERTEX`变量,并将下载的JSON格式变量完整地粘贴到变量中。\ 参考格式 ``` VERTEX={ "type": "service_account", "project_id": "XXXXXXXXXXX", "private_key_id": "XXXXXXXXXXX", "private_key": "-----BEGIN PRIVATE KEY-----\ABCD\n-----END PRIVATE KEY-----\n", "client_email": "XXXXXXXXXXX.iam.gserviceaccount.com", "client_id": "XXXXXXXXXXX", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/ "universe_domain": "googleapis.com" } ``` ================================================ FILE: doc/Usage/在客户端中使用.md ================================================ ================================================ FILE: doc/Usage/配置API连接.md ================================================ # 在管理UI中配置API连接 ## 添加 AI Studio 密钥 * 在 `Gemini API Keys` 界面中的 `API Key Value` 中填写并添加 Gemini Api 密钥,可选择批量进行添加,批量添加时使用英文逗号 `,` 进行分隔,例如 `key1,key2,kye3`。在使用批量添加功能时请不要添加自定义名称功能。自定义名称可留空。 ![](image/1.0.jpg) ## 添加一个模型 * 在 `Managed Models` 界面中添加想要使用的模型,当正确添了 Gemini Api 密钥后,刷新页面,脚本将自动获取当前可用的模型列表。 ![](image/3.0.jpg) * 您可以选择在类别中切换模型的类别以匹配不同的额度,当然,大多数情况下脚本可用做到自动匹配。 ![](image/3.1.jpg) * 当使用 Custom 类别的模型时,您可用输入一个基于模型的额度,Custom 类别中的每个模型的额度都会被独立管理。设置 `0` 或 `none` 表示无限额度。 ![](image/3.1.1.jpg) ## 添加一个请求 Api 密钥 除了添加的 Gemini Api 外,您还需要添加用于请求到当前脚本的 Api 密钥。 * 在 `Worker API Keys` 界面中添加密钥,点击 `Generate Random Key` 可用使用随机生成的密钥,或者您可以自行填写密钥,注意密钥中不要包含特殊字符。密钥的名称可自定义或留空。 ![](image/2.0.jpg) * 您可用管理或分发多个 Api 密钥,该密钥为客户端请求时使用的密钥。 ## 测试 Gemini Api 密钥的可用性 当正确配置 Gemini Api 密钥以及添加模型后,您可用点击密钥的显示卡片展开密钥使用情况,点击 `Test` 并选择一个测试模型即可快速测试密钥的可用性。 ![](image/1.1.jpg) ## 管理安全设置 使用本项目可用管理请求密钥在使用时的安全设定,当安全设定为 `Disabled` 时,将在转发 Gemini Api 请求时关闭默认的安全审查机制。您可以给不同的请求密钥设置不同的安全设定以适配不同的使用环境。当使用 `KEEPALIVE` 机制进行伪流式请求时需要关闭安全设定才会生效。 ![](image/2.1.jpg) ## 管理配额 在 `Managed Models` 界面点击 `Set Category Quotas`,可以设定 Pro 与 Flash 类别模型不同的每日额度。默认额度为 Pro 每天 50 次,Flash 每天 1500 次,请根据实际情况进行调整。 ![](image/3.1.2.jpg) ![](image/3.1.3.jpg) ## 添加 Vertex 配置 本项目支持连接到Vertex AI平台的Gemini模型,Vertex配置的申请操作请参考:[Vertex代理配置](Vertex/Vertex代理配置.md) 切换到Vertex标签后即可在网页中配置Vertex Api,支持两种方式连接到Vertex Api #### 服务账号 (JSON) - 选择`服务账号 (JSON)`并在输入框填写完整的 Google Cloud Service Account JSON 配置,点击`保存 Vertex 配置`即可保存服务账号信息。 ![](image/vertex-1.jpg) #### 快捷模式 (API Key) - 选择`快捷模式 (API Key)`并在输入框填写Express API Key,点击`保存 Vertex 配置`即可保存快捷模式密钥。 ![](image/vertex-2.jpg) #### 配置完成 保存Vertex配置后,网页将会显示使用的Vertex配置信息,并且显示为`已启用`,此时连接到api端点即可使用带有`[v]`前缀的模型连接到Vertex Api。 再次添加配置会覆盖当前的Vertex配置信息,点击`清除配置`将会删除保存的Vertex配置信息并停用Vertex代理功能。 ![](image/vertex-3.jpg) ## 其他系统设置 点击网页右上角的设置按钮,即可调整其他的一些系统功能 ![](image/setting.jpg) - **KEEPALIVE**:启用后可以使用保持连接方式处理请求,也被成为假流式,具体使用请参考[KEEPALIVE模式介绍](KEEPALIVE.md) - **联网搜索**:默认关闭,启用后将会在模型列表中添加`-search`后缀的模型,使用时将会允许模型通过互联网搜索信息,暂时仅对AI Studio的模型生效。 - **最大重试次数**:请求失败后将会自动使用下一个有效的gemini api密钥重试请求,在此处修改允许重试的最大次数。 ================================================ FILE: doc/项目介绍.md ================================================ # JimiHub ## 项目简介 JimiHub 是一款将 Gemini API 请求转换为 OpenAI API 格式的代理工具,支持多个项目轮询、密钥管理分发等功能。 ## 主要功能 - **简洁的管理界面** - **支持流式/非流式响应,图片/文件上传,工具函数调用** - **多个 Gemini API Key 轮询** - **快速测试 Gemini API Key 可用性** - **简单便捷的模型管理** - **管理分发多个请求密钥** - **灵活且直观的额度管理及负载均衡** - **每日自动刷新额度** - **管理请求中的安全设置** - **可设置 GitHub 自动同步数据** - **开发中功能可能有变化** ## 开始使用 本项目支持多种部署方式,任何支持 Docker 容器以及 Node.js 的环境均可使用: - [Koyeb 部署](Deploy/Koyeb/Koyeb部署.md)(免费,试用7天后需要绑定银行卡,ip不干净可能导致无法使用) - [Colab 部署](Deploy/Colab/Colab部署.md) (免费,门槛低,但无法持久运行,每次使用可快速部署) - [Hugging Face Space 部署](Deploy/HuggingFace/Hugging%20Face%20Space部署.md) (免费,目前抱脸封号严重,请自行尝试或使用其他部署方式) - [Render 部署](Deploy/Render/Render部署.md)(免费,部署时需要绑定银行卡,使用干净的ip地址可以跳过绑卡) - [本地/VPS 部署](Deploy/Local/本地部署.md) - **VPS 一键部署脚本**\ 脚本将自动配置环境,并安装项目,根据提示设置管理密码即可。\ 适用于 Debian/Ubuntu/CentOS 系统: ```bash curl -fsSL https://raw.githubusercontent.com/dreamhartley/JimiHub/refs/heads/main/get-jimihub.sh -o get-jimihub.sh && sudo bash get-jimihub.sh ``` ## 部署后配置 - [管理界面的使用](Usage/配置API连接.md) ## 可选功能 - [KEEPALIVE](Usage/KEEPALIVE.md) - [Vertex 代理配置](Usage/Vertex/Vertex代理配置.md) ================================================ FILE: docker-compose.yml ================================================ version: '3.8' services: app: image: dreamhartley705/jimihub:latest container_name: jimihub ports: - "3000:3000" env_file: - .env volumes: - ./data:/app/data ================================================ FILE: get-jimihub.sh ================================================ #!/bin/bash # JimiHub管理脚本 # 版本: 1.0 # 定义颜色 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 定义路径 INSTALL_DIR="/opt/jimihub" SCRIPT_PATH="/usr/local/bin/jimihub" # 显示ASCII图案 show_ascii() { echo -e "${BLUE}" cat << 'EOF' ██╗██╗███╗ ███╗██╗██╗ ██╗██╗ ██╗██████╗ ██║██║████╗ ████║██║██║ ██║██║ ██║██╔══██╗ ██║██║██╔████╔██║██║███████║██║ ██║██████╔╝ ██ ██║██║██║╚██╔╝██║██║██╔══██║██║ ██║██╔══██╗ ╚█████╔╝██║██║ ╚═╝ ██║██║██║ ██║╚██████╔╝██████╔╝ ╚════╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ EOF echo -e "${NC}" } # 显示欢迎信息 show_welcome() { clear show_ascii echo -e "${GREEN}欢迎使用JimiHub管理脚本${NC}" echo -e "${YELLOW}================================================${NC}" echo "" } # 检查是否为root用户 check_root() { if [[ $EUID -ne 0 ]]; then echo -e "${RED}错误:此脚本需要root权限运行${NC}" exit 1 fi } # 检查安装状态 check_install_status() { if [ -d "$INSTALL_DIR" ] && [ -f "$INSTALL_DIR/docker-compose.yml" ]; then echo -e "${GREEN}✓ JimiHub已安装${NC}" INSTALLED=true else echo -e "${RED}✗ JimiHub未安装${NC}" INSTALLED=false fi } # 检查容器运行状态 check_container_status() { if [ "$INSTALLED" = true ]; then if docker ps | grep -q "jimihub"; then echo -e "${GREEN}✓ 容器正在运行${NC}" RUNNING=true show_access_url else echo -e "${YELLOW}✗ 容器未运行${NC}" RUNNING=false fi fi } # 显示访问URL show_access_url() { if [ -f "$INSTALL_DIR/.env" ]; then PORT=$(grep "PORT=" "$INSTALL_DIR/.env" | cut -d'=' -f2) if [ -z "$PORT" ]; then PORT=3000 fi # 检查是否为本地访问 if grep -q "127.0.0.1" "$INSTALL_DIR/docker-compose.yml"; then echo -e "${BLUE}访问地址: http://127.0.0.1:$PORT${NC}" else LOCAL_IP=$(hostname -I | awk '{print $1}') echo -e "${BLUE}访问地址: http://$LOCAL_IP:$PORT${NC}" fi fi } # 获取外部IP get_external_ip() { external_ip=$(curl -s https://ipv4.icanhazip.com/ || curl -s https://api.ipify.org) if [ -z "$external_ip" ]; then external_ip=$(hostname -I | awk '{print $1}') fi echo "$external_ip" } # 安装依赖 install_dependencies() { echo -e "${YELLOW}正在安装依赖...${NC}" # 更新包列表 if command -v apt-get &> /dev/null; then apt-get update apt-get install -y curl wget git elif command -v yum &> /dev/null; then yum install -y curl wget git elif command -v dnf &> /dev/null; then dnf install -y curl wget git else echo -e "${RED}错误:无法识别的包管理器${NC}" exit 1 fi } # 检查Docker Compose命令 check_docker_compose() { if docker compose version &> /dev/null; then DOCKER_COMPOSE_CMD="docker compose" elif command -v docker-compose &> /dev/null; then DOCKER_COMPOSE_CMD="docker-compose" else return 1 fi return 0 } # 安装Docker install_docker() { echo -e "${YELLOW}正在检查Docker安装状态...${NC}" if ! command -v docker &> /dev/null; then echo -e "${YELLOW}Docker未安装,正在安装...${NC}" curl -fsSL https://get.docker.com -o get-docker.sh sh get-docker.sh systemctl start docker systemctl enable docker rm get-docker.sh echo -e "${GREEN}Docker安装完成${NC}" else echo -e "${GREEN}Docker已安装${NC}" fi # 检查Docker Compose if ! check_docker_compose; then echo -e "${YELLOW}Docker Compose未安装,正在安装...${NC}" # 尝试安装Docker Compose插件 if command -v apt-get &> /dev/null; then apt-get update apt-get install -y docker-compose-plugin elif command -v yum &> /dev/null; then yum install -y docker-compose-plugin elif command -v dnf &> /dev/null; then dnf install -y docker-compose-plugin fi # 如果插件安装失败,则安装独立版本 if ! check_docker_compose; then echo -e "${YELLOW}正在安装独立版本的Docker Compose...${NC}" curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose fi echo -e "${GREEN}Docker Compose安装完成${NC}" else echo -e "${GREEN}Docker Compose已安装${NC}" fi } # 创建.env文件 create_env_file() { echo -e "${YELLOW}正在创建配置文件...${NC}" echo -n "请输入管理密码: " read ADMIN_PASSWORD echo "" cat > "$INSTALL_DIR/.env" << EOF ADMIN_PASSWORD=$ADMIN_PASSWORD EOF echo -e "使用默认端口3000? (y/n) [默认: y]: " read -r use_default_port use_default_port=${use_default_port:-y} if [ "$use_default_port" = "n" ] || [ "$use_default_port" = "N" ]; then echo -n "请输入自定义端口: " read -r custom_port echo "PORT=$custom_port" >> "$INSTALL_DIR/.env" PORT=$custom_port else PORT=3000 fi } # 创建docker-compose.yml文件 create_docker_compose() { echo -e "${YELLOW}正在创建Docker Compose文件...${NC}" echo -e "允许外部访问? (y/n) [默认: y]: " read -r allow_external allow_external=${allow_external:-y} if [ "$allow_external" = "n" ] || [ "$allow_external" = "N" ]; then PORTS_MAPPING="127.0.0.1:$PORT:$PORT" else PORTS_MAPPING="$PORT:$PORT" fi cat > "$INSTALL_DIR/docker-compose.yml" << EOF version: '3.8' services: app: image: dreamhartley705/jimihub:latest container_name: jimihub ports: - "$PORTS_MAPPING" env_file: - .env volumes: - ./data:/app/data restart: unless-stopped EOF } # 安装JimiHub install_gemini_proxy_panel() { echo -e "${YELLOW}开始安装JimiHub...${NC}" # 安装依赖 install_dependencies # 安装Docker install_docker # 检查Docker Compose命令 if ! check_docker_compose; then echo -e "${RED}错误:Docker Compose未正确安装${NC}" return 1 fi # 创建安装目录 mkdir -p "$INSTALL_DIR" cd "$INSTALL_DIR" # 创建.env文件 create_env_file # 创建docker-compose.yml文件 create_docker_compose # 启动容器 echo -e "${YELLOW}正在启动容器...${NC}" $DOCKER_COMPOSE_CMD up -d # 等待容器启动 sleep 5 if docker ps | grep -q "jimihub"; then echo -e "${GREEN}✓ 安装完成!${NC}" echo "" # 显示访问地址 if [ "$allow_external" = "n" ] || [ "$allow_external" = "N" ]; then echo -e "${BLUE}本地访问地址: http://127.0.0.1:$PORT${NC}" else external_ip=$(get_external_ip) echo -e "${BLUE}访问地址: http://$external_ip:$PORT${NC}" fi else echo -e "${RED}✗ 安装失败,请检查错误信息${NC}" echo -e "${YELLOW}容器日志:${NC}" $DOCKER_COMPOSE_CMD logs fi } # 启动容器 start_container() { if [ "$INSTALLED" = true ]; then echo -e "${YELLOW}正在启动容器...${NC}" cd "$INSTALL_DIR" if check_docker_compose; then $DOCKER_COMPOSE_CMD up -d sleep 3 if docker ps | grep -q "jimihub"; then echo -e "${GREEN}✓ 容器启动成功${NC}" else echo -e "${RED}✗ 容器启动失败${NC}" fi else echo -e "${RED}Docker Compose未找到${NC}" fi else echo -e "${RED}请先安装JimiHub${NC}" fi } # 停止容器 stop_container() { if [ "$INSTALLED" = true ]; then echo -e "${YELLOW}正在停止容器...${NC}" cd "$INSTALL_DIR" if check_docker_compose; then $DOCKER_COMPOSE_CMD down echo -e "${GREEN}✓ 容器已停止${NC}" else echo -e "${RED}Docker Compose未找到${NC}" fi else echo -e "${RED}请先安装JimiHub${NC}" fi } # 重启容器 restart_container() { if [ "$INSTALLED" = true ]; then echo -e "${YELLOW}正在重启容器...${NC}" cd "$INSTALL_DIR" if check_docker_compose; then $DOCKER_COMPOSE_CMD restart sleep 3 if docker ps | grep -q "jimihub"; then echo -e "${GREEN}✓ 容器重启成功${NC}" else echo -e "${RED}✗ 容器重启失败${NC}" fi else echo -e "${RED}Docker Compose未找到${NC}" fi else echo -e "${RED}请先安装JimiHub${NC}" fi } # 更新JimiHub update_jimihub() { if [ "$INSTALLED" = false ]; then echo -e "${RED}JimiHub未安装,无法更新${NC}" return fi echo -e "${YELLOW}开始更新JimiHub...${NC}" cd "$INSTALL_DIR" if ! check_docker_compose; then echo -e "${RED}Docker Compose未找到${NC}" return fi echo "正在拉取最新的Docker镜像..." if ! docker pull dreamhartley705/jimihub:latest; then echo -e "${RED}✗ 拉取最新镜像失败,请检查网络或镜像名称。${NC}" return fi echo "正在停止并使用新镜像重新创建容器..." $DOCKER_COMPOSE_CMD up -d --force-recreate sleep 5 if docker ps | grep -q "jimihub"; then echo -e "${GREEN}✓ 更新完成!${NC}" else echo -e "${RED}✗ 更新失败,请检查错误信息${NC}" echo -e "${YELLOW}容器日志:${NC}" $DOCKER_COMPOSE_CMD logs fi } # 卸载JimiHub uninstall_jimihub() { if [ "$INSTALLED" = false ]; then echo -e "${RED}JimiHub未安装,无需卸载${NC}" return fi echo -e "${YELLOW}警告:这将停止并删除JimiHub容器。${NC}" echo -n "是否保留数据库文件? (y/n) [默认: y]: " read -r keep_data keep_data=${keep_data:-y} echo -e "${YELLOW}开始卸载JimiHub...${NC}" if [ -d "$INSTALL_DIR" ]; then cd "$INSTALL_DIR" if check_docker_compose; then echo "正在停止并删除JimiHub容器..." $DOCKER_COMPOSE_CMD down fi cd .. fi if [[ "$keep_data" == "n" || "$keep_data" == "N" ]]; then echo "正在删除安装目录(包括数据)..." rm -rf "$INSTALL_DIR" echo -e "${GREEN}✓ JimiHub及其数据已完全删除。${NC}" else echo -e "${GREEN}✓ JimiHub容器已停止。本地文件(包括数据)已保留在 $INSTALL_DIR ${NC}" fi echo -n "是否要卸载Docker? (y/n) [默认: n]: " read -r uninstall_docker uninstall_docker=${uninstall_docker:-n} if [[ "$uninstall_docker" == "y" || "$uninstall_docker" == "Y" ]]; then # 检查是否还有其他Docker容器 if [ -n "$(docker ps -aq)" ]; then echo -e "${YELLOW}警告:检测到系统上存在其他Docker容器。为避免影响其他应用,Docker未被卸载。${NC}" else echo "正在卸载Docker..." if command -v apt-get &> /dev/null; then apt-get purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras apt-get autoremove -y --purge rm -rf /var/lib/docker /etc/docker elif command -v yum &> /dev/null; then yum remove -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin rm -rf /var/lib/docker /var/lib/containerd elif command -v dnf &> /dev/null; then dnf remove -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin rm -rf /var/lib/docker /var/lib/containerd fi echo -e "${GREEN}✓ Docker卸载完成。${NC}" fi fi unregister_command echo -e "${GREEN}✓ JimiHub卸载完成!感谢使用!${NC}" exit 0 } # 注册系统命令 register_command() { if [ ! -f "$SCRIPT_PATH" ]; then cp "$0" "$SCRIPT_PATH" chmod +x "$SCRIPT_PATH" echo -e "${GREEN}✓ 已注册系统命令 'jimihub'${NC}" fi } # 注销系统命令 unregister_command() { if [ -f "$SCRIPT_PATH" ]; then rm -f "$SCRIPT_PATH" echo -e "${GREEN}✓ 已注销系统命令 'jimihub'${NC}" fi } # 显示菜单 show_menu() { echo "" echo -e "${YELLOW}请选择操作:${NC}" echo "1. 安装 JimiHub" echo "2. 启动 JimiHub 容器" echo "3. 停止 JimiHub 容器" echo "4. 重启 JimiHub 容器" echo "5. 更新 JimiHub" echo "6. 卸载 JimiHub" echo "0. 退出" echo "" echo -n "请输入选项 [0-6]: " } # 主函数 main() { check_root # 如果是卸载命令,直接执行 if [[ "$1" == "uninstall" ]]; then check_install_status uninstall_jimihub exit 0 fi register_command while true; do show_welcome check_install_status check_container_status show_menu read -r choice case $choice in 1) install_gemini_proxy_panel echo "" echo -n "按回车键继续..." read -r ;; 2) start_container echo "" echo -n "按回车键继续..." read -r ;; 3) stop_container echo "" echo -n "按回车键继续..." read -r ;; 4) restart_container echo "" echo -n "按回车键继续..." read -r ;; 5) update_jimihub echo "" echo -n "按回车键继续..." read -r ;; 6) uninstall_jimihub ;; 0) echo -e "${GREEN}感谢使用!${NC}" echo -e "${BLUE}提示:下次可以直接使用 'jimihub' 命令进入管理脚本${NC}" exit 0 ;; *) echo -e "${RED}无效选项,请重新选择${NC}" sleep 2 ;; esac done } # 运行主函数 main "$@" ================================================ FILE: package.json ================================================ { "name": "jimihub", "version": "1.0.0", "main": "src/index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node src/index.js" }, "keywords": [], "author": "dream_hartley", "license": "Apache-2.0", "description": "A Gemini to OpenAI format proxy supporting multi-apikey rotation. Supports multiple deployment methods.", "dependencies": { "@google-cloud/vertexai": "^0.5.0", "@google/genai": "^0.12.0", "@octokit/rest": "^20.0.0", "cookie-parser": "^1.4.7", "cors": "^2.8.5", "dotenv": "^16.4.7", "express": "^4.18.2", "mime-types": "^2.1.35", "node-cron": "^4.2.1", "node-fetch": "^2.7.0", "socks-proxy-agent": "^8.0.3", "sqlite3": "^5.1.7", "uuid": "^9.0.1" } } ================================================ FILE: public/admin/index.html ================================================ JimiHub

正在验证身份...

如果页面长时间无响应,请 返回登录页面