>FFmpegLab Sign In
Self-Hosting & Deployment

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.

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.

Key takeaways

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:

curl -sSL https://ffmpeglab.com/sh/install.sh | bash

The installer will:

  1. Check all prerequisites (curl, git, docker, docker compose, npm, psql, openssl)
  2. Automatically set up self‑hosted Supabase (clones and starts Supabase locally)
  3. Enable pgmq and create the rendering_queue
  4. Create the storage bucket and set RLS policies
  5. Clone the FFmpegLab Server repository
  6. Install dependencies and run TypeORM migrations
  7. Generate an API key and insert it into the database
  8. 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/bash set -e # FFmpegLab Server - Agent-First Setup # Main installer that orchestrates all phases BASE_URL="https://ffmpeglab.com/sh" LOG_FILE="ffmpeglab-setup.log" # Colors RED='\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 script run_phase() { local script=$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 ]; then echo -e "${RED}❌ Phase $script failed. Check $LOG_FILE${NC}" exit 1 fi echo -e "${GREEN}✅ Phase $script completed${NC}" } # Check prerequisites echo -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) export SUPABASE_CHOICE=2 # Run phases run_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/bash set -e # Supabase Setup Phase # Configures PostgreSQL, pgmq, storage buckets, and RLS policies if [ -z "$SUPABASE_CHOICE" ]; then echo -e "${RED}❌ SUPABASE_CHOICE not set. Run install.sh first.${NC}" exit 1 fi # Colors RED='\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 present if [ ! -d "supabase" ]; then git clone --depth 1 https://github.com/supabase/supabase.git fi # Create project directory and copy configuration if [ ! -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 else cd 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" export DATABASE_URL S3_BUCKET SUPABASE_URL SUPABASE_ANON_KEY SUPABASE_SERVICE_ROLE_KEY DB_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/bash set -e source ./.env.sh # FFmpegLab Server Setup Phase # Clones repo, installs, runs migrations, generates API keys if [ -z "$DATABASE_URL" ] || [ -z "$S3_BUCKET_ID" ]; then echo -e "${RED}❌ DATABASE_URL or S3_BUCKET not set. Run supabase-setup.sh first.${NC}" exit 1 fi # Colors RED='\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 fi cd $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}" export API_KEY echo -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.sh echo "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/bash set -e source ./.env.sh # Finalize Phase # Starts Docker Compose and displays summary if [ -z "$API_KEY" ]; then echo -e "${RED}❌ API_KEY not set. Run server-setup.sh first.${NC}" exit 1 fi # Colors RED='\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:

VariableDescription
DATABASE_URLPostgreSQL connection string
DB_MIGRATION_ENABLEDAuto‑run database migrations
S3_BUCKET_IDStorage bucket name
S3_ACCESS_KEYS3 access key
API_KEYGenerated API key for authentication
SUPABASE_URLSelf‑hosted Supabase URL
SUPABASE_ANON_KEYSupabase anonymous key
SUPABASE_SERVICE_ROLE_KEYSupabase service role key

All variables are written to .env.sh for reuse.

Troubleshooting

IssueLikely CauseFix
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:

curl -sSL https://ffmpeglab.com/sh/install.sh | bash

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.