dapservant/laravel-consul

Laravel package for Consul integration - Service discovery, registration, and health checks

Installs: 99

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Forks: 0

pkg:composer/dapservant/laravel-consul

1.2.0 2026-01-15 14:56 UTC

This package is not auto-updated.

Last update: 2026-01-29 15:11:29 UTC


README

GitHub release GitHub Tests GitHub Code Style

Un package Laravel développé par Dap pour intégrer facilement votre application avec HashiCorp Consul. Gérez la découverte de services, l'enregistrement automatique et les health checks de manière simple et élégante.

✨ Fonctionnalités

  • 🚀 Enregistrement manuel ou automatique de services dans Consul
    • Mode manuel : contrôle complet via commandes Artisan
    • Mode automatique : enregistrement au démarrage de l'application
  • 🔐 Deux modes de connexion
    • Mode Direct : Connexion directe à Consul avec ACL tokens
    • Mode Gateway : Connexion via Gateway sécurisée avec OAuth2 (Keycloak) ✨ Nouveau v1.2.0
  • 🔍 Découverte de services avec mise en cache intelligente
  • ❤️ Health checks configurables et personnalisables (HTTP/HTTPS)
  • 🔐 Support HTTPS/TLS pour les connexions sécurisées
  • 🎫 Authentification OAuth2 Client Credentials avec cache automatique des tokens
  • 🏷️ Tags et métadonnées pour organiser vos services
  • 🛠️ Commandes Artisan intuitives pour la gestion
  • ⚙️ Configuration flexible via variables d'environnement
  • 🎯 Support multi-instances pour la scalabilité
  • 🔑 Authentification ACL avec tokens Consul
  • 🧪 Suite de tests complète avec 57+ tests

📋 Prérequis

  • PHP 8.1+
  • Laravel 10.x, 11.x, ou 12.x
  • HashiCorp Consul server (mode direct) ou Gateway Consul (mode gateway)
  • Accès au repository GitLab privé Dap

🚀 Installation

1. Installer le package

composer require dapservant/laravel-consul

2. Publication de la configuration

php artisan vendor:publish --tag=consul-config

3. Configuration des variables d'environnement

Le package supporte deux modes de connexion : Direct et Gateway.

🔌 Modes de connexion

Mode Direct (connexion directe à Consul)

Connexion directe à Consul avec support des ACL tokens.

Architecture :

Laravel App → Consul Server

Configuration .env :

# Mode de connexion
CONSUL_CONNECTION_MODE=direct

# Configuration Consul
CONSUL_HOST=localhost:8500
CONSUL_SCHEME=http
CONSUL_TLS_ENABLED=false

# ACL Token (optionnel)
CONSUL_TOKEN=
CONSUL_TOKEN_HEADER=X-Consul-Token

# Configuration du service
CONSUL_SERVICE_NAME=${APP_NAME}
CONSUL_SERVICE_HOST=localhost
CONSUL_SERVICE_PORT=${APP_PORT:-8000}
CONSUL_SERVICE_ID=${APP_NAME}-${APP_ENV}

# Auto-registration
CONSUL_AUTO_REGISTER=false
CONSUL_AUTO_DEREGISTER_ON_SHUTDOWN=true

# Health Check
CONSUL_HEALTH_CHECK_ENABLED=true
CONSUL_HEALTH_CHECK_ENDPOINT=/health
CONSUL_HEALTH_CHECK_INTERVAL=10s
CONSUL_HEALTH_CHECK_TIMEOUT=5s
CONSUL_HEALTH_CHECK_AUTO_DEREGISTER=true
CONSUL_HEALTH_CHECK_DEREGISTER_AFTER=30m

Mode Gateway (via Gateway + OAuth2) ✨ Nouveau v1.2.0

Connexion sécurisée via une Gateway avec authentification OAuth2 Keycloak.

Architecture :

Laravel App → Gateway (OAuth2 Keycloak) → Consul Server

Avantages :

  • 🔐 Authentification centralisée via Keycloak
  • 🎫 Tokens Bearer avec renouvellement automatique
  • 🛡️ Couche de sécurité supplémentaire
  • 🌐 Ideal pour architectures microservices avec API Gateway

