Networking
Lucity handles networking through standard Kubernetes primitives: Gateway API for public traffic, ClusterIP Services for internal communication. No proprietary service mesh, no custom proxy layer, no magic environment variables that break when you leave.
Domain Separation (Security)
Your platform domain (where the Lucity dashboard and API live) must be different from your workload domain (where user applications are served). This prevents cross-site scripting (XSS) attacks where a malicious deployed application could access cookies or session tokens from the platform's domain.
For example:
- Platform domain:
platform.lucity.app(dashboard, API) - Workload domain:
apps.lucity.app(deployed services)
This separation ensures that even if a deployed application contains malicious JavaScript, it cannot read or modify cookies belonging to the platform interface.
Configure these in your Lucity installation:
# Platform config
WORKLOAD_DOMAIN: apps.lucity.app # wildcard DNS for generated domains
DOMAIN_TARGET: lb.lucity.app # CNAME target for custom domains
Expose a Public Service
Each service can have multiple domains, both platform-generated and custom. Domains are stored per-environment in values.yaml:
services:
api:
image:
repository: registry.example.com/myapp/api
tag: latest
port: 3000
domains:
- api-production.apps.lucity.app # platform domain (auto-generated)
- api.example.com # custom domain
A service becomes publicly accessible when it has domains. No explicit public flag. If a service has domains listed, Lucity generates an HTTPRoute (Gateway API) that routes external traffic to it. Services without domains are internal-only. Gateway API is the modern successor to Kubernetes Ingress: more expressive, more portable, and backed by the Kubernetes project itself.
Generate a Platform Domain
Click Generate Domain in the service settings to auto-generate a domain in the format {service}-{environment}.{workloadDomain}. The platform checks for collisions across all projects and appends a numeric suffix if needed (e.g. api-production-2.apps.lucity.app).
Platform domains use wildcard DNS on the workload domain. No additional DNS configuration required.
Add a Custom Domain
Enter your own hostname (e.g. api.example.com) to add a custom domain. You'll need to configure DNS to point to your load balancer:
| Type | Name | Value |
|---|---|---|
| CNAME | api.example.com | lb.lucity.app |
The dashboard shows DNS status for custom domains. A green checkmark means DNS is resolving correctly. A yellow warning means the DNS record hasn't been detected yet; changes can take up to 48 hours to propagate.
Remove a Domain
Click the remove button next to any domain to detach it. This removes the hostname from the HTTPRoute but does not affect your DNS records.
Reach Internal Services
Every service gets a ClusterIP Service automatically. Other services in the same namespace reach it via Kubernetes DNS:
http://api:3000
Or with the fully qualified name:
http://api.myproject-production.svc.cluster.local:3000
Simple, reliable, zero platform magic. This is how Kubernetes service discovery has worked since day one, and it's how it works after ejection too.
Service Discovery That Survives Ejection
Lucity uses Kubernetes-native DNS for service discovery. Your application references other services by their Kubernetes DNS name, the same name that works on any Kubernetes cluster.
Some platforms use proprietary variable interpolation for service discovery. That works great until you leave, and suddenly every connection string needs rewriting. With Lucity, there's nothing to rewrite. The DNS names are standard Kubernetes. They work before, during, and after ejection.
What Happens on Eject
You get standard HTTPRoute and Service manifests. They work with any Gateway API-compatible controller: Envoy Gateway, NGINX Gateway Fabric, Traefik, Cilium. Your internal service DNS names don't change. Your public routes keep working with the same controller. No rewiring, no search-and-replace across your codebase.