VeilBrowserDocs

Onboarding walkthrough

A step-by-step tour of the first-run setup wizard, from creating the admin to launching your first worker.

The first-run wizard configures a fresh control plane end to end. It creates the admin, names the cluster and its hostnames, sets up TLS, adds your first worker, and renders the live load-balancer config. This page walks through every step so you know what each field does and how to pick the right options.

Overview

The wizard appears automatically on any control plane with an empty database or an unconfigured cluster. It is the only thing the UI serves until an admin exists and the cluster has been rendered at least once.

You can reach and complete most of the wizard over plain http://<ip> before any DNS exists, which is the intended bootstrap path. You only need a hostname and TLS once you want clients to connect over wss://…/launch. See Installation for how to get the container running first.

Bootstrap order

Open the manager at http://<ip>/, walk through the wizard, and switch to a real hostname plus TLS at the TLS step once your DNS record points here. There is no need to configure DNS before you start.

Step 1: Create admin

The first screen creates the initial admin account. It requires a one-time setup token that the container generates on first boot.

Find the token in either place:

  • The install.sh output prints it directly at the end of a fresh install.
  • The container logs via docker logs <container> (bare metal: the service logs).

Paste the token, then choose an admin username and password. On success a session is minted immediately, so you stay logged in and move straight to the next step.

Step 2: Cluster basics

Name the cluster and set its hostnames:

  • Cluster name is a label for this control plane.
  • Main hostname serves both the console (UI + API) and client connections at wss://<host>/launch on a single domain. This is the address your automation connects to.
  • Release hostname (optional) is a second domain for browser and profile bundle downloads, needed when you run workers on other servers.
  • Advanced: split subdomains separates the console, launch, and release origins onto distinct subdomains instead of sharing one.
  • IP-only evaluation is an opt-out that skips the hostname and TLS entirely so you can try the cluster over http://<ip>. It is fine for a quick evaluation. Switch to a hostname and TLS before production, since wss://…/launch effectively requires HTTPS.

Step 3: TLS

The TLS step offers several modes. Traffic to the end user is always HTTPS. Pick the mode that matches how requests reach this host.

Cloudflare is for a domain proxied through Cloudflare (the orange cloud). Cloudflare terminates TLS with the browser, then connects to your origin. Choose a sub-mode to match your Cloudflare SSL/TLS setting:

  • Flexible: the origin serves plain HTTP on port 80 and Cloudflare handles TLS at the edge. No origin certificate is needed.
  • Full: the origin serves HTTPS on port 443. The certificate source is a self-signed origin cert (default, valid for Full) or a Cloudflare Origin CA cert (for Full strict, issued through the Cloudflare API using a one-time token that is never stored). You can also enable optional mTLS / Authenticated Origin Pulls so only Cloudflare can complete the origin handshake.

When Cloudflare fronts the cluster, the origin is locked to Cloudflare IP ranges by default so nobody can bypass Cloudflare by hitting the origin IP.

Bring your own certificate lets you paste a PEM certificate and private key. They are stored on the cm-state volume and served directly on port 443. Use this when you have a certificate from your own CA or provider.

Automatic HTTPS (Let's Encrypt) issues and renews a certificate on-box using lua-resty-acme inside OpenResty, with no cron and no extra services. It uses an HTTP-01 challenge, so DNS must point straight at the origin. You may supply an optional email for expiry notices. Prerequisites:

  • An A record for your main hostname points to this host.
  • Ports 80 and 443 are open. Port 80 answers the ACME challenge and 443 serves the issued certificate.

Issuance runs right after you save, and renewal happens automatically in the background. Behind Cloudflare's proxy, use Cloudflare + Full instead, since the proxy intercepts the port 80 challenge. For how each mode behaves and how the edge blocks direct-IP scans, see Edge security & TLS.

Automatic HTTPS troubleshooting

If issuance fails, the wizard reports which check failed. The common causes are:

  • DNS not pointing here: the A record for the hostname does not resolve to this host's public IP yet. Wait for propagation or fix the record.
  • DNS points at Cloudflare's proxy: the orange cloud intercepts the port 80 challenge, so HTTP-01 cannot complete. Switch to Cloudflare + Full instead.
  • Port 80 or 443 blocked: a firewall or security group is closing the ports Let's Encrypt needs. Open both and retry.
  • Let's Encrypt rate limit: too many recent attempts for the domain. Wait for the window to reset before retrying.

Step 4: Add a worker

Workers run the actual browsers. Add your first one:

  • Add local worker provisions a worker on this same host with one click (it requires the Docker socket mount from the install step).
  • Copy-paste docker run is for a remote or bring-your-own host. Copy the generated docker run snippet and run it on that machine. This is today's model for anything not on the manager's own box.

Step 5: Review & launch

The final step summarizes your choices. Click Render & Reload to write the real load-balancer config and reload OpenResty, then the wizard runs an automatic health check on the cluster.

When it finishes, point your automation at the connect URL:

wss://<public-hostname>/launch

Roadmap / Coming soon

Richer worker provisioning is planned but not available yet. These are future direction, not current features:

  • Remote worker over SSH: the manager would SSH into a remote server and install the worker there for you, replacing the manual docker run step.
  • Cloud deployments: provision workers directly on providers such as AWS and Hetzner from the console, without touching a server yourself.

For now, add remote workers with the copy-paste docker run snippet from Step 4.

Next steps

Was this page helpful?

On this page