Configuration .env :

# Mode de connexion
CONSUL_CONNECTION_MODE=gateway

# Configuration Gateway
GATEWAY_URL=https://xxxxxx/my-gateway
GATEWAY_CLIENT_ID=my-client
GATEWAY_CLIENT_SECRET=MY_CLIENT_SECRET

# Cache des tokens (recommandé)
GATEWAY_TOKEN_CACHE_ENABLED=true
GATEWAY_TOKEN_CACHE_TTL=240  # 4 minutes (token valide 5 min)
GATEWAY_TOKEN_CACHE_KEY=consul_gateway_token

# Configuration du service
CONSUL_SERVICE_NAME=${APP_NAME}
CONSUL_SERVICE_HOST=app.example.com
CONSUL_SERVICE_PORT=443
CONSUL_SERVICE_ID=${APP_NAME}-${APP_ENV}

# Auto-registration
CONSUL_AUTO_REGISTER=true
CONSUL_AUTO_DEREGISTER_ON_SHUTDOWN=true

# Health Check
CONSUL_HEALTH_CHECK_ENABLED=true
CONSUL_HEALTH_CHECK_ENDPOINT=/health
CONSUL_HEALTH_CHECK_INTERVAL=10s
CONSUL_HEALTH_CHECK_TIMEOUT=5s
CONSUL_HEALTH_CHECK_AUTO_DEREGISTER=true
CONSUL_HEALTH_CHECK_DEREGISTER_AFTER=30m

Tableau comparatif des modes

CaractéristiqueMode DirectMode Gateway
AuthentificationACL Token ConsulOAuth2 Client Credentials
ConnexionDirecte à ConsulVia Gateway API
SécuritéToken statiqueToken dynamique avec expiration
Cache de tokenNon applicableOui, avec TTL configurable
Renouvellement autoNonOui, avant expiration
Use caseInfra simple, réseau sécuriséMicroservices, multi-tenant
ConfigurationCONSUL_HOST, CONSUL_TOKENGATEWAY_URL, GATEWAY_CLIENT_ID

4. Créer l'endpoint de santé

Créez un endpoint de santé pour Consul dans routes/api.php :

Route::get('/health', function () {
    return response()->json([
        'status' => 'healthy',
        'timestamp' => now(),
        'service' => config('consul.service.name'),
        'version' => config('consul.meta.version', '1.0.0')
    ]);
});

📖 Utilisation

🎯 Modes d'enregistrement

Le package supporte deux modes d'enregistrement distincts :

Mode Manuel (recommandé pour développement local)

CONSUL_AUTO_REGISTER=false
# Enregistrer manuellement le service
php artisan consul:register

# Désenregistrer manuellement le service
php artisan consul:deregister

Mode Automatique (recommandé pour production)

CONSUL_AUTO_REGISTER=true
CONSUL_AUTO_DEREGISTER_ON_SHUTDOWN=true

Le service s'enregistre automatiquement au démarrage et se désenregistre à l'arrêt.

Commandes Artisan

Les commandes fonctionnent de manière identique dans les deux modes (direct et gateway).

# Enregistrer un service
php artisan consul:register

# Avec paramètres personnalisés
php artisan consul:register --name=mon-service --host=192.168.1.100 --port=8080

# Désenregistrer un service
php artisan consul:deregister

# Désenregistrer un service spécifique
php artisan consul:deregister mon-service-id

# Lister tous les services
php artisan consul:services

# Services locaux uniquement
php artisan consul:services --local

# État de santé d'un service
php artisan consul:services --health=mon-service

Utilisation programmatique

Le code reste identique quel que soit le mode (direct ou gateway) :

Via la facade

use Dap\LaravelConsul\Facades\Consul;

// Enregistrer un service (fonctionne en mode direct et gateway)
$response = Consul::registerService();

if ($response->successful()) {
    echo "Service enregistré avec succès !";
}

// Découvrir des services
$services = Consul::discoverService('user-service');
foreach ($services as $service) {
    echo "Service trouvé : {$service['ServiceAddress']}:{$service['ServicePort']}";
}

