# Headless Browsers

Headless browsers power web scraping, automated testing, Search Engine Optimization (SEO) rendering, and synthetic monitoring.
They're resource-intensive, security-sensitive, and often run in short bursts—making them ideal candidates for microVM-based, scale-to-zero infrastructure.


## Why headless browsers on Unikraft Cloud

### ⚡ Instant startups

Instances on Unikraft Cloud boot in milliseconds, so browsers spin up only when needed:

* Perfect for on-demand scraping and CI/CD testing.
* No idle costs when browsers aren't running.

### 🔒 Strong security

Untrusted content exposes browsers.
With Unikraft Cloud:

* Each browser runs in its own VM, isolated by design.
* Minimal OS footprint drastically reduces attack surface.

### 💸 Cost-efficient scale-to-zero

Scraping jobs or test suites often run in short, irregular bursts:

* Browsers scale-to-zero when idle, cutting infrastructure waste.
* Pay only for the seconds of actual execution.

### 🌍 Serverless-ready

Integrate with pipelines and workloads that demand ephemeral execution:

* Trigger browsers via APIs or serverless functions.
* Distribute workloads globally to run close to data sources.


## Getting started

Headless browsers on **Unikraft Cloud** run faster, safer, and cheaper.
Whether scraping, testing, or monitoring, you get instant scale-out and zero idle costs—without sacrificing isolation.

This guide shows you how to use [Puppeteer](https://pptr.dev/), a Node.js
library which provides a high-level API to control browsers, including the
option to run them headless (no UI).

To run it, follow these steps:

1. Install the CLI and a container runtime engine (for example, [Docker](https://docs.docker.com/engine/install/)).
   Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install).

1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node-express-puppeteer/` directory:

```bash
git clone https://github.com/unikraft-cloud/examples
cd examples/node-express-puppeteer/
```

Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you.
This guide uses `fra` (Frankfurt, 🇩🇪):

<CodeTabs syncKey="cli-tool">

```bash title="unikraft"
unikraft login
```

```bash title="kraft"
# Set Unikraft Cloud access token
export UKC_TOKEN=token
# Set metro to Frankfurt, DE
export UKC_METRO=fra
```

</CodeTabs>

The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI.

:::note

A Puppeteer instance on Unikraft Cloud requires 4GB to run.
Request an increase in the instance memory quota when you need more memory.

:::

When done, invoke the following command to deploy this app on Unikraft Cloud:

<CodeTabs syncKey="cli-tool">

```bash title="unikraft"
unikraft build . --output <my-org>/node-express-puppeteer:latest
unikraft run --metro=fra -p 443:3000/http+tls -m 4Gi --image=<my-org>/node-express-puppeteer:latest
```

```bash title="kraft"
kraft cloud deploy -p 443:3000 -M 4Gi .
```

</CodeTabs>

The output shows the instance address and other details:

```ansi
[90m[[0m[92m●[0m[90m][0m Deployed successfully!
 [90m│[0m
 [90m├[0m[90m──────────[0m [90mname[0m: node-express-puppeteer-7afg3
 [90m├[0m[90m──────────[0m [90muuid[0m: 7bb479d7-5b3e-444f-b07c-eae4da6f57cc
 [90m├[0m[90m─────────[0m [90mstate[0m: [92mstarting[0m
 [90m├[0m[90m────────[0m [90mdomain[0m: https://nameless-fog-0tvh1uov.fra.unikraft.app
 [90m├[0m[90m─────────[0m [90mimage[0m: node-express-puppeteer@sha256:78d0b180161c876f17d05116b93011ddcd44c76758d6fa0359f05938e67cea65
 [90m├[0m[90m────────[0m [90mmemory[0m: 4096 MiB
 [90m├[0m[90m───────[0m [90mservice[0m: little-snow-7qwu6vv5
 [90m├[0m[90m──[0m [90mprivate fqdn[0m: node-express-puppeteer-7afg3.internal
 [90m├[0m[90m────[0m [90mprivate ip[0m: 172.16.3.1
 [90m└[0m[90m──────────[0m [90margs[0m: /usr/bin/wrapper.sh /usr/bin/node /app/bin/www
```

In this case, the instance name is `node-express-puppeteer-7afg3`.
They're different for each run.

Use a browser to access the landing page of the Puppeteer (that uses [ExpressJS](https://expressjs.com/)).
The app and the landing page are part of [this repository](https://github.com/christopher-talke/node-express-puppeteer-pdf-example).

In the example run above, the landing page is at the address `https://nameless-fog-0tvh1uov.fra.unikraft.app`.
You can use the landing page to generate the PDF version of a remote page.

At any time, you can list information about the instance:

<CodeTabs syncKey="cli-tool">

```bash title="unikraft"
unikraft instances list node-express-puppeteer-7afg3
```

```bash title="kraft"
kraft cloud instance list node-express-puppeteer-7afg3
```

</CodeTabs>

```text
NAME                          FQDN                                           STATE    STATUS        IMAGE                              MEMORY   ARGS                               BOOT TIME
node-express-puppeteer-7afg3  node-express-puppeteer-7afg3.fra.unikraft.app  running  since 6mins   node-express-puppeteer-7afg3@s...  4.0 GiB  /usr/bin/wrapper.sh /usr/bin/n...  15.27 ms
```

When done, you can remove the instance:

<CodeTabs syncKey="cli-tool">

```bash title="unikraft"
unikraft instances delete node-express-puppeteer-7afg3
```

```bash title="kraft"
kraft cloud instance remove node-express-puppeteer-7afg3
```

</CodeTabs>

### Customize your deployment

The current deployment uses an ExpressJS service that uses the [PDF generating functionality of Puppeteer](https://devdocs.io/puppeteer/).
Customizing the deployment means updating the service, such as adding new functionalities provided by Puppeteer.
You can update the service itself to provide a Representational State Transfer (REST)-like interface.

## Learn more

Use the `--help` option for detailed information on using Unikraft Cloud:

<CodeTabs syncKey="cli-tool">

```bash title="unikraft"
unikraft --help
```

```bash title="kraft"
kraft cloud --help
```

</CodeTabs>

Or visit the [CLI Reference](/docs/cli/unikraft) or the [legacy CLI reference](/docs/cli/kraft/overview).
