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

# Service manifest: expose deployments with ingress

> Reference for the Service manifest, which links a Deployment to a domain name and enables automatic HTTPS via the Caddy server embedded in orun.

A Service manifest is a YAML file stored at `services/<name>.yaml` in your manifest repository. It exposes a Deployment over HTTP or HTTPS by configuring the Caddy server that orun embeds on every node. Caddy handles routing and, when SSL is enabled, provisions TLS certificates from Let's Encrypt automatically — you do not need to manage certificates manually. Each Service targets exactly one Deployment by name and configures the domain or domains under which it is reachable.

## Example

```yaml theme={null}
apiVersion: run.orcra.dev/v0alpha
kind: Service
metadata:
  name: hello-world
spec:
  deployment: hello-world
  ingress:
    domain:
      default: hello-world.example.com
      environment: hello-world.$ENV.example.com
    ssl: true
```

## Fields

<ParamField path="deployment" type="string" required>
  Name of the Deployment this Service exposes. The value must match the `metadata.name` of an existing Deployment manifest in the same repository. orun routes incoming requests for the configured domain to the container ports defined in that Deployment.
</ParamField>

<ParamField path="ingress" type="object">
  Ingress configuration block. Defines the domain and SSL behaviour for the service.
</ParamField>

<ParamField path="ingress.domain" type="object">
  Domain configuration for the ingress. At minimum, set `default`.
</ParamField>

<ParamField path="ingress.domain.default" type="string" required>
  The primary domain for the service, used when no environment-specific domain applies — for example, `hello-world.example.com`. This domain must resolve to the node's IP address for routing and SSL provisioning to work.
</ParamField>

<ParamField path="ingress.domain.environment" type="string">
  A domain template for environment-specific routing. Use the placeholder `$ENV` where the node's environment identifier should appear — for example, `hello-world.$ENV.example.com`. orun replaces `$ENV` with the node's environment identifier at runtime, allowing a single manifest to route differently across staging and production nodes.
</ParamField>

<ParamField path="ingress.ssl" type="boolean" default="false">
  When `true`, Caddy automatically provisions and renews a TLS certificate for the configured domain via Let's Encrypt. The node must be publicly reachable on ports 80 and 443 for the ACME challenge to succeed.
</ParamField>

## Automatic TLS

When `ingress.ssl: true`, Caddy uses the ACME HTTP-01 challenge to obtain a certificate from Let's Encrypt. No manual configuration is required beyond ensuring your DNS record points at the node and the necessary ports are open.

<Warning>
  Ports 80 and 443 must be open on the node's firewall for automatic certificate provisioning to work. If port 80 is blocked, Let's Encrypt cannot complete the ACME challenge and Caddy will not serve HTTPS traffic.
</Warning>

<Note>
  The `$ENV` placeholder in `ingress.domain.environment` is replaced with the node's environment identifier. This lets you commit a single Service manifest and have it resolve to environment-specific domains — for example, `hello-world.staging.example.com` on the staging node and `hello-world.production.example.com` on the production node.
</Note>