// Obtenir tous les services
$allServices = Consul::getAllServices();

// Services locaux
$localServices = Consul::getLocalServices();

// Vérifier la santé d'un service
$health = Consul::getServiceHealth('payment-service');

Via l'injection de dépendance

use Dap\LaravelConsul\Services\ConsulAgentService;

class MicroserviceController extends Controller
{
    public function __construct(private ConsulAgentService $consul) {}
    
    public function discover()
    {
        // Fonctionne automatiquement en mode direct ou gateway
        $services = $this->consul->discoverService('user-service');
        
        return response()->json($services);
    }
    
    public function register()
    {
        $response = $this->consul->registerService([
            'name' => 'custom-service',
            'host' => '192.168.1.100',
            'port' => 9000,
            'id' => 'custom-service-production'
        ]);
        
        return $response->successful() 
            ? 'Service enregistré !' 
            : 'Erreur : ' . $response->body();
    }
}

⚙️ Configuration

Mode de connexion

// config/consul.php

// Mode : 'direct' ou 'gateway'
'connection_mode' => env('CONSUL_CONNECTION_MODE', 'direct'),

Configuration Direct

'host' => env('CONSUL_HOST', '127.0.0.1:8500'),
'scheme' => env('CONSUL_SCHEME', 'http'),
'tls_enabled' => env('CONSUL_TLS_ENABLED', false),
'token' => env('CONSUL_TOKEN'),
'token_header' => env('CONSUL_TOKEN_HEADER', 'X-Consul-Token'),

Configuration Gateway ✨ Nouveau v1.2.0

'gateway' => [
    'url' => env('GATEWAY_URL', 'https://xxxxxx/my-gateway'),
    'client_id' => env('GATEWAY_CLIENT_ID', ''),
    'client_secret' => env('GATEWAY_CLIENT_SECRET', ''),
    'token_cache_enabled' => env('GATEWAY_TOKEN_CACHE_ENABLED', true),
    'token_cache_ttl' => env('GATEWAY_TOKEN_CACHE_TTL', 240), // 4 minutes
    'token_cache_key' => env('GATEWAY_TOKEN_CACHE_KEY', 'consul_gateway_token'),
],

Configuration du service

'service' => [
    'name' => env('CONSUL_SERVICE_NAME', env('APP_NAME', 'laravel-app')),
    'host' => env('CONSUL_SERVICE_HOST', 'localhost'),
    'port' => env('CONSUL_SERVICE_PORT', env('APP_PORT', 8000)),
    'id' => env('CONSUL_SERVICE_ID', env('APP_NAME', 'laravel-app')),
],

Auto-registration

'auto_register' => env('CONSUL_AUTO_REGISTER', false),
'auto_deregister_on_shutdown' => env('CONSUL_AUTO_DEREGISTER_ON_SHUTDOWN', true),

Health checks

'health_check' => [
    'enabled' => env('CONSUL_HEALTH_CHECK_ENABLED', true),
    'endpoint' => env('CONSUL_HEALTH_CHECK_ENDPOINT', '/health'),
    'interval' => env('CONSUL_HEALTH_CHECK_INTERVAL', '10s'),
    'timeout' => env('CONSUL_HEALTH_CHECK_TIMEOUT', '5s'),
    'auto_deregister' => env('CONSUL_HEALTH_CHECK_AUTO_DEREGISTER', true),
    'deregister_after' => env('CONSUL_HEALTH_CHECK_DEREGISTER_AFTER', '30m'),
],

🔐 Authentification

Mode Direct : ACL Consul

Authentification via tokens ACL Consul.

CONSUL_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
CONSUL_TOKEN_HEADER=X-Consul-Token

Le token est automatiquement injecté dans toutes les requêtes via le header X-Consul-Token.

Mode Gateway : OAuth2 Keycloak ✨ Nouveau v1.2.0

Authentification OAuth2 avec grant type client_credentials.

GATEWAY_URL=https://xxxxxx/my-gateway
GATEWAY_CLIENT_ID=my-client
GATEWAY_CLIENT_SECRET=MY_CLIENT_SECRET

