CloakBrowser Manager: Manage Independent Browser Profiles

Deploy a persistent manager, create separate test profiles, connect their CDP endpoints, verify account identity, and manage stopping and backup.

16Yun Engineering TeamOct 28, 20263 min read

Two test accounts should not accidentally share cookies, writable browser directories, or network settings. A profile manager gives these settings an explicit identity that automation can target.

This tutorial deploys CloakBrowser Manager, signs into two test profiles manually, and reads an account marker through Playwright. It focuses on identity ownership rather than detector claims.

Distinguish management and engine configuration

The manager source and required browser binary have different licenses. The engine requires a license key, and account capacity determines whether profiles can run simultaneously. Use them sequentially if necessary. See the official project.

Deploy with Docker:

docker volume create cloakprofiles
export MANAGER_TOKEN='replace-with-your-manager-token'
docker run --name profile-manager   -p 127.0.0.1:8080:8080   -v cloakprofiles:/data   -e AUTH_TOKEN="$MANAGER_TOKEN"   cloakhq/cloakbrowser-manager

Open the local UI, authenticate with the management token, and enter your own engine license in Settings. Select the intended release channel and wait for engine preparation.

The management token authorizes UI/API access. The license key authorizes engine use. They are not interchangeable.

Create two explicit identities

Create account-a-test and account-b-test. Record profile name, ID, purpose, network policy, and data location.

Begin with direct connectivity or a deliberate fixed proxy. Do not put credentials into profile names or rotate an account's required exit unpredictably.

Start each profile and manually sign into the corresponding account in your own test system. Check its displayed account marker. Two profiles must not share the same writable directory.

Read identity through each CDP endpoint

Use the CDP address associated with each running profile. Changing a display name while reusing the same endpoint does not create a different identity.

Prepare the Node.js 24 client:

mkdir profile-check
cd profile-check
npm init -y
npm install playwright

Configure it:

export MANAGER_URL='http://localhost:8080'
export PROFILE_IDS='replace-with-profile-a-id,replace-with-profile-b-id'
export DASHBOARD_URL='https://example.16yun.cn/account'
export ACCOUNT_SELECTOR='[data-testid="account-name"]'

Replace the dashboard and selector with your actual test system. For example, a read-only account marker might be a span with the given test attribute. The tool cannot infer an arbitrary dashboard's identity contract.

Create check_profiles.mts:

import { writeFile } from 'node:fs/promises';
import { chromium } from 'playwright';
 
const base = process.env.MANAGER_URL;
const token = process.env.MANAGER_TOKEN;
const dashboard = process.env.DASHBOARD_URL;
const selector = process.env.ACCOUNT_SELECTOR;
const ids = process.env.PROFILE_IDS?.split(',').filter(Boolean);
if (!base || !token || !dashboard || !selector || !ids?.length) {
    throw new Error('缺少 Manager、Profile 或后台配置');
}
const results: unknown[] = [];
for (const id of ids) {
    const endpoint = new URL(
        '/api/profiles/' + encodeURIComponent(id) + '/cdp', base,
    ).href;
    const browser = await chromium.connectOverCDP(endpoint, {
        headers: { Authorization: 'Bearer ' + token },
    });
    try {
        const context = browser.contexts()[0];
        if (!context) throw new Error('Profile 没有可用上下文');
        const page = await context.newPage();
        await page.goto(dashboard, { waitUntil: 'domcontentloaded' });
        const account = (await page.locator(selector).innerText()).trim();
        if (!account) throw new Error('未取得账号标识');
        results.push({ profile_id: id, account, source_url: page.url() });
        await page.close();
    } finally {
        await browser.close();
    }
}
await writeFile('profile-results.json', JSON.stringify(results, null, 2));
console.log({ profiles_checked: results.length });

Run node check_profiles.mts and compare each profile's account with the manual expectation.

The code creates a page in the existing context. A new independent context may not inherit the profile's established cookies.

Stop and back up through the owning manager

After client disconnection, inspect the manager's running list and stop profiles that are no longer needed. Finishing the Playwright code does not independently establish that the profile stopped.

Restart the same profile and verify login again. Persistent storage does not prevent the target from expiring a session.

Stop profiles and the manager before using your platform's volume-backup process. Preserve the data volume plus necessary configuration and versions. Test restoration in a separate volume before touching active data.

Do not treat directories from different engines or release channels as freely interchangeable. Preserve rollback data and check UI, browser startup, and account identity after upgrades.

Troubleshoot

UI works but the browser does not: inspect engine availability, licensing, and capacity.

Both results show one account: compare profile IDs, CDP endpoints, and writable directories, then verify each profile manually.

CDP authentication fails: use the management token in the authorization header, not an engine license key.

A new context loses login: connect to the existing context that owns the session instead of copying another account's cookies.

Profiles disappear after a container update: confirm the original data volume is still mounted.

Resources remain after the script: inspect the manager and stop only profiles owned by the task.

Clear ownership of account, directory, network, and running state is the foundation of understandable multi-profile automation.

Need an enterprise proxy plan?

We can tailor architecture to your target domains, concurrency, and reliability goals.