feat: 支持 Docker 部署和环境变量配置

- webui.py 支持从环境变量读取配置 (WEBUI_HOST, WEBUI_PORT 等)
- 添加 Dockerfile 与 docker-compose.yml 方便本地与容器化部署
- 添加 GitHub Actions 配置,支持推送到 GitHub Container Registry (GHCR)
This commit is contained in:
yunxilyf
2026-03-20 10:26:03 +08:00
parent f4f17ebb5d
commit b6163293c1
4 changed files with 133 additions and 54 deletions

68
.github/workflows/docker-publish.yml vendored Normal file
View File

@@ -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

View File

@@ -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 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 . 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 . . COPY . .
# Create data directory # 暴露端口
RUN mkdir -p data logs EXPOSE 1455
# Expose port # 启动 WebUI
EXPOSE 8000
# Environment variables
ENV PYTHONUNBUFFERED=1
# Run the application
CMD ["python", "webui.py"] CMD ["python", "webui.py"]

View File

@@ -1,26 +1,19 @@
version: '3.8' version: '3.8'
services: services:
codex-register: webui:
build: . build: .
container_name: codex-register
ports: 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: volumes:
# 挂载数据目录以持久化数据库和日志
- ./data:/app/data - ./data:/app/data
- ./logs:/app/logs - ./logs:/app/logs
environment: restart: unless-stopped
- 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

View File

@@ -112,30 +112,42 @@ def start_webui():
def main(): def main():
"""主函数""" """主函数"""
import argparse import argparse
import os
parser = argparse.ArgumentParser(description="OpenAI/Codex CLI 自动注册系统 Web UI") parser = argparse.ArgumentParser(description="OpenAI/Codex CLI 自动注册系统 Web UI")
parser.add_argument("--host", help="监听主机") parser.add_argument("--host", help="监听主机 (也可通过 WEBUI_HOST 环境变量设置)")
parser.add_argument("--port", type=int, help="监听端口") parser.add_argument("--port", type=int, help="监听端口 (也可通过 WEBUI_PORT 环境变量设置)")
parser.add_argument("--debug", action="store_true", help="启用调试模式") parser.add_argument("--debug", action="store_true", help="启用调试模式 (也可通过 DEBUG=1 环境变量设置)")
parser.add_argument("--reload", action="store_true", help="启用热重载") parser.add_argument("--reload", action="store_true", help="启用热重载")
parser.add_argument("--log-level", help="日志级别") parser.add_argument("--log-level", help="日志级别 (也可通过 LOG_LEVEL 环境变量设置)")
parser.add_argument("--access-password", help="Web UI 访问密钥") parser.add_argument("--access-password", help="Web UI 访问密钥 (也可通过 WEBUI_ACCESS_PASSWORD 环境变量设置)")
args = parser.parse_args() args = parser.parse_args()
# 更新配置 # 更新配置
from src.config.settings import update_settings from src.config.settings import update_settings
updates = {} updates = {}
if args.host:
updates["webui_host"] = args.host # 优先使用命令行参数,如果没有则尝试从环境变量获取
if args.port: host = args.host or os.environ.get("WEBUI_HOST")
updates["webui_port"] = args.port if host:
if args.debug: updates["webui_host"] = host
updates["debug"] = args.debug
if args.log_level: port = args.port or os.environ.get("WEBUI_PORT")
updates["log_level"] = args.log_level if port:
if args.access_password: updates["webui_port"] = int(port)
updates["webui_access_password"] = args.access_password
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: if updates:
update_settings(**updates) update_settings(**updates)