HashiCorp Consul Service Discovery
Service mesh and configuration with Consul cluster, ACL, and UI.
Overview
HashiCorp Consul is a distributed service mesh solution that provides service discovery, configuration management, and secure service-to-service communication across any cloud or runtime environment. Originally developed by HashiCorp in 2014, Consul has become the backbone for microservices architectures requiring dynamic service registration, health checking, and distributed configuration management. Unlike simple key-value stores like etcd, Consul offers a comprehensive service networking platform with built-in DNS interface, HTTP API, and advanced features like service intentions for zero-trust networking.
This deployment creates a production-grade Consul cluster with three server nodes for high availability, complemented by Prometheus for metrics collection and Grafana for visualization. The three-server configuration ensures fault tolerance with proper quorum consensus, while the dedicated consul-agent demonstrates client-side service registration patterns. Prometheus integrates with Consul's built-in metrics endpoint to monitor cluster health, service discovery events, and performance metrics across the entire service mesh.
This stack is ideal for platform engineering teams implementing microservices architecture, DevOps engineers managing multi-datacenter deployments, and organizations transitioning from monolithic applications to distributed systems. The combination of Consul's service mesh capabilities with Prometheus monitoring provides complete visibility into service communication patterns, health status, and performance bottlenecks. Companies like Criteo, Citadel, and many Fortune 500 enterprises rely on similar Consul deployments to manage thousands of services across hybrid cloud environments.
Key Features
- Multi-raft consensus algorithm with 3-node server cluster for Byzantine fault tolerance
- DNS-based service discovery on port 8600 with automatic SRV record generation
- HTTP API for dynamic service registration and health check configuration
- Web UI dashboard for visual service topology and key-value store management
- Gossip protocol for efficient cluster membership and failure detection
- Built-in health checking with HTTP, TCP, and script-based health monitors
- Prometheus metrics integration with /v1/agent/metrics endpoint
- Key-value store with hierarchical configuration management and watch capabilities
Common Use Cases
- 1Microservices platforms requiring dynamic service registration and discovery
- 2Multi-region application deployments with cross-datacenter service communication
- 3Legacy application modernization with gradual service mesh adoption
- 4Configuration management for applications requiring real-time config updates
- 5Load balancer backends requiring automatic upstream service detection
- 6Development environments mimicking production service discovery patterns
- 7Container orchestration platforms needing external service registry integration
Prerequisites
- Minimum 2GB RAM for 3-node Consul cluster plus monitoring stack
- Available ports 8500 (HTTP), 8600 (DNS), 3000 (Grafana), 9090 (Prometheus)
- prometheus.yml configuration file in current directory with Consul scrape targets
- GRAFANA_PASSWORD environment variable set for admin authentication
- Understanding of service discovery concepts and REST API interaction
- Network connectivity allowing inter-container communication on consul_net bridge
For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms
docker-compose.yml
docker-compose.yml
1services: 2 consul-server-1: 3 image: hashicorp/consul:latest4 command: agent -server -bootstrap-expect=3 -ui -client=0.0.0.0 -bind=0.0.0.05 ports: 6 - "8500:8500"7 - "8600:8600/udp"8 environment: 9 - CONSUL_BIND_INTERFACE=eth010 volumes: 11 - consul_server_1:/consul/data12 networks: 13 - consul_net1415 consul-server-2: 16 image: hashicorp/consul:latest17 command: agent -server -retry-join=consul-server-1 -client=0.0.0.0 -bind=0.0.0.018 environment: 19 - CONSUL_BIND_INTERFACE=eth020 volumes: 21 - consul_server_2:/consul/data22 depends_on: 23 - consul-server-124 networks: 25 - consul_net2627 consul-server-3: 28 image: hashicorp/consul:latest29 command: agent -server -retry-join=consul-server-1 -client=0.0.0.0 -bind=0.0.0.030 environment: 31 - CONSUL_BIND_INTERFACE=eth032 volumes: 33 - consul_server_3:/consul/data34 depends_on: 35 - consul-server-136 networks: 37 - consul_net3839 consul-agent: 40 image: hashicorp/consul:latest41 command: agent -retry-join=consul-server-1 -client=0.0.0.0 -bind=0.0.0.042 environment: 43 - CONSUL_BIND_INTERFACE=eth044 depends_on: 45 - consul-server-146 networks: 47 - consul_net4849 prometheus: 50 image: prom/prometheus:latest51 ports: 52 - "9090:9090"53 volumes: 54 - ./prometheus.yml:/etc/prometheus/prometheus.yml55 - prometheus_data:/prometheus56 networks: 57 - consul_net5859 grafana: 60 image: grafana/grafana:latest61 ports: 62 - "3000:3000"63 environment: 64 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}65 volumes: 66 - grafana_data:/var/lib/grafana67 networks: 68 - consul_net6970volumes: 71 consul_server_1: 72 consul_server_2: 73 consul_server_3: 74 prometheus_data: 75 grafana_data: 7677networks: 78 consul_net: .env Template
.env
1# Consul Cluster2GRAFANA_PASSWORD=secure_grafana_password34# Consul UI at http://localhost:85005# DNS at localhost:8600Usage Notes
- 1Consul UI at http://localhost:8500
- 2DNS interface at port 8600/UDP
- 33-node server cluster for HA
- 4Service registration via API
- 5KV store for configuration
Individual Services(6 services)
Copy individual services to mix and match with your existing compose files.
consul-server-1
consul-server-1:
image: hashicorp/consul:latest
command: agent -server -bootstrap-expect=3 -ui -client=0.0.0.0 -bind=0.0.0.0
ports:
- "8500:8500"
- 8600:8600/udp
environment:
- CONSUL_BIND_INTERFACE=eth0
volumes:
- consul_server_1:/consul/data
networks:
- consul_net
consul-server-2
consul-server-2:
image: hashicorp/consul:latest
command: agent -server -retry-join=consul-server-1 -client=0.0.0.0 -bind=0.0.0.0
environment:
- CONSUL_BIND_INTERFACE=eth0
volumes:
- consul_server_2:/consul/data
depends_on:
- consul-server-1
networks:
- consul_net
consul-server-3
consul-server-3:
image: hashicorp/consul:latest
command: agent -server -retry-join=consul-server-1 -client=0.0.0.0 -bind=0.0.0.0
environment:
- CONSUL_BIND_INTERFACE=eth0
volumes:
- consul_server_3:/consul/data
depends_on:
- consul-server-1
networks:
- consul_net
consul-agent
consul-agent:
image: hashicorp/consul:latest
command: agent -retry-join=consul-server-1 -client=0.0.0.0 -bind=0.0.0.0
environment:
- CONSUL_BIND_INTERFACE=eth0
depends_on:
- consul-server-1
networks:
- consul_net
prometheus
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
networks:
- consul_net
grafana
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
volumes:
- grafana_data:/var/lib/grafana
networks:
- consul_net
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 consul-server-1:5 image: hashicorp/consul:latest6 command: agent -server -bootstrap-expect=3 -ui -client=0.0.0.0 -bind=0.0.0.07 ports:8 - "8500:8500"9 - "8600:8600/udp"10 environment:11 - CONSUL_BIND_INTERFACE=eth012 volumes:13 - consul_server_1:/consul/data14 networks:15 - consul_net1617 consul-server-2:18 image: hashicorp/consul:latest19 command: agent -server -retry-join=consul-server-1 -client=0.0.0.0 -bind=0.0.0.020 environment:21 - CONSUL_BIND_INTERFACE=eth022 volumes:23 - consul_server_2:/consul/data24 depends_on:25 - consul-server-126 networks:27 - consul_net2829 consul-server-3:30 image: hashicorp/consul:latest31 command: agent -server -retry-join=consul-server-1 -client=0.0.0.0 -bind=0.0.0.032 environment:33 - CONSUL_BIND_INTERFACE=eth034 volumes:35 - consul_server_3:/consul/data36 depends_on:37 - consul-server-138 networks:39 - consul_net4041 consul-agent:42 image: hashicorp/consul:latest43 command: agent -retry-join=consul-server-1 -client=0.0.0.0 -bind=0.0.0.044 environment:45 - CONSUL_BIND_INTERFACE=eth046 depends_on:47 - consul-server-148 networks:49 - consul_net5051 prometheus:52 image: prom/prometheus:latest53 ports:54 - "9090:9090"55 volumes:56 - ./prometheus.yml:/etc/prometheus/prometheus.yml57 - prometheus_data:/prometheus58 networks:59 - consul_net6061 grafana:62 image: grafana/grafana:latest63 ports:64 - "3000:3000"65 environment:66 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}67 volumes:68 - grafana_data:/var/lib/grafana69 networks:70 - consul_net7172volumes:73 consul_server_1:74 consul_server_2:75 consul_server_3:76 prometheus_data:77 grafana_data:7879networks:80 consul_net:81EOF8283# 2. Create the .env file84cat > .env << 'EOF'85# Consul Cluster86GRAFANA_PASSWORD=secure_grafana_password8788# Consul UI at http://localhost:850089# DNS at localhost:860090EOF9192# 3. Start the services93docker compose up -d9495# 4. View logs96docker compose logs -fOne-Liner
Run this command to download and set up the recipe in one step:
terminal
1curl -fsSL https://docker.recipes/api/recipes/consul-cluster/run | bashTroubleshooting
- Consul leader election failed: Check server logs for port conflicts and ensure all three servers can communicate on port 8300
- Service registration returns 500 error: Verify consul-agent is connected to cluster using 'consul members' command
- DNS queries to port 8600 timeout: Confirm CONSUL_BIND_INTERFACE=eth0 environment variable and UDP port exposure
- Prometheus cannot scrape Consul metrics: Add 'prometheus_retention_time' to Consul config and verify /v1/agent/metrics endpoint accessibility
- Grafana dashboard shows no data: Check Prometheus data source configuration points to prometheus:9090 internal hostname
- Consul UI shows failed health checks: Review service definition health check intervals and ensure target services respond correctly
Community Notes
Loading...
Loading notes...
Download Recipe Kit
Get all files in a ready-to-deploy package
Includes docker-compose.yml, .env template, README, and license
Components
consul-serverconsul-agentnginxprometheus
Tags
#consul#hashicorp#service-discovery#mesh#configuration
Category
DevOps & CI/CDAd Space
Shortcuts: C CopyF FavoriteD Download