Fonctionnement :

  1. Authentification initiale :

    POST https://xxxxxx/my-gateway/authx
    Content-Type: application/x-www-form-urlencoded
       
    grant_type=client_credentials
    client_id=my-client
    client_secret=MY_CLIENT_SECRET
    
  2. Réponse :

    {
      "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIg...",
      "expires_in": 300,
      "token_type": "Bearer"
    }
    
  3. Utilisation du token :

    PUT https://xxxxxx/my-gateway/v1/agent/service/register
    Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIg...
    Content-Type: application/json
       
    { ... payload Consul ... }
    

Gestion automatique :

  • ✅ Cache du token avec TTL configurable
  • ✅ Renouvellement automatique avant expiration
  • ✅ Retry automatique sur erreur 401
  • ✅ Invalidation du cache en cas d'erreur

🔧 Exemples de configuration par environnement

Développement local (Mode Direct)

CONSUL_CONNECTION_MODE=direct
CONSUL_HOST=localhost:8500
CONSUL_SCHEME=http
CONSUL_AUTO_REGISTER=false  # Manuel pour le debug

Staging (Mode Gateway)

CONSUL_CONNECTION_MODE=gateway
GATEWAY_URL=https://staging-gateway.dap.local/my-gateway
GATEWAY_CLIENT_ID=staging-client
GATEWAY_CLIENT_SECRET=${STAGING_CLIENT_SECRET}
CONSUL_AUTO_REGISTER=true

Production (Mode Gateway + HTTPS)

CONSUL_CONNECTION_MODE=gateway
GATEWAY_URL=https://prod-gateway.dap.local/my-gateway
GATEWAY_CLIENT_ID=prod-client
GATEWAY_CLIENT_SECRET=${PROD_CLIENT_SECRET}

# Service HTTPS
CONSUL_SERVICE_HOST=api-payment.dap.local
CONSUL_SERVICE_PORT=443
CONSUL_SCHEME=https
CONSUL_TLS_ENABLED=true

# Auto-registration
CONSUL_AUTO_REGISTER=true
CONSUL_AUTO_DEREGISTER_ON_SHUTDOWN=true

# Cache de tokens
GATEWAY_TOKEN_CACHE_ENABLED=true
GATEWAY_TOKEN_CACHE_TTL=240

Docker (Mode Gateway)

CONSUL_CONNECTION_MODE=gateway
GATEWAY_URL=https://gateway.dap.local/my-gateway
GATEWAY_CLIENT_ID=docker-client
GATEWAY_CLIENT_SECRET=${DOCKER_CLIENT_SECRET}

CONSUL_SERVICE_NAME=payment-api
CONSUL_SERVICE_HOST=payment-api-container
CONSUL_SERVICE_PORT=8000

CONSUL_AUTO_REGISTER=true
CONSUL_AUTO_DEREGISTER_ON_SHUTDOWN=true

🧪 Tests

Le package inclut une suite de tests complète couvrant les deux modes de connexion.

# Lancer tous les tests
./vendor/bin/phpunit

# Tests avec couverture
./vendor/bin/phpunit --coverage-html coverage

# Tests spécifiques
./vendor/bin/phpunit tests/Unit/KeycloakAuthServiceTest.php
./vendor/bin/phpunit tests/Feature/GatewayConsulServiceTest.php
./vendor/bin/phpunit tests/Unit/ConsulAgentServiceTest.php
./vendor/bin/phpunit tests/Feature/ConsulCommandsTest.php

Résultats des tests

Tests: 57+, Assertions: 102+, Failures: 0 ✅
Couverture de code: 90%+

Tests par catégorie

CatégorieTestsDescription
KeycloakAuthService6 testsAuthentification OAuth2, cache, refresh
GatewayConsulService8 testsOpérations via Gateway, retry 401
ConsulAgentService11 testsMode direct, ACL, health checks
Commands11 testsCommandes Artisan
Auto-registration11 testsEnregistrement automatique
Facade10+ testsFacade et intégration

🐛 Dépannage

Mode Direct

Connection refused

# Vérifier que Consul est démarré
consul agent -dev

# Tester la connectivité
curl http://localhost:8500/v1/status/leader

Permission denied (ACL)

