Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@

> **约定**:已修问题从 [`docs/known-issues.md`](docs/known-issues.md)「毕业」到这里(发布即定稿);未修/进行中留在 known-issues;硬 bug 的根因证据链存在 [`findings/`](findings/)。

## Unreleased — WSL2 容器化部署

### 新增 Added

- **WSL2 容器化代理部署**(实验性):将 CSSwitch 翻译代理以 Docker 容器方式部署在 WSL2 中,供 Windows 上的 OpenAI/Anthropic 兼容客户端使用。
- `proxy/csswitch_proxy.py` 新增 `--host` / `CSSWITCH_BIND_HOST` 参数,支持绑定 `0.0.0.0` 监听任意地址(默认 `127.0.0.1`)。
- `docker/Dockerfile`:基于 `python:3.11-slim`,非 root 运行,零 pip 依赖。
- `docker/docker-compose.yml`:proxy 服务编排(env_file、端口映射、健康检查、自动重启、日志卷),可选 Caddy TLS 反代(`--profile tls`)。
- `scripts/docker-build.sh` / `scripts/wsl2-deploy.sh` / `scripts/wsl2-stop.sh` / `scripts/wsl2-logs.sh`:WSL2/Linux 容器管理脚本。
- `scripts/wsl2-deploy.ps1` / `scripts/wsl2-stop.ps1` / `scripts/wsl2-logs.ps1`:Windows PowerShell 包装,自动探测 WSL2 IP 并输出连接地址。
- `docs/wsl2-container-deployment.md`:完整部署指南(前置条件、网络说明、安全提示、故障排查)。
- `scripts/doctor.sh` 新增 Docker / docker compose / WSL2 环境检测。
- `test/test_container.sh`:可选容器冒烟测试(`RUN_CONTAINER_TESTS=1`)。
- README 增加 WSL2/Docker 徽章与入口链接。

## [0.2.0] — 2026-07-03

> 主题:一键**幂等化**——修 #3(运行中再点的分派)与 #6 的「复发」部分(更新后对话「不见」),并随三轮外部复审全面加固代理与进程路径。
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License">
<img src="https://img.shields.io/badge/platform-macOS%20(Apple%20Silicon)-1d1d1f.svg" alt="macOS">
<img src="https://img.shields.io/badge/built%20with-Tauri%202-C25A34.svg" alt="Tauri 2">
<img src="https://img.shields.io/badge/WSL2%20%7C%20Docker-2496ED.svg?logo=docker" alt="WSL2 / Docker">
</p>

# CSSwitch
Expand Down Expand Up @@ -56,6 +57,8 @@ DeepSeek 原生 Anthropic 端点 / 通义千问等 OpenAI 兼容端点

开发者的命令行用法(手动起代理与沙箱)、构建与测试,见 [`docs/DEVELOPMENT.md`](./docs/DEVELOPMENT.md) 与 [`desktop/README.md`](./desktop/README.md)。

**Windows / WSL2 用户**:可将 CSSwitch 翻译代理以 Docker 容器方式部署在 WSL2 中,供 Windows 上的 OpenAI/Anthropic 兼容客户端使用。见 [`docs/wsl2-container-deployment.md`](./docs/wsl2-container-deployment.md)(实验性)。

## 更新计划(Roadmap)

以下为规划方向,不代表时间承诺。欢迎以 issue / PR 参与共建。
Expand Down
35 changes: 35 additions & 0 deletions docker/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# 版本管理
.git
.gitignore
.gitattributes
.gitmodules
.gitleaks.toml

# GitHub
.github

# 运行时
.sandbox
.sandbox/

# 项目特有
findings/
findings/auto-maint/
desktop/
docs/assets/
node_modules/

# Python
__pycache__/
*.pyc
*.pyo
*.egg-info/

# 日志
*.log
logs/

# 本地 env(按 .env.example 模板手写,不提交)
.env
.env.local
.env.production
29 changes: 29 additions & 0 deletions docker/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# CSSwitch 代理容器环境变量配置
# 复制本文件为 .env,填入你的 key 后启动:
# cp .env.example .env
# docker compose -f docker/docker-compose.yml up -d

# ----- 必须设置一个(视 provider 而定)-----

# DeepSeek API Key(选择 deepseek provider 时必填)
# 获取:https://platform.deepseek.com/api_keys
DEEPSEEK_API_KEY=

# 阿里通义千问(DashScope)API Key(选择 qwen provider 时必填)
# 获取:https://bailian.console.aliyun.com/
DASHSCOPE_API_KEY=

