Ctrl K
ComunidadGuías…

SETUP.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Setting up Ghost Browser on your own VPS

By the end of this you will have a real Chromium running on a server, that you drive from a web
console or an HTTP API — and, if you want it, **leaving through your own home internet connection
instead of the datacentre's**, so the sites it visits see a normal residential address.

It takes about ten minutes.

---

## 1. What you need

- A Linux VPS (any provider, any size from ~1 GB RAM up — a browser is memory-hungry, give it room).
- **Docker** on it. That is the whole runtime: the image already contains Chromium, the Xvfb
  virtual display it needs, and Tailscale. You do not install those yourself.
- Optional, for the AI agent: an [Ollama](https://ollama.com) API key (cloud) or a self-hosted
  Ollama endpoint. You can skip this and use Ghost Browser purely as a scriptable browser.

---

## 2. Run it

Build the image from this repo and start it:

```bash
git clone https://github.com/Wvdstoep/ghost-browser.git
cd ghost-browser
docker build -t ghost-browser .

docker run -d --name ghost \
  -p 3000:3000 \
  -e API_KEYS="pick-a-long-secret:team" \
  -v ghost-profiles:/profiles \
  ghost-browser
```

Two things matter here:

- **`API_KEYS`** is required — the server refuses to start without it. A session costs real memory
  for its whole life, so there is no anonymous access. The format is `key:plan,key:plan`; `team` is
  the highest-concurrency plan.
- **The `/profiles` volume** is where everything durable lives — logins, cookies, saved flows,
  roles, the agent's model key. Mount it, or you lose all of that on every restart.

Open `http://YOUR_VPS_IP:3000`. The first visit creates the owner account. (Put it behind a reverse
proxy with TLS before you expose it to the internet — it holds live logins.)

---

## 3. Drive it

Three ways, all the same browser:

- **The console** — click into a session and use it by hand, or watch the agent work.
- **The HTTP API** — `POST /v1/sessions`, then `navigate`, `analyze`, `click`, `type`, `read`.
  Auth is `Authorization: Bearer <your key>`. See the [README](README.md) for the full surface.
- **The agent** — give it a goal and let it drive, through the same numbered Set-of-Mark view a
  person sees. Writes that a real person would notice (posting, following, messaging) go through an
  act-gate that shows you the exact text and waits for approval.

For the agent, open **Model** in the console and point it at Ollama (cloud key, or a self-hosted
`OLLAMA_URL`). The key is stored on the `/profiles` volume and never comes back out of the API.

---

## 4. The part that makes it different: leave through your home connection

A browser running in a datacentre has a datacentre IP, and a lot of sites treat that as a red flag —
sign-ups get extra scrutiny, some content is geo- or bot-gated. Ghost Browser can route a profile's
traffic **out through a device you own at home**, so the exit address is an ordinary residential one
in your own country.

It does this with [Tailscale](https://tailscale.com) (already in the image), using a home machine as
an *exit node*. Nothing about this is a fingerprint trick — it is just choosing where your own
traffic leaves the internet.

### 4a. Turn a home device into an exit node

On any machine at home that stays on — a spare laptop, a Raspberry Pi, your desktop:

```bash
# install tailscale (see tailscale.com/download), then:
sudo tailscale up --advertise-exit-node
```

Then in the [Tailscale admin console](https://login.tailscale.com/admin/machines), open that
machine's `...` menu and **approve it as an exit node** (Tailscale requires this once, on purpose).

### 4b. Connect Ghost Browser to your tailnet

1. Create an [auth key](https://login.tailscale.com/admin/settings/keys) in the Tailscale admin
   (a reusable one is convenient).
2. In the Ghost Browser console, open the **exit / network** panel and paste the auth key. The
   browser joins your tailnet as a device called `ghost-browser`.
3. Choose your **home device** as the exit node. From now on, sessions leave through your home
   connection by default. (A device only appears here if it is advertising itself as an exit node —
   step 4a.)

### 4c. Prove it worked

Point a session at an IP-echo service and check the address:

```bash
curl -s -H "Authorization: Bearer YOUR_KEY" -X POST http://YOUR_VPS_IP:3000/v1/sessions
# then navigate that session to https://ipinfo.io/json and read it —
# the "org" and "city" should be your home ISP, not your VPS provider.
```

Per-profile control: a profile can leave through the tailnet (the default once one is connected),
or be pinned to leave straight from the server (`direct`) when a residential exit is not wanted.

---

## 5. Keep it running (production)

- **Persist `/profiles`** on a real volume. It is the whole state of the thing.
- **One browser per container.** Sessions are heavy; scale out with more containers, not more
  sessions per container. Watch `GET /v1/capacity`.
- **Kubernetes:** a Helm chart is included under [`deploy/ghost-tool`](deploy/ghost-tool). It mints
  an API key on first install and re-uses it on upgrades, so the key is stable across rolls.

---

## 6. Environment reference

| Variable | Default | What it does |
|---|---|---|
| `API_KEYS` | *(required)* | `key:plan,key:plan` — who may open a browser, at what concurrency |
| `PROFILE_DIR` | `/profiles` | where logins, flows, roles and the model key are stored |
| `PORT` | `3000` | HTTP port |
| `MAX_CONTEXTS` | `8` | sessions per container before it stops accepting more |
| `IDLE_MS` | `300000` | close a session after this long idle |
| `SESSION_TTL_MS` | `7200000` | absolute session lifetime |
| `MEMORY_LIMIT_PCT` | `80` | drain and recycle the container at this cgroup-memory fraction |
| `OLLAMA_URL` | — | self-hosted Ollama endpoint for the agent |
| `OLLAMA_API_KEY` | — | Ollama Cloud key for the agent (or set it in the console) |
| `TAILSCALE_HOSTNAME` | `ghost-browser` | the name this browser joins your tailnet as |
| `HEADLESS` | `false` | keep it false — a headful Chromium on Xvfb is far less detectable |

---

## Troubleshooting

- **"refuses to start"** — you did not set `API_KEYS`. That is deliberate.
- **The exit node does not appear** — the home device is not advertising itself (step 4a) or has not
  been approved in the admin console (both are required, once).
- **A live view is black** — the session's page is a background tab or a nearly-blank bot wall; the
  screencast only paints on change. This is one of the rough edges where **UI help is very welcome** —
  see [CONTRIBUTING.md](CONTRIBUTING.md).