Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { withMediaTransfers } from "../../lib/media-transfer";
import { processVideo } from "../../lib/media-video";
import {
getActiveDirectVideoProcessCount,
getMaxConcurrentDirectVideoProcesses,
tryAcquireDirectVideoProcessSlot,
} from "../../lib/video-capacity";

Expand Down Expand Up @@ -238,15 +239,18 @@ describe("local audio levels integration", () => {
expect(objects.publications()).toBe(0);
});
test("leaves an occupied conversion slot available to its current owner", async () => {
const slot = tryAcquireDirectVideoProcessSlot(() => true);
expect(slot).not.toBeNull();
const max = getMaxConcurrentDirectVideoProcesses();
const slots = Array.from({ length: max }, () =>
tryAcquireDirectVideoProcessSlot(() => true),
);
expect(slots.every((slot) => slot !== null)).toBe(true);
try {
const objects = storage();
expect(await call()).toEqual({ status: "unchanged", reason: "capacity" });
expect(objects.preparations()).toBe(0);
expect(getActiveDirectVideoProcessCount()).toBe(1);
expect(getActiveDirectVideoProcessCount()).toBe(max);
} finally {
slot?.release();
for (const slot of slots) slot?.release();
}
});
test("cancels optional work on shutdown and releases its processing slot", async () => {
Expand Down
13 changes: 13 additions & 0 deletions apps/web/content/docs/self-hosting.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,19 @@ By default, login links are printed to the server logs. To send emails:
RESEND_FROM_DOMAIN=yourdomain.com
```

## Media Server Tuning

The media server allows one direct video conversion at a time by default. It still turns work away when CPU or memory pressure is high. To raise the limit after measuring CPU and memory usage on your deployment, add these values to `.env` in the bundled Compose deployments (the media-server service forwards them):

```bash
MEDIA_SERVER_MAX_CONCURRENT_DIRECT_CONVERSIONS=2 # direct /video/convert requests
MEDIA_SERVER_MAX_CONCURRENT_VIDEO_PROCESSES=4 # all video jobs
```

Apply changes with `docker compose up -d --force-recreate media-server`. With `docker-compose.template.yml`, use `docker compose -f docker-compose.template.yml up -d --force-recreate cap-media-server`. In Coolify, update the environment variables and redeploy the `media-server` service. For a custom Compose file, also add these variables to the media-server service’s `environment` mapping; `.env` alone does not pass variables into a container.

On `docker compose stop` the media server stops taking new work and lets active work finish for up to `MEDIA_SERVER_SHUTDOWN_GRACE_MS` (25s in the bundled compose files). It then cancels what is left and sends each cancelled job's webhook: an attempt already in flight can take up to 5s, then up to 3 tries of 5s with 1.5s of backoff (16.5s). That is 46.5s before cleanup, so the compose files set `stop_grace_period: 60s`. If you raise the grace period, raise `stop_grace_period` by the same amount, or Docker kills the container before it finishes.

## Optional Features

### AI Features
Expand Down
8 changes: 8 additions & 0 deletions docker-compose.coolify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,15 @@ services:
media-server:
image: 'ghcr.io/capsoftware/cap-media-server:latest'
restart: unless-stopped
# Shutdown budget: up to 25s drain (MEDIA_SERVER_SHUTDOWN_GRACE_MS), then
# cancel webhooks for aborted jobs (an in-flight attempt finishes first, up
# to 5s, then 3 tries x 5s + 1.5s backoff = 16.5s), then cleanup.
# 25 + 5 + 16.5 = 46.5s, so 60s leaves ~13s for cleanup before SIGKILL.
stop_grace_period: 60s
environment:
MEDIA_SERVER_SHUTDOWN_GRACE_MS: '25000'
MEDIA_SERVER_MAX_CONCURRENT_DIRECT_CONVERSIONS: ${MEDIA_SERVER_MAX_CONCURRENT_DIRECT_CONVERSIONS:-0}
MEDIA_SERVER_MAX_CONCURRENT_VIDEO_PROCESSES: ${MEDIA_SERVER_MAX_CONCURRENT_VIDEO_PROCESSES:-0}
PORT: 3456
MEDIA_SERVER_WEBHOOK_SECRET: '${SERVICE_HEX_32_MEDIASERVER}'
healthcheck:
Expand Down
8 changes: 8 additions & 0 deletions docker-compose.template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,15 @@ services:
context: ./apps/media-server
dockerfile: Dockerfile.standalone
restart: unless-stopped
# Shutdown budget: up to 25s drain (MEDIA_SERVER_SHUTDOWN_GRACE_MS), then
# cancel webhooks for aborted jobs (an in-flight attempt finishes first, up
# to 5s, then 3 tries x 5s + 1.5s backoff = 16.5s), then cleanup.
# 25 + 5 + 16.5 = 46.5s, so 60s leaves ~13s for cleanup before SIGKILL.
stop_grace_period: 60s
environment:
MEDIA_SERVER_SHUTDOWN_GRACE_MS: "25000"
MEDIA_SERVER_MAX_CONCURRENT_DIRECT_CONVERSIONS: ${MEDIA_SERVER_MAX_CONCURRENT_DIRECT_CONVERSIONS:-0}
MEDIA_SERVER_MAX_CONCURRENT_VIDEO_PROCESSES: ${MEDIA_SERVER_MAX_CONCURRENT_VIDEO_PROCESSES:-0}
PORT: 3456
MEDIA_SERVER_WEBHOOK_SECRET: fe337b52749070bb7b5d2c78cff9948439ea73cbc1869ba39d350e6c24db53b1
ports:
Expand Down
8 changes: 8 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,15 @@ services:
context: ./apps/media-server
dockerfile: Dockerfile.standalone
restart: unless-stopped
# Shutdown budget: up to 25s drain (MEDIA_SERVER_SHUTDOWN_GRACE_MS), then
# cancel webhooks for aborted jobs (an in-flight attempt finishes first, up
# to 5s, then 3 tries x 5s + 1.5s backoff = 16.5s), then cleanup.
# 25 + 5 + 16.5 = 46.5s, so 60s leaves ~13s for cleanup before SIGKILL.
stop_grace_period: 60s
environment:
MEDIA_SERVER_SHUTDOWN_GRACE_MS: "25000"
MEDIA_SERVER_MAX_CONCURRENT_DIRECT_CONVERSIONS: ${MEDIA_SERVER_MAX_CONCURRENT_DIRECT_CONVERSIONS:-0}
MEDIA_SERVER_MAX_CONCURRENT_VIDEO_PROCESSES: ${MEDIA_SERVER_MAX_CONCURRENT_VIDEO_PROCESSES:-0}
PORT: 3456
MEDIA_SERVER_WEBHOOK_SECRET: ${MEDIA_SERVER_WEBHOOK_SECRET:-fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210}
healthcheck:
Expand Down
Loading