---
layout: docs
page_title: Kubernetes - YAML-Free Deployment
description: |-
  For many applications, Waypoint can deploy to Kubernetes with only a handful of lines of configuration in the `waypoint.hcl` file and zero external configuration.
---

# Deploying Applications without YAML

For many applications, Waypoint can deploy to Kubernetes with only
a handful of lines of configuration in the `waypoint.hcl` file and zero
external configuration. For new applications, this is a great option to
get up and running easily. If your application becomes more complex later,
you can always switch deployment plugins.

-> **Prefer writing YAML? That's okay!** Waypoint supports
[Helm](/docs/kubernetes/helm-deploy) and raw
[`kubectl apply`](/docs/kubernetes/kubectl-deploy) as first-class
deployment plugins, too.

## A Simple Application

For a simple web application, you can get started with almost zero configuration:

```hcl
app "my-app" {
  deploy {
    use "kubernetes" {}
  }
}
```

With zero configuration, Waypoint will create a Kubernetes `Deployment`
with a `PORT` environment variable that your application is expected to listen
on. And Waypoint will expose this application using a `ClusterIP` service.
This is a perfect, minimal deployment for an internal service.

-> **Common mistake:** your application must be written to listen on the
`PORT` environment variable for this to _just work_. If you want to change
the port to something else, specify it using the `ports` configuration
shown below.

### Scaling Up

With one more line of configuration, you can scale your application to more replicas:

```hcl
app "my-app" {
  deploy {
    use "kubernetes" {
      replicas = 3
    }
  }
}
```

### Health Checking

With one line of configuration, you can specify an HTTP health check that
Kubernetes will use for both liveness and readiness. This HTTP endpoint
should listen on the service port and respond with a `2XX` status code
for success.

```hcl
app "my-app" {
  deploy {
    use "kubernetes" {
      probe_path = "/_healthz"
    }
  }
}
```

### Alternate or Additional Ports

With zero configuration, your application must listen on the `PORT`
environment variable set by Waypoint. You can change the primary
service port using `service_port`:

```hcl
app "my-app" {
  deploy {
    use "kubernetes" {
	  service_port = 1234
    }
  }
}
```

This is optimized and very simple for applications that have only one
primary listening port. If you require multiple ports, you must use the
slightly more complex `ports` configuration and must NOT use the `service_port`
field (they are mutually exclusive).

```hcl
app "my-app" {
  deploy {
    use "kubernetes" {
      pod {
        container {
          port {
            name = "http"
            port = 1234
          }

          port {
            name = "https"
            port = 2345
          }
        }
      }
    }
  }
}
```

-> **Important! The first port is special.** The first port is used
as the expected HTTP listening port (regardless of name or any other
settings).

### Autoscaling

Waypoint can configure [horizontal autoscaling](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/)
in just a few lines:

```hcl
app "my-app" {
  deploy {
    use "kubernetes" {
      cpu {
        request = "250m"
        limit   = "500m"
      }

      autoscale {
        min_replicas = 1
        max_replicas = 5
        cpu_percent = 20
      }
    }
  }
}
```

Note that this requires that a [metrics server](https://kubernetes.io/docs/tasks/debug-application-cluster/resource-metrics-pipeline/#metrics-server)
is running in your Kubernetes cluster. Waypoint will not set this up
automatically. Installing the metrics server is typically a single
`kubectl apply` or Helm install.

## Release Management

With the default Kubernetes deployment configuration, Waypoint creates
a single `ClusterIP` type service. This is perfect for internal services
but doesn't work if you want to expose your application to the public internet.
By configuring a `kubernetes` [release stanza](/docs/waypoint-hcl/release),
configuring release management for your service is also only a few lines
of HCL.

-> **Be careful!** This section is configuring the `release` stanza, _not_
the `deploy` stanza. If you're scrolling down this will be a very subtle
difference.

### `LoadBalancer` Service

The simplest way to expose your application to the global internet is to
use a `LoadBalancer` service type. This is a one line change:

```hcl
app "my-app" {
  release {
    use "kubernetes" {
      load_balancer = true
    }
  }
}
```

### Ingress

You can expose your application through a
[Kubernetes Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/):

```hcl
app "my-app" {
  release {
    use "kubernetes" {
      ingress "http" {
        path_type = "Prefix"
        path      = "/"
      }
    }
  }
}
```

-> **This requires that you have an Ingress controller configured.**
Kubernetes does not do this by default. See the
[official Kubernetes documentation](https://kubernetes.io/docs/concepts/services-networking/ingress/)
for more information.

## Reference Documentation

To view a full list of the available options for the Kubernetes plugin,
please see the [plugin reference documentation](/plugins/kubernetes).
This documentation is more dense and has less examples, but is an
exhaustive list of the available options.
