Learn Envoy Proxy - Installation & Hello Envoy
Episode 3 of 23

Learn Envoy Proxy - Installation & Hello Envoy

It's time to write your first configuration. This episode covers downloading Envoy via Docker, assembling a minimal configuration for simple HTTP proxying, running it, and verifying traffic through Envoy.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Episode 3 is your "hello world" moment with Envoy. After understanding the architecture in episode 2, we now write a real configuration: download the Envoy image, assemble a minimal bootstrap to proxy HTTP, run it, and prove that traffic truly flows through Envoy.

You'll see the pattern repeated throughout the series: a listener on port 10000, an HTTP connection manager as the filter, one virtual host, and one backend cluster. This configuration is deliberately kept as simple as possible — additional variables and features will be added in episodes 4 through 8.

Downloading Envoy

Choosing an Image Distribution

The most practical way is to use the official image from Docker Hub:

Menarik image Envoy resmi
docker pull envoyproxy/envoy:v1.31.0

There are a few variants you should know:

  • envoyproxy/envoy:latest — the latest release, convenient for labs but changes quickly.
  • envoyproxy/envoy:v1.31.0 — a specific version, stable for repeated use.
  • envoyproxy/envoy:distroless — a minimal variant without a shell, for production.

For this series we consistently use envoyproxy/envoy:v1.31.0 so the output across all episodes is reproducible.

Running Envoy with a Custom Config

The default image contains a built-in config that runs the admin and a simple listener. To use your own config, mount the YAML file:

Jalankan Envoy dengan config kita
docker run -d --name envoy-hello \
  -v ~/envoy-lab/configs:/etc/envoy \
  -p 10000:10000 -p 9901:9901 \
  envoyproxy/envoy:v1.31.0

We'll fill the ~/envoy-lab/configs directory with a hello.yaml file. This docker run command mounts the config directory into the container and exposes ports 10000 and 9901.

Minimal Configuration for HTTP Proxying

Hello Envoy Bootstrap

Create the file configs/hello.yaml with the following content:

hello.yaml - proxy HTTP minimum
admin:
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 9901
static_resources:
  listeners:
    - name: listener_0
      address:
        socket_address:
          address: 0.0.0.0
          port_value: 10000
      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
                route_config:
                  name: local_route
                  virtual_hosts:
                    - name: local_service
                      domains:
                        - "*"
                      routes:
                        - match:
                            prefix: "/"
                          route:
                            cluster: service_backend
                http_filters:
                  - name: envoy.filters.http.router
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
  clusters:
    - name: service_backend
      connect_timeout: 0.25s
      type: STRICT_DNS
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: service_backend
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: 10.0.0.1
                      port_value: 8080

Let's break down the important parts: filter_chains contains a single http_connection_manager filter that wraps route_config and the list of http_filters. The route maps all / prefixes to the cluster service_backend, which contains a single endpoint at 10.0.0.1:8080.

Running a Test Backend

Since 10.0.0.1:8080 may not exist, start a dummy backend first so this hello world is complete:

Backend uji sederhana
python3 -m http.server 8080 &
curl -s http://localhost:8080/

The python3 -m http.server 8080 command runs a static file server on port 8080 — good enough as a target to see whether Envoy forwards requests correctly.

Verifying Traffic

Testing Through Envoy

Now point curl at Envoy's port, not directly at the backend:

Request melalui Envoy
curl -s -H "Host: localhost" http://localhost:10000/

Notice the difference: port 10000 is Envoy's listener, while port 8080 is the backend. If Envoy works, you'll see the same directory listing as when calling the backend directly. The Host header is used to select the virtual host.

Checking Statistics

For stronger proof that traffic flows through Envoy, look at the counters in the admin interface:

Cek counter di admin Envoy
curl -s localhost:9901/stats | grep "http.ingress_http"
curl -s localhost:9901/clusters

The stats output will show ingress_http requests increasing, and clusters displays endpoint status. The ingress_http statistics are Envoy's observability language, which you'll keep reading all the way to episode 21.

Validating Configuration

Before production, make a habit of validating your YAML first:

Validasi config tanpa menjalankan
docker run --rm -v ~/envoy-lab/configs:/etc/envoy \
  envoyproxy/envoy:v1.31.0 envoy --mode validate -c /etc/envoy/hello.yaml

The envoy --mode validate -c hello.yaml command checks the config without starting the proxy. An OK output means the YAML is valid and all resources are known to Envoy. This habit will pay off greatly in episode 20 when we integrate into CI/CD.

Common Mistakes in Hello Envoy

Endpoint Unreachable

The most common error in this episode is a failed connection because the backend doesn't exist. Make sure python3 -m http.server 8080 is really running, then check:

Debug koneksi ke backend
curl -v -H "Host: localhost" http://localhost:10000/

The curl -v part shows handshake details and the response code. If you see 502, inspect Envoy's logs with docker logs envoy-hello and make sure the backend address in the config is correct.

Invalid YAML

Wrong indentation produces an error at startup. Use a YAML linter and keep two spaces per level. If Envoy rejects your config, run envoy --mode validate to find the offending line.

Closing

Episode 3 took you from zero to a working proxy: pulling the image, writing a minimal bootstrap, running a test backend, and proving traffic flows through Envoy via the admin statistics.

Key takeaways:

  • The official envoyproxy/envoy:v1.31.0 image is enough for the whole series.
  • A minimal config needs a listener, an HTTP filter chain, a route, and a cluster.
  • http_connection_manager turns TCP into routable HTTP requests.
  • Verify with curl against the listener port and check statistics on port 9901.
  • Always run envoy --mode validate before production.
  • python3 -m http.server is a handy test backend for learning.

In the next episode, episode 4, we'll discuss listener, filter chain, and route configuration — virtual hosts, path matching, header manipulation, redirect, and rewrite, so your routing is no longer just forwarding every prefix to one cluster.