mirror of
https://github.com/coder/coder.git
synced 2025-07-30 22:19:53 +00:00
feat: add nomad template (#9786)
This commit is contained in:
committed by
GitHub
parent
b742661abd
commit
fa858531a8
96
examples/templates/nomad-docker/README.md
Normal file
96
examples/templates/nomad-docker/README.md
Normal file
@@ -0,0 +1,96 @@
|
||||
---
|
||||
name: Develop in a Nomad Docker Container
|
||||
description: Get started with Nomad Workspaces.
|
||||
tags: [cloud, nomad]
|
||||
icon: /icon/nomad.svg
|
||||
---
|
||||
|
||||
# Develop in a Nomad Docker Container
|
||||
|
||||
This example shows how to use Nomad service tasks to be used as a development environment using docker and host csi volumes.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Nomad](https://www.nomadproject.io/downloads)
|
||||
- [Docker](https://docs.docker.com/get-docker/)
|
||||
|
||||
## Setup
|
||||
|
||||
### 1. Start the CSI Host Volume Plugin
|
||||
|
||||
The CSI Host Volume plugin is used to mount host volumes into Nomad tasks. This is useful for development environments where you want to mount persistent volumes into your container workspace.
|
||||
|
||||
1. Login to the Nomad server using SSH.
|
||||
|
||||
2. Append the following stanza to your Nomad server configuration file and restart the nomad service.
|
||||
|
||||
```hcl
|
||||
plugin "docker" {
|
||||
config {
|
||||
allow_privileged = true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```shell
|
||||
sudo systemctl restart nomad
|
||||
```
|
||||
|
||||
3. Create a file `hostpath.nomad` with following content:
|
||||
|
||||
```hcl
|
||||
job "hostpath-csi-plugin" {
|
||||
datacenters = ["dc1"]
|
||||
type = "system"
|
||||
|
||||
group "csi" {
|
||||
task "plugin" {
|
||||
driver = "docker"
|
||||
|
||||
config {
|
||||
image = "registry.k8s.io/sig-storage/hostpathplugin:v1.10.0"
|
||||
|
||||
args = [
|
||||
"--drivername=csi-hostpath",
|
||||
"--v=5",
|
||||
"--endpoint=${CSI_ENDPOINT}",
|
||||
"--nodeid=node-${NOMAD_ALLOC_INDEX}",
|
||||
]
|
||||
|
||||
privileged = true
|
||||
}
|
||||
|
||||
csi_plugin {
|
||||
id = "hostpath"
|
||||
type = "monolith"
|
||||
mount_dir = "/csi"
|
||||
}
|
||||
|
||||
resources {
|
||||
cpu = 256
|
||||
memory = 128
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
4. Run the job:
|
||||
|
||||
```shell
|
||||
nomad job run hostpath.nomad
|
||||
```
|
||||
|
||||
### 2. Setup the Nomad Template
|
||||
|
||||
1. Create the template by running the following command:
|
||||
|
||||
```shell
|
||||
coder template init nomad-docker
|
||||
cd nomad-docker
|
||||
coder template create
|
||||
```
|
||||
|
||||
2. Set up Nomad server address and optional authentication:
|
||||
|
||||
3. Create a new workspace and start developing.
|
192
examples/templates/nomad-docker/main.tf
Normal file
192
examples/templates/nomad-docker/main.tf
Normal file
@@ -0,0 +1,192 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
coder = {
|
||||
source = "coder/coder"
|
||||
}
|
||||
nomad = {
|
||||
source = "hashicorp/nomad"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "nomad_provider_address" {
|
||||
type = string
|
||||
description = "Nomad provider address. e.g., http://IP:PORT"
|
||||
default = "http://localhost:4646"
|
||||
}
|
||||
|
||||
variable "nomad_provider_http_auth" {
|
||||
type = string
|
||||
description = "Nomad provider http_auth in the form of `user:password`"
|
||||
sensitive = true
|
||||
default = ""
|
||||
}
|
||||
|
||||
provider "coder" {}
|
||||
|
||||
provider "nomad" {
|
||||
address = var.nomad_provider_address
|
||||
http_auth = var.nomad_provider_http_auth == "" ? null : var.nomad_provider_http_auth
|
||||
}
|
||||
|
||||
data "coder_parameter" "cpu" {
|
||||
name = "cpu"
|
||||
display_name = "CPU"
|
||||
description = "The number of CPU cores"
|
||||
default = "1"
|
||||
icon = "/icon/memory.svg"
|
||||
mutable = true
|
||||
option {
|
||||
name = "1 Cores"
|
||||
value = "1"
|
||||
}
|
||||
option {
|
||||
name = "2 Cores"
|
||||
value = "2"
|
||||
}
|
||||
option {
|
||||
name = "3 Cores"
|
||||
value = "3"
|
||||
}
|
||||
option {
|
||||
name = "4 Cores"
|
||||
value = "4"
|
||||
}
|
||||
}
|
||||
|
||||
data "coder_parameter" "memory" {
|
||||
name = "memory"
|
||||
display_name = "Memory"
|
||||
description = "The amount of memory in GB"
|
||||
default = "2"
|
||||
icon = "/icon/memory.svg"
|
||||
mutable = true
|
||||
option {
|
||||
name = "2 GB"
|
||||
value = "2"
|
||||
}
|
||||
option {
|
||||
name = "4 GB"
|
||||
value = "4"
|
||||
}
|
||||
option {
|
||||
name = "6 GB"
|
||||
value = "6"
|
||||
}
|
||||
option {
|
||||
name = "8 GB"
|
||||
value = "8"
|
||||
}
|
||||
}
|
||||
|
||||
data "coder_workspace" "me" {}
|
||||
|
||||
resource "coder_agent" "main" {
|
||||
os = "linux"
|
||||
arch = "amd64"
|
||||
startup_script_timeout = 180
|
||||
startup_script = <<-EOT
|
||||
set -e
|
||||
# install and start code-server
|
||||
curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server
|
||||
/tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 &
|
||||
EOT
|
||||
|
||||
metadata {
|
||||
display_name = "Load Average (Host)"
|
||||
key = "load_host"
|
||||
# get load avg scaled by number of cores
|
||||
script = <<EOT
|
||||
echo "`cat /proc/loadavg | awk '{ print $1 }'` `nproc`" | awk '{ printf "%0.2f", $1/$2 }'
|
||||
EOT
|
||||
interval = 60
|
||||
timeout = 1
|
||||
}
|
||||
}
|
||||
|
||||
# code-server
|
||||
resource "coder_app" "code-server" {
|
||||
agent_id = coder_agent.main.id
|
||||
slug = "code-server"
|
||||
display_name = "code-server"
|
||||
icon = "/icon/code.svg"
|
||||
url = "http://localhost:13337?folder=/home/coder"
|
||||
subdomain = false
|
||||
share = "owner"
|
||||
|
||||
healthcheck {
|
||||
url = "http://localhost:13337/healthz"
|
||||
interval = 3
|
||||
threshold = 10
|
||||
}
|
||||
}
|
||||
|
||||
locals {
|
||||
workspace_tag = "coder-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}"
|
||||
home_volume_name = "coder_${data.coder_workspace.me.id}_home"
|
||||
}
|
||||
|
||||
resource "nomad_namespace" "coder_workspace" {
|
||||
name = local.workspace_tag
|
||||
description = "Coder workspace"
|
||||
meta = {
|
||||
owner = data.coder_workspace.me.owner
|
||||
}
|
||||
}
|
||||
|
||||
data "nomad_plugin" "hostpath" {
|
||||
plugin_id = "hostpath"
|
||||
wait_for_healthy = true
|
||||
}
|
||||
|
||||
resource "nomad_csi_volume" "home_volume" {
|
||||
depends_on = [data.nomad_plugin.hostpath]
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = all
|
||||
}
|
||||
plugin_id = "hostpath"
|
||||
volume_id = local.home_volume_name
|
||||
name = local.home_volume_name
|
||||
namespace = nomad_namespace.coder_workspace.name
|
||||
|
||||
capability {
|
||||
access_mode = "single-node-writer"
|
||||
attachment_mode = "file-system"
|
||||
}
|
||||
|
||||
mount_options {
|
||||
fs_type = "ext4"
|
||||
}
|
||||
}
|
||||
|
||||
resource "nomad_job" "workspace" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
depends_on = [nomad_csi_volume.home_volume]
|
||||
jobspec = templatefile("${path.module}/workspace.nomad.tpl", {
|
||||
coder_workspace_owner = data.coder_workspace.me.owner
|
||||
coder_workspace_name = data.coder_workspace.me.name
|
||||
workspace_tag = local.workspace_tag
|
||||
cores = tonumber(data.coder_parameter.cpu.value)
|
||||
memory_mb = tonumber(data.coder_parameter.memory.value * 1024)
|
||||
coder_init_script = coder_agent.main.init_script
|
||||
coder_agent_token = coder_agent.main.token
|
||||
workspace_name = data.coder_workspace.me.name
|
||||
home_volume_name = local.home_volume_name
|
||||
})
|
||||
deregister_on_destroy = true
|
||||
purge_on_destroy = true
|
||||
}
|
||||
|
||||
resource "coder_metadata" "workspace_info" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
resource_id = nomad_job.workspace[0].id
|
||||
item {
|
||||
key = "CPU (Cores)"
|
||||
value = data.coder_parameter.cpu.value
|
||||
}
|
||||
item {
|
||||
key = "Memory (GiB)"
|
||||
value = data.coder_parameter.memory.value
|
||||
}
|
||||
}
|
53
examples/templates/nomad-docker/workspace.nomad.tpl
Normal file
53
examples/templates/nomad-docker/workspace.nomad.tpl
Normal file
@@ -0,0 +1,53 @@
|
||||
job "workspace" {
|
||||
datacenters = ["dc1"]
|
||||
namespace = "${workspace_tag}"
|
||||
type = "service"
|
||||
group "workspace" {
|
||||
volume "home_volume" {
|
||||
type = "csi"
|
||||
source = "${home_volume_name}"
|
||||
read_only = false
|
||||
attachment_mode = "file-system"
|
||||
access_mode = "single-node-writer"
|
||||
}
|
||||
network {
|
||||
port "http" {}
|
||||
}
|
||||
task "workspace" {
|
||||
driver = "docker"
|
||||
config {
|
||||
image = "codercom/enterprise-base:ubuntu"
|
||||
ports = ["http"]
|
||||
labels {
|
||||
name = "${workspace_tag}"
|
||||
managed_by = "coder"
|
||||
}
|
||||
hostname = "${workspace_name}"
|
||||
entrypoint = ["sh", "-c", "sudo chown coder:coder -R /home/coder && echo '${base64encode(coder_init_script)}' | base64 --decode | sh"]
|
||||
}
|
||||
volume_mount {
|
||||
volume = "home_volume"
|
||||
destination = "/home/coder"
|
||||
}
|
||||
resources {
|
||||
cores = ${cores}
|
||||
memory = ${memory_mb}
|
||||
}
|
||||
env {
|
||||
CODER_AGENT_TOKEN = "${coder_agent_token}"
|
||||
}
|
||||
meta {
|
||||
tag = "${workspace_tag}"
|
||||
managed_by = "coder"
|
||||
}
|
||||
}
|
||||
meta {
|
||||
tag = "${workspace_tag}"
|
||||
managed_by = "coder"
|
||||
}
|
||||
}
|
||||
meta {
|
||||
tag = "${workspace_tag}"
|
||||
managed_by = "coder"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user