This guide explains how to expose your Neo4j deployments for access from outside the Kubernetes cluster.
The Neo4j Kubernetes Operator supports multiple methods for external access:
- Port Forwarding - Quick access for development/testing
- LoadBalancer - Cloud provider managed load balancers
- NodePort - Direct node access (on-premise/development)
- Ingress - HTTP/HTTPS access through ingress controllers
The fastest way to access Neo4j during development:
# For Neo4jEnterpriseCluster
kubectl port-forward svc/my-cluster-client 7474:7474 7687:7687
# For Neo4jEnterpriseStandalone
kubectl port-forward svc/my-standalone-service 7474:7474 7687:7687Access Neo4j Browser at: http://localhost:7474
apiVersion: neo4j.io/v1alpha1
kind: Neo4jEnterpriseCluster
metadata:
name: production-cluster
spec:
service:
type: LoadBalancer
annotations:
# AWS Network Load Balancer
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
# GCP Load Balancer
# cloud.google.com/load-balancer-type: "Internal"
# Azure Load Balancer
# service.beta.kubernetes.io/azure-load-balancer-internal: "true"After deployment:
# Get the external IP/hostname
kubectl get svc production-cluster-clientspec:
service:
type: NodePortAccess via any node IP and the assigned port:
# Get the node port
kubectl get svc my-cluster-client -o jsonpath='{.spec.ports[?(@.name=="bolt")].nodePort}'Note: Currently, Ingress needs to be manually created for Neo4jEnterpriseCluster and is not yet supported for Neo4jEnterpriseStandalone.
spec:
service:
ingress:
enabled: true
className: nginx
host: neo4j.example.com
tlsSecretName: neo4j-tls
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"After configuring external access:
- Port Forward: http://localhost:7474
- LoadBalancer: http://:7474
- NodePort: http://:
- Ingress: https://neo4j.example.com
- Port Forward: bolt://localhost:7687
- LoadBalancer: bolt://:7687
- NodePort: bolt://:
- With TLS: bolt+ssc://:7687
spec:
tls:
mode: cert-manager
issuerRef:
name: ca-cluster-issuer
kind: ClusterIssuerFor LoadBalancer services, use source ranges:
spec:
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-source-ranges: "10.0.0.0/8,172.16.0.0/12"spec:
auth:
adminSecretName: neo4j-admin-secret
passwordPolicy:
minLength: 12
requireUppercase: true
requireNumbers: true
requireSpecialChars: trueapiVersion: neo4j.io/v1alpha1
kind: Neo4jEnterpriseCluster
metadata:
name: aws-cluster
spec:
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "tcp"
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "3600"spec:
service:
type: LoadBalancer
annotations:
cloud.google.com/load-balancer-type: "Internal"
networking.gke.io/internal-load-balancer-allow-global-access: "true"spec:
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "false"
service.beta.kubernetes.io/azure-dns-label-name: "my-neo4j-cluster"Until automatic Ingress creation is implemented, create it manually:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: neo4j-ingress
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
spec:
ingressClassName: nginx
tls:
- hosts:
- neo4j.example.com
secretName: neo4j-tls
rules:
- host: neo4j.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-cluster-client # or my-standalone-service
port:
number: 7474-
Check service status:
kubectl get svc kubectl describe svc <service-name>
-
Verify endpoints:
kubectl get endpoints <service-name>
-
Test connectivity from within cluster:
kubectl run test-pod --image=busybox -it --rm -- sh wget -O- http://<service-name>:7474
- Check cloud provider quota
- Verify IAM permissions
- Check service annotations
- Increase timeout values in load balancer annotations
- Check security groups/firewall rules
- Verify Neo4j is ready:
kubectl logs <pod-name>
- Use LoadBalancer for Production: Most reliable for cloud deployments
- Port Forwarding for Development: Simple and secure for local access
- Always Enable TLS: Essential for production security
- Monitor External IPs: Set up alerts for IP changes
- Use DNS: Point domain names to load balancer IPs
- Implement Rate Limiting: Protect against abuse
The operator team is working on:
- Automatic Ingress creation for clusters
- Ingress support for standalone deployments
- Better service configuration for standalone
- Built-in DNS management
- OAuth/OIDC integration for Browser access