In this tutorial, we'll learn how to install and configure Envoy Proxy on AlmaLinux 10.
What Is Envoy Proxy and Why Use It?
Envoy is a high-performance, open-source Layer 7 proxy designed for modern cloud-native applications. Originally developed by Lyft, it has grown into one of the most widely adopted proxies for microservices and service mesh architectures.
Key benefits:
- Advanced load balancing: Outlier detection, retries, circuit breaking.
- Service discovery support: Works with Consul, Kubernetes, DNS, and custom SDS.
- First-class observability: Metrics, logging, and distributed tracing.
- HTTP/2 and gRPC support: Ideal for modern APIs.
- Security: mTLS, rate limiting, and RBAC with extensions.
- Service mesh-ready: Core component of Istio and other meshes.
You’ll likely use Envoy when building a large-scale API platform, managing microservice traffic, deploying an edge proxy, or integrating a service mesh.
Prerequisites
Before we begin, ensure we have the following:
- An AlmaLinux 10 on dedicated server or KVM VPS.
- Basic Linux Command Line Knowledge.
Install Envoy Proxy on AlmaLinux 10
Step 1: Update packages
sudo dnf update -y
Step 2: Install Docker
Add Docker repo
sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
Install Docker Engine
sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
Enable and start Docker
sudo systemctl enable --now docker
Verify installation
docker --version
docker info
Pull Envoy Proxy Docker Image
docker pull envoyproxy/envoy:v1.36-latest
We use an official build from Envoy Proxy’s maintainers.
Step 3: Create envoy.yaml (Minimal Working Example)
We’ll start with a clean, minimal config and expand later.
Create:
sudo mkdir -p /etc/envoy
sudo nano /etc/envoy/envoy.yaml
Paste the following minimal configuration:
static_resources:
listeners:
- name: listener_8080
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
route_config:
name: local_route
virtual_hosts:
- name: backend
domains: ["*"]
routes:
- match: { prefix: "/" }
route: { cluster: local_service }
http_filters:
- name: envoy.filters.http.router
clusters:
- name: local_service
connect_timeout: 2s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: local_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 9001
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address:
address: 0.0.0.0
port_value: 9901
This config:
Listens on port 8080
Routes all paths / → upstream service on 127.0.0.1:9001
Enables Envoy’s admin panel on port 9901
You’ll replace this upstream soon.
Run Envoy in Docker (CLI + Docker Compose)
Option 1: Run Envoy directly
docker run -d \
--name envoy \
-p 8080:8080 \
-p 9901:9901 \
-v /etc/envoy/envoy.yaml:/etc/envoy/envoy.yaml \
envoyproxy/envoy:v1.32-latest
Option 2: Docker Compose
Create /etc/envoy/docker-compose.yml:
services:
envoy:
image: envoyproxy/envoy:v1.32-latest
container_name: envoy
volumes:
- ./envoy.yaml:/etc/envoy/envoy.yaml
ports:
- "8080:8080"
- "9901:9901"
restart: unless-stopped
Save and exit the file.
Run it:
docker compose up -d
Check logs:
docker logs -f envoy
Test Envoy
If your backend service on port 9001 is running:
curl -v http://localhost:8080/
Admin dashboard:
http://SERVER-IP:9901
Add Upstream Backend Services (3 Servers Example)
Now the real-world scenario: routing request load to three backend API servers.
Servers:
10.0.0.11 (orders node 1)
10.0.0.12 (orders node 2)
10.0.0.13 (orders node 3)
All running on port 9001 for this example.
We will modify the cluster config to load balance between the three.
Configure Reverse Proxy for /api/orders
Secondary keyword: AlmaLinux 10 reverse proxy included.
Open your config:
sudo nano /etc/envoy/envoy.yaml
Replace everything under route_config with a more advanced setup:
Full Working Envoy YAML with Multi-Server Routing
static_resources:
listeners:
- name: listener_8080
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
route_config:
name: api_routes
virtual_hosts:
- name: orders_backend
domains: ["*"]
routes:
- match:
prefix: "/api/orders"
route:
cluster: orders_cluster
- match:
prefix: "/"
route:
cluster: fallback_cluster
http_filters:
- name: envoy.filters.http.router
clusters:
- name: orders_cluster
connect_timeout: 2s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: orders_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 10.0.0.11
port_value: 9001
- endpoint:
address:
socket_address:
address: 10.0.0.12
port_value: 9001
- endpoint:
address:
socket_address:
address: 10.0.0.13
port_value: 9001
- name: fallback_cluster
connect_timeout: 2s
type: STATIC
load_assignment:
cluster_name: fallback_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 9001
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address:
address: 0.0.0.0
port_value: 9901
What this config does
Feature Explanation
/api/ordersLoad balances across 3 backend serversROUND_ROBINFair distribution of requests- fallback_cluster Catch-all for non-orders paths
- Admin interface Enables Envoy metrics, stats, logs
Test the /api/orders route
curl -v http://localhost:8080/api/orders
Run multiple times to watch the load balancing.
Monitoring & Logs
Envoy exposes metrics, logs, and admin controls.
Access admin UI
http://YOUR-IP:9901/server_info
http://YOUR-IP:9901/stats
http://YOUR-IP:9901/clusters
Check Docker logs
docker logs envoy
Enable access logs
Add this to HttpConnectionManager:
access_log:
- name: envoy.access_loggers.file
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
path: /tmp/envoy_access.log
Restart Envoy:
docker restart envoy
Production Hardening
1. Limit resource usage
Use Docker resource constraints:
deploy:
resources:
limits:
cpus: "1.0"
memory: "1G"
2. Enable health checks
health_checks:
- timeout: 1s
interval: 3s
healthy_threshold: 1
unhealthy_threshold: 3
http_health_check:
path: "/health"
3. Use static tagged images
Avoid latest:
envoyproxy/envoy:v1.36.3
4. Put Envoy behind a firewall
Restrict admin panel to internal/IP whitelist.
5. Configure TLS termination
Add:
transport_socket:
name: envoy.transport_sockets.tls
Follow official docs:
https://www.envoyproxy.io/docs/envoy/latest
Conclusion
You now have a production-ready Envoy Proxy running inside Docker on AlmaLinux 10. This setup gives you:
- High-performance reverse proxying
- Load balancing across multiple backend servers
- Centralized admin interface
- Docker-based portability
- Full YAML configuration flexibility
Whether deploying microservices, API gateways, or service mesh components, Envoy on AlmaLinux 10 is a stable and scalable foundation.
Frequently Asked Questions
1. What is Envoy Proxy used for?
Envoy is a high-performance Layer 4/Layer 7 proxy used for reverse proxying, service mesh sidecars, routing, retries, metrics, and observability.
2. Can I run Envoy on AlmaLinux 10?
Yes. Using Docker is the simplest, most stable approach.
3. Does Envoy support load balancing?
Yes. It supports ROUND_ROBIN, LEAST_REQUEST, and MAGLEV.
4. How do I expose Envoy’s admin dashboard?
Expose port 9901 and access /server_info, /stats, and /clusters.
5. Can Envoy reverse proxy multiple backend servers?
Yes. In this tutorial, /api/orders routes across three servers.
