Symptoms
After upgrading Docker to stable-11146, old branding or UI overrides appear to vanish. Issue #2291 reports a missing custom home-page title. It does not establish a universal error message. The reporter’s custom content was already appended to the generated interface file, and the web logs did not explain the failure. [S1]
Do not treat a missing title alone as proof that the files were ignored. Confirm the served content first, as the maintainer requested. [S1]
Cause
PR #2258 changed containers to the unprivileged s6 user, UID/GID 1000, and moved runtime configuration away from the host-mounted input directory. Writable storage needs UID 1000 access; input files need to be readable by that user. Changing the host username does not change these numeric container IDs. [S2]
In both checked Docker tags, startup copies /config/. into /run/web/config, generates config.js, then appends custom-config.js. It also appends custom-interface_config.js to interface_config.js. Nginx serves the generated files. A stale host-side config.js is therefore not evidence of what clients receive. [S4][S5]
The reporter rewrote the interface customization and recovered. The maintainer agreed that a missing comment opener could explain it. This remains a possible syntax error, not a confirmed rootless regression. No fix release or PR was identified for #2291 as of 2026-10-05. fixed_in is n/a because no upstream defect was established. stable-11248, published 2026-09-14, is still the latest release checked on that date. [S1][S6]
Fix
Docker first: stable-11146 and stable-11248
-
Locate the actual input directory. Work from your existing Compose project. Read
CONFIGin.env; the default is~/.jitsi-meet-cfg. Put the files in itswebsubdirectory, not directly in the parent. The Compose mount maps${CONFIG}/webto/config. [S3][S5]Default host paths: [S3]
Text~/.jitsi-meet-cfg/web/custom-config.js ~/.jitsi-meet-cfg/web/custom-interface_config.js -
Give UID 1000 access. On a Linux host using that default directory, run this for each file that exists. These commands set owner/group 1000 and owner-readable mode 0644; parent directories also need traversal access. Custom inputs do not need world-write permissions. Substitute your actual
CONFIGpath if different. [S2][S13]Terminalsudo chown 1000:1000 ~/.jitsi-meet-cfg/web/custom-config.js sudo chmod 0644 ~/.jitsi-meet-cfg/web/custom-config.js sudo chown 1000:1000 ~/.jitsi-meet-cfg/web/custom-interface_config.js sudo chmod 0644 ~/.jitsi-meet-cfg/web/custom-interface_config.jsOwnership is one way to grant access, not a reason to recursively change unrelated host data. The rootless migration separately requires writable storage directories. [S2]
-
Prefer supported
.envcontrols. The following mappings exist in both checked tags. Move these settings out of old interface overrides and use one source of truth. This is a maintenance recommendation, not a new requirement to abandon custom files. [S7]Setting Docker variable Generated key Prejoin ENABLE_PREJOIN_PAGEconfig.prejoinConfig.enabledWelcome page ENABLE_WELCOME_PAGEconfig.welcomePage.disabled, invertedToolbar TOOLBAR_BUTTONSconfig.toolbarButtonsInitially mute audio START_WITH_AUDIO_MUTEDconfig.startWithAudioMutedInitially mute video START_WITH_VIDEO_MUTEDconfig.startWithVideoMutedExample
.enventries, merge into your existing file: [S7]dotenvENABLE_PREJOIN_PAGE=1 ENABLE_WELCOME_PAGE=1 START_WITH_AUDIO_MUTED=1 START_WITH_VIDEO_MUTED=0 TOOLBAR_BUTTONS=microphone,camera,desktop,chat,hangup -
Keep remaining overrides small. For a setting without a suitable Docker variable, use assignments to the existing object. Avoid copying an entire old configuration. Startup appends this code last, so later assignments win. [S4]
Example content for
custom-config.js: [S4][S7]JavaScriptconfig.startWithAudioMuted = true;This demonstrates the syntax; prefer its
.envequivalent above. For the application name,APP_NAMEstill exists in Jitsi Meet’s interface file at release 11248. Example content forcustom-interface_config.js: [S14]JavaScriptinterfaceConfig.APP_NAME = 'Example Meetings';The upstream interface file is deprecated and explicitly says toolbar buttons moved to
config.js. Deprecation does not mean every interface option stopped working. Do not assumeAPP_NAMEcontrols every visible heading. [S14] -
Recreate the web container. This reruns generation and applies changed environment values. Use the same Compose files and project selection as your normal deployment. [S4][S9]
Terminaldocker compose up -d --no-deps --force-recreate web
Debian/Ubuntu packages: Jitsi Meet 2.0.11248
The Docker custom-file append mechanism and UID 1000 migration do not apply. The package installer creates a domain-specific configuration, and the Nginx template serves that file. For meet.example.com, append a small assignment after the existing configuration, with a backup first. [S8][S13]
sudo cp -p /etc/jitsi/meet/meet.example.com-config.js /etc/jitsi/meet/meet.example.com-config.js.bak
printf '\nconfig.startWithAudioMuted = true;\n' | sudo tee -a /etc/jitsi/meet/meet.example.com-config.jsThe key exists in upstream configuration. Packages install the interface file at /usr/share/jitsi-meet/interface_config.js; edit that file for APP_NAME, not a Docker custom file. Recheck package-owned customizations after upgrades. [S8][S14]
Verify
For either install type, request the served JavaScript. These commands use curl’s documented failure, header and output options. [S1][S5][S8][S10]
curl -fsS https://meet.example.com/config.js
curl -fsS https://meet.example.com/interface_config.jsFor the custom examples, find these exact lines, including any later assignment that could replace them: [S4][S14]
config.startWithAudioMuted = true;
interfaceConfig.APP_NAME = 'Example Meetings';Their presence proves delivery of the assignments, not successful execution. In browser DevTools, select Network, enable Disable cache, reload, and inspect each response. Check the Console for JavaScript errors. Confirm the intended UI behavior too. [S11]
If a CDN fronts the server, compare against the origin while keeping HTTPS hostname validation. Replace the example IP with your origin address. [S10]
curl -fsS --resolve meet.example.com:443:203.0.113.10 https://meet.example.com/config.jsIf origin and public responses differ, investigate the proxy/cache route. Cloudflare supports purging individual URLs; purge both configuration URLs when cached. Disabling browser cache does not purge a CDN. [S10][S11][S12]
If it still fails
For both checked Docker tags, inspect input and generated files, then the web startup logs. [S1][S4][S9]
docker compose exec web ls -ln /config /run/web/config
docker compose exec web cat /run/web/config/config.js
docker compose exec web cat /run/web/config/interface_config.js
docker compose logs --tail 200 webMissing input suggests a mount/path problem. Input present but absent from generated output suggests a generation problem. Correct HTTP content with broken behavior suggests syntax, obsolete keys or a later override. These are diagnostic inferences from the loading sequence, not guaranteed error signatures. [S4]
For packages, verify the domain-specific file and Nginx mapping; the template uses /var/log/nginx/access.log for requests. A successful request alone does not prove JavaScript execution. [S8][S11]
FAQ
Were custom files removed in stable-11146?
No. The checked startup scripts still append both files. [S4]
Why does editing the host config.js do nothing?
Docker generates a new runtime file on startup. Edit custom inputs or supported environment variables instead. [S4]
Must every setting move to .env?
No. Prefer available variables; use small custom assignments for other supported keys. [S4][S7]
Is changing ownership enough?
No. Readability, correct mounts, valid JavaScript and fresh HTTP responses must all agree. #2291 already had appended content before it recovered. [S1][S4][S11]
Sources
[S1] Issue #2291 and discussion, August 2026, community report and maintainer comments.
[S2] PR #2258 Rootless containers, merged 2026-06-19, maintainer comment and source code.
[S3] Docker handbook, configuration files, checked 2026-10-05, official doc.
[S4] Web startup scripts: stable-11146, stable-11248, checked 2026-10-05, source code.
[S5] Compose mounts and Nginx mappings, checked 2026-10-05, source code.
[S6] Latest release API and stable-11248, 2026-09-14, checked 2026-10-05, release note.
[S7] Settings templates: stable-11146, stable-11248, checked 2026-10-05, source code.
[S8] Package installer, file manifest, config and Nginx template, release 11248, checked 2026-10-05, source code.
[S9] Docker Compose up, exec, logs, checked 2026-10-05, official doc.
[S10] curl manual, checked 2026-10-05, official doc.
[S11] Chrome DevTools Network reference and Console, checked 2026-10-05, official doc.
[S12] Cloudflare purge by URL, checked 2026-10-05, official doc.
[S13] GNU Coreutils manual, checked 2026-10-05, official doc, ownership, modes, copying and text output.
[S14] interface_config.js at release 11248, checked 2026-10-05, source code.
Open questions
The precise syntax failure in #2291 was never demonstrated. These instructions were checked against sources, not exercised on a real Jitsi server. Verify title behavior on your installed frontend, and inspect the actual browser-requested configuration URL when using subdomains or a custom proxy. [S1][S5][S14]