# environments.<name>.services

> Per-service overrides for this environment (deep-merged over the base service).

Per-service overrides for this environment (deep-merged over the base service).

- **Type:** map of names to object
- **Since:** manifest v1

## Example

```yaml
environments:
  production:
    services:
      web:
        replicas: 1
        resources:
          cpu: 0.5
          memory: 512MB
```

## Fields

### description

`environments.<name>.services.<name>.description`

What the service does, shown in the dashboard.

- **Type:** string
- **Maximum length:** 500
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        description: Public website and dashboard
```

### root

`environments.<name>.services.<name>.root`

Directory of the service in the repository.

- **Type:** string
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        root: apps/web
```

### watch

`environments.<name>.services.<name>.watch`

Globs of paths that trigger a rebuild on push. Defaults to `<root>/**` plus shared lockfiles.

- **Type:** list of string
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        watch:
          - apps/web/**
          - packages/ui/**
          - pnpm-lock.yaml
```

### build

`environments.<name>.services.<name>.build`

How the service is built. Without this block Guv detects a Dockerfile or uses Railpack.

- **Type:** object
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        build:
          builder: dockerfile
          dockerfile: services/api/Dockerfile
```

#### builder

`environments.<name>.services.<name>.build.builder`

`railpack` auto-detects the stack, `dockerfile` builds a Dockerfile, `image` deploys a prebuilt image.

- **Type:** `railpack`, `dockerfile`, `image`
- **Default:** `railpack`
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        build:
          builder: dockerfile
```

#### dockerfile

`environments.<name>.services.<name>.build.dockerfile`

Path to the Dockerfile, relative to the repository root.

- **Type:** string
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        build:
          dockerfile: services/api/Dockerfile
```

#### context

`environments.<name>.services.<name>.build.context`

Build context directory, relative to the repository root. Defaults to `root`.

- **Type:** string
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        build:
          context: services/api
```

#### image

`environments.<name>.services.<name>.build.image`

Image to deploy when `builder` is `image` (Docker Hub, GHCR or a private registry).

- **Type:** string
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        build:
          image: ghcr.io/acme/api:1.4.2
```

#### registry_credentials

`environments.<name>.services.<name>.build.registry_credentials`

Secret holding credentials for a private registry.

- **Type:** string
- **Pattern:** `^secret://[A-Za-z_][A-Za-z0-9_-]{0,127}$`
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        build:
          registry_credentials: secret://ghcr-token
```

### start

`environments.<name>.services.<name>.start`

Start command. Detected when omitted.

- **Type:** string
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        start: pnpm --filter web start
```

### pre_deploy

`environments.<name>.services.<name>.pre_deploy`

Command run once per deployment, in a separate VM with the same variables, before traffic moves (for migrations). Failure stops the rollout.

- **Type:** string
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        pre_deploy: pnpm --filter db migrate deploy
```

### port

`environments.<name>.services.<name>.port`

Port the app listens on. Services with a port get a generated domain unless `private`.

- **Type:** integer
- **Range:** 1 to 65535
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        port: 3000
```

### healthcheck

`environments.<name>.services.<name>.healthcheck`

How Guv decides a new deployment is healthy before moving traffic. A string is shorthand for an HTTP path.

- **Type:** string or object
- **Since:** manifest v1

**Accepted forms**

- string
- object: the full form, with the fields below

```yaml
environments:
  production:
    services:
      web:
        healthcheck: /healthz
```

```yaml
environments:
  production:
    services:
      web:
        healthcheck:
          path: /healthz
          timeout: 10s
```

#### type

`environments.<name>.services.<name>.healthcheck.type`

HTTP GET expecting 2xx/3xx, or a TCP connect.

- **Type:** `http`, `tcp`
- **Default:** `http`
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        healthcheck:
          type: http
```

#### path

`environments.<name>.services.<name>.healthcheck.path`

Path for HTTP checks.

- **Type:** string
- **Default:** `/`
- **Pattern:** `^/`
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        healthcheck:
          path: /healthz
```

#### port

`environments.<name>.services.<name>.healthcheck.port`

Port to check; defaults to the service port.

- **Type:** integer
- **Range:** 1 to 65535
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        healthcheck:
          port: 3000
```

#### timeout

`environments.<name>.services.<name>.healthcheck.timeout`

Per-check timeout (up to 60s).

- **Type:** [duration](/docs/manifest/#duration)
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        healthcheck:
          timeout: 10s
```

#### interval

`environments.<name>.services.<name>.healthcheck.interval`

Time between checks.

- **Type:** [duration](/docs/manifest/#duration)
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        healthcheck:
          interval: 10s
```

#### start_timeout

`environments.<name>.services.<name>.healthcheck.start_timeout`

How long a new deployment has to become healthy (up to 15m).

- **Type:** [duration](/docs/manifest/#duration)
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        healthcheck:
          start_timeout: 5m
```

### domains

`environments.<name>.services.<name>.domains`

Custom domains. They attach to the production environment unless set under `environments.<env>.services.<svc>.domains`.

- **Type:** list of [hostname](/docs/manifest/#hostname) or object
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        domains:
          - www.primecarers.co.uk
          - primecarers.co.uk
```

#### host

`environments.<name>.services.<name>.domains[].host`

Hostname.

- **Type:** [hostname](/docs/manifest/#hostname)
- **Required:** yes
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        domains:
          - host: primecarers.co.uk
```

#### redirect_to

`environments.<name>.services.<name>.domains[].redirect_to`

Redirect every request to this hostname (permanent redirect), instead of serving.

- **Type:** [hostname](/docs/manifest/#hostname)
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        domains:
          - redirect_to: www.primecarers.co.uk
```

### private

`environments.<name>.services.<name>.private`

No public domain; reachable only on the environment's private network as `<name>.guv.internal`.

- **Type:** boolean
- **Default:** `false`
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        private: true
```

### replicas

`environments.<name>.services.<name>.replicas`

Number of copies. An integer fixes the count; an object enables autoscaling.

- **Type:** integer or object
- **Since:** manifest v1

**Accepted forms**

- integer
- object: the full form, with the fields below

```yaml
environments:
  production:
    services:
      web:
        replicas: 2
```

```yaml
environments:
  production:
    services:
      web:
        replicas:
          min: 2
          max: 6
          scale_on:
            cpu: 70%
```

#### min

`environments.<name>.services.<name>.replicas.min`

Fewest replicas. 0 allows scaling to zero.

- **Type:** integer
- **Default:** `1`
- **Range:** 0 to 20
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        replicas:
          min: 2
```

#### max

`environments.<name>.services.<name>.replicas.max`

Most replicas.

- **Type:** integer
- **Range:** 1 to 20
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        replicas:
          max: 6
```

#### scale_on

`environments.<name>.services.<name>.replicas.scale_on`

Targets for horizontal autoscaling between `min` and `max`.

- **Type:** object
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        replicas:
          scale_on:
            cpu: 70%
            concurrency: 80
```

### resources

`environments.<name>.services.<name>.resources`

Limits per replica. You are billed for actual use, not for limits.

- **Type:** object
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        resources:
          cpu: 1
          memory: 1GB
```

#### cpu

`environments.<name>.services.<name>.resources.cpu`

vCPU limit, in steps of 0.1.

- **Type:** number
- **Range:** 0.1 to 32
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        resources:
          cpu: 1
```

```yaml
environments:
  production:
    services:
      web:
        resources:
          cpu: 0.5
```

#### memory

`environments.<name>.services.<name>.resources.memory`

Memory limit (at least 128MB).

- **Type:** [size](/docs/manifest/#size)
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        resources:
          memory: 1GB
```

### sleep_when_idle

`environments.<name>.services.<name>.sleep_when_idle`

Scale to zero after 10 minutes without requests; the next request wakes it in 1–3 seconds.

- **Type:** boolean
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        sleep_when_idle: false
```

### env

`environments.<name>.services.<name>.env`

Variables for this service.

- **Type:** [env](/docs/manifest/#env)
- **Since:** manifest v1

### volumes

`environments.<name>.services.<name>.volumes`

Volumes to mount. A service with a single-server volume runs one replica.

- **Type:** list of object
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        volumes:
          - name: rota-cache
            mount: /data
```

#### name

`environments.<name>.services.<name>.volumes[].name`

Volume name.

- **Type:** [name](/docs/manifest/#name)
- **Required:** yes
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        volumes:
          - name: rota-cache
```

#### mount

`environments.<name>.services.<name>.volumes[].mount`

Absolute mount path inside the service.

- **Type:** string
- **Required:** yes
- **Pattern:** `^/`
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        volumes:
          - mount: /data
```

### cron

`environments.<name>.services.<name>.cron`

Five-field cron schedule. Makes the service a scheduled job; you are billed for run time only.

- **Type:** string
- **Pattern:** `^(@(hourly|daily|weekly|monthly|yearly)|(\S+\s+){4}\S+)$`
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        cron: 0 2 * * *
```

### timezone

`environments.<name>.services.<name>.timezone`

IANA time zone for `cron`.

- **Type:** string
- **Default:** `Europe/London`
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        timezone: Europe/London
```

### timeout

`environments.<name>.services.<name>.timeout`

Maximum run time of each cron run.

- **Type:** [duration](/docs/manifest/#duration)
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        timeout: 30m
```

### concurrency_policy

`environments.<name>.services.<name>.concurrency_policy`

What to do if a cron run is still going when the next is due.

- **Type:** `forbid`, `allow`, `replace`
- **Default:** `forbid`
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        concurrency_policy: forbid
```

### restart

`environments.<name>.services.<name>.restart`

Restart behaviour when the process exits.

- **Type:** object
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        restart:
          policy: on_failure
          max_retries: 10
```

#### policy

`environments.<name>.services.<name>.restart.policy`

When to restart.

- **Type:** `on_failure`, `always`, `never`
- **Default:** `on_failure`
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        restart:
          policy: on_failure
```

#### max_retries

`environments.<name>.services.<name>.restart.max_retries`

Restarts before the service is marked crashed.

- **Type:** integer
- **Default:** `10`
- **Range:** 0 to 100
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        restart:
          max_retries: 10
```

### overlap

`environments.<name>.services.<name>.overlap`

How long the previous deployment keeps serving after traffic moves.

- **Type:** [duration](/docs/manifest/#duration)
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        overlap: 20s
```

### auto_rollback

`environments.<name>.services.<name>.auto_rollback`

Roll back automatically if a new deployment crash-loops or fails health checks. Defaults to true in production.

- **Type:** boolean
- **Since:** manifest v1

```yaml
environments:
  production:
    services:
      web:
        auto_rollback: true
```

## See also

- [environments](/docs/manifest/environments/): all fields of `environments`
- [guv.yaml reference](/docs/manifest/)
