Nomad Templates
Nomad templates in knot define environments using a Nomad job specification and optional volume definitions. When a developer creates and starts a space from a template, knot automatically provisions the required volumes and launches the job within the Nomad cluster.
The editor uses Nomad HCL completion for the job field and YAML completion for Nomad volume definitions. Save-time validation parses the job through Nomad and validates the volume YAML before the template is stored.
For enhanced isolation, namespaces can be set within the job specification. For example:
namespace="${{ .user.username }}"
This ensures that jobs for each developer are placed in their own namespaces.
Nomad Job
To create a Nomad template:
- Navigate to
Templatesand selectNew Template. - Complete the form, ensuring the
NameandNomad Jobfields are filled.
Template Platform Nomadmust be selected underPlatform.- The
Nomad Jobfield requires an HCL job specification. See example environments for reference.
When a template is updated, all running spaces are marked as having an update available. However, spaces are not automatically restarted. Restarting a space applies the updated template.
Using Template Variables
Template variables can store sensitive information, such as registry login credentials. For example:
image = "paularlott/knot-ubuntu:24.04"
auth {
username = "${{ .var.registry_user }}"
password = "${{ .var.registry_pass }}"
}Variables are stored as plain text within the Nomad template and can be viewed via the Nomad web interface. For sensitive environments, consider using a solution like Vault for compliance and security.
Example Nomad Job
Below is an example of a Nomad job specification:
job "${{.space.name}}-${{.user.username}}" {
datacenters = ["dc1"]
update {
max_parallel = 1
min_healthy_time = "30s"
healthy_deadline = "1m"
auto_revert = true
}
group "ubuntu" {
count = 1
volume "home_volume" {
type = "csi"
source = "ubuntu_${{.space.id}}_home"
read_only = false
attachment_mode = "file-system"
access_mode = "single-node-writer"
}
volume "data_volume" {
type = "csi"
source = "ubuntu_${{.space.id}}_data"
read_only = false
attachment_mode = "file-system"
access_mode = "single-node-writer"
}
volume "host_volume" {
type = "host"
source = "vol-${{.space.id}}"
read_only = false
}
task "ubuntu" {
driver = "docker"
config {
image = "paularlott/knot-ubuntu:24.04"
hostname = "${{ .space.name }}"
}
env {
KNOT_SERVER = "${{.server.url}}"
KNOT_AGENT_ENDPOINT = "${{.server.agent_endpoint}}"
KNOT_SPACEID = "${{.space.id}}"
KNOT_SSH_PORT = "22"
KNOT_CODE_SERVER_PORT = "49374"
KNOT_USER = "${{.user.username}}"
TZ = "${{ .user.timezone }}"
}
volume_mount {
volume = "home_volume"
destination = "/home"
}
volume_mount {
volume = "data_volume"
destination = "/data"
}
volume_mount {
volume = "host_volume"
destination = "/host-volume"
propagation_mode = "private"
}
resources {
cores = 4
memory = 4096
}
}
}
}Volumes
Templates can define one or more volumes. These volumes are:
- Created: When the space is deployed.
- Destroyed: When the space is deleted.
- Persistent: Starting and stopping the space does not affect the contents of the volumes unless the template is modified to remove a volume.
Deleting a space will destroy its volumes and all data stored on them.
Example CSI Volume Definition
Below is an example YAML configuration for defining CSI volumes:
volumes:
- id: "ubuntu_${{.space.id}}_home"
name: "ubuntu_${{.space.id}}_home"
type: "csi"
plugin_id: "hostpath"
capacity_min: 1G
capacity_max: 10G
mount_options:
fs_type: "ext4"
mount_flags:
- rw
- noatime
capabilities:
- access_mode: "single-node-writer"
attachment_mode: "file-system"
- id: "ubuntu_${{.space.id}}_data"
name: "ubuntu_${{.space.id}}_data"
type: "csi"
plugin_id: "hostpath"
capacity_min: 1G
capacity_max: 10G
mount_options:
fs_type: "ext4"
mount_flags:
- rw
- noatime
capabilities:
- access_mode: "single-node-writer"
attachment_mode: "file-system"In this example, the volume ID ubuntu_${{.space.id}}_home dynamically incorporates the unique space ID.
Example Host Volume Definition
Below is an example YAML configuration for defining a host volume:
volumes:
- name: "vol-${{.space.id}}"
type: "host"
plugin_id: "mkdir"
parameters:
mode: "0755"
uid: 999
gid: 999Nomad volume definitions can include both csi and host volume types.
If volume definitions are added or removed from a template, the changes will take effect the next time the space is started. Any data in a deleted volume will be permanently lost.