Air-gapped installation

An air-gapped install has no cloud API keys. Users should see the Ollama models you pulled, plus local Whisper for speech-to-text and Piper for spoken answers — and nothing that would call out to the internet.

The catalog is still seeded in full. Rows for providers with no key stay hidden from users. Saving a key later would surface that provider immediately, which is why the Helm allow-list below also soft-disables every provider you did not name.


1. Point at an Ollama you already filled

Pull the models on the Ollama host before people sign in. A model that is not pulled is hidden from users (administrators see it badged Not pulled).

ollama pull bge-m3
ollama pull llama3.2:3b

Then set the URL the backend can reach:

OLLAMA_BASE_URL=http://ollama:11434

With Docker Compose, the local-ai profile starts a bundled Ollama and can download bge-m3 (and, if you opt in, a local chat model) on first start. On a network with no route to the model registry, that download cannot run — pull the models on a connected machine and copy the Ollama data volume, or point OLLAMA_BASE_URL at an Ollama that already has them. Import what it lists under Operate → AI infrastructure → Models & keys → Local AI → Import pulled models. Details: Local AI.

2. Keep browser speech on the server

Chrome's Web Speech API sends audio to Google. Turn it off so the microphone records and the server transcribes:

WEB_SPEECH_ENABLED=false

Local speech-to-text is the catalog model Whisper (local). It is available when WHISPER_ENABLED is on (the image default) and the whisper.cpp binary plus the model file named by WHISPER_DEFAULT_MODEL (tiny, base, small, medium, or large) are present. The local-ai Compose profile turns Whisper on. Firefox and every other browser then use the same record-and-upload path.

Spoken answers stay local when Piper answers at SYNAPLAN_TTS_URL. See Text-to-Speech.

3. Lock the catalog to those providers

Hiding follows credentials on its own: with no cloud keys, users already see only the local models. The allow-list is the extra lock, so a key pasted later — or a cloud provider added in a future release — does not appear until you opt in.

Kubernetes. Install with the overlay examples/values-airgap.yaml (synaplan 4.3.6 or newer):

helm install synaplan ./charts/synaplan -f examples/values-airgap.yaml

It sets models.providers.only to ollama, piper, and whisper, blanks the default Triton URL, and sets WEB_SPEECH_ENABLED=false. Replace ollama.baseUrl in that file with your service address. only cannot be combined with models.providers.enabled or models.providers.disabled.

Compose or a shell on the server:

php bin/console app:model:enable --only ollama --only piper --only whisper

Disable is soft: rows stay in the database (BACTIVE=0, BSELECTABLE=0) and survive the next app:seed. Re-enable a provider with app:model:enable --provider <name> when you do want it.

4. Check the result

php bin/console app:provider:list --fresh

Ollama, Whisper, and Piper should read as available. Cloud providers should read as not available, or as soft-disabled if you applied the allow-list. Sign in as a regular user and open the model picker: the pulled Ollama models and local Whisper are there. Sign in as an administrator and open Manage → Assistants → Models: the rest of the catalog is still listed, greyed, with Provider not configured or Not pulled.

How the filter works in general, including the case where you do want a cloud key: AI providers & models.