# ----- 可选配置(按需修改)-----

# Provider:deepseek(默认)或 qwen
CSSWITCH_PROVIDER=deepseek

# 代理监听端口(需与 docker-compose.yml ports 映射一致)
CSSWITCH_PROXY_PORT=18991

# 路径 secret 鉴权(建议设置随机字符串,防未经授权的访问)
# 生成:openssl rand -hex 16
CSSWITCH_AUTH_TOKEN=

# 上游 URL 覆盖(仅高级用法,一般无需设置)
# CSSWITCH_UPSTREAM_URL=https://api.deepseek.com/anthropic/v1/messages
22 changes: 22 additions & 0 deletions docker/Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# CSSwitch Caddy TLS 反代配置
# 用于 docker-compose.yml 的 caddy 服务(需启用 tls profile)
# 提供本地 HTTPS 保护 path secret 不在 WSL2 内部明文传输。
#
# 使用自签名证书(tls internal),适合本地/内网环境。
# 生产环境请替换 tls internal 为你的真实证书。

:8443 {
# 自签名 TLS(本地/内网适用)
tls internal

# 反代到 csswitch-proxy 容器
reverse_proxy csswitch-proxy:{$CSSWITCH_PROXY_PORT:-18991} {
# 透传原始 Host 与 path(含 path secret)
header_up Host {host}
}

# 访问日志
log {
output file /data/access.log
}
}
22 changes: 22 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# CSSwitch 翻译代理容器镜像
# - 纯 Python 标准库,零 pip 依赖
# - 非 root 运行,最小攻击面
# - 默认监听 0.0.0.0:18991(`--host` 与 `--port` 可通过 CMD 覆盖)
FROM python:3.11-slim

# 创建非 root 用户
RUN addgroup --system --gid 1001 csswitch \
&& adduser --system --uid 1001 --ingroup csswitch --no-create-home csswitch

WORKDIR /app

# 只拷代理脚本及支持文件(纯 stdlib,无 requirements.txt)
COPY proxy/csswitch_proxy.py /app/csswitch_proxy.py

# 容器内默认绑定 0.0.0.0 监听所有接口
ENV PYTHONUNBUFFERED=1
EXPOSE 18991

USER csswitch

ENTRYPOINT ["python3", "/app/csswitch_proxy.py", "--host", "0.0.0.0"]
71 changes: 71 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# CSSwitch 容器化代理 — Docker Compose 编排
#
# 快速启动:
# cp docker/.env.example docker/.env
# # 编辑 docker/.env,填入你的 API key
# docker compose -f docker/docker-compose.yml up -d
#
# 可选 Caddy TLS 反代(保护 path secret 不在明文 HTTP 上传输):
# 取消下方 caddy 服务的注释,并:
# docker compose -f docker/docker-compose.yml --profile tls up -d
#
# 健康检查:
# curl http://localhost:18991/<secret>/health

name: csswitch

services:
csswitch-proxy:
image: csswitch-proxy:latest
build:
context: ..
dockerfile: docker/Dockerfile
container_name: csswitch-proxy
env_file:
- .env
ports:
- "${CSSWITCH_PROXY_PORT:-18991}:${CSSWITCH_PROXY_PORT:-18991}"
healthcheck:
test: ["CMD", "python3", "-c",
"import urllib.request, os, sys; \
t=os.environ.get('CSSWITCH_AUTH_TOKEN',''); \
p=os.environ.get('CSSWITCH_PROXY_PORT','18991'); \
u=f'http://127.0.0.1:{p}/{\"\" if not t else t}/health'; \
sys.exit(0 if 200==urllib.request.urlopen(u,timeout=3).getcode() else 1)"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s
volumes:
- csswitch-logs:/app/logs
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

# ── 可选:Caddy 本地 HTTPS/TLS 反代 ──────────────────────────
# 启用方式:docker compose -f docker/docker-compose.yml --profile tls up -d
#
# 注意:Caddy 使用自签名证书(tls internal),适合本地/内网环境。
# 浏览器首次访问需确认安全例外;curl 加 -k 或 --insecure。
#
# caddy:
# profiles: ["tls"]
# image: caddy:2-alpine
# container_name: csswitch-caddy
# restart: unless-stopped
# ports:
# - "8443:8443"
# volumes:
# - ./Caddyfile:/etc/caddy/Caddyfile:ro
# - caddy-data:/data
# - caddy-config:/config
# depends_on:
# - csswitch-proxy

volumes:
csswitch-logs:
caddy-data:
caddy-config:
Loading