@@ -15,7 +15,7 @@ services:
1515 - NEXT_PUBLIC_VIDEO_EXPORT_CTA_DESTINATION=${NEXT_PUBLIC_VIDEO_EXPORT_CTA_DESTINATION:-}
1616 - NEXT_PUBLIC_ENABLE_PPTX_IMPORT=${NEXT_PUBLIC_ENABLE_PPTX_IMPORT:-}
1717 ports :
18- - " 3000:3000"
18+ - ' 3000:3000'
1919 env_file :
2020 - .env.local
2121 environment :
@@ -49,7 +49,7 @@ services:
4949 # before using the stack outside a local trusted environment.
5050 - POSTGRES_PASSWORD=${PERSISTENCE_POSTGRES_PASSWORD:-openmaic-dev}
5151 healthcheck :
52- test : [" CMD-SHELL", " pg_isready -U openmaic -d openmaic" ]
52+ test : [' CMD-SHELL', ' pg_isready -U openmaic -d openmaic' ]
5353 interval : 5s
5454 timeout : 5s
5555 retries : 10
@@ -76,26 +76,35 @@ services:
7676 profiles :
7777 - video-export
7878 expose :
79- - " 9000"
79+ - ' 9000'
8080 # Required for the entrypoint's iptables egress lockdown. Without it the
8181 # service still boots, but logs a warning and does NOT block Chromium egress.
8282 cap_add :
8383 - NET_ADMIN
8484 environment :
8585 - PORT=9000
86- # Use Chromium's HeadlessExperimental.beginFrame capture path instead of
87- # the CPU-bound Page.captureScreenshot fallback. The default "software" GPU
88- # mode (SwiftShader) silently force-enables screenshot capture, which pegs
89- # all cores on CPU rasterization and caps throughput at ~10 fps. Selecting
90- # "hardware" keeps beginFrame active — measured ~2x capture throughput
91- # (~10 -> ~19 fps, 900-frame clip 100s -> 62s), roughly half the CPU, and
92- # pixel-identical static frames (animation frames differ only in sub-pixel
93- # edge antialiasing). No real GPU is required: the win is the faster capture
94- # API, not hardware rasterization — beginFrame falls back gracefully if the
95- # host lacks a GPU.
86+ # Keep the beginFrame-capable browser path available when producer decides
87+ # the cgroup has enough memory. Under this service's 4 GiB limit producer's
88+ # automatic low-memory profile safely selects screenshot capture + one
89+ # worker instead of multiplying Chromium for unvalidated 1080p/4K renders.
9690 - PRODUCER_BROWSER_GPU_MODE=hardware
97- # Tune for the host; each concurrent render drives a full Chromium + FFmpeg.
98- - RENDER_MAX_CONCURRENCY=2
91+ - PRODUCER_HEADLESS_SHELL_PATH=/usr/bin/chromium-headless-shell
92+ - RENDER_MAX_CONCURRENCY=1
93+ - RENDER_MAX_CONCURRENT_EXTRACTIONS=1
94+ # Producer's browser pool shares a Chromium compositor across capture
95+ # sessions. Keep it disabled so an operator who raises memory and opts into
96+ # parallel capture gets independent browsers; the 4 GiB default resolves to
97+ # one worker, so this does not multiply memory by itself.
98+ - PRODUCER_ENABLE_BROWSER_POOL=false
99+ # Leave producer workers unset: producer 0.7.60 applies its cgroup memory,
100+ # CPU, small-job, low-memory, and capture-cost guards. Operators may opt
101+ # into the measured 720p latency profile documented in the service README.
102+ # Long compositions still need CDP headroom even with one adaptive worker.
103+ - PRODUCER_PUPPETEER_PROTOCOL_TIMEOUT_MS=900000
104+ # OpenMAIC's long slide exports currently exhaust producer's 15s static
105+ # verification budget and disable dedup anyway. Skip that guaranteed-lost
106+ # startup cost until the verifier can share/scale its plan across workers.
107+ - HF_STATIC_DEDUP=false
99108 # In this default topology the app is exposed directly and does NOT set
100109 # TRUST_PROXY_HEADERS, so every caller collapses to one identity. A
101110 # per-identity limit would then throttle the whole deployment to a single
@@ -107,6 +116,9 @@ services:
107116 # heavy, and extraction is capped separately (RENDER_MAX_CONCURRENT_EXTRACTIONS).
108117 # Raise for higher RENDER_MAX_CONCURRENCY / larger classrooms.
109118 mem_limit : 4g
119+ # Chromium media/frame work can exceed Docker's 64 MiB default shared-memory
120+ # mount. This is a ceiling inside the same 4 GiB cgroup, not eager allocation.
121+ shm_size : 2gb
110122 networks :
111123 - render
112124 restart : unless-stopped
0 commit comments