# Vérifier le token
curl -H "X-Consul-Token: $CONSUL_TOKEN" \
     http://localhost:8500/v1/catalog/services

Mode Gateway ✨ Nouveau v1.2.0

Failed to obtain access token

Erreur :

Failed to obtain access token from Gateway

Solutions :

  1. Vérifier les credentials :

    # Test manuel
    curl -X POST https://xxxxxx/my-gateway/authx \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "grant_type=client_credentials" \
      -d "client_id=my-client" \
      -d "client_secret=MY_CLIENT_SECRET"
    
  2. Vérifier la configuration :

    grep GATEWAY .env
    
  3. Vérifier les logs :

    tail -f storage/logs/laravel.log | grep "access token"
    

Token expired / 401 Unauthorized

Le package gère automatiquement le renouvellement, mais si vous rencontrez des problèmes :

# Vider le cache des tokens
php artisan cache:forget consul_gateway_token

# Forcer un nouveau token
php artisan tinker
>>> app(\Dap\LaravelConsul\Services\KeycloakAuthService::class)->refreshToken();

Gateway timeout

# Augmenter le TTL du cache
GATEWAY_TOKEN_CACHE_TTL=240  # 4 minutes (avant expiration de 5 min)

Logs et debugging

Mode Direct

# Vérifier les logs Laravel
tail -f storage/logs/laravel.log | grep Consul

# Debug HTTP
APP_DEBUG=true
LOG_LEVEL=debug

Mode Gateway

# Logs d'authentification
tail -f storage/logs/laravel.log | grep "access token"

# Logs des requêtes Gateway
tail -f storage/logs/laravel.log | grep Gateway

# Vérifier le cache
php artisan tinker
>>> Cache::get('consul_gateway_token');

Commandes utiles pour le debugging

# Mode Direct
curl http://localhost:8500/v1/catalog/services
curl http://localhost:8500/v1/agent/services

# Mode Gateway
curl -X POST https://xxxxxx/my-gateway/authx \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=my-client" \
  -d "client_secret=MY_CLIENT_SECRET"

curl -H "Authorization: Bearer $TOKEN" \
  https://xxxxxx/my-gateway/v1/catalog/services

🔄 Migration entre modes

Passer de Direct à Gateway

  1. Mettre à jour .env :

    # Avant
    CONSUL_CONNECTION_MODE=direct
    CONSUL_HOST=localhost:8500
    CONSUL_TOKEN=xxx
       
    # Après
    CONSUL_CONNECTION_MODE=gateway
    GATEWAY_URL=https://xxxxxx/my-gateway
    GATEWAY_CLIENT_ID=my-client
    GATEWAY_CLIENT_SECRET=MY_CLIENT_SECRET
    
  2. Aucun changement de code nécessaire ! ✅

  3. Tester :

    php artisan consul:register
    php artisan consul:services
    

Passer de Gateway à Direct

  1. Mettre à jour .env :

    # Avant
    CONSUL_CONNECTION_MODE=gateway
    GATEWAY_URL=https://xxxxxx/my-gateway
       
    # Après
    CONSUL_CONNECTION_MODE=direct
    CONSUL_HOST=localhost:8500
    CONSUL_TOKEN=xxx
    
  2. Aucun changement de code nécessaire ! ✅

🛠️ Développement

Structure du projet

src/
├── Console/Commands/           # Commandes Artisan
│   ├── ConsulRegisterCommand.php
│   ├── ConsulDeregisterCommand.php
│   └── ConsulServicesCommand.php
├── Facades/                    # Facades Laravel
│   └── Consul.php
├── Services/                   # Services métier
│   ├── ConsulAgentService.php      # Mode Direct
│   ├── GatewayConsulService.php    # Mode Gateway ✨ v1.2.0
│   └── KeycloakAuthService.php     # Auth OAuth2 ✨ v1.2.0
└── ConsulServiceProvider.php   # Service Provider

tests/
├── Feature/                    # Tests d'intégration
│   ├── ConsulCommandsTest.php
│   ├── ConsulAutoRegistrationTest.php
│   └── GatewayConsulServiceTest.php     # ✨ v1.2.0
├── Unit/                       # Tests unitaires
│   ├── ConsulAgentServiceTest.php
│   ├── ConsulFacadeTest.php
│   └── KeycloakAuthServiceTest.php      # ✨ v1.2.0
└── TestCase.php               # Base des tests

