logo

Applications and Servers

A server represents a deployment unit in Namespace. Configuration for a server includes:

  • Build plan: how the server image is built.
  • Deployment and running configuration: arguments, environment variables, statefulness, replica count, etc.
  • Network configuration: how the server is exposed to other servers and the internet.

Building

Namespace simplifies the process of building your servers. Instead of creating and maintaining a custom Dockerfile (which is also supported for complex cases), you can use one of the supported integrations (Go, Node.js or Shellscript at the moment, with Java, Python, and Ruby coming soon).

Integrations are simple to use and require no configuration in most cases but can be customized if needed (for example, you can choose a subdirectory with the sources within a package).

Deploying

Servers are run as containers in Kubernetes. Under the hood, a deployed server is either a Kubernetes Deployment (for stateless servers) or a StatefulSet.

Servers can depend on each other, forming a dependency graph that can be deployed as a whole. Namespace fully manages the lifecycle of the deployed servers.

Networking

Servers can talk to each other and the outside world. This is configured via services. A service is an exposed port with a name and additional metadata that helps Namespace to forward it correctly. Besides the server itself, sidecars may also expose services.

Intra-cluster communication

When a server depends on another server, Namespace can inject the address of the dependency as an environment variable using fromServiceEndpoint or read at runtime from the Namespace runtime config.

Public services

By default, a service is private and only available from within the cluster. Use ingress: true to make Namespace automatically generate and configure domains for the service on deployment (available only locally in dev environment, exposed to the internet in prod). Ingress can be further customized to expose a sub-path only.

Example of a server definition

server: {
	name: "go-server"
 
	// Build the Go code from the package root
	integration: "go"
 
	env: {
		// Pass an environment variable to the container
		MY_ENV: "value"
		// Inject the address of another server as an environment variable
		MINIO: fromServiceEndpoint: "namespacelabs.dev/anotherserver:service1"
	}
 
	services: {
		webapi: {
			// The server exposes port 4000 as a public endpoint
			port: 4000
			kind: "http"
 
			ingress: true
 
			// The server readiness probe checks "/readyz"
			probe: http: "/readyz"
		}
	}
 
	requires: [
		// Dependency on another server.
		// The current server is deployed after the dependency (on the first
		// deployment) and the address of the dependency can be injected as
		// an environment variable or read from the Namespace config.
		"namespacelabs.dev/anotherserver",
	]
}