diff --git a/cmd/audit-service/main.go b/cmd/audit-service/main.go index 1003982..871ae22 100644 --- a/cmd/audit-service/main.go +++ b/cmd/audit-service/main.go @@ -183,7 +183,13 @@ func registerLifecycle( serviceID := fmt.Sprintf("audit-service-%d", time.Now().Unix()) host := cfg.GetString("services.audit.host") if host == "" { - host = "localhost" + // In Docker, use service name for Consul to reach the service + // For local development, use localhost + if os.Getenv("ENVIRONMENT") == "production" || os.Getenv("DOCKER") == "true" { + host = "audit-service" // Docker service name + } else { + host = "localhost" + } } port := grpcServer.Port() diff --git a/cmd/auth-service/main.go b/cmd/auth-service/main.go index 4fc271e..be0e110 100644 --- a/cmd/auth-service/main.go +++ b/cmd/auth-service/main.go @@ -190,7 +190,13 @@ func registerLifecycle( serviceID := fmt.Sprintf("auth-service-%d", time.Now().Unix()) host := cfg.GetString("services.auth.host") if host == "" { - host = "localhost" + // In Docker, use service name for Consul to reach the service + // For local development, use localhost + if os.Getenv("ENVIRONMENT") == "production" || os.Getenv("DOCKER") == "true" { + host = "auth-service" // Docker service name + } else { + host = "localhost" + } } port := grpcServer.Port() diff --git a/cmd/authz-service/main.go b/cmd/authz-service/main.go index ea880a1..d214907 100644 --- a/cmd/authz-service/main.go +++ b/cmd/authz-service/main.go @@ -183,7 +183,13 @@ func registerLifecycle( serviceID := fmt.Sprintf("authz-service-%d", time.Now().Unix()) host := cfg.GetString("services.authz.host") if host == "" { - host = "localhost" + // In Docker, use service name for Consul to reach the service + // For local development, use localhost + if os.Getenv("ENVIRONMENT") == "production" || os.Getenv("DOCKER") == "true" { + host = "authz-service" // Docker service name + } else { + host = "localhost" + } } port := grpcServer.Port() diff --git a/cmd/identity-service/main.go b/cmd/identity-service/main.go index c79ba48..37416fb 100644 --- a/cmd/identity-service/main.go +++ b/cmd/identity-service/main.go @@ -183,7 +183,13 @@ func registerLifecycle( serviceID := fmt.Sprintf("identity-service-%d", time.Now().Unix()) host := cfg.GetString("services.identity.host") if host == "" { - host = "localhost" + // In Docker, use service name for Consul to reach the service + // For local development, use localhost + if os.Getenv("ENVIRONMENT") == "production" || os.Getenv("DOCKER") == "true" { + host = "identity-service" // Docker service name + } else { + host = "localhost" + } } port := grpcServer.Port() diff --git a/config/default.yaml b/config/default.yaml index 57df19d..fe57402 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -36,6 +36,8 @@ registry: timeout: "3s" deregister_after: "30s" http: "/healthz" + grpc: "grpc.health.v1.Health" + use_grpc: true services: audit: diff --git a/internal/di/providers.go b/internal/di/providers.go index b945e0b..e867427 100644 --- a/internal/di/providers.go +++ b/internal/di/providers.go @@ -218,8 +218,14 @@ func ProvideServiceRegistry() fx.Option { healthCheckDeregisterAfter = 30 * time.Second } healthCheckHTTP := cfg.GetString("registry.consul.health_check.http") - if healthCheckHTTP == "" { - healthCheckHTTP = "/healthz" + healthCheckGRPC := cfg.GetString("registry.consul.health_check.grpc") + useGRPC := cfg.GetBool("registry.consul.health_check.use_grpc") + // Default to gRPC if not explicitly set (services are gRPC by default) + if !cfg.IsSet("registry.consul.health_check.use_grpc") { + useGRPC = true + } + if healthCheckGRPC == "" { + healthCheckGRPC = "grpc.health.v1.Health" } consulCfg.HealthCheck = consul.HealthCheckConfig{ @@ -227,6 +233,8 @@ func ProvideServiceRegistry() fx.Option { Timeout: healthCheckTimeout, DeregisterAfter: healthCheckDeregisterAfter, HTTP: healthCheckHTTP, + GRPC: healthCheckGRPC, + UseGRPC: useGRPC, } return consul.NewRegistry(consulCfg) diff --git a/internal/registry/consul/consul.go b/internal/registry/consul/consul.go index f11c73c..82433f5 100644 --- a/internal/registry/consul/consul.go +++ b/internal/registry/consul/consul.go @@ -29,7 +29,9 @@ type HealthCheckConfig struct { Interval time.Duration // Health check interval Timeout time.Duration // Health check timeout DeregisterAfter time.Duration // Time to wait before deregistering unhealthy service - HTTP string // HTTP health check endpoint (e.g., "/healthz") + HTTP string // HTTP health check endpoint (e.g., "/healthz") - for HTTP services + GRPC string // gRPC health check service name (e.g., "grpc.health.v1.Health") - for gRPC services + UseGRPC bool // Whether to use gRPC health checks instead of HTTP } // NewRegistry creates a new Consul-based service registry. @@ -68,7 +70,21 @@ func (r *ConsulRegistry) Register(ctx context.Context, service *registry.Service } // Add health check if configured - if r.config.HealthCheck.HTTP != "" { + if r.config.HealthCheck.UseGRPC { + // Use gRPC health check for gRPC services + // Format: host:port/service or host:port (uses default health service) + grpcAddr := fmt.Sprintf("%s:%d", service.Address, service.Port) + if r.config.HealthCheck.GRPC != "" { + grpcAddr = fmt.Sprintf("%s:%d/%s", service.Address, service.Port, r.config.HealthCheck.GRPC) + } + registration.Check = &consulapi.AgentServiceCheck{ + GRPC: grpcAddr, + Interval: r.config.HealthCheck.Interval.String(), + Timeout: r.config.HealthCheck.Timeout.String(), + DeregisterCriticalServiceAfter: r.config.HealthCheck.DeregisterAfter.String(), + } + } else if r.config.HealthCheck.HTTP != "" { + // Use HTTP health check for HTTP services healthCheckURL := fmt.Sprintf("http://%s:%d%s", service.Address, service.Port, r.config.HealthCheck.HTTP) registration.Check = &consulapi.AgentServiceCheck{ HTTP: healthCheckURL,