# How to Run CloakBrowser in Docker with Persistent Profile Volumes

> Run CloakBrowser in Docker with persistent profile volumes. Bind-mount host directories and set CLOAKBROWSER_CACHE_DIR to save cookies and fingerprints across restarts.

- Repository: [CloakHQ/CloakBrowser](https://github.com/CloakHQ/CloakBrowser)
- Tags: how-to-guide
- Published: 2026-05-09

---

**Bind-mount a host directory to `/root/.cloakbrowser` and set the `CLOAKBROWSER_CACHE_DIR` environment variable to preserve cookies, fingerprints, and the Chromium binary across CloakBrowser container restarts.**

CloakBrowser is a stealth browser automation framework from CloakHQ/CloakBrowser that manages sophisticated fingerprints and session state. When running in Docker, all runtime data—including the stealth Chromium binary, cookies, local storage, and generated fingerprints—is stored in a cache directory that defaults to `~/.cloakbrowser`. Without persistent volumes, this profile data disappears when containers stop. This guide explains how to configure Docker volumes to maintain stateful, repeatable browsing sessions.

## Understanding the CloakBrowser Cache Directory

According to [`cloakbrowser/config.py`](https://github.com/CloakHQ/CloakBrowser/blob/main/cloakbrowser/config.py), the library resolves the cache path using `Path.home() / ".cloakbrowser"` unless overridden by the `CLOAKBROWSER_CACHE_DIR` environment variable. Since the official Docker image runs as the `root` user, `Path.home()` resolves to `/root`, making the default container path `/root/.cloakbrowser`.

The `Dockerfile` pre-downloads the stealth Chromium binary during the build process and clears the welcome flag (`~/.cloakbrowser/.welcome_shown`) to suppress first-run UI elements. However, without a volume mount, this directory exists only in the container's ephemeral writable layer and is lost on shutdown.

## Basic Docker Run Command with Volume Mounting

To maintain persistent profiles, bind-mount a host directory over the container's cache path. This allows CloakBrowser to read and write cookies, local storage, and browser fingerprints to stable host storage.

```bash

# Create the host directory

mkdir -p "${HOME}/.cloakbrowser"

# Run with persistent volume

docker run -it --rm \
  -v "${HOME}/.cloakbrowser:/root/.cloakbrowser" \
  -e CLOAKBROWSER_CACHE_DIR=/root/.cloakbrowser \
  -p 9222:9222 \
  cloakhq/cloakbrowser:<tag> \
  python -m cloakbrowser --launch firefox https://example.com

```

*Explanation of flags:*

- **`-v "${HOME}/.cloakbrowser:/root/.cloakbrowser"`** – Binds the host's profile directory to the container's expected cache location.
- **`-e CLOAKBROWSER_CACHE_DIR=/root/.cloakbrowser`** – Explicitly sets the environment variable to ensure the library uses the mounted path (optional but recommended).
- **`-p 9222:9222`** – Exposes the Chrome DevTools Protocol port defined in the `Dockerfile` for debugging and automation.
- **`python -m cloakbrowser`** – Executes the CLI module with standard flags like `--launch` or `--proxy`.

## Handling Headed Mode with Xvfb

The container supports headed browsing for visual debugging or CAPTCHA solving via the entrypoint script at [`bin/docker-entrypoint.sh`](https://github.com/CloakHQ/CloakBrowser/blob/main/bin/docker-entrypoint.sh). This script automatically starts an Xvfb server (virtual display) before executing your command, allowing you to run graphical browsers while maintaining persistent storage.

```bash
docker run -it --rm \
  -v "${HOME}/.cloakbrowser:/root/.cloakbrowser" \
  -e CLOAKBROWSER_CACHE_DIR=/root/.cloakbrowser \
  cloakhq/cloakbrowser:<tag> \
  python -m cloakbrowser --launch chrome --headed https://example.com

```

The `Dockerfile` sets `ENV DISPLAY=:99`, and [`bin/docker-entrypoint.sh`](https://github.com/CloakHQ/CloakBrowser/blob/main/bin/docker-entrypoint.sh) initializes the virtual display at that address. When you pass `--headed`, CloakBrowser launches the browser in this virtual framebuffer while continuing to read from and write to the persistent volume.

## Configuring Custom Cache Locations

If you prefer to store profiles outside the home directory, specify a custom path using both the volume mount and environment variable:

```bash
docker run -it --rm \
  -v /data/cloak-cache:/data/cloak-cache \
  -e CLOAKBROWSER_CACHE_DIR=/data/cloak-cache \
  cloakhq/cloakbrowser:<tag> \
  python -m cloakbrowser --launch firefox

```

On first run, CloakBrowser automatically creates the necessary subdirectories—including `geoip`, browser-specific folders, and extension storage—inside `/data/cloak-cache`. The [`cloakbrowser/config.py`](https://github.com/CloakHQ/CloakBrowser/blob/main/cloakbrowser/config.py) logic respects the `CLOAKBROWSER_CACHE_DIR` variable for all file operations, ensuring complete profile persistence regardless of the mount point.

## Summary

- **Cache resolution:** By default, CloakBrowser stores data at `~/.cloakbrowser` (host) and `/root/.cloakbrowser` (container) as implemented in [`cloakbrowser/config.py`](https://github.com/CloakHQ/CloakBrowser/blob/main/cloakbrowser/config.py).
- **Volume mounting:** Use `-v "${HOME}/.cloakbrowser:/root/.cloakbrowser"` to persist profiles across container restarts.
- **Environment override:** Set `CLOAKBROWSER_CACHE_DIR` to customize storage locations when using non-standard mount points.
- **Headed support:** The [`bin/docker-entrypoint.sh`](https://github.com/CloakHQ/CloakBrowser/blob/main/bin/docker-entrypoint.sh) script manages Xvfb initialization, allowing headed mode with persistent profiles.
- **State retention:** The mounted directory preserves cookies, local storage, extensions, fingerprints, and the pre-downloaded Chromium binary between runs.

## Frequently Asked Questions

### Where does CloakBrowser store cookies and fingerprints in Docker?

Inside the container, CloakBrowser stores all session data—including cookies, local storage, extensions, and generated fingerprints—in the directory returned by `Path.home() / ".cloakbrowser"` in [`cloakbrowser/config.py`](https://github.com/CloakHQ/CloakBrowser/blob/main/cloakbrowser/config.py), which resolves to `/root/.cloakbrowser` when running as root. You can override this location by setting the `CLOAKBROWSER_CACHE_DIR` environment variable to any writable path.

### Why do I lose my browser data when the Docker container stops?

Without a bind-mount, the cache directory exists only in the container's ephemeral writable layer. When the container stops, Docker discards this layer and all associated data. To prevent data loss, mount a host directory to `/root/.cloakbrowser` (or your custom `CLOAKBROWSER_CACHE_DIR` path) so state persists on the host filesystem across container lifecycles.

### Can I run CloakBrowser in headed mode with persistent profiles?

Yes. The [`bin/docker-entrypoint.sh`](https://github.com/CloakHQ/CloakBrowser/blob/main/bin/docker-entrypoint.sh) script automatically starts Xvfb (virtual framebuffer) to support headed mode without requiring host display access. Simply pass the `--headed` flag to your CloakBrowser command. The persistent volume mount functions identically in both headless and headed configurations, preserving your session state, cookies, and fingerprint settings.

### How do I migrate an existing profile to a new Docker container?

Copy your existing `~/.cloakbrowser` directory from the source host to the new host machine (or ensure it's accessible via network storage), then mount it to `/root/.cloakbrowser` when running the container. Since CloakBrowser stores the stealth binary, fingerprints, and session data in this single directory hierarchy, the container will resume using the existing profile immediately upon startup without requiring reconfiguration.