Envoy’s bootstrap config isn’t just a config file; it’s the genesis of the entire process, dictating how Envoy starts up and where it finds its actual configuration.

Let’s get Envoy running with a minimal bootstrap config. We’ll aim for a single static HTTP listener that returns a fixed response.

First, the bootstrap.yaml itself. This file tells Envoy where to find its other configuration files and some basic operational settings.

static_resources:
  listeners:
  - name: http_listener
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 8080
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          stat_prefix: ingress_http
          codec_type: AUTO
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                route:
                  # This is where we define the static response
                  direct_response:
                    status:
                      code: 200
                    body:
                      inline_string: "Hello from Envoy!"
admin:
  access_log_path: /tmp/envoy.log
  address:
    socket_address:
      address: 127.0.0.1
      port_value: 9901

Here’s how you’d run Envoy with this:

/usr/local/bin/envoy -c bootstrap.yaml

Now, let’s see it in action. Send a request to port 8080:

curl http://localhost:8080

Output:

Hello from Envoy!

This bootstrap.yaml is the bedrock. It defines two key sections: static_resources and dynamic_resources (though we’re only using static_resources here). The static_resources section contains configurations that are baked into the bootstrap file and don’t change unless you restart Envoy. This includes listeners, clusters, routes, etc. The dynamic_resources section, on the other hand, is where you’d point to a Discovery Service (like xDS) for Envoy to fetch its configuration on the fly.

The listeners define the network endpoints Envoy listens on. Each listener has an address and a filter_chain. The filter_chain is a sequence of network filters that process incoming connections. In our case, the http_connection_manager is the crucial filter for HTTP traffic. It handles HTTP parsing, routing, and a host of other HTTP-specific tasks.

Within the http_connection_manager, route_config defines how incoming requests are routed. We’ve set up a simple virtual_host that matches any domain ("*"). The routes section then specifies how to handle requests based on their path. Here, a prefix: "/" matches all requests. Instead of forwarding to a backend cluster (which we haven’t defined), we’re using direct_response to immediately send a 200 OK with a static body.

The admin section provides an administrative interface, typically on 127.0.0.1:9901. This interface is invaluable for introspection and debugging, allowing you to query Envoy’s state, view stats, and even update configuration dynamically (if not using static config).

The real power of Envoy’s configuration model lies in its separation of concerns. The bootstrap config is just the starting point. For any non-trivial setup, you’d typically use dynamic_resources to configure listeners, routes, and clusters via xDS APIs, allowing for zero-downtime updates without restarting Envoy.

The admin interface, accessible via curl http://127.0.0.1:9901/clusters?format=json, reveals Envoy’s internal understanding of its configured clusters. Even though we haven’t explicitly defined a cluster in our bootstrap, the direct_response route effectively acts as a terminal node in the request path, meaning Envoy doesn’t need to look up a backend cluster for this specific route.

The next step is likely exploring how to define actual upstream clusters and use routes to forward traffic to them, moving beyond static responses.

Want structured learning?

Take the full Envoy course →