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:

ComponentContents
Binariesvoice-gateway binary for linux/amd64 and linux/arm64
ASR ModelsPre-downloaded whisper models (configurable)
TTS VoicesPre-downloaded Piper voice models
Container ImagesDocker/OCI images for all services (if using containers)
Helm ChartKubernetes Helm chart (if using Kubernetes)
ConfigurationTemplate configuration files
ScriptsInstallation, verification, and upgrade scripts
ChecksumsSHA256 checksums for all files
SignaturesGPG 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 TypeModelsApproximate Size
Minimalwhisper-base~300 MB
Standardwhisper-medium~2.2 GB
Fullwhisper-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

  1. Create a new bundle on an internet-connected machine
  2. Transfer the bundle to the air-gapped environment
  3. 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:

  1. Download new models on an internet-connected machine
  2. Transfer model files to the air-gapped environment
  3. Place in the models directory
  4. 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