Installation Guide
Deploy Align on your Kubernetes cluster.
Getting the Helm Chart
Align's chart and images are served from a private, credentialed OCI registry. The registry host, and the credentials that reach it, are issued to you at onboarding alongside your license. There is no public Align registry to pull from anonymously.
These pages write $ALIGN_REGISTRY for that host. Set it once and the examples below work
as written:
export ALIGN_REGISTRY="<the registry host issued to you at onboarding>"
export ALIGN_REGISTRY_REGION="<the region issued to you at onboarding>"
export ALIGN_CHART_VERSION="<the chart version for your release>"
export ALIGN_VERSION="<the release tag for your release, e.g. v0.22.26>"
Authenticate to the registry
Do this first. Every helm and docker command on this page pulls from a private registry,
and without credentials the very first one fails with a 401 rather than anything that names
the cause.
The registry is AWS ECR, and onboarding grants your AWS account pull access to it. One token serves both clients:
# Helm, for the chart
aws ecr get-login-password --region "$ALIGN_REGISTRY_REGION" | \
helm registry login "$ALIGN_REGISTRY" --username AWS --password-stdin
# Docker, for the images - only needed if you are mirroring (Option B below)
aws ecr get-login-password --region "$ALIGN_REGISTRY_REGION" | \
docker login "$ALIGN_REGISTRY" --username AWS --password-stdin
These are your credentials, so that your machine can pull. They are a different thing
from the imagePullSecrets created further down this page, which are what let the
cluster pull images at runtime. You need both, and neither substitutes for the other.
ECR tokens are short-lived, so re-run the login if a pull starts returning 401 partway through an upgrade.
Your onboarding pack names both versions above. To see what the registry actually holds:
helm show chart oci://$ALIGN_REGISTRY/align/charts/align # omit --version to take the latest
Option A: OCI Registry (Recommended)
# Pull the chart
helm pull oci://$ALIGN_REGISTRY/align/charts/align --version "$ALIGN_CHART_VERSION"
# Or install directly
helm install align \
oci://$ALIGN_REGISTRY/align/charts/align \
--version "$ALIGN_CHART_VERSION" \
--namespace align \
--values values.yaml
For production deployments, we recommend mirroring artifacts to your own registry (Option B below).
Option B: Mirror to Your Registry (Recommended for Production)
For production deployments, we recommend mirroring all artifacts to your own registry. This provides:
- Reliability - No dependency on Align's infrastructure
- Security - Full control over what runs in your cluster
- Compliance - Artifacts scanned by your security tools
- Air-gap support - Works in isolated environments
Step 1: Mirror the Helm Chart
# Pull the chart from Align's registry
helm pull oci://$ALIGN_REGISTRY/align/charts/align --version "$ALIGN_CHART_VERSION"
# Push to your registry (choose your cloud provider)
helm push "align-${ALIGN_CHART_VERSION}.tgz" oci://your-registry/align/charts
Step 2: Mirror Docker Images
All images for a release use the same version tag:
VERSION="$ALIGN_VERSION"
SOURCE_REGISTRY="$ALIGN_REGISTRY/align"
# Set your target registry based on your cloud:
# AWS ECR: TARGET_REGISTRY="123456789.dkr.ecr.us-east-1.amazonaws.com/align"
# Azure ACR: TARGET_REGISTRY="myregistry.azurecr.io/align"
# GCP: TARGET_REGISTRY="us-docker.pkg.dev/my-project/align"
# Docker Hub: TARGET_REGISTRY="docker.io/myorg/align"
TARGET_REGISTRY="your-registry/align"
IMAGES=(
"gateway"
"brain"
"ui"
"migrations"
"connector-slack"
"connector-github"
"connector-jira"
"connector-teams"
"connector-align"
)
for image in "${IMAGES[@]}"; do
docker pull "${SOURCE_REGISTRY}/${image}:${VERSION}"
docker tag "${SOURCE_REGISTRY}/${image}:${VERSION}" "${TARGET_REGISTRY}/${image}:${VERSION}"
docker push "${TARGET_REGISTRY}/${image}:${VERSION}"
done
Step 3: Configure Helm to Use Your Registry
# values.yaml
global:
# Your container registry ROOT - not including the `align/` path segment, which the
# chart already carries in each image's repository. The mirror step above pushes to
# ${TARGET_REGISTRY}/<image>, so `your-registry` here resolves to
# `your-registry/align/gateway`, which is exactly where the mirror put it.
# AWS ECR: imageRegistry: "123456789.dkr.ecr.us-east-1.amazonaws.com"
# Azure ACR: imageRegistry: "myregistry.azurecr.io"
# GCP: imageRegistry: "us-docker.pkg.dev/my-project"
imageRegistry: your-registry
# Registry authentication (if required)
imagePullSecrets:
- name: registry-credentials
Creating Registry Pull Secrets
AWS ECR
# Create secret with ECR credentials
kubectl create secret docker-registry ecr-credentials \
--namespace align \
--docker-server=123456789.dkr.ecr.us-east-1.amazonaws.com \
--docker-username=AWS \
--docker-password=$(aws ecr get-login-password --region us-east-1)
Or use ECR credential helper with IRSA.
Azure ACR
# Create secret with ACR credentials
kubectl create secret docker-registry acr-credentials \
--namespace align \
--docker-server=myregistry.azurecr.io \
--docker-username=<service-principal-id> \
--docker-password=<service-principal-password>
Or use ACR with AKS managed identity.
Google Artifact Registry
# Create secret with GCP credentials
kubectl create secret docker-registry gcr-credentials \
--namespace align \
--docker-server=us-docker.pkg.dev \
--docker-username=_json_key \
--docker-password="$(cat service-account-key.json)"
Or use Workload Identity.
Align is distributed as signed container images and a Helm chart from Align's private registry - source code is never distributed. Licensing is validated locally with an offline JWT license file. See Licensing for details.
Prerequisites
Before you begin, ensure you have:
- Kubernetes 1.25+ cluster (EKS, AKS, GKE, or self-managed)
- Helm 3.10+
-
kubectlconfigured for your cluster - PostgreSQL 15+ database with pgvector extension:
- AWS: RDS PostgreSQL or Aurora PostgreSQL
- Azure: Azure Database for PostgreSQL Flexible Server
- GCP: Cloud SQL for PostgreSQL
- Self-hosted: PostgreSQL with pgvector installed
- Ingress controller (Traefik, nginx, or cloud-native like ALB/Application Gateway)
- (Recommended) cert-manager for TLS
Step 1: Create Namespace
kubectl create namespace align
Step 2: Configure Database
Option A: Use Existing PostgreSQL (Recommended)
Create a secret with your database credentials:
kubectl create secret generic align-database \
--namespace align \
--from-literal=url="postgresql://user:password@host:5432/align" \
--from-literal=host="your-db-host.example.com" \
--from-literal=port="5432" \
--from-literal=username="align" \
--from-literal=password="your-secure-password"
Option B: Deploy PostgreSQL in Cluster
For development/testing, you can deploy PostgreSQL alongside Align:
# values.yaml
postgresql:
enabled: true
auth:
database: align
username: align
password: your-secure-password
In-cluster PostgreSQL is not recommended for production. Use a managed database service:
- AWS: RDS PostgreSQL or Aurora PostgreSQL
- Azure: Azure Database for PostgreSQL Flexible Server
- GCP: Cloud SQL for PostgreSQL
Step 3: Configure Secrets
Align requires several secrets for operation. See Secrets Management for detailed options.
Minimal Secrets
At minimum, create internal secrets:
kubectl create secret generic align-internal \
--namespace align \
--from-literal=jwt-secret="$(openssl rand -base64 32)" \
--from-literal=cookie-secret="$(openssl rand -base64 32)" \
--from-literal=encryption-key="$(openssl rand -base64 32)" \
--from-literal=service-auth-token="$(openssl rand -base64 32)"
LLM Secrets (Required for AI features)
kubectl create secret generic align-llm \
--namespace align \
--from-literal=openai-api-key="sk-..." \
# OR
--from-literal=anthropic-api-key="sk-ant-..."
Or see LLM Setup for self-hosted models.
Step 4: Create Values File
Create a values.yaml file for your deployment:
# values.yaml
global:
environment: production
# REQUIRED. The registry root your images come from - the Align registry host issued at
# onboarding, or your own registry once you have mirrored our images into it. The chart
# refuses to render if this is unset: an empty value would produce a bare image name, and
# Docker resolves a bare name against Docker Hub rather than anywhere Align controls.
imageRegistry: "<your ALIGN_REGISTRY, or your own registry root>"
# Database
database:
secretName: align-database
# Gateway
gateway:
replicaCount: 2
frontendUrl: "https://app.yourdomain.com"
ingress:
enabled: true
className: "nginx" # or "traefik"
hosts:
- host: api.yourdomain.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: api-tls
hosts:
- api.yourdomain.com
# UI
ui:
replicaCount: 2
ingress:
enabled: true
className: "nginx"
hosts:
- host: app.yourdomain.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: app-tls
hosts:
- app.yourdomain.com
# Brain (AI Service)
brain:
replicaCount: 2
# Connectors - disable unused ones
connectors:
slack:
enabled: true
teams:
enabled: true
jira:
enabled: true
github:
enabled: true
linear:
enabled: false # Enable if needed
align:
enabled: false # Enable for AI assistant integration (Claude, Cursor)
# Secrets
secrets:
create: false # Use pre-created secrets
See Configuration Reference for all options.
Step 4b: GPU Inference (Optional)
To run LLM inference locally instead of using cloud APIs, add GPU configuration to your values file. This requires GPU nodes in your cluster.
# values.yaml (add to existing file)
gpu:
devicePlugin:
enabled: true
llmServer:
enabled: true
# Tell Brain which model the local server runs
brain:
extraEnv:
- name: LOCAL_LLM_MODEL
value: "meta-llama/Llama-3.1-8B-Instruct"
If you need a HuggingFace token for gated models (e.g., Llama), create the secret:
kubectl create secret generic hf-token \
--namespace align \
--from-literal=token="hf_..."
See LLM Configuration - GPU Inference for full GPU setup including node requirements.
GPU inference is optional. Without it, Align uses cloud APIs (OpenAI/Anthropic) or CPU-based models (Ollama). You can add GPU later without downtime.
Step 5: Install Align
From Your Mirrored Registry (Recommended)
helm install align \
oci://your-registry/align/charts/align \
--version "$ALIGN_CHART_VERSION" \
--namespace align \
--values values.yaml
From Align's Registry (Direct)
helm install align \
oci://$ALIGN_REGISTRY/align/charts/align \
--version "$ALIGN_CHART_VERSION" \
--namespace align \
--values values.yaml
Step 6: Verify Installation
# Check pods are running
kubectl get pods -n align
# Expected output:
# NAME READY STATUS RESTARTS AGE
# align-gateway-xxx 1/1 Running 0 2m
# align-brain-xxx 1/1 Running 0 2m
# align-ui-xxx 1/1 Running 0 2m
# align-connector-slack-xxx 1/1 Running 0 2m
# ...
# Check services
kubectl get svc -n align
# Check ingress
kubectl get ingress -n align
Step 7: Run Migrations
Migrations run automatically as a Helm pre-install hook. Verify they completed:
kubectl get jobs -n align
# Should show:
# NAME COMPLETIONS DURATION AGE
# align-migrations 1/1 30s 5m
Step 8: Access Align
- Ensure DNS is configured for your domains
- Navigate to
https://app.yourdomain.com - Sign in or create your first user
Troubleshooting
Pods not starting
# Check pod status
kubectl describe pod -n align <pod-name>
# Check logs
kubectl logs -n align <pod-name>
Database connection issues
# Verify secret exists
kubectl get secret align-database -n align
# Test connection from a pod
kubectl run -it --rm debug --image=postgres:15 \
--restart=Never -n align -- \
psql "postgresql://user:pass@host:5432/align"
Ingress not working
# Check ingress status
kubectl describe ingress -n align
# Verify TLS secret exists
kubectl get secret api-tls -n align
Next Steps
- Configure OAuth Apps for Slack, Teams, etc.
- Set up LLM for decision synthesis
- Configure secrets properly for production