Schema
Top-level fields
Must be
caravanserai/v1.Must be
Project.Identity metadata for the resource.
Unique name for the Project within the cluster. Used to reference the Project in
caractrl commands and as the basis for Docker resource names (cara-{name} for the network, {name}-{service} for containers).Arbitrary key/value pairs for grouping and selection.
The desired state of the Project.
spec.services
The ordered list of containers to run. At least one service is required.One or more service definitions.
Name of the service within the Project. This name is used as the DNS hostname inside the shared bridge network — other services can reach this container at
http://{name}:{port}.Docker image reference, for example
nginx:alpine or postgres:15.Environment variables injected into the container at runtime.
Environment variable name, for example
DATABASE_URL.Environment variable value.
Volumes to attach to this container. Each entry must reference a volume defined in
spec.volumes.Name of the volume to mount. Must match a name in
spec.volumes.Absolute path inside the container where the volume is mounted, for example
/var/lib/mysql.spec.volumes
Named volumes shared across services. Optional.
Volume name. Referenced by
spec.services[].volumeMounts[].name.Volume lifecycle type. Currently the only supported value is
Ephemeral: the volume is discarded when the Project is stopped or moved to another node. No backup or restore occurs.spec.ingress
HTTP routing rules for exposing services. Optional.
Identifier for this ingress rule.
Hostname for the ingress rule. If the value contains a dot it is used verbatim; otherwise the final hostname is assembled as
{host}.{environment}.{baseDomain}.The backend service and port to forward traffic to.
Name of the service (must match a name in
spec.services) to route traffic to.Port on the target service to forward traffic to.
Visibility settings for the ingress endpoint.
Controls where the route is reachable. Currently the only supported value is
Internal, which limits access to the Headscale overlay network.spec.expireAt
An RFC 3339 timestamp. When set, the garbage collection controller automatically deletes the Project after this time. Useful for ephemeral preview environments. Example:
2026-04-30T00:00:00Z.Examples
- Minimal (nginx)
- Multi-service with volumes (WordPress)
- Project with ingress
A single-service Project running an nginx web server. No volumes or ingress required.
nginx-project.yaml
Validation
Caravanserai validates your manifest when you runcaractrl apply. The following fields are required:
apiVersionkindmetadata.namespec.services(at least one entry)spec.services[].nameandspec.services[].imageon each servicespec.volumes[].nameandspec.volumes[].typeon each volumespec.ingress[].name,spec.ingress[].target.service, andspec.ingress[].target.porton each ingress rule
Service names resolve as hostnames within the Project’s Docker bridge network. Use the service name directly as the hostname when configuring inter-service connections — for example,
WORDPRESS_DB_HOST: db connects the app service to the db service.