config/
└── consul.php                 # Configuration du package

Architecture technique

┌─────────────────────┐
│   Laravel App       │
│                     │
│  - Controllers      │
│  - Commands         │
│  - Middleware       │
└──────────┬──────────┘
           │
           ├─────────────────────────────────┐
           │                                 │
           ▼                                 ▼
┌────────────────────┐           ┌────────────────────┐
│  ConsulAgentService│           │ GatewayConsulService│
│   (Mode Direct)    │           │   (Mode Gateway)   │
└──────────┬─────────┘           └──────────┬─────────┘
           │                                 │
           │                                 ├─────────────┐
           │                                 │             │
           │                                 ▼             ▼
           │                     ┌────────────────────┐   │
           │                     │ KeycloakAuthService│   │
           │                     │  (OAuth2 + Cache)  │   │
           │                     └────────────────────┘   │
           │                                 │             │
           ▼                                 ▼             │
┌─────────────────┐              ┌─────────────────┐     │
│  Consul Server  │              │     Gateway     │◄────┘
│  (HTTP/HTTPS)   │              │   (OAuth2 +     │
│                 │              │  Consul Proxy)  │
│  - ACL          │              └────────┬────────┘
│  - Services     │                       │
│  - Health       │                       ▼
└─────────────────┘              ┌─────────────────┐
                                 │  Consul Server  │
                                 │  (Backend)      │
                                 └─────────────────┘

📈 Roadmap

Version 1.3 (Planifié Q1 2025)

  • [ ] Cache intelligent des découvertes de services
  • [ ] Métriques Prometheus/Grafana
  • [ ] Support Docker Compose avec exemple complet
  • [ ] Retry configurable avec backoff exponentiel
  • [ ] Health check personnalisable par service

Version 1.4 (Planifié Q2 2025)

  • [ ] Interface web de gestion
  • [ ] Integration avec Laravel Horizon
  • [ ] Support Consul Connect (Service Mesh)
  • [ ] Load balancing automatique
  • [ ] Dashboard temps réel

Version 2.0 (Futur)

  • [ ] Support Consul KV Store
  • [ ] Support Consul Sessions
  • [ ] Support Consul Prepared Queries
  • [ ] Multi-datacenter support

🏆 Historique des versions

VersionDateChangements principaux
v1.2.02025-01-15✨ Mode Gateway avec OAuth2 Keycloak, Cache intelligent des tokens
v1.1.02025-01-10✨ Support HTTPS/TLS, Auto-registration, ACL headers configurables
v1.0.12025-01-05🐛 Corrections de bugs mineurs
v1.0.02025-01-01🎉 Release initiale

🤝 Contribution

Les contributions de l'équipe Dap sont les bienvenues !

🔒 Sécurité

Si vous découvrez une vulnérabilité de sécurité, veuillez contacter l'équipe sécurité Dap en interne.

Contact sécurité : security@dap.local

📄 Licence

Ce package est sous licence MIT pour usage interne Dap.

🙏 Remerciements

  • HashiCorp pour Consul
  • Laravel pour le framework
  • Keycloak pour OAuth2/OpenID Connect
  • L'équipe Dap/SED pour le support et les tests

📚 Ressources

Documentation externe

Ressources internes Dap

  • Standards de développement Dap
  • Architecture microservices Dap
  • Guide d'infrastructure Consul Dap
  • Guide Gateway API Dap
  • Procédures OAuth2/Keycloak

📊 Statistiques

  • Lignes de code : ~2,000+
  • Tests : 57+ tests
  • Assertions : 102+ assertions
  • Couverture : 90%+
  • Documentation : 100%
**Développé avec ❤️ par l'équipe Dap/SED** *Usage interne exclusif* [Documentation](https://gitlab.dap.local/packages/laravel-consul) • [Issues](https://gitlab.dap.local/packages/laravel-consul/issues) • [Changelog](CHANGELOG.md)