All posts
ffmpeg docker

Self-Hosted FFmpeg in Docker vs. a Hosted FFmpeg API

Run FFmpeg in your own Docker container or call a hosted FFmpeg API? A fair comparison of setup, scaling, security, limits and cost, with a Dockerfile to start from.

Self-hosting FFmpeg in Docker gives you full control and can be cheaper at a steady high volume. A hosted FFmpeg API removes the servers, the queue and the scaling work, and you pay per job. The FFmpeg command is the same in both; what changes is who runs everything around it.

This guide compares the two fairly, with a Dockerfile to start from and a short list of when each one is the better choice. For all the ways to run FFmpeg off your laptop, see how to run FFmpeg in the cloud.

Summary

FFmpeg in your own Docker containerHosted FFmpeg API (Xora)
SetupImage, queue, workers, storage, retriesAn API key
FFmpeg buildAny build you want, including GPU buildsA full GPL build, the same for all jobs
ScalingYou add machines or set autoscalingConcurrent jobs per plan (2 to 50)
Cost when idleThe machines still runNothing
Cost when busyUsually lower per minute at steady high volumeCredits for machine time and output size
LimitsYour machine sizesInput size per plan (250 MB to 6 GB), 15 minutes per raw FFmpeg job
Untrusted uploadsYou isolate and patch FFmpegJobs run in an isolated sandbox
Data locationYour networkXora’s cloud, or outputs in your own R2 bucket

Option 1: FFmpeg in Docker

A Dockerfile to start from

Dockerfile
FROM debian:bookworm-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends ffmpeg ca-certificates \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /work
ENTRYPOINT ["ffmpeg"]
Terminal window
docker build -t my-ffmpeg .
docker run --rm -v "$PWD:/work" my-ffmpeg -i input.mov -c:v libx264 -crf 23 -c:a aac output.mp4

The FFmpeg in the distribution packages is often older than the current release and can miss some encoders. For a newer build, copy a static build into the image, or build FFmpeg yourself with the libraries you need.

What you build around it

One docker run works for one file. A product that processes uploads also needs:

  • A queue and workers. Encodes take seconds to minutes, so an HTTP request cannot wait for them. You need a job queue, workers that take jobs, and a way to report progress.
  • Retries and timeouts. Workers crash and inputs are broken. Each job needs a time limit, a retry rule, and a clear failed state.
  • Storage. Inputs must be downloaded and outputs uploaded, and temporary files must be deleted, or the disk fills.
  • Scaling. One encode can use all CPUs on a machine. More jobs at once means more machines, and autoscaling on queue length.
  • Isolation. User uploads are untrusted input to a complex parser. Run each job in a container with no network access to your other systems, limit CPU, memory and disk, and update FFmpeg when security fixes come out.
  • Monitoring. Failed jobs, slow jobs and full disks need alerts.

Where Docker is the better choice

  • You have a steady high volume, so the machines are busy most of the time.
  • You need GPU encoding, a custom FFmpeg build, or filters and libraries that an API does not have.
  • Media must stay in your own network for compliance reasons.
  • Single jobs run longer than an API allows, for example very long raw FFmpeg encodes.
  • You already run a container platform and a queue, so the extra work is small.

Option 2: A hosted FFmpeg API

With Xora, the same FFmpeg arguments go in a JSON body, and Xora runs the queue, the workers, the storage and the retries:

POST /v1/jobs
{
"mode": "ffmpeg",
"input_files": { "in_1": "https://example.com/upload.mov" },
"output_files": { "out_1": "upload_web.mp4" },
"ffmpeg": {
"args": ["-i", "{{in_1}}", "-c:v", "libx264", "-crf", "23", "-c:a", "aac", "-movflags", "+faststart", "{{out_1}}"]
},
"webhookUrl": "https://your-app.com/webhooks/xora",
"idempotencyKey": "upload-123-web"
}

The response is { id, state }. A webhook or GET /v1/jobs/{id} gives the result as a signed URL, or the file is written to your own Cloudflare R2 bucket on paid plans. Errors come back as JSON with a code, and failed and rejected jobs cost nothing. For common jobs there are recipes, such as compress, trim and webReady, so you do not have to write the arguments.

Where an API is the better choice

  • Volume is low or comes in bursts, so a server would be idle most of the time.
  • You do not want to run and patch video infrastructure.
  • An AI agent or an automation tool sends the jobs. Xora has an MCP server for agents.
  • You want to start now and decide later. The arguments are the same, so you can move jobs to your own containers when volume grows.

Limits to know

Raw FFmpeg jobs on Xora have a 15-minute time limit and 10 GB of working disk, and the input size limit depends on the plan (250 MB on Free, 2 GB on Build, 6 GB on Scale). Some flags and protocols are blocked for safety. See custom FFmpeg commands for the full list.

How to compare the cost

There is no single answer, so use your own numbers:

  1. Machine cost. The price of the servers you would run, for the hours they run, including idle hours.
  2. Your time. Building the queue, retries, storage and monitoring, and keeping them working.
  3. API cost. Run a few of your real jobs on the Free plan (25 credits, no card), and multiply the credits by your monthly volume. See pricing.

If the machines would be busy most of the day and you already have the infrastructure, self-hosting usually wins. If not, the API usually costs less in total.

Next steps

Frequently asked questions

How do I run FFmpeg in Docker?

Use an image that has FFmpeg, or install it in your own image: FROM debian:bookworm-slim, then RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg. Mount a folder for the files and run docker run --rm -v "$PWD:/work" -w /work your-image ffmpeg -i input.mov output.mp4.

Is it cheaper to self-host FFmpeg or use an API?

It depends on volume and on how steady it is. A server that is busy most of the day is usually cheaper per minute than an API. When jobs come in bursts, an idle server still costs money, and you also pay in time to build the queue, retries, storage and monitoring. Compare your own machine cost and expected use with the API's published prices.

Is it safe to run FFmpeg on user uploads?

FFmpeg parses many complex file formats, and media parsers have had security bugs. Run it in an isolated container with no access to your other systems, limit CPU, memory, disk and time, keep FFmpeg up to date, and accept only the formats you need.

When should I self-host FFmpeg?

When you have a steady high volume, need GPUs or a custom FFmpeg build, must keep media in your own network for compliance, or run jobs longer than an API allows. For bursty or low volume, or when you do not want to run video infrastructure, an API is usually simpler.

Ready to try Xora?

Replace your local FFmpeg binaries with a secure, high-performance cloud API.