Air-Gapped Deployment
Deploy voicetyped in isolated networks with no internet connectivity.
voicetyped is designed to run in fully air-gapped environments — classified networks, regulated facilities, and infrastructure with no internet access. The offline installer bundles everything needed: binaries, models, container images, and configuration templates.
What’s Included
The air-gapped installer bundle contains:
| Component | Contents |
|---|---|
| Binaries | voice-gateway binary for linux/amd64 and linux/arm64 |
| ASR Models | Pre-downloaded whisper models (configurable) |
| TTS Voices | Pre-downloaded Piper voice models |
| Container Images | Docker/OCI images for all services (if using containers) |
| Helm Chart | Kubernetes Helm chart (if using Kubernetes) |
| Configuration | Template configuration files |
| Scripts | Installation, verification, and upgrade scripts |
| Checksums | SHA256 checksums for all files |
| Signatures | GPG signatures for integrity verification |
Creating the Bundle
On a machine with internet access, create the offline bundle:
# Download the bundle creator
curl -sSL https://get.voicetyped.com/offline-bundle.sh -o bundle.sh
chmod +x bundle.sh
# Create a full bundle with whisper-medium model
./bundle.sh create \
--models whisper-medium \
--tts-voices en_US-amy-medium \
--platform linux/amd64 \
--output voice-gateway-offline.tar.gz
# Create a minimal bundle (whisper-base, smaller download)
./bundle.sh create \
--models whisper-base \
--minimal \
--output voice-gateway-offline-minimal.tar.gz
# Create a Kubernetes bundle (includes container images)
./bundle.sh create \
--models whisper-medium,whisper-large-v3 \
--kubernetes \
--output voice-gateway-k8s-offline.tar.gz
Bundle Sizes
| Bundle Type | Models | Approximate Size |
|---|---|---|
| Minimal | whisper-base | ~300 MB |
| Standard | whisper-medium | ~2.2 GB |
| Full | whisper-medium + large-v3 | ~5.5 GB |
| Kubernetes (Standard) | whisper-medium + images | ~4 GB |
| Kubernetes (Full) | All models + images | ~8 GB |
Transfer to Air-Gapped Environment
Transfer the bundle using your approved method:
- USB drive / removable media
- Sneakernet
- Cross-domain transfer system
- Approved file transfer mechanism
Verify Integrity
After transfer, verify the bundle:
# Verify SHA256 checksum
sha256sum -c voice-gateway-offline.tar.gz.sha256
# Verify GPG signature (if available)
gpg --verify voice-gateway-offline.tar.gz.sig voice-gateway-offline.tar.gz
Single-Node Installation
# Extract the bundle
tar xzf voice-gateway-offline.tar.gz
cd voice-gateway-offline/
# Run the installer
sudo ./install.sh \
--models-dir /var/lib/voice-gateway/models \
--config-dir /etc/voice-gateway \
--no-internet
# The installer will:
# 1. Install the voice-gateway binary
# 2. Copy models to the specified directory
# 3. Generate a default configuration
# 4. Create a systemd service
# 5. Verify the installation
Installer Options
sudo ./install.sh \
--models-dir /var/lib/voice-gateway/models \ # Model storage
--config-dir /etc/voice-gateway \ # Configuration directory
--log-dir /var/log/voice-gateway \ # Log directory
--user voicegateway \ # Service user
--no-internet \ # Skip internet checks
--no-systemd \ # Don't create systemd service
--verify-only # Verify without installing
Kubernetes Installation (Air-Gapped)
Load Container Images
# Extract container images
cd voice-gateway-offline/images/
# Load into local Docker daemon
for img in *.tar; do
docker load < "$img"
done
# Or load into containerd (k3s, RKE2)
for img in *.tar; do
ctr images import "$img"
done
# Or push to an internal registry
for img in *.tar; do
# Load, tag, and push
IMAGE_NAME=$(docker load < "$img" | awk '{print $3}')
docker tag "$IMAGE_NAME" "registry.internal/$IMAGE_NAME"
docker push "registry.internal/$IMAGE_NAME"
done
Install with Helm
# Extract Helm chart
cd voice-gateway-offline/helm/
# Install with internal registry
helm install voice-gateway ./voice-gateway \
--namespace voice-gateway \
--create-namespace \
--set global.image.repository=registry.internal/voicetyped/voice-gateway \
--set speechGateway.modelStorage.existingClaim=models-pvc \
-f values-airgapped.yaml
Air-Gapped values.yaml
# values-airgapped.yaml
global:
image:
repository: registry.internal/voicetyped/voice-gateway
pullPolicy: IfNotPresent
speechGateway:
config:
model: whisper-medium
modelStorage:
enabled: true
# Pre-populate models PVC from the bundle
initContainer:
enabled: true
image: registry.internal/voicetyped/model-loader:latest
# Disable components that require internet
redis:
image:
registry: registry.internal
global:
imageRegistry: registry.internal
observability:
tracing:
enabled: false # No external OTLP endpoint
Verification
After installation, verify everything works:
# System verification
voice-gateway verify
# Expected output:
# ✓ Binary installed: /usr/local/bin/voice-gateway (v1.0.0)
# ✓ Model loaded: whisper-medium (1.5 GB)
# ✓ TTS voice loaded: en_US-amy-medium
# ✓ Configuration valid: /etc/voice-gateway/config.yaml
# ✓ SIP port available: 5060
# ✓ REST API port available: 8080
# ✓ Metrics port available: 9100
# ✓ No internet connectivity detected (expected for air-gapped)
# ✓ All checks passed
# Run a self-test (synthesizes speech, transcribes it, verifies)
voice-gateway self-test
Upgrading in Air-Gapped Environments
- Create a new bundle on an internet-connected machine
- Transfer the bundle to the air-gapped environment
- Run the upgrade:
# Extract the new bundle
tar xzf voice-gateway-offline-v1.1.0.tar.gz
cd voice-gateway-offline/
# Upgrade (preserves configuration)
sudo ./upgrade.sh \
--preserve-config \
--backup-dir /var/lib/voice-gateway/backups
# Verify the upgrade
voice-gateway verify
voice-gateway version
Considerations
No External Dependencies
In air-gapped mode, voicetyped has zero external dependencies:
- ASR models are local
- TTS voices are local
- No license server phone-home
- No telemetry or analytics
- No package manager dependencies at runtime
Model Updates
To update ASR or TTS models:
- Download new models on an internet-connected machine
- Transfer model files to the air-gapped environment
- Place in the models directory
- Update configuration and restart
Time Synchronization
Ensure the air-gapped system has accurate time (via GPS clock, NTP over local network, or manual sync). Certificate validation and log correlation depend on accurate timestamps.
Next Steps
- Security — mTLS and audit logging for classified environments
- Single-Node Deployment — detailed single-node setup
- Observability — monitoring without external services