Agent-First Setup – FFmpegLab Server with Self-Hosted Supabase
Complete guide to setting up FFmpegLab Server using self-hosted Supabase. One-line install with modular bash scripts for PostgreSQL, pgmq, and S3 storage.
FFmpeg tutorial · ~10 min read · Updated August 2026
Setting up FFmpegLab Server from scratch requires a database, a job queue, and storage. This guide provides modular bash scripts that automate the entire setup process — from configuring a self‑hosted Supabase instance to deploying the FFmpegLab Server — all with a single command.
Self‑hosted Supabase — the script clones and configures Supabase locally
Modular scripts — each phase is a separate script for flexibility
PostgreSQL + pgmq — Supabase provides both the database and the job queue
API keys — generated automatically and inserted into the database
All logs — written to ffmpeglab-setup.log for debugging
The Gap: From Zero to Running Server
The FFmpegLab Server documentation covers the architecture, but setting it up from scratch requires knowing the exact steps. This guide fills that gap with a complete, automated approach using modular bash scripts.
install.sh→supabase-setup.sh→server-setup.sh→finalize.sh (One command runs all phases)
Quick Start – One‑Line Install
Run the main installer to set up everything automatically:
Automatically set up self‑hosted Supabase (clones and starts Supabase locally)
Enable pgmq and create the rendering_queue
Create the storage bucket and set RLS policies
Clone the FFmpegLab Server repository
Install dependencies and run TypeORM migrations
Generate an API key and insert it into the database
Deploy the server with Docker Compose
All logs are written to ffmpeglab-setup.log for debugging.
Modular Setup Scripts
The scripts are designed to be run individually or as part of the main installer. They are hosted at ffmpeglab.com/sh/.
1. Main Installer
URL:ffmpeglab.com/sh/install.sh
#!/bin/bashset -e
# FFmpegLab Server - Agent-First Setup# Main installer that orchestrates all phasesBASE_URL="https://ffmpeglab.com/sh"LOG_FILE="ffmpeglab-setup.log"# ColorsRED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'BLUE='\033[0;34m'NC='\033[0m'echo -e "${BLUE}🚀 FFmpegLab Server - Agent-First Setup${NC}"echo"================================================"echo"Logs written to: $LOG_FILE"# Function to run a phase scriptrun_phase() {
localscript=$1
echo -e "${BLUE}▶ Running phase: $script${NC}"curl -sSL "$BASE_URL/$script" | bash -s 2>&1 | tee -a "$LOG_FILE"if [ ${PIPESTATUS[0]} -ne 0 ]; thenecho -e "${RED}❌ Phase $script failed. Check $LOG_FILE${NC}"exit 1
fiecho -e "${GREEN}✅ Phase $script completed${NC}"
}
# Check prerequisitesecho -e "${YELLOW}🔍 Checking prerequisites...${NC}"command -v curl >/dev/null 2>&1 || { echo -e "${RED}❌ curl is required.${NC}"; exit 1; }
command -v git >/dev/null 2>&1 || { echo -e "${RED}❌ git is required.${NC}"; exit 1; }
command -v docker >/dev/null 2>&1 || { echo -e "${RED}❌ docker is required.${NC}"; exit 1; }
command -v docker compose >/dev/null 2>&1 || command -v docker-compose >/dev/null 2>&1 || { echo -e "${RED}❌ docker compose is required.${NC}"; exit 1; }
command -v npm >/dev/null 2>&1 || { echo -e "${RED}❌ npm is required.${NC}"; exit 1; }
command -v psql >/dev/null 2>&1 || { echo -e "${RED}❌ psql is required.${NC}"; exit 1; }
command -v openssl >/dev/null 2>&1 || { echo -e "${RED}❌ openssl is required.${NC}"; exit 1; }
echo -e "${GREEN}✅ All prerequisites satisfied.${NC}"# Set to self-hosted mode (the script no longer asks for cloud vs local)exportSUPABASE_CHOICE=2
# Run phasesrun_phase"supabase-setup.sh"run_phase"server-setup.sh"run_phase"finalize.sh"
💡
Note
The installer no longer prompts for Supabase Cloud vs self‑hosted. It always sets up a self‑hosted Supabase instance locally.
2. Supabase Setup
URL:ffmpeglab.com/sh/supabase-setup.sh
This script clones and configures a self‑hosted Supabase instance:
#!/bin/bashset -e
# Supabase Setup Phase# Configures PostgreSQL, pgmq, storage buckets, and RLS policiesif [ -z "$SUPABASE_CHOICE" ]; thenecho -e "${RED}❌ SUPABASE_CHOICE not set. Run install.sh first.${NC}"exit 1
fi# ColorsRED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'BLUE='\033[0;34m'NC='\033[0m'echo -e "${BLUE}🔧 Configuring Supabase...${NC}"# Self-hosted setup (always used)echo -e "${BLUE}📦 Setting up self-hosted Supabase...${NC}"# Clone Supabase if not presentif [ ! -d "supabase" ]; then
git clone --depth 1 https://github.com/supabase/supabase.git
fi# Create project directory and copy configurationif [ ! -d "supabase-project" ]; then
mkdir supabase-project
cp -rf supabase/docker/. supabase-project/
cd supabase-project && cp .env.example .env
sh utils/generate-keys.sh
sh utils/add-new-auth-keys.sh
docker compose pull
elsecd supabase-project
fi# Start Supabase
docker compose up -d
cd ..
# Load environment variables from Supabase .env
ENV_VARS="$(cat supabase-project/.env | awk '!/^\s*#/' | awk '!/^\s*$/')"eval"$( printf '%s\n' "$ENV_VARS" | while IFS='' read -r line; do
key=$(printf '%s\n' "$line"| sed 's/"/\\"/g' | cut -d '=' -f 1)
value=$(printf '%s\n' "$line" | cut -d '=' -f 2- | sed 's/"/\\\"/g')
printf '%s\n' "export $key=\"$value\""
done )"# Set Supabase URLs and credentials
SUPABASE_URL="http://localhost:8000"
SUPABASE_ANON_KEY="$ANON_KEY"
SUPABASE_SERVICE_ROLE_KEY="$SERVICE_ROLE_KEY"
DB_PASSWORD="$POSTGRES_PASSWORD"
DB_NAME=postgres
DB_USER=postgres.your-tenant-id# Storage bucket name
read -p "Storage Bucket Name [ffmpeglab-assets]: " S3_BUCKET
S3_BUCKET=${S3_BUCKET:-ffmpeglab-assets}
# Build DATABASE_URL
DATABASE_URL="postgresql://${DB_USER}:${DB_PASSWORD}@${SUPABASE_FQDN}/postgres"exportDATABASE_URLS3_BUCKETSUPABASE_URLSUPABASE_ANON_KEYSUPABASE_SERVICE_ROLE_KEYDB_PASSWORD# Write environment variables to .env.sh
rm -rf .env.sh
echo"export DATABASE_URL=${DATABASE_URL}" >> .env.sh
echo"export DB_MIGRATION_ENABLED=true" >> .env.sh
echo"export S3_BUCKET_ID=${S3_BUCKET}" >> .env.sh
echo"export S3_ACCESS_KEY=${S3_PROTOCOL_ACCESS_KEY_ID}" >> .env.sh
3. Server Setup
URL:ffmpeglab.com/sh/server-setup.sh
This script clones the FFmpegLab Server, starts it, and generates an API key:
#!/bin/bashset -e
source ./.env.sh
# FFmpegLab Server Setup Phase# Clones repo, installs, runs migrations, generates API keysif [ -z "$DATABASE_URL" ] || [ -z "$S3_BUCKET_ID" ]; thenecho -e "${RED}❌ DATABASE_URL or S3_BUCKET not set. Run supabase-setup.sh first.${NC}"exit 1
fi# ColorsRED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'BLUE='\033[0;34m'NC='\033[0m'echo -e "${BLUE}📦 Setting up FFmpegLab Server...${NC}"# Clone repo
REPO_DIR="ffmpeglab"if [ ! -d "$REPO_DIR" ]; then
git clone https://github.com/ffmpeglab/server.git ffmpeglab
ficd $REPO_DIR
# Pull and start Docker Compose
docker compose pull
docker compose up -d
sleep 10
# Generate API key
API_KEY_SECRET=$(openssl rand -hex 32 2>/dev/null || echo "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6")
API_KEY="${API_KEY_SECRET}"exportAPI_KEYecho -e "${BLUE}💾 Inserting user and API key...${NC}"PGPASSWORD="$DB_PASSWORD" psql "$DATABASE_URL" <<EOF
INSERT INTO "user" (id, email, password_hash, data)
VALUES (
'550e8400-e29b-41d4-a716-446655440000',
'[email protected]',
'',
'{"roles": ["admin"]}'
) ON CONFLICT DO NOTHING;
INSERT INTO apikey (id, title, apikey, user_id, data)
VALUES (
'550e8400-e29b-41d4-a716-446655440001',
'Admin API Key',
'${API_KEY}',
'550e8400-e29b-41d4-a716-446655440000',
'{"permissions": ["render:*", "project:*", "user:read"]}'
) ON CONFLICT DO NOTHING;
EOF
# Write API key to .env.shecho"export API_KEY=${API_KEY}" >> ../.env.sh
echo -e "${GREEN}✅ User and API key inserted.${NC}"
4. Finalize
URL:ffmpeglab.com/sh/finalize.sh
This script starts the server and displays the final summary:
#!/bin/bashset -e
source ./.env.sh
# Finalize Phase# Starts Docker Compose and displays summaryif [ -z "$API_KEY" ]; thenecho -e "${RED}❌ API_KEY not set. Run server-setup.sh first.${NC}"exit 1
fi# ColorsRED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'BLUE='\033[0;34m'NC='\033[0m'echo -e "${BLUE}🐳 Starting FFmpegLab Server with Docker Compose...${NC}"
docker compose up -d
echo -e "${BLUE}📊 Service status:${NC}"
docker compose ps
echo -e "${GREEN}✅ Setup complete!${NC}"echo"================================================"echo -e "${GREEN}🔑 Your API Key: ${API_KEY}${NC}"echo -e "${BLUE}🌐 API Server: http://localhost:3000${NC}"echo -e "${BLUE}📝 Test with:${NC}"echo" curl -v -H 'Authorization: Bearer ${API_KEY}' http://localhost:3000/renders"
curl -v -H "Authorization: Bearer ${API_KEY}""http://localhost:3000/renders"
Environment Variables
The scripts automatically generate and export the following environment variables:
Variable
Description
DATABASE_URL
PostgreSQL connection string
DB_MIGRATION_ENABLED
Auto‑run database migrations
S3_BUCKET_ID
Storage bucket name
S3_ACCESS_KEY
S3 access key
API_KEY
Generated API key for authentication
SUPABASE_URL
Self‑hosted Supabase URL
SUPABASE_ANON_KEY
Supabase anonymous key
SUPABASE_SERVICE_ROLE_KEY
Supabase service role key
All variables are written to .env.sh for reuse.
Troubleshooting
Issue
Likely Cause
Fix
Migrations fail
Database not accessible or pgmq not enabled
Check DATABASE_URL; ensure Supabase is running
API key not working
Key format incorrect or user doesn't exist
Verify key format matches ffmpeglab_sk_ prefix
Runners not picking up jobs
pgmq queue not created
Create the rendering_queue in Supabase
Port conflict
Port 3000 already in use
Change PORT in .env or stop the conflicting service
psql connection error
Supabase not running
Run docker compose up -d in the supabase-project directory
Frequently Asked Questions (FAQ)
What does the one-line install do?
The one-line install automatically sets up a self-hosted Supabase instance, configures PostgreSQL with pgmq, creates storage buckets with RLS policies, clones and deploys FFmpegLab Server, and generates an API key — all with a single command.
What prerequisites are required?
You need curl, git, docker, docker compose, npm, psql, and openssl. The install script checks for these automatically.
Where are the logs stored?
All logs are written to ffmpeglab-setup.log in the current directory for debugging.
Can I run the scripts individually?
Yes. The scripts are modular and can be run individually: install.sh orchestrates everything, supabase-setup.sh configures Supabase, server-setup.sh deploys FFmpegLab Server, and finalize.sh completes the setup.
How do I get the API key after installation?
The API key is displayed at the end of the installation. It is also stored in .env.sh and can be retrieved with source .env.sh && echo $API_KEY.
Final Word
Setting up FFmpegLab Server with self‑hosted Supabase is now completely automated. With a single command, you get:
PostgreSQL — for application data
pgmq — for durable job queuing
S3 Storage — for media assets (via Supabase Storage)
Authentication — API keys generated automatically
FFmpegLab Server — running and ready to accept renders
With your instance up and running, you can begin submitting render jobs, managing projects, and scaling your video processing pipeline — all backed by self‑hosted Supabase.