So you’re building an AI agent. The prompt engineering is crisp, the logic is tight, and it works perfectly on your machine.

Then you try to run it on a server and the entire thing falls apart.

Cloudflare says no, session state evaporates into the ether, and you spend the next three days debugging cursed browser infra instead of actually shipping.

We’ve been there. It’s cringe.

That’s why we built Steel. It’s an open-source browser API that handles the messy parts of web automation so you can focus on your agent.

While our Steel Cloud is the fastest way to get started with zero infra management, we know that for many builders, control is everything. You want to run it on your own metal, in your own VPC, or just tinker with the code.

This guide is for you. Here’s how to self-host Steel Browser, from a 1-click deploy to building from source. Choose your difficulty.

Easy Mode: 1-Click Deploy

You have an idea and you need a browser API running, like, yesterday. You don’t want to see a Dockerfile. You just want an endpoint. Sent.

If you’re looking to deploy to a cloud provider, we’ve got you covered. You can use our pre-built Docker image for API-only deployments or try our 1-click Railway deployment for the simplest setup.

The Lowdown: This is the best of both worlds—you get a dedicated instance without the DevOps overhead. Perfect for hackathons, prototypes, or small-to-medium scale agents.

Normal Mode: Docker on Your Machine

This is the canonical way to run Steel locally. You want a stable, production-equivalent environment on your dev machine without cloning the whole repo.

  1. Make sure you have Docker installed.

  2. Create a docker-compose.yml file:

    services:
      api:
        image: ghcr.io/steel-dev/steel-browser-api:latest
        ports:
          - "3000:3000"    # API Server
          - "9223:9223"    # CDP Redirect
        networks:
          - steel-network
    
      ui:
        image: ghcr.io/steel-dev/steel-browser-ui:latest
        ports:
          - "5173:80"
        environment:
          - API_URL=http://api:3000
        depends_on:
          - api
        networks:
          - steel-network
    
    networks:
      steel-network:
        driver: bridge
  3. Spin it up:

    docker compose up

The Lowdown: This yanks our pre-cooked images from GitHub Container Registry. You get the Steel API at http://localhost:3000 and the UI at http://localhost:5173. It’s fast, isolated, and just works. This is the way for 90% of local development.

Hard Mode: Bare Metal with Node.js

You’re a purist. You hate Docker. You have Node.js and Chrome already installed and you just want to run the server directly. We respect it.

  1. Clone the repo:

    git clone https://github.com/steel-dev/steel-browser.git
    cd steel-browser
  2. Install dependencies and run:

    npm install
    npm run dev

The Lowdown: This starts the API and UI dev servers directly on your machine. It’s great for quick changes, but comes with a few gotchas.

⚠️ Heads Up: This method expects a Chrome executable to exist at a standard location. If you have a custom install path (or you’re using Chromium), you’ll need to tell Steel where to find it. Just set the CHROME_EXECUTABLE_PATH environment variable:

export CHROME_EXECUTABLE_PATH=/path/to/your/chrome
npm run dev

Nightmare Mode: Build From Source (For Contributors)

You’re not just here to use Steel, you’re here to cook. You’ve found a bug, want to add a feature, or just see how the sausage is made. This is your setup.

  1. Clone the repo: (You already did this, right?)

    git clone https://github.com/steel-dev/steel-browser.git
    cd steel-browser
  2. Use the developer Compose file:

    docker compose -f docker-compose.dev.yml up --build

The Lowdown: The --build flag is key. It tells Docker to rebuild the api and ui images from your local source code instead of pulling them. Any change you make to the code in the api/ or ui/ directories will be reflected the next time you run this command. Welcome to the kitchen.

The Payoff: Connecting to Your Instance

Okay, so you’ve got Steel running. Now what?

You get a WebSocket endpoint (ws://localhost:3000) that you can connect to with any CDP-compatible client, like Puppeteer or Playwright.

Here’s how easy it is. The repl package in the repo has this exact script:

// repl/src/script.ts
import puppeteer from "puppeteer-core";

async function run() {
  // Point this to your new Steel instance
  const wsEndpoint = "ws://localhost:3000";
  const browser = await puppeteer.connect({ browserWSEndpoint: wsEndpoint });
  
  try {
    const page = await browser.newPage();

    await page.goto("https://steel.dev");
    console.log(`Page title: ${await page.title()}`);

  } finally {
    await browser.disconnect();  
  }
}

run().catch(console.error);

You just connect to your endpoint and use Puppeteer like normal. All the session management, proxying, and anti-detection is handled for you.

Now Go Cook Something

You’re all set up with a powerful, self-hosted browser API. What you build next is up to you.

  • Check out the Cookbook for more examples.

  • Got questions? Join us in the Discord.

  • Find something cursed? Open an issue on GitHub.

We’re hyped to see what you ship. 🚀

Jul 20, 2025

Jul 20, 2025

Jul 20, 2025

Ship Your AI Web Agent Faster: A Guide to Self-Hosting Steel Browser

Ship Your AI Web Agent Faster: A Guide to Self-Hosting Steel Browser

Ship Your AI Web Agent Faster: A Guide to Self-Hosting Steel Browser

Learn to self-host Steel Browser for AI web agents. Complete guide with 1-click deploy, Docker setup, and bare metal installation options.

Ready to

Build with Steel?

Ready to

Build with Steel?

Ready to

Build with Steel?

Ready to Build with Steel?

A better way to take your LLMs online.

© Steel · Inc. 2024.

All Systems Operational

Platform

Join the community