---
title: Configuration file
description: Configure locally-managed tunnels with a YAML configuration file.
image: https://developers.cloudflare.com/core-services-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/tunnel/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

### Tags

[ YAML ](https://developers.cloudflare.com/search/?tags=YAML) 

# Configuration file

Note

[Quick tunnels](https://developers.cloudflare.com/tunnel/faq/#quick-tunnels) do not need a configuration file.

Locally-managed tunnels run as an instance of `cloudflared` on your machine. You can configure `cloudflared` properties by modifying [command line parameters](https://developers.cloudflare.com/tunnel/configuration/#run-parameters) or by editing the tunnel [configuration file](https://developers.cloudflare.com/tunnel/other-tunnel-types/local-management/create-local-tunnel/#4-create-a-configuration-file).

The CLI provides a quick way to handle configurations if you are connecting a single service through `cloudflared`. The tunnel configuration file is useful if you are connecting multiple services and need to configure properties or exceptions for specific origins. In the configuration file, you can define top-level properties for your `cloudflared` instance as well as [origin-specific properties](https://developers.cloudflare.com/tunnel/configuration/#origin-parameters). For a full list of configuration options, type `cloudflared tunnel help` in your terminal.

In the absence of a configuration file, `cloudflared` will proxy outbound traffic through port `8080`.

## File structure for published applications

If you are exposing local services to the Internet, you can assign a public hostname to each service:

```

tunnel: 6ff42ae2-765d-4adf-8112-31c55c1551ef

credentials-file: /root/.cloudflared/6ff42ae2-765d-4adf-8112-31c55c1551ef.json


ingress:

  - hostname: gitlab.widgetcorp.tech

    service: http://localhost:80

  - hostname: gitlab-ssh.widgetcorp.tech

    service: ssh://localhost:22

  - service: http_status:404


```

Configuration files that contain ingress rules must always include a catch-all rule that concludes the file. In this example, `cloudflared` will respond with a `404` status code when the request does not match any of the previous hostnames.

### How traffic is matched

When `cloudflared` receives an incoming request, it evaluates each ingress rule from top to bottom to find which rule matches the request. Rules can match either the hostname or path of an incoming request, or both. If a rule does not specify a hostname, all hostnames will be matched. If a rule does not specify a path, all paths will be matched.

The last ingress rule must be a catch-all rule that matches all traffic.

Here is an example configuration file that specifies several rules:

```

tunnel: 6ff42ae2-765d-4adf-8112-31c55c1551ef

credentials-file: /root/.cloudflared/6ff42ae2-765d-4adf-8112-31c55c1551ef.json


ingress:

  # Rules map traffic from a hostname to a local service:

  - hostname: example.com

    service: https://localhost:8000

  # Rules can match the request's path to a regular expression:

  - hostname: static.example.com

    path: \.(jpg|png|css|js)$

    service: https://localhost:8001

  # Rules can match the request's hostname to a wildcard character:

  - hostname: "*.example.com"

    service: https://localhost:8002

  # An example of a catch-all rule:

  - service: https://localhost:8003


```

#### Wildcards

You can use wildcards to match traffic to multiple subdomains. For example, if you set the `hostname` key to `*.example.com`, both `alpha.example.com` and `beta.example.com` will route traffic to your origin. `cloudflared` does not support wildcards in the middle of the hostname, such as `test.*.example.com`.

You can also enter regular expressions for the `path` key. For example, if `hostname` is `static.example.com` and `path` is `\.(jpg|png|css|js)$`, matching URLs could include `https://static.example.com/data.js`, `http://static.example.com/images/photo.jpg`, and so on. Cloudflare parses the path regex using the [Go syntax package ↗](https://pkg.go.dev/regexp/syntax).

### Services

In addition to HTTP, `cloudflared` supports protocols like SSH, RDP, arbitrary TCP services, and Unix sockets. You can also route traffic to the built-in `hello_world` test server or respond to traffic with an HTTP status. For a full list of supported service types, refer to [Protocols for published applications](https://developers.cloudflare.com/tunnel/routing/#supported-protocols).

```

tunnel: 6ff42ae2-765d-4adf-8112-31c55c1551ef

credentials-file: /root/.cloudflared/6ff42ae2-765d-4adf-8112-31c55c1551ef.json


ingress:

  # Example of a request over TCP:

  - hostname: example.com

    service: tcp://localhost:8000

  # Example of an HTTP request over a Unix socket:

  - hostname: staging.example.com

    service: unix:/home/production/echo.sock

  # Example of a request mapping to the Hello World test server:

  - hostname: test.example.com

    service: hello_world

  # Example of a rule responding to traffic with an HTTP status:

  - service: http_status:404


```

### Origin configuration

If you need to proxy traffic to multiple origins within one instance of `cloudflared`, you can define the way `cloudflared` sends requests to each service by specifying [configuration options](https://developers.cloudflare.com/tunnel/configuration/#origin-parameters) as part of your ingress rules.

In the following example, the top-level configuration `connectTimeout: 30s` sets a 30-second connection timeout for all services within that instance of `cloudflared`. The ingress rule for `service: localhost:8002` then configures an exception to the top-level configuration by setting `connectTimeout` for that service at `10s`. The 30-second connection timeout still applies to all other services.

```

tunnel: 6ff42ae2-765d-4adf-8112-31c55c1551ef

credentials-file: /root/.cloudflared/6ff42ae2-765d-4adf-8112-31c55c1551ef.json

originRequest: # Top-level configuration

  connectTimeout: 30s


ingress:

  # The localhost:8000 service inherits all root-level configuration.

  # In other words, it will use a connectTimeout of 30 seconds.

  - hostname: example.com

    service: localhost:8000

  - hostname: example2.com

    service: localhost:8001

  # The localhost:8002 service overrides some root-level config.

  - service: localhost:8002

    originRequest:

      connectTimeout: 10s

      disableChunkedEncoding: true

  # Some built-in services such as `http_status` do not use any configuration.

  # The service below will simply respond with HTTP 404.

  - service: http_status:404


```

### Validate ingress rules

To validate the ingress rules in your configuration file, run:

Terminal window

```

cloudflared tunnel ingress validate


```

This will ensure that the set of ingress rules specified in your config file is valid.

### Test ingress rules

To verify that `cloudflared` will proxy the right traffic to the right local service, use `cloudflared tunnel ingress rule`. This checks a URL against every rule, from first to last, and shows the first rule that matches. For example:

Terminal window

```

cloudflared tunnel ingress rule https://foo.example.com


```

```

Using rules from /usr/local/etc/cloudflared/config.yml

Matched rule #3

  hostname: *.example.com

  service: https://localhost:8000


```

## Update a configuration file

When making changes to the configuration file for a given tunnel, we suggest relying on [cloudflared replicas](https://developers.cloudflare.com/tunnel/configuration/#replicas-and-high-availability) to propagate the new configuration with minimal downtime.

1. Have a `cloudflared` instance running with the original version of the configuration file.
2. Start a `cloudflared` replica running with the updated version of the configuration file.
3. Wait for the replica to be fully running and usable.
4. Stop the first instance of `cloudflared`.

Your `cloudflared` will now be running with the updated version of your configuration file.

Traffic handling

When the first instance of `cloudflared` is stopped, long-lived HTTP requests (for example, Websocket) and TCP connections (for example, SSH) will be dropped. UDP flows will also be dropped, as they are modeled based on timeouts. When the new replica connects, it will handle all new traffic, including new HTTP requests, TCP connections, and UDP flows.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/tunnel/","name":"Cloudflare Tunnel"}},{"@type":"ListItem","position":3,"item":{"@id":"/tunnel/advanced/","name":"Advanced"}},{"@type":"ListItem","position":4,"item":{"@id":"/tunnel/advanced/local-management/","name":"Locally-managed tunnels"}},{"@type":"ListItem","position":5,"item":{"@id":"/tunnel/advanced/local-management/configuration-file/","name":"Configuration file"}}]}
```
