15% off your first purchase with code WELCOME15, up to 25 GB.

See pricing

Integration · AI & workflow tools

How to use a proxy with self-hosted Firecrawl

Self-hosted Firecrawl reads three variables from the .env file in the repository root: PROXY_SERVER, PROXY_USERNAME and PROXY_PASSWORD. Both scraping engines use them, the plain fetch engine in the API container and the Playwright service, so every page the instance fetches leaves through the gateway. The hosted Firecrawl API is different: its proxy parameter chooses between Firecrawl's own proxy modes and has no field for your own gateway.

Reviewed 30 Oct 2026

your proxy, as a URL
http://USERNAME_pool-arcfast_country-de:PASSWORD@proxy.arcproxies.io:8000

The short answer

  • Three variables in .env: server as http://host:port, username and password on their own lines.
  • The setting is instance-wide. One username means one country and one session mode for every job until you change it and recreate the containers.
  • Use a rotating username (no _session- token) for a shared instance; a sticky one would pin every job to the same exit.
  • BLOCK_MEDIA=true stops the Playwright service loading images and media, one of the larger savings in reducing proxy bandwidth.

Setup

Set up Firecrawl (self-hosted) with a proxy, step by step

  1. 01

    Add the proxy variables to .env

    Firecrawl's self-hosting guide starts from a minimal .env in the repository root; add the three proxy lines and, optionally, BLOCK_MEDIA. PROXY_SERVER may be given without a scheme, in which case http:// is assumed.

    .env
    # minimal self-host settings from the Firecrawl guideUSE_DB_AUTHENTICATION=falsePOSTGRES_USER=postgresPOSTGRES_PASSWORD=change-mePOSTGRES_DB=postgres# ARC gateway: rotating German residential exitsPROXY_SERVER=http://proxy.arcproxies.io:8000PROXY_USERNAME=USERNAME_pool-arcfast_country-dePROXY_PASSWORD=PASSWORD# skip images and media in the Playwright serviceBLOCK_MEDIA=true
  2. 02

    Build and start the stack

    docker-compose.yaml passes the proxy variables to both the API and the Playwright service. Check that every service is up before sending a scrape. For proxy settings in other containers, see the Docker guide.

    shell
    docker compose up --build -ddocker compose ps --allcurl -s http://localhost:3002/v0/health/readiness   # {"status":"ok"}
  3. 03

    Scrape an IP echo service to confirm the exit

    The markdown in the response should contain a German IP, not your server's address. Run it twice: with a rotating username the two answers usually differ.

    shell
    curl -s -X POST http://localhost:3002/v2/scrape \  -H 'Content-Type: application/json' \  -d '{"url": "https://api.ipify.org?format=json", "formats": ["markdown"]}'
  4. 04

    Change the country by recreating the containers

    Containers read .env when they are created, not on every request. Edit the username, then recreate the stack so the API and the Playwright service pick up the new value together.

    shell
    # .env: PROXY_USERNAME=USERNAME_pool-arcfast_country-frdocker compose up -d --force-recreate

What the Firecrawl proxy variables cover

ComponentReads the proxy variablesHow it authenticates
API fetch engine (apps/api)Yesundici ProxyAgent with a Basic token built from username and password
Playwright serviceYesA local proxy-chain server forwards to the gateway with the credentials in the upstream URL
PDF and document downloadsYes, through the fetch engineSame as the API; failures report a proxy error naming PROXY_SERVER
Hosted Firecrawl APINoUses Firecrawl's own proxy modes (basic, auto and an enhanced tier)

Read from the Firecrawl source on 30 October 2026 (apps/api/src/scraper/scrapeURL/engines/utils/safeFetch.ts, apps/playwright-service-ts/api.ts). We did not build the stack for this guide, so run the IP check above on your own instance.

Several countries from one Firecrawl setup

Because the proxy is set per instance, per-job country targeting is not possible through these variables. Two practical patterns: run one small Firecrawl stack per market, each with its own .env and port, or keep one instance on a country-less rotating username and do geo-specific fetching elsewhere, for example with Crawl4AI, which takes a proxy per run.

Whichever you choose, keep the instance private. Firecrawl's guide notes the quickstart has authentication disabled; anyone who can reach port 3002 can spend your proxy bandwidth.

Rotating or sticky on a shared crawler

A rotating username lets each new connection leave from a different exit, which spreads a crawl's load across many addresses. A sticky username (_session-…_sesstime-…) would hold one exit for every concurrent job on the instance and concentrate their traffic on one IP and its rate limit. On Firecrawl, sticky only makes sense for a dedicated instance that runs one multi-step job at a time. Rotating vs sticky sessions explains the difference in more detail.

The problem

Common pitfalls

Credentials inside PROXY_SERVER

Put the username and password in their own variables. The Playwright service rebuilds the upstream URL from the three values, and the API builds its own authorisation header from them.

Editing .env without recreating containers

A running container keeps the environment it was created with. After changing the username, recreate the services; restarting the process inside an old container is not enough.

An exposed instance

With USE_DB_AUTHENTICATION=false, the API accepts requests from anyone who can reach it. Bind it to localhost or a private network; otherwise strangers can scrape on your bandwidth.

Expecting the hosted API to accept your proxy

The proxy field on Firecrawl's hosted API selects Firecrawl's own modes. To route through ARC, you need the self-hosted stack.

FAQ

Questions

Something not covered? Write to contact@arcproxies.io.

How do I add a proxy to self-hosted Firecrawl?

Set PROXY_SERVER=http://host:port, PROXY_USERNAME and PROXY_PASSWORD in the .env file at the repository root, then rebuild or recreate the containers with Docker Compose. Both the fetch engine and the Playwright service read these variables.

Can I use my own proxy with the Firecrawl cloud API?

No field for that is documented. The hosted API's proxy parameter chooses between Firecrawl's own proxy types (basic, auto and an enhanced tier). Your own gateway works with the self-hosted version.

How do I target a different country in Firecrawl?

Change the _country- token in PROXY_USERNAME and recreate the containers. The setting applies to the whole instance, so for several countries at once run one instance per country.

Does BLOCK_MEDIA reduce proxy costs in Firecrawl?

It stops the Playwright service from loading images and media, which are often most of a rendered page's bytes. The saving depends on the site; compare the dashboard's usage for a sample crawl with and without it.

Sources & review

Last reviewed by the ARC Proxies team. Prices are read from the live catalog at build time.

  1. [1]Firecrawl: Self-hosting Firecrawl: .env, Docker Compose and smoke test
  2. [2]Firecrawl (GitHub): apps/api/.env.example: PROXY_SERVER, PROXY_USERNAME, PROXY_PASSWORD, BLOCK_MEDIA
  3. [3]Firecrawl (GitHub): docker-compose.yaml: proxy variables passed to the API and Playwright service
  4. [4]Firecrawl: Proxies: basic, auto and enhanced modes on the hosted API

Next

What people build with it

Get started

Get credentials and paste them in.

Sign up, buy a gigabyte, generate a username in the dashboard. Code WELCOME15 takes 15% off your first purchase; bandwidth never expires.