diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 0000000..874d40b --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,68 @@ +name: Docker Image CI + +on: + push: + branches: [ "master", "main" ] + # 当发布新版本时触发 + tags: [ 'v*.*.*' ] + pull_request: + branches: [ "master", "main" ] + +env: + # GitHub Container Registry 的地址 + REGISTRY: ghcr.io + # 镜像名称,默认为 GitHub 用户名/仓库名 + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + # 如果需要签名生成的镜像,可以使用 id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # 设置 Docker Buildx 用于构建多平台镜像 (可选) + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + # 登录到 Docker 镜像仓库 + # 如果只是在 PR 中测试构建,则跳过登录 + - name: Log in to the Container registry + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # 提取 Docker 镜像的元数据(标签、注释等) + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=schedule + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha + type=raw,value=latest,enable={{is_default_branch}} + + # 构建并推送 Docker 镜像 + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index f6b89d8..db63397 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,30 +1,36 @@ -FROM python:3.10-slim +# 使用官方 Python 基础镜像 (使用 slim 版本减小体积) +FROM python:3.11-slim -# Install system dependencies -RUN apt-get update && apt-get install -y \ - curl \ - && rm -rf /var/lib/apt/lists/* - -# Set working directory +# 设置工作目录 WORKDIR /app -# Copy requirements first for better caching +# 设置环境变量 +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + # WebUI 默认配置 + WEBUI_HOST=0.0.0.0 \ + WEBUI_PORT=1455 \ + LOG_LEVEL=info \ + DEBUG=0 + +# 安装系统依赖 +# (curl_cffi 等库可能需要编译工具) +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + gcc \ + python3-dev \ + && rm -rf /var/lib/apt/lists/* + +# 复制依赖文件并安装 COPY requirements.txt . +RUN pip install --no-cache-dir --upgrade pip \ + && pip install --no-cache-dir -r requirements.txt -# Install Python dependencies -RUN pip install --no-cache-dir -r requirements.txt - -# Copy application code +# 复制项目代码 COPY . . -# Create data directory -RUN mkdir -p data logs +# 暴露端口 +EXPOSE 1455 -# Expose port -EXPOSE 8000 - -# Environment variables -ENV PYTHONUNBUFFERED=1 - -# Run the application +# 启动 WebUI CMD ["python", "webui.py"] diff --git a/docker-compose.yml b/docker-compose.yml index 80c8fd6..bd2b5e9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,26 +1,19 @@ version: '3.8' services: - codex-register: + webui: build: . - container_name: codex-register ports: - - "${APP_PORT:-8000}:8000" + - "1455:1455" + environment: + - WEBUI_HOST=0.0.0.0 + - WEBUI_PORT=1455 + - DEBUG=0 + - LOG_LEVEL=info + # 如果需要访问密码,可以在这里取消注释并设置 + # - WEBUI_ACCESS_PASSWORD=your_secure_password volumes: + # 挂载数据目录以持久化数据库和日志 - ./data:/app/data - ./logs:/app/logs - environment: - - PYTHONUNBUFFERED=1 - # Web UI 配置(也可在 .env 文件中设置) - - APP_HOST=0.0.0.0 - - APP_PORT=${APP_PORT:-8000} - - APP_ACCESS_PASSWORD=${APP_ACCESS_PASSWORD:-admin123} - # 数据库(默认 SQLite,如需 PostgreSQL 取消下方注释) - # - APP_DATABASE_URL=postgresql://user:password@db:5432/codex - # HTTP 代理(如需代理取消下方注释) - # - HTTP_PROXY=http://your-proxy:port - # - HTTPS_PROXY=http://your-proxy:port - env_file: - - path: .env - required: false - restart: unless-stopped + restart: unless-stopped \ No newline at end of file diff --git a/webui.py b/webui.py index 1ce7222..b548512 100644 --- a/webui.py +++ b/webui.py @@ -112,30 +112,42 @@ def start_webui(): def main(): """主函数""" import argparse + import os parser = argparse.ArgumentParser(description="OpenAI/Codex CLI 自动注册系统 Web UI") - parser.add_argument("--host", help="监听主机") - parser.add_argument("--port", type=int, help="监听端口") - parser.add_argument("--debug", action="store_true", help="启用调试模式") + parser.add_argument("--host", help="监听主机 (也可通过 WEBUI_HOST 环境变量设置)") + parser.add_argument("--port", type=int, help="监听端口 (也可通过 WEBUI_PORT 环境变量设置)") + parser.add_argument("--debug", action="store_true", help="启用调试模式 (也可通过 DEBUG=1 环境变量设置)") parser.add_argument("--reload", action="store_true", help="启用热重载") - parser.add_argument("--log-level", help="日志级别") - parser.add_argument("--access-password", help="Web UI 访问密钥") + parser.add_argument("--log-level", help="日志级别 (也可通过 LOG_LEVEL 环境变量设置)") + parser.add_argument("--access-password", help="Web UI 访问密钥 (也可通过 WEBUI_ACCESS_PASSWORD 环境变量设置)") args = parser.parse_args() # 更新配置 from src.config.settings import update_settings updates = {} - if args.host: - updates["webui_host"] = args.host - if args.port: - updates["webui_port"] = args.port - if args.debug: - updates["debug"] = args.debug - if args.log_level: - updates["log_level"] = args.log_level - if args.access_password: - updates["webui_access_password"] = args.access_password + + # 优先使用命令行参数,如果没有则尝试从环境变量获取 + host = args.host or os.environ.get("WEBUI_HOST") + if host: + updates["webui_host"] = host + + port = args.port or os.environ.get("WEBUI_PORT") + if port: + updates["webui_port"] = int(port) + + debug = args.debug or os.environ.get("DEBUG", "").lower() in ("1", "true", "yes") + if debug: + updates["debug"] = debug + + log_level = args.log_level or os.environ.get("LOG_LEVEL") + if log_level: + updates["log_level"] = log_level + + access_password = args.access_password or os.environ.get("WEBUI_ACCESS_PASSWORD") + if access_password: + updates["webui_access_password"] = access_password if updates: update_settings(**updates)