Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Symfony Consul Bundle Laravel Package

akondas/symfony-consul-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle

    composer require akondas/symfony-consul-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        Akondas\ConsulBundle\ConsulBundle::class => ['all' => true],
    ];
    
  2. Configure in config/packages/consul.yaml

    consul:
        service:
            name: 'your-service-name'  # e.g., 'api-service'
            host: '%env(CONSUL_HOST)%'  # Defaults to 'localhost'
            port: '%env(int:CONSUL_PORT)%'  # Defaults to 8000
        client:
            base_uri: 'http://%env(CONSUL_SERVER)%:8500'  # Defaults to 'http://127.0.0.1:8500'
    
  3. Enable Routing (Optional) Add to config/routes.yaml:

    consul_bundle:
        resource: '@ConsulBundle/Resources/config/routing.yml'
    
  4. First Registration Run the registration command:

    php bin/console consul:register
    

    Verify in Consul UI (http://<consul-server>:8500/ui) under Services.


First Use Case: Dynamic Service Discovery

  • Scenario: Register a Symfony API service in Consul for service mesh discovery (e.g., with Envoy or Traefik).
  • Workflow:
    1. Configure consul.yaml with your service name (name: 'api-service').
    2. Run consul:register during deployment (e.g., in a post-deploy hook).
    3. Use Consul’s DNS (api-service.service.consul) or HTTP API to resolve the service dynamically in your app.

Implementation Patterns

1. Automated Registration in Deployment

  • Pattern: Trigger registration via a Symfony Event Listener (e.g., KernelEvents::TERMINATE).
    // src/EventListener/ConsulRegistrationListener.php
    namespace App\EventListener;
    
    use Akondas\ConsulBundle\Command\RegisterCommand;
    use Symfony\Component\HttpKernel\Event\TerminateEvent;
    use Symfony\Component\HttpKernel\KernelEvents;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    class ConsulRegistrationListener implements EventSubscriberInterface
    {
        public static function getSubscribedEvents(): array
        {
            return [
                KernelEvents::TERMINATE => 'registerService',
            ];
        }
    
        public function registerService(TerminateEvent $event): void
        {
            $command = new RegisterCommand();
            $command->run(new \Symfony\Component\Console\Input\ArrayInput([]), new \Symfony\Component\Console\Output\BufferedOutput());
        }
    }
    
    Pros: No manual CLI calls needed; service registers on app startup. Cons: Requires Consul client to be reachable at boot.

2. Health Checks with Custom Scripts

  • Pattern: Extend the default HTTP check with a custom script (e.g., a /health endpoint). Configure in consul.yaml:
    consul:
        service:
            checks:
                - name: 'HTTP API Health Check'
                  script: 'curl -s http://localhost:8000/health | grep -q "ok"'
                  interval: '10s'
    
    Use Case: Validate business logic (e.g., DB connectivity) beyond HTTP status.

3. Environment-Specific Config

  • Pattern: Use Symfony’s %env% for dynamic Consul server URLs.
    consul:
        client:
            base_uri: 'http://%env(CONSUL_SERVER)%:8500'
    
    Deployment Example:
    • Dev: CONSUL_SERVER=localhost
    • Prod: CONSUL_SERVER=consul.prod.example.com Tooling: Integrate with Ansible/Terraform to set CONSUL_SERVER via environment variables.

4. Deregistration on Shutdown

  • Pattern: Use a TerminateEvent listener to deregister gracefully.
    // src/EventListener/ConsulDeregistrationListener.php
    use Akondas\ConsulBundle\Command\DeregisterCommand;
    
    class ConsulDeregistrationListener implements EventSubscriberInterface
    {
        public static function getSubscribedEvents(): array
        {
            return [
                KernelEvents::TERMINATE => 'deregisterService',
            ];
        }
    
        public function deregisterService(TerminateEvent $event): void
        {
            $command = new DeregisterCommand();
            $command->run(new \Symfony\Component\Console\Input\ArrayInput([]), new \Symfony\Component\Console\Output\BufferedOutput());
        }
    }
    
    Why: Prevents "zombie" services in Consul after container crashes.

5. Integration with Docker/Kubernetes

  • Pattern: Use consul:register in a Docker entrypoint script or Kubernetes postStart hook. Example (Dockerfile):
    COPY docker-entrypoint.sh /usr/local/bin/
    RUN chmod +x /usr/local/bin/docker-entrypoint.sh
    ENTRYPOINT ["docker-entrypoint.sh"]
    
    docker-entrypoint.sh:
    #!/bin/sh
    php bin/console consul:register
    exec "$@"
    
    Kubernetes:
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "php bin/console consul:register"]
    

Gotchas and Tips

1. Consul Client Connectivity

  • Gotcha: If Consul’s base_uri is unreachable, the bundle silently fails. Debug:
    php bin/console debug:consul-check
    
    Fix: Use a retry mechanism (e.g., Guzzle middleware) or wrap the command in a try-catch:
    try {
        $command->run($input, $output);
    } catch (\Exception $e) {
        // Log and continue (e.g., for non-critical services)
        $this->logger->warning('Consul registration failed', ['error' => $e->getMessage()]);
    }
    

2. Port vs. Host Configuration

  • Gotcha: If your app binds to 0.0.0.0 (e.g., Docker), use host: '0.0.0.0' in consul.yaml. Example:
    consul:
        service:
            host: '0.0.0.0'  # Critical for Docker/K8s
            port: 8000
    
    Why: Consul advertises the service as http://0.0.0.0:8000, which works for internal service mesh traffic.

3. Health Check Failures

  • Gotcha: Default HTTP checks may fail if your app uses HTTPS internally. Fix: Configure a custom check:
    consul:
        service:
            checks:
                - name: 'HTTPS Health Check'
                  http: 'https://localhost:8000/health'
                  interval: '10s'
                  tls_skip_verify: true  # For self-signed certs
    

4. Service Name Collisions

  • Gotcha: Registering the same service name twice (e.g., multiple containers) causes conflicts. Solution:
    • Use unique suffixes (e.g., api-service-{{HOSTNAME}}).
    • Leverage Consul’s tags to distinguish environments:
      consul:
          service:
              tags: ['env=prod', 'version=v1.2']
      

5. Debugging Commands

  • Tip: Use debug:consul-check to validate checks before registration:
    php bin/console debug:consul-check
    
    Output Example:
    [OK] HTTP check for http://localhost:8000/health passed (status: 200)
    [WARN] Script check failed: "curl: (7) Failed to connect to localhost port 8000: Connection refused"
    

6. Extending the Bundle

  • Extension Point: Override the service definition by extending the bundle’s ConsulService class. Example:
    // src/Consul/CustomConsulService.php
    namespace App\Consul;
    
    use Akondas\ConsulBundle\Service\ConsulService as BaseConsulService;
    
    class CustomConsulService extends BaseConsulService
    {
        public function getServiceDefinition(): array
        {
            $definition = parent::getServiceDefinition();
            $definition['meta'] = ['team' => 'backend
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle