将 DICloak 指纹浏览器完整打包进 Docker 镜像。无需在宿主机安装任何软件,一条命令即可启动具备完整指纹伪装能力的浏览器环境,通过标准 CDP 协议与 Playwright、Puppeteer 无缝集成。
镜像: `dicloakinc/dicloak-runtime-image`
协议: Chrome DevTools Protocol (CDP)
并发上限: 100 个浏览器实例
认证方式: 邮箱 + 密码
浏览器模式: 非 Headless(带完整浏览器界面)
docker run -d \
--name dicloak-runtime \
-e USER_EMAIL=your@email.com \
-e USER_PASSWD=your_password \
-e PORT=52140 \
-e DOCKER=1 \
-p 52140:52140 \
-p 127.0.0.1:45000-45099:45000-45099 \
--shm-size=1g \
dicloakinc/dicloak-runtime-image:latest
概述
DICloak Runtime Image 是一个预配置好的 Docker 镜像,内置了 DICloak 指纹浏览器的完整运行时。它解决的核心问题是:普通 Headless Chromium 的浏览器指纹高度一致,极易被网站识别为自动化程序。
启动后,镜像会在容器内运行一个 Local API 服务(默认端口 52140)。你的代码通过这个 API 管理浏览器环境(Environment),每个环境拥有独立的指纹参数。环境启动后,会动态分配一个 CDP 调试端口,供 Playwright 或 Puppeteer 连接。
镜像启动的浏览器为非 Headless 模式,带有完整的浏览器界面,行为与用户手动操作的真实浏览器一致,具备更强的反检测能力。
适合的场景
- AI Agent 需要持久化、带登录状态的浏览器会话
- 自动化脚本需要绕过机器人检测
- 多账号业务需要隔离浏览器环境
- CI/CD 需要稳定、可复现的浏览器测试环境
工作流程
1. 拉取并启动容器 — 通过环境变量传入账号信息和端口配置,Local API 服务在容器内自动启动。
2. 调用 Local API 打开浏览器环境 — 向 `http://127.0.0.1:52140/openapi/v1/env/{env_id}/open` 发送请求,获取该环境的 CDP 调试端口号(`debug_port`)。
3. 获取 WebSocket 调试地址 — 请求 `http://127.0.0.1:{debug_port}/json/version`,获取 `webSocketDebuggerUrl`。
4. 连接并执行自动化逻辑 — 用 `connectOverCDP(wsUrl)` 连接到浏览器,指纹由 DICloak 自动处理,其余操作与普通 Playwright/Puppeteer 完全相同。
5. 关闭或复用环境 — 通过 API 关闭浏览器实例,释放端口资源。如果挂载了 Volume,会话数据会被保留,下次启动时自动恢复。
前置条件
系统要求
| 资源 | 最低要求 | 说明 |
| CPU | 2 核 | 每个并发浏览器实例额外占用约 0.2–0.5 核 |
| 内存 | 4 GB | 每个活跃浏览器实例约占 200–400 MB |
| 磁盘 | 10 GB | 镜像本身约 3–5 GB,Profile 数据按需增长 |
| 共享内存 | 1 GB | Chrome 大量使用 /dev/shm,不足会导致渲染崩溃,通过 --shm-size=1g 设置 |
| Docker | 20.10+ | 建议使用最新稳定版 |
DICloak 账号与套餐
使用本镜像前,需要完成以下步骤:
- 前往 dicloak.com 注册账号
2. 购买 Plus(高阶版)或更高套餐,Docker 运行时功能仅对 Plus 及以上用户开放
3. 在 DICloak 控制台的 设置 → Open API 页面获取 API Key
关于账号类型的重要说明
> 强烈建议不要使用注册时的超级管理员账号运行 Docker。
> DICloak 的超级管理员账号为单点登录设计——同一账号同一时间只能在一处保持登录状态。如果用超管账号启动 Docker 容器,会导致你在其他设备或浏览器上的登录会话被踢出。
> 正确做法: 在 DICloak 控制台中为 Docker 专门创建一个内部成员账号,用该成员账号的邮箱和密码作为容器的认证信息。成员账号不受单点登录限制,不会干扰超管的正常使用。
快速开始
第一步:拉取镜像
docker pull dicloakinc/dicloak-runtime-image:latest
第二步:启动容器
将 `your@email.com` 和 `your_password` 替换为 DICloak 内部成员账号的邮箱和密码:
docker run -d \
--name dicloak-runtime \
-e USER_EMAIL=your@email.com \
-e USER_PASSWD=your_password \
-e PORT=52140 \
-e DOCKER=1 \
-p 52140:52140 \
-p 127.0.0.1:45000-45099:45000-45099 \
--shm-size=1g \
dicloakinc/dicloak-runtime-image:latest
第三步:验证服务已就绪
curl "http://127.0.0.1:52140/openapi/v1/env/list?page_no=1&page_size=1" \
-H "X-API-KEY: YOUR_API_KEY"
收到 {"code": 0, ...} 的响应即表示 Local API 服务正常运行。
> 注意: 如果容器启动后立即退出,运行 `docker logs dicloak-runtime` 查看日志,最常见原因是邮箱密码填写错误,或账号未购买 Plus 套餐。
环境变量
通过 -e KEY=VALUE(docker run)或 environment:(Compose)传入。
| 变量名 | 必须 | 默认值 | 说明 |
USER_EMAIL | 必须 | — | DICloak 内部成员账号的邮箱 |
USER_PASSWD | 必须 | — | DICloak 内部成员账号的密码 |
PORT | 必须 | 52140 | Local API 监听端口。修改此值时,-p 端口映射也需同步更改 |
DOCKER | 必须 | — | 固定设为 1,告知程序当前运行在 Docker 环境中,不可省略 |
端口映射详解
容器使用两组端口,在启动时必须通过 -p 参数映射到宿主机,否则宿主机无法访问容器内的服务。
端口总览
| 端口 | 方向 | 用途 |
| `52140` | 宿主机 → 容器 | Local API端口 — 管理浏览器环境的生命周期(列表、打开、关闭等) |
| `45000–45099` | 宿主机 → 容器 | 浏览器 CDP端口 — 每个活跃环境分配一个端口,通过此端口控制浏览器 |
### `-p` 参数格式说明
-p [宿主机绑定地址:]宿主机端口:容器端口
– **`宿主机绑定地址`**(可选):省略时默认绑定 `0.0.0.0`(所有网卡)。指定 `127.0.0.1` 表示只有本机可以访问。
– **`宿主机端口`**:外部(宿主机或其他服务)访问时使用的端口。
– **`容器端口`**:容器内部监听的端口,通常与容器内配置一致,不需要修改。
推荐配置
# Local API:对本机开放(自动化脚本与容器在同一台机器时)
-p 127.0.0.1:52140:52140
# 浏览器 CDP 端口:对本机开放(同上)
-p 127.0.0.1:45000-45099:45000-45099
跨机器访问
如果自动化脚本运行在另一台机器上,需要将绑定地址改为 `0.0.0.0`,使端口对外网卡可见:
-p 0.0.0.0:52140:52140
-p 0.0.0.0:45000-45099:45000-45099
# 等价简写(省略地址即为 0.0.0.0)
-p 52140:52140
-p 45000-45099:45000-45099
> 安全提示: 将端口暴露到公网会带来安全风险,任何能访问该 IP 的人都可以控制容器内的浏览器。建议只在受信任的内网环境中使用,或通过 VPN / SSH 隧道转发端口。
端口冲突处理
如果 52140 端口已被占用,修改 PORT 环境变量和对应的宿主机端口:
docker run -d \
-e PORT=52200 \
-p 127.0.0.1:52200:52200 \
... # 其余参数不变
查找占用端口的进程:
lsof -i :52140 # macOS / Linux
netstat -ano | findstr :52140 # Windows
数据持久化
默认情况下,容器内的所有数据(浏览器 Profile、Cookie、LocalStorage、指纹配置等)在容器删除后会丢失。通过挂载 Volume,可以将这些数据保存到宿主机,实现容器重启后自动恢复会话。
| 容器内路径 | 内容 |
/root/.config/DICloakCache | 浏览器配置文件、Cookie、会话数据、指纹参数 |
挂载示例
docker run -d \
--name dicloak-runtime \
-e USER_EMAIL=your@email.com \
-e USER_PASSWD=your_password \
-e PORT=52140 \
-e DOCKER=1 \
-p 127.0.0.1:52140:52140 \
-p 127.0.0.1:45000-45099:45000-45099 \
-v ./data:/root/.config/DICloakCache \
--shm-size=1g \
dicloakinc/dicloak-runtime-image:latest
数据将保存在当前目录的 ./data/ 文件夹中。删除容器或更新镜像版本后,重新挂载同一目录,所有 Profile 和会话状态自动恢复。
> 提示: 生产环境建议使用绝对路径,例如 `-v /data/dicloak:/root/.config/DICloakCache`,避免因工作目录变化导致数据丢失。
Local API 使用
本镜像的浏览器控制依赖 DICloak Local API。容器启动后,API 服务监听在 `PORT` 对应的端口上。
完整接口文档:DICloak API 开发指南
认证方式
所有请求需在 Header 中携带 API Key:
X-API-KEY: YOUR_API_KEY
API Key 在 DICloak 控制台的 设置 → Open API 中获取。
Base URL
http://127.0.0.1:52140/openapi
响应格式
// 成功
{ "code": 0, "msg": "success", "data": { ... } }
// 失败
{ "code": 500, "msg": "错误描述" }
核心接口
获取环境列表
GET /v1/env/list?page_no=1&page_size=20
X-API-KEY: YOUR_API_KEY
返回所有已创建的浏览器环境及其 ID,env_id 在后续接口中使用。
打开浏览器环境
PATCH /v1/env/{env_id}/open
X-API-KEY: YOUR_API_KEY
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"debug_port": 45001
}
}
返回的 debug_port 是该浏览器实例的 CDP 调试端口,范围在 45000–45099 之间。
关闭浏览器环境
PATCH /v1/env/{env_id}/close
X-API-KEY: YOUR_API_KEY
获取 CDP WebSocket 地址
打开环境后,用 debug_port 请求以下地址,获取 Playwright/Puppeteer 所需的 WebSocket URL:
GET http://127.0.0.1:{debug_port}/json/version
响应示例:
{
"webSocketDebuggerUrl": "ws://127.0.0.1:45001/devtools/browser/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
连接浏览器
获取到 webSocketDebuggerUrl 后,直接用 Playwright 或 Puppeteer 连接。
Playwright(JavaScript)
const { chromium } = require('playwright');
// 1. 打开环境,获取 debug_port
const openRes = await fetch(
'http://127.0.0.1:52140/openapi/v1/env/YOUR_ENV_ID/open',
{
method: 'PATCH',
headers: { 'X-API-KEY': 'YOUR_API_KEY' },
},
);
const {
data: { debug_port },
} = await openRes.json();
// 2. 获取 WebSocket 调试地址
const versionRes = await fetch(`http://127.0.0.1:${debug_port}/json/version`);
const { webSocketDebuggerUrl } = await versionRes.json();
// 3. 通过 CDP 连接浏览器
const browser = await chromium.connectOverCDP(webSocketDebuggerUrl);
const page = await browser.newPage();
// 4. 正常使用,指纹由 DICloak 自动处理
await page.goto('https://example.com');
// 5. 完成后关闭环境
await fetch('http://127.0.0.1:52140/openapi/v1/env/YOUR_ENV_ID/close', {
method: 'PATCH',
headers: { 'X-API-KEY': 'YOUR_API_KEY' },
});
Playwright(Python)
import requests
from playwright.sync_api import sync_playwright
API_BASE = "http://127.0.0.1:52140/openapi"
API_KEY = "YOUR_API_KEY"
ENV_ID = "YOUR_ENV_ID"
HEADERS = {"X-API-KEY": API_KEY}
# 1. 打开环境,获取 debug_port
res = requests.patch(f"{API_BASE}/v1/env/{ENV_ID}/open", headers=HEADERS)
debug_port = res.json()["data"]["debug_port"]
# 2. 获取 WebSocket 调试地址
version = requests.get(f"http://127.0.0.1:{debug_port}/json/version").json()
ws_url = version["webSocketDebuggerUrl"]
# 3. 通过 CDP 连接浏览器
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(ws_url)
page = browser.new_page()
# 4. 正常使用
page.goto("https://example.com")
# 5. 完成后关闭环境
requests.patch(f"{API_BASE}/v1/env/{ENV_ID}/close", headers=HEADERS)
Puppeteer
const puppeteer = require('puppeteer');
// 1. 打开环境,获取 debug_port
const openRes = await fetch(
'http://127.0.0.1:52140/openapi/v1/env/YOUR_ENV_ID/open',
{
method: 'PATCH',
headers: { 'X-API-KEY': 'YOUR_API_KEY' },
},
);
const {
data: { debug_port },
} = await openRes.json();
// 2. 获取 WebSocket 调试地址
const versionRes = await fetch(`http://127.0.0.1:${debug_port}/json/version`);
const { webSocketDebuggerUrl } = await versionRes.json();
// 3. 通过 CDP 连接浏览器
const browser = await puppeteer.connect({
browserWSEndpoint: webSocketDebuggerUrl,
});
const page = await browser.newPage();
// 4. 正常使用
await page.goto('https://example.com');
// 5. 完成后关闭环境
await fetch('http://127.0.0.1:52140/openapi/v1/env/YOUR_ENV_ID/close', {
method: 'PATCH',
headers: { 'X-API-KEY': 'YOUR_API_KEY' },
});
生产部署(Docker Compose)
生产环境推荐使用 Docker Compose,可以统一管理配置、自动重启、数据持久化,并方便后续扩展服务。
docker-compose.yml
services:
dicloak-runtime:
image: dicloakinc/dicloak-runtime-image:latest
container_name: dicloak-runtime
restart: unless-stopped # 异常退出自动重启;手动 stop 不重启
environment:
USER_EMAIL: ${DICLOAK_EMAIL} # 从 .env 文件读取,避免密码明文写入 yml
USER_PASSWD: ${DICLOAK_PASSWD}
PORT: 52140
DOCKER: 1
ports:
- '127.0.0.1:52140:52140'
- '127.0.0.1:45000-45099:45000-45099'
volumes:
- ./data:/root/.config/DICloakCache
shm_size: '1gb'
.env 文件
将账号密码存入 .env,避免敏感信息出现在版本控制历史中:
# .env
DICLOAK_EMAIL=member@yourcompany.com
DICLOAK_PASSWD=your_member_password
确保 .env 已加入 .gitignore。
Compose 常用命令
# 后台启动
docker compose up -d
# 查看实时日志
docker compose logs -f
# 停止并移除容器(数据在 ./data 中保留)
docker compose down
# 更新镜像后重新部署
docker compose pull && docker compose up -d
容器管理
基本操作
# 查看实时日志
docker logs -f dicloak-runtime
# 停止容器
docker stop dicloak-runtime
# 启动已停止的容器
docker start dicloak-runtime
# 删除容器(如果挂载了 Volume,数据仍保留在 ./data 中)
docker rm -f dicloak-runtime
更新镜像
# 1. 拉取最新镜像
docker pull dicloakinc/dicloak-runtime-image:latest
# 2. 删除旧容器
docker rm -f dicloak-runtime
# 3. 用相同参数重新运行(数据已通过 Volume 持久化,不受影响)
docker run -d \
--name dicloak-runtime \
-e USER_EMAIL=your@email.com \
-e USER_PASSWD=your_password \
-e PORT=52140 \
-e DOCKER=1 \
-p 127.0.0.1:52140:52140 \
-p 127.0.0.1:45000-45099:45000-45099 \
-v ./data:/root/.config/DICloakCache \
--shm-size=1g \
dicloakinc/dicloak-runtime-image:latest
故障排查
容器启动后立即退出
症状: `docker ps` 中看不到容器,或 STATUS 显示 Exited。
排查:
docker logs dicloak-runtime
常见原因:
- 邮箱或密码错误,认证失败
- 账号未购买 Plus 套餐,没有使用权限
- 使用了超管账号,被单点登录机制踢出(换用内部成员账号)
- 缺少
-e DOCKER=1参数 - 网络问题导致无法连接 DICloak 服务器
API 请求返回 401 / 403
症状: 请求 Local API 返回认证错误。
检查清单:
- 确认 Header 名称为
X-API-KEY(大小写敏感)
– 确认 API Key 来自 DICloak 控制台的 设置 → Open API,不是账号密码
- 确认账号已购买 Plus 套餐
端口已被占用
症状: 启动时报 `port is already allocated` 或 `bind: address already in use`。
排查:
lsof -i :52140 # macOS / Linux
netstat -ano | findstr :52140 # Windows
解决: 停止占用端口的进程,或修改 `PORT` 环境变量和对应的 `-p` 映射。
浏览器实例崩溃或卡死
症状: 浏览器启动后无响应,或页面渲染出错,容器日志出现 `shared memory` 相关错误。
解决: Chrome 大量使用 `/dev/shm`(共享内存)进行渲染。确保启动命令包含 `–shm-size=1g`。并发实例数量多时适当增大该值(如 `–shm-size=2g`)。
# 查看当前共享内存使用情况
docker exec dicloak-runtime df -h /dev/shm
无法通过 CDP 连接到浏览器
症状: Playwright 或 Puppeteer 抛出连接超时或拒绝连接错误。
检查清单:
- 确认已调用
/v1/env/{env_id}/open并成功获取debug_port - 确认
debug_port对应的端口在-p映射中包含(45000–45099范围) - 确认先请求了
/json/version获取完整的webSocketDebuggerUrl,而非直接拼接地址 - 如果从另一台机器连接,确认绑定地址是
0.0.0.0而非127.0.0.1 - 查看容器日志确认无异常
性能问题 / 运行缓慢
并发实例数量超过硬件承载能力时会出现性能下降。建议:
- 每增加 10 个并发实例,增加约 2 GB 内存
- CPU 核心数与并发实例数比例建议不低于 1:5
- 将 Volume 挂载到 SSD,加快 Profile 读写速度
相关链接
| 资源 | 地址 |
| Docker Hub 镜像页 | https://hub.docker.com/r/dicloakinc/dicloak-runtime-image |
| DICloak Local API 开发指南 | https://help.dicloak.com/zh/dicloak-api%e5%bc%80%e5%8f%91%e6%8c%87%e5%8d%97/ |
| DICloak 官网 | https://dicloak.com |