← Back

Backend Setup Guide

Follow these steps to deploy the backend on Railway (free tier works). The frontend stays on Vercel.

The backend requires ffmpeg and yt-dlp to run — Railway auto-installs both via the railway.toml config below. You don't need to install anything manually on the server.

Deploy Instructions

WHY YOUTUBE BLOCKS DOWNLOADS:
Railway's servers are data center IPs. YouTube sees this and blocks the request as a bot.
The fix: bgutil automatically generates "Proof-of-Origin" tokens YouTube requires.
It runs as a separate lightweight Railway service — isolated, stable, free tier friendly.

─── PART 1: Deploy bgutil as a second Railway service ────────────────────────

STEP 1 — In your Railway project, click "+ New" → "Docker Image"
  Enter this image name exactly:
    brainicism/bgutil-ytdlp-pot-provider:latest
  Click Deploy and wait ~1 minute for it to start.

STEP 2 — Set variables on the bgutil service:
  Click the bgutil service → Variables tab → add:
    PORT  =  4416
    HOST  =  0.0.0.0

STEP 3 — Generate a public URL for bgutil:
  Click bgutil service → Settings → Networking → Generate Domain
  You'll get: https://bgutil-production-xxxx.up.railway.app
  Copy this URL.

─── PART 2: Connect your main backend to bgutil ──────────────────────────────

STEP 4 — Add BGUTIL_URL to your MAIN backend service:
  Click your main backend service → Variables tab → add:
    BGUTIL_URL  =  https://bgutil-production-xxxx.up.railway.app
  (paste your actual bgutil URL from Step 3)
  Railway will auto-redeploy your main backend.

─── PART 3: Update your main backend code ────────────────────────────────────

STEP 5 — Replace these 2 files in your GitHub repo with the versions from this page:
  - processor.js   (reads BGUTIL_URL and uses it for PO tokens)
  - railway.toml   (installs the bgutil yt-dlp client plugin via pip)
  Push to GitHub → Railway auto-redeploys.

─── DONE ─────────────────────────────────────────────────────────────────────

HOW IT WORKS:
  processor.js reads BGUTIL_URL env var → calls bgutil for a fresh PO token
  → passes it to yt-dlp → YouTube accepts it → download works automatically.

FALLBACK CHAIN (all automatic, no action needed):
  bgutil PO token → android client → ios client → safari → mweb → Invidious proxy → cookies.txt

Backend Files (copy each one)