| 1 | --- |
| 2 | title: Kubernetes |
| 3 | description: Run containers and Effect programs on any Kubernetes cluster with Alchemy. Declare Deployments, Jobs, raw manifests, and Helm charts in the same typed program as the rest of your infrastructure. No YAML, no kubectl apply. |
| 4 | --- |
| 5 | |
| 6 | `alchemy/Kubernetes` manages workloads on **any Kubernetes cluster**, |
| 7 | such as a cluster on your laptop, k3s on a VM, an on-prem fleet, GKE, |
| 8 | AKS, or EKS. You describe servers, jobs, and raw Kubernetes objects |
| 9 | as Resources in TypeScript. Alchemy builds your programs into images |
| 10 | and applies everything to the cluster with server-side apply. It |
| 11 | tracks everything in state and deletes it on destroy. |
| 12 | |
| 13 | ```typescript |
| 14 | import * as Alchemy from "alchemy"; |
| 15 | import * as Kubernetes from "alchemy/Kubernetes"; |
| 16 | import * as Effect from "effect/Effect"; |
| 17 | |
| 18 | export default Alchemy.Stack( |
| 19 | "MyApp", |
| 20 | { |
| 21 | providers: Kubernetes.providers(), |
| 22 | state: Alchemy.localState(), |
| 23 | }, |
| 24 | Effect.gen(function* () { |
| 25 | const cluster = yield* Kubernetes.LocalCluster("Cluster", { |
| 26 | name: "alchemy", |
| 27 | }); |
| 28 | |
| 29 | const web = yield* Kubernetes.Deployment("Web", { |
| 30 | cluster, |
| 31 | name: "web", |
| 32 | image: "ghcr.io/stefanprodan/podinfo:6.15.0", |
| 33 | port: 9898, |
| 34 | replicas: 2, |
| 35 | serviceType: "ClusterIP", |
| 36 | }); |
| 37 | |
| 38 | return { service: web.serviceName }; |
| 39 | }), |
| 40 | ); |
| 41 | ``` |
| 42 | |
| 43 | `Kubernetes.LocalCluster` starts a cluster on your machine, so you |
| 44 | can try everything here without a hosted cluster. When you're ready, |
| 45 | point the same resources at a real one. |
| 46 | |
| 47 | New here? Follow [Setup](/kubernetes/setup), then start the |
| 48 | [tutorial](/kubernetes/tutorial/part-1). |
| 49 | |
| 50 | ## Clusters |
| 51 | |
| 52 | Every resource takes a `cluster` prop that says where it runs, how |
| 53 | to authenticate, and where to push images. |
| 54 | |
| 55 | - **[Connecting to clusters](/kubernetes/clusters/connecting).** Use |
| 56 | `Kubernetes.KubeConfig(...)` for anything `kubectl` can reach, or a |
| 57 | raw `Kubernetes.Connection` with a bearer token, client |
| 58 | certificate, or exec plugin. |
| 59 | - **[Container registries](/kubernetes/clusters/registries).** |
| 60 | Workloads built from your code are pushed to a registry so the |
| 61 | cluster can pull them. |
| 62 | - **[Local clusters](/kubernetes/clusters/local).** |
| 63 | `Kubernetes.LocalCluster` runs a [kind](https://kind.sigs.k8s.io) |
| 64 | cluster in Docker with an image registry built in. |
| 65 | - **[Amazon EKS](/kubernetes/clusters/eks).** Pass an EKS cluster |
| 66 | from the same Stack and get ECR images, AWS bindings, and public |
| 67 | load balancers. |
| 68 | - **[Cluster adapters](/kubernetes/clusters/cluster-adapters).** An |
| 69 | adapter is the extension point that gives each cluster platform its |
| 70 | authentication, registry, and identity behavior. |
| 71 | |
| 72 | ## Workloads |
| 73 | |
| 74 | - **[Deployments](/kubernetes/workloads/deployments).** A replicated |
| 75 | server made of a Kubernetes `Deployment`, `Service`, and |
| 76 | `ServiceAccount`. It runs an image or an Effect HTTP server. |
| 77 | - **[Jobs & CronJobs](/kubernetes/workloads/jobs).** |
| 78 | Run-to-completion work, from a container image or an Effect |
| 79 | program. Set `schedule` and the Job becomes a `CronJob`. |
| 80 | - **[Container images](/kubernetes/workloads/images).** Every |
| 81 | workload runs exactly one of `image` (a registry reference), |
| 82 | `context` (your Dockerfile), or `main` (a bundled Effect program). |
| 83 | - **[Configuration & bindings](/kubernetes/workloads/bindings).** |
| 84 | Environment variables, values from other resources, and bindings. |
| 85 | - **[How objects are managed](/kubernetes/workloads/object-lifecycle).** |
| 86 | Server-side apply, apply and delete ordering, pruning, drift, and |
| 87 | what triggers a replacement. |
| 88 | |
| 89 | ## Objects |
| 90 | |
| 91 | - **[Manifests](/kubernetes/objects/manifests).** Apply any single |
| 92 | Kubernetes object, such as Namespaces, ConfigMaps, StatefulSets, |
| 93 | Ingresses, and custom resources. |
| 94 | - **[Helm charts](/kubernetes/objects/helm-charts).** Render a chart |
| 95 | with the local `helm` CLI and apply its objects as one resource. |
| 96 | |
| 97 | ## What are you building? |
| 98 | |
| 99 | - **An HTTP service from a public image.** Use |
| 100 | [`Deployment`](/kubernetes/workloads/deployments) with `image`. |
| 101 | - **An HTTP server written in Effect.** Use |
| 102 | [`Deployment`](/kubernetes/workloads/deployments#effect-servers) |
| 103 | with `main`. |
| 104 | - **A database migration, seed, or smoke test.** Use |
| 105 | [`Job`](/kubernetes/workloads/jobs). |
| 106 | - **A nightly batch task.** Use |
| 107 | [`Job`](/kubernetes/workloads/jobs#run-on-a-schedule) with |
| 108 | `schedule`. |
| 109 | - **A Namespace, ConfigMap, or Secret.** Use |
| 110 | [`Manifest`](/kubernetes/objects/manifests). |
| 111 | - **A StatefulSet, Ingress, or custom resource.** Use |
| 112 | [`Manifest`](/kubernetes/objects/manifests). |
| 113 | - **A cluster add-on (metrics, ingress, operators).** Use |
| 114 | [`HelmChart`](/kubernetes/objects/helm-charts). |
| 115 | |
| 116 | ## Where next |
| 117 | |
| 118 | - [Setup](/kubernetes/setup) shows how to install Alchemy and connect |
| 119 | it to a local or hosted cluster. |
| 120 | - [Tutorial](/kubernetes/tutorial/part-1) takes you from an empty |
| 121 | directory to a local cluster running a service, Effect Jobs, a |
| 122 | CronJob, and a Helm chart. It ends on a cluster of your own. |
| 123 | - API reference for [`LocalCluster`](/providers/kubernetes/localcluster), |
| 124 | [`Deployment`](/providers/kubernetes/deployment), |
| 125 | [`Job`](/providers/kubernetes/job), |
| 126 | [`Manifest`](/providers/kubernetes/manifest), |
| 127 | [`HelmChart`](/providers/kubernetes/helmchart). |