Deploy on Amazon EKS
A documented procedure for running knext on EKS — S3 for assets, ElastiCache/Redis for the cache, ECR for digest-pinned images.
This is a documented procedure for EKS. The steps below are documented but not yet validated on a live EKS cluster — see the callout below before relying on it in production.
Not yet validated on a live EKS cluster. knext's deployment has been exercised live on other clouds, not on EKS. Treat this guide as a procedure to validate in your own environment, not a battle-tested runbook.
This guide assumes Knative Serving, Kourier, cert-manager, and the knext operator are already installed (those are cloud-agnostic):
Prerequisite: the common install page. It covers Knative Serving + Kourier (networking), cert-manager, and the knext operator. This guide only covers the EKS-specific pieces: cluster, the EBS CSI driver, storage, cache, and registry.
1. Create the cluster
The quickest path is eksctl:
eksctl create cluster \
--name knext \
--region us-east-1 \
--nodes 2 \
--node-type m5.large \
--with-oidc # required for IRSA, below--with-oidc provisions the OIDC provider that IRSA (IAM Roles for Service Accounts) needs —
that's how the app authenticates to S3 without static keys.
After the cluster is up, follow the common install page to install Knative, Kourier, cert-manager, and the operator.
2. Install the EBS CSI driver
knext itself needs no persistent volume — its compile cache is baked into the image. But any
stateful component you run alongside it (Postgres, Redis) needs a StorageClass backed by a real
volume provisioner. On EKS that's the EBS CSI driver, exposing gp3 / gp2:
eksctl create addon --name aws-ebs-csi-driver --cluster knext --forceA gp3 StorageClass (preferred over gp2):
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
type: gp3Point any stateful component's PVC at this StorageClass.
3. Storage: S3
With object storage configured, knext uploads build output (static assets) to an object store keyed by build ID and serves it from
assetPrefix. On EKS that store is an S3 bucket:
aws s3api create-bucket \
--bucket my-app-assets \
--region us-east-1 \
--create-bucket-configuration LocationConstraint=us-east-1Auth uses IRSA — bind the app's Kubernetes ServiceAccount to an IAM role that grants
s3:PutObject / s3:GetObject on the bucket (knext writes build assets to it; browsers read them
over the public publicUrl / CDN):
eksctl create iamserviceaccount \
--cluster knext \
--namespace default \
--name my-app \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess \
--approveFor least privilege, replace the managed policy with a custom policy scoped to
s3:PutObject / s3:GetObject on arn:aws:s3:::my-app-assets/*.
In the config, provider: 's3' with a region. Serve publicUrl either directly from S3 or
through a CloudFront distribution / custom endpoint:
storage: {
provider: 's3',
bucket: 'my-app-assets',
region: 'us-east-1',
publicUrl: 'https://my-app-assets.s3.us-east-1.amazonaws.com',
// CloudFront: set publicUrl to the distribution domain instead.
// S3-compatible store: set `endpoint`.
},knext's storage validator accepts gcs, s3, minio, and azure. On EKS use s3 (or any
S3-compatible store via s3 + endpoint) — see Multi-cloud deploy.
4. Cache: Redis (ElastiCache)
knext's data cache is Redis — the only implemented cache provider. Provision an ElastiCache for
Redis cluster and wire its endpoint into cache. cache.url is required when
provider: 'redis'; keep it in a Kubernetes Secret:
cache: {
provider: 'redis',
url: process.env.REDIS_URL!, // injected from a K8s Secret
keyPrefix: 'my-app',
},5. Registry: ECR
Push the runtime image to ECR. The operator rejects :latest — images must be
digest-pinned (@sha256:), so let the CLI build and push.
aws ecr create-repository --repository-name knext-repo --region us-east-1
aws ecr get-login-password --region us-east-1 \
| docker login --username AWS --password-stdin \
<account-id>.dkr.ecr.us-east-1.amazonaws.comSet registry to the ECR repo path:
registry: '<account-id>.dkr.ecr.us-east-1.amazonaws.com/knext-repo',6. Complete config
import type { KnativeNextConfig } from '@getknext/core';
const config: KnativeNextConfig = {
name: 'my-app',
// Static assets → S3, served from assetPrefix
storage: {
provider: 's3',
bucket: 'my-app-assets',
region: 'us-east-1',
publicUrl: 'https://my-app-assets.s3.us-east-1.amazonaws.com',
},
// ISR / data cache → Redis (ElastiCache)
cache: {
provider: 'redis',
url: process.env.REDIS_URL!,
keyPrefix: 'my-app',
},
// ECR — image is digest-pinned by the CLI
registry: '<account-id>.dkr.ecr.us-east-1.amazonaws.com/knext-repo',
// Knative autoscaling — minScale 0 = scale to zero
scaling: {
minScale: 0,
maxScale: 5,
memoryRequest: '256Mi',
memoryLimit: '512Mi',
},
// Prometheus metrics + Grafana dashboards
observability: {
enabled: true,
},
// Redis URL lives in a K8s Secret, never in this file
secrets: {
envFrom: ['my-app-credentials'],
},
};
export default config;7. Build and deploy
kn-next build # builds the standalone image, pushes a digest-pinned ref
kn-next deploy # emits the NextApp CR; the operator reconciles itThe CLI never touches Knative directly — it applies a NextApp resource and the operator
reconciles it into a scaled-to-zero Knative Service. See
Operator & the NextApp CRD for the CRD shape, digest-pinning enforcement, and
the operator's security defaults. For the scale-to-zero wake path, see
Scale-to-zero & cold starts.
Deploy on Google Kubernetes Engine (GKE)
A reference walkthrough for running knext on GKE — GCS for assets, Redis for the data cache, Artifact Registry for digest-pinned images.
Deploy on Azure Kubernetes Service (AKS)
Run knext on AKS with MinIO (or an S3 gateway) for assets, Azure Cache for Redis, and ACR — Azure Blob is not a knext storage provider.