Skip to main content
By the end of this tutorial you’ll have a go-livepeer orchestrator running on Arbitrum One, registered on-chain, visible in the Explorer, and ready to receive video transcoding jobs. This is a learning path — it makes opinionated choices so you can get to a working node in about an hour. When you want to change those choices, the how-to guides cover each step in depth.
We’ll use Docker and GPU video transcoding throughout. Adding AI inference is a separate step once this is working — see Add AI inference.

Before you start

You need:
RequirementDetails
GPUNVIDIA with NVENC (GTX 1060+ for transcoding)
OSLinux (recommended for production)
DockerDocker Engine + NVIDIA Container Toolkit
Wallet fundsETH and LPT on Arbitrum One
NetworkPort 8935/tcp open to the public internet
RPCAn Arbitrum One endpoint (Alchemy or Infura free tier)
Acquiring LPT on Arbitrum can take hours to days (exchange settlement + bridging). Start that now — it’s the slowest part. See Acquire LPT, which applies to orchestrators too.

Step 1 — Confirm your GPU and Docker

# List your NVIDIA GPUs (note the device IDs)
nvidia-smi -L

# Confirm Docker can see the GPU
docker run --gpus all nvidia/cuda:12.0-base nvidia-smi
If the second command fails, install the NVIDIA Container Toolkit before continuing (sudo apt-get install -y nvidia-container-toolkit && sudo systemctl restart docker).

Step 2 — Get an Arbitrum One RPC URL

Create a free app at Alchemy (select ArbitrumMainnet) and copy the HTTPS URL. Verify it points at Arbitrum One — the chain ID must be 0xa4b1 (42161):
curl -s -X POST -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' \
  YOUR_RPC_URL
# Expect: {"result":"0xa4b1"}
A 0x1 result means you’re on Ethereum L1 — switch to an Arbitrum endpoint.

Step 3 — Start the node

Run go-livepeer in combined orchestrator + transcoder mode. On first start it creates an Ethereum account and prompts for a passphrase.
docker run --name livepeer-orchestrator \
  -v ~/.lpData/:/root/.lpData/ \
  --network host \
  --gpus all \
  livepeer/go-livepeer:latest \
  -network arbitrum-one-mainnet \
  -ethUrl YOUR_RPC_URL \
  -orchestrator \
  -transcoder \
  -nvidia 0 \
  -maxSessions 10 \
  -pricePerUnit 1000 \
  -serviceAddr YOUR_PUBLIC_IP:8935
Mounting ~/.lpData/ is what persists your keystore between restarts. Without it, a new wallet is created every run and any staked LPT becomes unreachable. Back up ~/.lpData/arbitrum-one-mainnet/keystore to offline storage immediately — a lost keystore cannot be recovered.
A quick orientation on the flags you just used:
  • -pricePerUnit 1000 — wei per pixel, not ETH. (Setting this in ETH prices you far above market.)
  • -maxSessions 10 — concurrent transcode sessions; tune later in Configure.
  • -serviceAddr — the public address gateways will reach. A domain name is more resilient than a bare IP.

Step 4 — Fund the wallet, stake LPT, and activate

Find your orchestrator address in the startup logs, then send it ETH on Arbitrum (≥ 0.05 ETH for gas) and LPT. Once both are in the wallet, open the CLI:
docker exec -it livepeer-orchestrator livepeer_cli
Then:
  1. Select the bond/stake option and stake your LPT (two transactions: approve, then bond).
  2. Select “Invoke multi-step ‘become an orchestrator’” and set:
PromptSuggested startMeaning
Reward Cut10You keep 10% of LPT inflation; delegators get 90%
Fee Cut95You keep 95% of ETH fees; delegators get 5%
Service addressYOUR_PUBLIC_IP:8935Must match -serviceAddr exactly
Your node enters the active set at the start of the next round (~22h) — and only if your total stake is in the top 100. Check the current threshold on the Explorer before acquiring LPT.

Step 5 — Verify

Open explorer.livepeer.org/orchestrators and search your address. Confirm:
  • Status is Active (may show Registered until the next round),
  • Service URI matches your -serviceAddr,
  • Stake, Reward Cut, and Fee Cut match what you set.
Confirm external reachability from a different machine:
curl -k https://YOUR_PUBLIC_IP:8935/status
Any response (even an error) means the port is reachable. A timeout means port 8935 is blocked — see the FAQ.

Step 6 — Confirm reward calling

go-livepeer calls reward() automatically each round by default. Make sure it isn’t disabled:
docker logs livepeer-orchestrator 2>&1 | grep -i reward
Your command should not contain -reward=false. A missed round forfeits that round’s LPT permanently — there’s no catch-up.

You’re live

Your orchestrator is on mainnet and discoverable. Where to go next:

Set competitive pricing

The biggest lever on whether gateways actually select you.

Add AI inference

Earn from AI pipelines alongside transcoding.

Monitor your node

Metrics, dashboards, and an alert for missed reward calls.

Not receiving jobs?

Work through the four common causes.