This guide covers deploying Girard AI within a customer's own Virtual Private Cloud (VPC) for maximum control and security.
Overview
Private VPC deployment provides:
- Full network control - Deploy within your existing VPC
- No internet exposure - Application accessible only via private network
- Custom security policies - Integrate with existing firewalls and security tools
- Data sovereignty - All data remains within your infrastructure
- Compliance - Meet strict regulatory requirements (FedRAMP, ITAR, etc.)
Architecture
┌─────────────────────────────────────────────────────────────────────────────┐
│ Customer VPC (10.0.0.0/16) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Private Subnet (10.0.1.0/24) │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Girard AI │ │ Girard AI │ │ Girard AI │ │ │
│ │ │ Node 1 │ │ Node 2 │ │ Node 3 │ │ │
│ │ │ (ECS/K8s) │ │ (ECS/K8s) │ │ (ECS/K8s) │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ │ │ │ │ │ │
│ │ └─────────────────┼─────────────────┘ │ │
│ │ │ │ │
│ │ ┌──────▼──────┐ │ │
│ │ │ Internal │ │ │
│ │ │ ALB │ │ │
│ │ └──────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Database Subnet (10.0.2.0/24) │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ PostgreSQL │ │ Redis │ │ S3/Minio │ │ │
│ │ │ Primary │──│ Cluster │ │ Storage │ │ │
│ │ │ + Replica │ │ │ │ │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
│ │ NAT Gateway │ │ VPN/Direct Connect │ │
│ │ (Outbound only) │ │ (Admin access) │ │
│ └─────────────────────────┘ └─────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────┐
│ External AI APIs │
│ (via NAT Gateway) │
│ - OpenAI │
│ - Anthropic │
│ - Google AI │
└─────────────────────────┘
Deployment Options
Option 1: Kubernetes (Helm)
Best for: Organizations with existing Kubernetes infrastructure.
Prerequisites
- Kubernetes 1.28+
- Helm 3.x
- kubectl configured
- Container registry access
- PostgreSQL 15+
- Redis 7+
Installation
- Add Helm Repository
# Add Girard AI Helm repo (private)
helm repo add girardai https://charts.girardai.com --username $HELM_USER --password $HELM_PASS
helm repo update
- Create Namespace
kubectl create namespace girardai
- Create Secrets
# Create secrets for sensitive configuration
kubectl create secret generic girardai-secrets \
--namespace girardai \
--from-literal=database-url="postgresql://user:pass@postgres.internal:5432/girardai?sslmode=require" \
--from-literal=encryption-key="$(openssl rand -hex 32)" \
--from-literal=clerk-secret-key="sk_live_xxx" \
--from-literal=stripe-secret-key="sk_live_xxx" \
--from-literal=anthropic-api-key="sk-ant-xxx" \
--from-literal=openai-api-key="sk-xxx"
- Create Values File
# values-private-vpc.yaml
replicaCount: 3
image:
repository: your-registry.internal/girardai
tag: "1.0.0"
pullPolicy: IfNotPresent
imagePullSecrets:
- name: registry-credentials
# Application configuration
config:
nodeEnv: production
appUrl: https://girardai.internal.company.com
logLevel: info
# Use existing secrets
existingSecret: girardai-secrets
# Database - use external PostgreSQL
postgresql:
enabled: false
externalDatabase:
host: postgres.internal
port: 5432
database: girardai
existingSecret: girardai-secrets
existingSecretKey: database-url
# Redis - use external Redis
redis:
enabled: false
externalRedis:
host: redis.internal
port: 6379
password: ""
# Storage configuration
storage:
type: s3 # or minio for on-prem
bucket: girardai-uploads
region: us-east-1
endpoint: https://s3.internal.company.com # For MinIO
accessKeyId: ""
secretAccessKey: ""
existingSecret: girardai-s3-secrets
# Ingress - Internal only
ingress:
enabled: true
className: nginx-internal
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "100m"
hosts:
- host: girardai.internal.company.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: girardai-tls
hosts:
- girardai.internal.company.com
# Resources
resources:
requests:
cpu: "1"
memory: "2Gi"
limits:
cpu: "2"
memory: "4Gi"
# Autoscaling
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 80
# Pod Disruption Budget
podDisruptionBudget:
enabled: true
minAvailable: 2
# Service Account
serviceAccount:
create: true
annotations:
# For AWS IRSA
eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/girardai-role
# Security Context
podSecurityContext:
runAsNonRoot: true
runAsUser: 1001
fsGroup: 1001
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
# Health checks
livenessProbe:
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
# Node selector for dedicated nodes
nodeSelector:
workload: girardai
# Tolerations
tolerations:
- key: "dedicated"
operator: "Equal"
value: "girardai"
effect: "NoSchedule"
# Affinity for HA
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- girardai
topologyKey: kubernetes.io/hostname
# Network Policy
networkPolicy:
enabled: true
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
- podSelector:
matchLabels:
app: monitoring
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/8 # Internal network
- to:
- ipBlock:
cidr: 0.0.0.0/0 # External AI APIs
ports:
- protocol: TCP
port: 443
# Monitoring
metrics:
enabled: true
serviceMonitor:
enabled: true
namespace: monitoring
- Install Chart
helm install girardai girardai/girardai \
--namespace girardai \
--values values-private-vpc.yaml \
--wait
- Run Database Migrations
# Create migration job
kubectl apply -f - <<EOF
apiVersion: batch/v1
kind: Job
metadata:
name: girardai-migration
namespace: girardai
spec:
template:
spec:
containers:
- name: migrate
image: your-registry.internal/girardai:1.0.0
command: ["npx", "prisma", "migrate", "deploy"]
envFrom:
- secretRef:
name: girardai-secrets
restartPolicy: Never
backoffLimit: 3
EOF
# Wait for completion
kubectl wait --for=condition=complete job/girardai-migration -n girardai --timeout=300s
Option 2: Docker Compose (Air-Gapped)
Best for: Smaller deployments or environments without Kubernetes.
Prerequisites
- Docker 24+
- Docker Compose 2.x
- PostgreSQL 15+ (external or included)
- 8GB RAM minimum
- 50GB storage
Installation
- Download Deployment Package
# Download from secure distribution (air-gapped transfer)
tar -xzf girardai-private-vpc-1.0.0.tar.gz
cd girardai-private-vpc
- Configure Environment
# Copy and edit environment file
cp .env.example .env
# .env
NODE_ENV=production
NEXT_PUBLIC_APP_URL=https://girardai.internal.company.com
# Database
DATABASE_URL=postgresql://girardai:secure_password@postgres:5432/girardai?sslmode=require
# Encryption (generate with: openssl rand -hex 32)
ENCRYPTION_KEY=your-32-char-encryption-key
# Authentication
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_xxx
CLERK_SECRET_KEY=sk_live_xxx
CLERK_WEBHOOK_SECRET=whsec_xxx
# Payments
STRIPE_SECRET_KEY=sk_live_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_xxx
# AI Providers
ANTHROPIC_API_KEY=sk-ant-xxx
OPENAI_API_KEY=sk-xxx
# Storage (MinIO for air-gapped)
S3_ENDPOINT=http://minio:9000
S3_ACCESS_KEY=minioadmin
S3_SECRET_KEY=minioadmin
S3_BUCKET=girardai-uploads
S3_REGION=us-east-1
# Redis
REDIS_URL=redis://redis:6379
- Docker Compose Configuration
# docker-compose.yml
version: '3.8'
services:
app:
image: girardai:1.0.0
build:
context: .
dockerfile: Dockerfile
restart: always
ports:
- "3000:3000"
environment:
- NODE_ENV=production
env_file:
- .env
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
minio:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
deploy:
replicas: 3
resources:
limits:
cpus: '2'
memory: 4G
reservations:
cpus: '1'
memory: 2G
networks:
- girardai-internal
postgres:
image: postgres:15-alpine
restart: always
environment:
POSTGRES_DB: girardai
POSTGRES_USER: girardai
POSTGRES_PASSWORD: secure_password
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init-db:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", "pg_isready -U girardai -d girardai"]
interval: 10s
timeout: 5s
retries: 5
networks:
- girardai-internal
redis:
image: redis:7-alpine
restart: always
command: redis-server --appendonly yes --maxmemory 1gb --maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- girardai-internal
minio:
image: minio/minio:latest
restart: always
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
volumes:
- minio_data:/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 10s
retries: 3
networks:
- girardai-internal
nginx:
image: nginx:alpine
restart: always
ports:
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certs:/etc/nginx/certs:ro
depends_on:
- app
networks:
- girardai-internal
- girardai-external
volumes:
postgres_data:
redis_data:
minio_data:
networks:
girardai-internal:
internal: true
girardai-external:
- Nginx Configuration
# nginx.conf
events {
worker_connections 1024;
}
http {
upstream girardai {
least_conn;
server app:3000 weight=1;
}
server {
listen 443 ssl http2;
server_name girardai.internal.company.com;
ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
location / {
proxy_pass http://girardai;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
client_max_body_size 100M;
}
location /api/health {
proxy_pass http://girardai;
proxy_http_version 1.1;
access_log off;
}
}
}
- Start Services
# Start all services
docker-compose up -d
# Run migrations
docker-compose exec app npx prisma migrate deploy
# Check health
curl -k https://girardai.internal.company.com/api/health
Option 3: AWS ECS in Private Subnets
Best for: AWS-native organizations wanting managed containers without Kubernetes.
Terraform Configuration
# private-vpc-ecs.tf
# VPC with no internet gateway
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
name = "girardai-private-vpc"
cidr = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-1b", "us-east-1c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
# No public subnets - completely private
enable_nat_gateway = false
enable_vpn_gateway = false
# VPC Endpoints for AWS services
enable_s3_endpoint = true
enable_ecr_api_endpoint = true
enable_ecr_dkr_endpoint = true
enable_logs_endpoint = true
enable_secrets_endpoint = true
tags = {
Environment = "production"
Application = "girardai"
}
}
# VPC Endpoints for AWS Services
resource "aws_vpc_endpoint" "ecr_api" {
vpc_id = module.vpc.vpc_id
service_name = "com.amazonaws.us-east-1.ecr.api"
vpc_endpoint_type = "Interface"
subnet_ids = module.vpc.private_subnets
security_group_ids = [aws_security_group.vpc_endpoints.id]
private_dns_enabled = true
}
resource "aws_vpc_endpoint" "ecr_dkr" {
vpc_id = module.vpc.vpc_id
service_name = "com.amazonaws.us-east-1.ecr.dkr"
vpc_endpoint_type = "Interface"
subnet_ids = module.vpc.private_subnets
security_group_ids = [aws_security_group.vpc_endpoints.id]
private_dns_enabled = true
}
resource "aws_vpc_endpoint" "secretsmanager" {
vpc_id = module.vpc.vpc_id
service_name = "com.amazonaws.us-east-1.secretsmanager"
vpc_endpoint_type = "Interface"
subnet_ids = module.vpc.private_subnets
security_group_ids = [aws_security_group.vpc_endpoints.id]
private_dns_enabled = true
}
resource "aws_vpc_endpoint" "logs" {
vpc_id = module.vpc.vpc_id
service_name = "com.amazonaws.us-east-1.logs"
vpc_endpoint_type = "Interface"
subnet_ids = module.vpc.private_subnets
security_group_ids = [aws_security_group.vpc_endpoints.id]
private_dns_enabled = true
}
# S3 Gateway Endpoint (free)
resource "aws_vpc_endpoint" "s3" {
vpc_id = module.vpc.vpc_id
service_name = "com.amazonaws.us-east-1.s3"
}
# Internal Application Load Balancer
resource "aws_lb" "internal" {
name = "girardai-internal-alb"
internal = true
load_balancer_type = "application"
security_groups = [aws_security_group.alb.id]
subnets = module.vpc.private_subnets
enable_deletion_protection = true
tags = {
Application = "girardai"
}
}
# ECS Cluster
resource "aws_ecs_cluster" "main" {
name = "girardai-private"
setting {
name = "containerInsights"
value = "enabled"
}
configuration {
execute_command_configuration {
kms_key_id = aws_kms_key.ecs.arn
logging = "OVERRIDE"
log_configuration {
cloud_watch_encryption_enabled = true
cloud_watch_log_group_name = aws_cloudwatch_log_group.ecs.name
}
}
}
}
# ECS Service
resource "aws_ecs_service" "app" {
name = "girardai"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.app.arn
desired_count = 3
launch_type = "FARGATE"
network_configuration {
subnets = module.vpc.private_subnets
security_groups = [aws_security_group.ecs_tasks.id]
assign_public_ip = false
}
load_balancer {
target_group_arn = aws_lb_target_group.app.arn
container_name = "girardai"
container_port = 3000
}
deployment_circuit_breaker {
enable = true
rollback = true
}
deployment_configuration {
maximum_percent = 200
minimum_healthy_percent = 100
}
}
# RDS in Private Subnet
resource "aws_db_instance" "postgres" {
identifier = "girardai-db"
engine = "postgres"
engine_version = "15"
instance_class = "db.r6g.large"
allocated_storage = 100
max_allocated_storage = 500
storage_encrypted = true
kms_key_id = aws_kms_key.rds.arn
db_name = "girardai"
username = "girardai"
password = random_password.db.result
multi_az = true
db_subnet_group_name = aws_db_subnet_group.main.name
vpc_security_group_ids = [aws_security_group.rds.id]
backup_retention_period = 30
deletion_protection = true
# No public accessibility
publicly_accessible = false
performance_insights_enabled = true
monitoring_interval = 60
monitoring_role_arn = aws_iam_role.rds_monitoring.arn
}
# ElastiCache Redis in Private Subnet
resource "aws_elasticache_replication_group" "redis" {
replication_group_id = "girardai-redis"
description = "Girard AI Redis cluster"
node_type = "cache.r6g.large"
num_cache_clusters = 2
port = 6379
subnet_group_name = aws_elasticache_subnet_group.main.name
security_group_ids = [aws_security_group.redis.id]
at_rest_encryption_enabled = true
transit_encryption_enabled = true
kms_key_id = aws_kms_key.redis.arn
automatic_failover_enabled = true
multi_az_enabled = true
snapshot_retention_limit = 7
}
# Security Groups
resource "aws_security_group" "ecs_tasks" {
name = "girardai-ecs-tasks"
description = "Security group for Girard AI ECS tasks"
vpc_id = module.vpc.vpc_id
ingress {
from_port = 3000
to_port = 3000
protocol = "tcp"
security_groups = [aws_security_group.alb.id]
}
egress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [module.vpc.vpc_cidr_block]
description = "VPC Endpoints"
}
egress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.rds.id]
description = "PostgreSQL"
}
egress {
from_port = 6379
to_port = 6379
protocol = "tcp"
security_groups = [aws_security_group.redis.id]
description = "Redis"
}
}
Network Configuration
No Internet Access
For completely air-gapped deployments:
# All external API calls must go through a proxy
AI_PROXY_URL: https://ai-proxy.internal.company.com
# The proxy handles:
# - OpenAI API calls
# - Anthropic API calls
# - Google AI calls
# - Webhook callbacks
Proxy Configuration
# AI API Proxy
server {
listen 443 ssl;
server_name ai-proxy.internal.company.com;
# Only allow specific endpoints
location /v1/chat/completions {
proxy_pass https://api.openai.com;
proxy_ssl_server_name on;
proxy_set_header Authorization $http_authorization;
}
location /v1/messages {
proxy_pass https://api.anthropic.com;
proxy_ssl_server_name on;
proxy_set_header x-api-key $http_x_api_key;
}
}
VPN/Direct Connect Access
# AWS Direct Connect for hybrid connectivity
resource "aws_dx_gateway" "main" {
name = "girardai-dx-gateway"
amazon_side_asn = "64512"
}
resource "aws_dx_gateway_association" "main" {
dx_gateway_id = aws_dx_gateway.main.id
associated_gateway_id = aws_vpn_gateway.main.id
}
Security Hardening
Network Segmentation
┌─────────────────────────────────────────────────────────────┐
│ Security Zones │
├─────────────────────────────────────────────────────────────┤
│ │
│ DMZ (Optional) │
│ ├── Reverse Proxy / WAF │
│ └── Load Balancer │
│ │
│ Application Zone │
│ ├── Girard AI Application Nodes │
│ └── Background Workers │
│ │
│ Data Zone │
│ ├── PostgreSQL │
│ ├── Redis │
│ └── Object Storage │
│ │
│ Management Zone │
│ ├── Monitoring │
│ ├── Logging │
│ └── Bastion Host │
│ │
└─────────────────────────────────────────────────────────────┘
Encryption
# All encryption keys managed by customer
encryption:
# Database encryption
database:
at_rest: AES-256 (customer KMS)
in_transit: TLS 1.3
# Storage encryption
storage:
at_rest: AES-256 (customer KMS)
in_transit: TLS 1.3
# Application secrets
secrets:
provider: HashiCorp Vault / AWS Secrets Manager
rotation: 90 days
Access Control
# Role-based access to infrastructure
roles:
admin:
- Full access via bastion host
- Requires MFA
- Session recording enabled
operator:
- Read-only access to logs/metrics
- Cannot access data stores directly
auditor:
- Read-only access to audit logs
- Compliance report generation
Monitoring
Internal Monitoring Stack
# docker-compose-monitoring.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
networks:
- girardai-internal
grafana:
image: grafana/grafana:latest
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/dashboards:/etc/grafana/provisioning/dashboards
networks:
- girardai-internal
alertmanager:
image: prom/alertmanager:latest
volumes:
- ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
networks:
- girardai-internal
loki:
image: grafana/loki:latest
volumes:
- loki_data:/loki
networks:
- girardai-internal
volumes:
prometheus_data:
grafana_data:
loki_data:
Metrics Exported
# Application metrics
- http_request_duration_seconds
- http_requests_total
- ai_generation_duration_seconds
- ai_tokens_used_total
- database_query_duration_seconds
- cache_hit_ratio
# Infrastructure metrics
- container_cpu_usage_seconds_total
- container_memory_usage_bytes
- container_network_receive_bytes_total
Backup & Recovery
Backup Strategy
# Database backup (daily)
pg_dump -h postgres -U girardai -Fc girardai > backup-$(date +%Y%m%d).dump
# Encrypt backup
gpg --encrypt --recipient backup@company.com backup-$(date +%Y%m%d).dump
# Transfer to secure storage
aws s3 cp backup-$(date +%Y%m%d).dump.gpg s3://company-backups/girardai/
Recovery Procedure
# Download backup
aws s3 cp s3://company-backups/girardai/backup-20260122.dump.gpg .
# Decrypt
gpg --decrypt backup-20260122.dump.gpg > backup.dump
# Restore
pg_restore -h postgres -U girardai -d girardai backup.dump
Maintenance
Updates
# Pull new version
docker pull your-registry.internal/girardai:1.1.0
# Rolling update (Kubernetes)
kubectl set image deployment/girardai girardai=your-registry.internal/girardai:1.1.0 -n girardai
# Rolling update (Docker Compose)
docker-compose up -d --no-deps app
Database Migrations
# Always backup first
pg_dump -h postgres -U girardai -Fc girardai > pre-migration-backup.dump
# Run migrations
docker-compose exec app npx prisma migrate deploy
# Verify
docker-compose exec app npx prisma migrate status
Troubleshooting
Common Issues
| Issue | Cause | Solution |
|---|---|---|
| Cannot pull images | No registry access | Configure registry mirror or pre-pull images |
| Database connection timeout | Network policy | Check security groups allow port 5432 |
| AI API errors | No internet access | Configure AI proxy |
| Slow performance | Insufficient resources | Scale up nodes or increase limits |
Health Checks
# Application health
curl -k https://girardai.internal/api/health
# Database connectivity
docker-compose exec app npx prisma db execute --stdin <<< "SELECT 1"
# Redis connectivity
docker-compose exec redis redis-cli ping
Support
For private VPC deployments, contact:
- Technical Support: support@girardai.com
- Professional Services: ps@girardai.com
- Emergency: +1-800-GIRARD-AI
Last updated: January 22, 2026