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
22 changes: 22 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# 构建上下文瘦身 + 秘密不入镜像(roadmap 约定:.env / data/ 永不入镜像)
.git
.github
.venv
.env
data
tests
docs
scripts
__pycache__
**/__pycache__
.pytest_cache
.ruff_cache
.mypy_cache
captcha_node/node_modules
*.md
Dockerfile
docker-compose.yml
.dockerignore
start.bat
start.sh
uv.lock
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
* text=auto eol=lf

*.bat text eol=crlf
*.cmd text eol=crlf
8 changes: 6 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ name: ci

on:
push:
branches: [main]
branches: [main, develop, "feat/**"]
pull_request:

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
Expand Down
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,12 @@ node_modules/
# 秘钥 / 凭证导出
*accounts*.json
zcode-accounts*.json

# 本地运行 / 工具杂物
serve.log
serve.err.log
serve.pid
.trae_*
.sg_*
.sg-js/
.sg_login.html
70 changes: 70 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# zcode-hub 容器镜像:Python 3.11 网关 + Node 22 验证码求解子进程 + Debian Chromium
#
# 运行时结构:
# /app 代码(app/ cli.py frontend/ captcha_node/)
# /app/data 持久化(accounts.db + device_mid),挂载卷
# /usr/bin/node 从 node:22 官方镜像复制(bookworm 与运行时基础镜像同系,glibc 兼容)
# /usr/bin/chromium Debian chromium,solver_pw.js findChromium() 默认探测路径之一
#
# captcha 求解依赖真浏览器(solver 已带 --no-sandbox/--disable-dev-shm-usage),
# 且 oom 看门狗需要写 /proc/*/oom_score_adj —— 容器以 root 运行是前提,勿改 USER。

# ── 阶段 1:求解器 Node 依赖(纯 JS,无原生编译) ─────────────────────────────
FROM node:22-bookworm-slim AS captcha-deps
WORKDIR /build
COPY captcha_node/package.json captcha_node/package-lock.json ./
RUN npm ci --omit=dev

# ── 阶段 2:运行时 ────────────────────────────────────────────────────────────
FROM python:3.11-slim-bookworm

ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=1 \
ZCODE_HOST=0.0.0.0 \
ZCODE_PORT=3000 \
ZCODE_DATA_DIR=/app/data \
ZCODE_NODE_PATH=/usr/local/bin/node \
ZCODE_CHROMIUM_PATH=/usr/bin/chromium

# tini 作 PID 1:回收 uvicorn→node→chrome 进程树遗留的僵尸
# fonts-noto-cjk:验证码挑战页含中文文案,缺字形可能影响求解
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
chromium \
fonts-noto-cjk \
fonts-liberation \
ca-certificates \
tini \
&& rm -rf /var/lib/apt/lists/*

# Node 运行时(构建期不需要 npm,只带 node 本体)
COPY --from=captcha-deps /usr/local/bin/node /usr/local/bin/node

WORKDIR /app

# 运行时依赖(与 requirements.txt 上半段保持一致;dev/test 工具不进镜像)
RUN pip install --no-cache-dir \
"fastapi>=0.115.0" \
"uvicorn[standard]>=0.30.0" \
"httpx>=0.27.0" \
"python-dotenv>=1.0.1" \
"cryptography>=42.0.0" \
"pyyaml>=6.0.0"

COPY app/ app/
COPY captcha_node/ captcha_node/
COPY --from=captcha-deps /build/node_modules/ captcha_node/node_modules/
COPY frontend/ frontend/
COPY cli.py ./

# data/ 不打进镜像(.dockerignore 双保险),挂卷持久化
RUN mkdir -p /app/data

EXPOSE 3000

ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["python", "cli.py", "serve"]

HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
CMD ["python", "-c", "import urllib.request;urllib.request.urlopen('http://127.0.0.1:3000/meta', timeout=4)"]
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,21 @@ cp .env.example .env # 按需修改密钥、端口等

> 使用 Z.AI **JWT 模式**需要 Node.js 求解验证码,首次先执行:`cd captcha_node && npm install`。

### Docker 部署(推荐)

镜像自带 Python 3.11 + Node 22 + Chromium,无需宿主机装任何运行时:

```bash
cp .env.example .env # 按需修改 ZCODE_ADMIN_KEY、端口等
docker compose up -d --build
```

- 访问 `http://127.0.0.1:3000/admin/login`;宿主机端口取 `.env` 的 `ZCODE_PORT`
- 账号库与设备指纹持久化在宿主机 `./data/`(首次启动自动生成,已有数据直接沿用)
- `.env` 里的 `ZCODE_CHROMIUM_PATH` 等宿主机路径会被 compose 覆盖为容器内路径,无需改动
- 容器内 CLI:`docker compose exec zcode-hub python cli.py accounts`(其余子命令同理)
- 停止:`docker compose down`(数据保留在 `./data/`)

## 快速上手一个账号

```bash
Expand Down
Loading