> ## Documentation Index
> Fetch the complete documentation index at: https://ryvn.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Routes

> Expose installations on the internet, your private network, and your own domains

Use Routes to expose your installations on the internet or on your environment's private network, and to serve them on
your own domains. Ryvn configures your environment's public and internal load balancers, manages DNS for your
environment's domains, and issues and renews TLS certificates. Routes are built on [Gateway API](https://gateway-api.sigs.k8s.io/).

<Note>
  Routes are in preview and aren't enabled by default. [Contact Ryvn support](/docs/support/contact-us) to enable them.
</Note>

## Server installations

Each port you expose on a [server installation](/docs/deploy/service-types/server) automatically gets a Route that serves it
on path `/`.

You can also write Routes that target server installations, for example to
[route paths to different installations](#route-paths-to-different-installations). A server installation's Service has
the installation's name, and its ports have the names you configured on the installation. Put the Route in the
installation's namespace, for example with the `ryvn-routes` chart below.

## Helm chart installations

Add a Route to your chart next to the Service it exposes:

```yaml theme={null}
apiVersion: networking.ryvn.app/v1alpha1
kind: Route
metadata:
  name: web
spec:
  exposure: [public]
  domains: [web.production.acme-7fk2q.ryvn.run]
  rules:
    - to: [{ name: web, port: http }]
```

`to` is a Service in the Route's namespace and one of its ports, by name or number. Once the installation deploys, the
Route serves `https://web.production.acme-7fk2q.ryvn.run`. Ryvn creates the DNS record and the certificate, and
redirects HTTP to HTTPS.

Routes deploy, update, roll back, and uninstall with their installation. Their URLs show up in the installation's
**Settings > Networking** tab and in `ryvn describe installation`.

To use the same chart in every environment, set the hostname in your installation config and read it from your chart's
values:

```yaml theme={null}
# Installation config
route:
  host: "web.{{ .ryvn.env.state.public_domain.name }}"
```

```yaml theme={null}
# templates/route.yaml
spec:
  domains: [{{ .Values.route.host | quote }}]
```

Many third-party charts create an Ingress to expose themselves. Turn it off in the chart's values and add a Route
instead.

<Tip>
  [`ryvn-routes`](https://github.com/ryvn-technologies/helm-charts) is a small chart that creates Routes from a list in
  its values. Use it for third-party charts you can't modify, or add it as a subchart when you wrap one in your own
  chart.
</Tip>

For example, to expose an existing installation of the [Zitadel chart](https://github.com/zitadel/zitadel-charts/tree/main/charts/zitadel),
in its values, set `ingress.enabled: false`, `zitadel.configmapConfig.ExternalDomain` to
`auth.production.acme-7fk2q.ryvn.run`, and `zitadel.configmapConfig.ExternalPort` to `443`. Install the `ryvn-routes`
chart from `https://charts.ryvn.app` in the same namespace with these values:

```yaml theme={null}
routes:
  - name: zitadel
    spec:
      exposure: [public]
      domains: [auth.production.acme-7fk2q.ryvn.run]
      rules:
        - to: [{ name: zitadel, port: http2-server }]
```

This example targets a Service named `zitadel` on the chart's default named port, `http2-server` (`8080`). If your chart uses a
different Service name or port, change `to` to match. The Route serves `https://auth.production.acme-7fk2q.ryvn.run`.

On Ryvn-managed clusters, Gateway API routes can't attach to Ryvn's gateways, so use Routes for those. Gateway API
resources for your own gateways work as usual.

## Public and internal

`exposure` sets where a Route is reachable. For the `billing` installation's `http` port:

### Public

This serves `https://billing.production.acme-7fk2q.ryvn.run` on the internet:

```yaml theme={null}
spec:
  exposure: [public]
  domains: [billing.production.acme-7fk2q.ryvn.run]
  rules:
    - to: [{ name: billing, port: http }]
```

### Internal

This serves `http://billing.internal.production.acme-7fk2q.ryvn.run` only to your environment's private network and
connected networks:

```yaml theme={null}
spec:
  exposure: [internal]
  domains: [billing.internal.production.acme-7fk2q.ryvn.run]
  rules:
    - to: [{ name: billing, port: http }]
```

## Route paths to different installations

Use paths to send one domain to different installations. This Route serves the `web` installation on `app.acme.com`
and the `api` installation under `/api`, stripping the prefix so a request for `/api/users` reaches the API as
`/users`:

```yaml theme={null}
apiVersion: networking.ryvn.app/v1alpha1
kind: Route
metadata:
  name: app
spec:
  exposure: [public]
  domains: [app.acme.com]
  rules:
    - path: /
      to: [{ name: web, port: http }]
    - path: /api
      replacePrefix: /
      to: [{ name: api, port: http }]
```

Routes from different installations can also share a domain, each with its own paths.

## Use your own domain

Routes with `public` exposure can also serve domains you own, such as `app.acme.com`. If you manage the domain's DNS
outside Ryvn, create two CNAME records for it at your DNS provider:

* A certificate record, which lets Ryvn issue and renew the domain's TLS certificate.
* A routing record, which points the domain at your environment's public load balancer.

Ryvn watches public DNS for these records. Once they resolve to the expected values, Ryvn issues the certificate and
starts serving the domain over HTTPS. Until then, the domain's status shows which record is missing or wrong. DNS
changes can take a few minutes to show up, depending on the records' TTL.

Keep both records while you use the domain, since Ryvn needs the certificate record to renew the certificate. If your
DNS provider proxies traffic, turn that off for these records, because Ryvn can't verify proxied records.

### Check required DNS records

You can check a domain's DNS records in the [Ryvn Dashboard](https://control.ryvn.app) or with the CLI. In the
dashboard, open the installation's **Settings > Networking** tab. A domain that still needs records shows **Complete DNS
setup**, which lists each record's type, name, value, and status.

With the CLI, describe the installation:

```bash theme={null}
ryvn describe installation web -e production
```

While any record is missing or wrong, the `Endpoints` section of the output lists the domain's records and their status:

```text theme={null}
Endpoints:
  - https://app.acme.com
    Exposure: public
    Port:     http (80)
    State:    Pending
    Reason:   Add a CNAME record for app.acme.com pointing to origin.production.acme-7fk2q.ryvn.run at your DNS provider.
    DNS records:
      CNAME app.acme.com -> origin.production.acme-7fk2q.ryvn.run (Missing)
      CNAME _acme-challenge.app.acme.com -> _acme-challenge.48a1541b.production.acme-7fk2q.ryvn.run (Missing)
```

A record shows `Missing` until Ryvn finds it, `Mismatch` if it points to a different value, and `Valid` once it's
correct.

## Troubleshooting

Use [Ryvn Connect](/docs/guides/jit-kubectl-access) to inspect a Route and its backend Service. Your access must allow
reading Routes, Services, and events in the installation's namespace. If access requires approval, follow the
request and resume steps in the Connect guide first.

For the Zitadel example in the `production` namespace:

```bash theme={null}
ryvn connect production
kubectl -n production get routes
kubectl -n production describe route zitadel
kubectl -n production get service zitadel -o yaml
exit
```

Check the Route's `Ready` condition and endpoint messages. For `InvalidTarget`, compare the Service's name and
`spec.ports` with the Route's `to` entry. For `DNSNotConfigured`, check the [required DNS records](#check-required-dns-records).
An installation can finish deploying before its Route is ready.
