diff --git a/examples/templates/incus/README.md b/examples/templates/incus/README.md new file mode 100644 index 0000000000..28cc08da72 --- /dev/null +++ b/examples/templates/incus/README.md @@ -0,0 +1,49 @@ +--- +name: Incus System Container with Docker +description: Develop in an Incus System Container with Docker using incus +tags: [local, incus, lxc, lxd] +icon: /icon/lxc.svg +--- + +# Incus System Container with Docker + +Develop in an Incus System Container and run nested Docker containers using Incus on your local infrastructure. + +## Prerequisites + +1. Install [Incus](https://linuxcontainers.org/incus/) on the same machine as Coder. +2. Allow Coder to access the Incus socket. + + - If you're running Coder as system service, run `sudo usermod -aG incus coder` and restart the Coder service. + - If you're running Coder as a Docker Compose service, get the group ID of the `incus` group by running `getent group incus` and add the following to your `compose.yaml` file: + + ```yaml + services: + coder: + volumes: + - /var/lib/incus/unix.socket:/var/lib/incus/unix.socket + group_add: + - 997 # Replace with the group ID of the `incus` group + ``` + +3. Create a storage pool named `coder` and `btrfs` as the driver by running `incus storage create coder btrfs`. + +## Usage + +> **Note:** this template requires using a container image with cloud-init installed such as `ubuntu/jammy/cloud/amd64`. + +1. Run `coder templates init -id incus` +1. Select this template +1. Follow the on-screen instructions + +## Extending this template + +See the [lxd/incus](https://registry.terraform.io/providers/lxc/incus/latest/docs) Terraform provider documentation to +add the following features to your Coder template: + +- HTTPS incus host +- Volume mounts +- Custom networks +- More + +We also welcome contributions! diff --git a/examples/templates/incus/main.tf b/examples/templates/incus/main.tf new file mode 100644 index 0000000000..ec7445bcb5 --- /dev/null +++ b/examples/templates/incus/main.tf @@ -0,0 +1,309 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + } + incus = { + source = "lxc/incus" + } + } +} + +data "coder_provisioner" "me" {} + +provider "incus" {} + +data "coder_workspace" "me" {} + +data "coder_parameter" "image" { + name = "image" + display_name = "Image" + description = "The container image to use. Be sure to use a variant with cloud-init installed!" + default = "ubuntu/jammy/cloud/amd64" + icon = "/icon/image.svg" + mutable = true +} + +data "coder_parameter" "cpu" { + name = "cpu" + display_name = "CPU" + description = "The number of CPUs to allocate to the workspace (1-8)" + type = "number" + default = "1" + icon = "https://raw.githubusercontent.com/matifali/logos/main/cpu-3.svg" + mutable = true + validation { + min = 1 + max = 8 + } +} + +data "coder_parameter" "memory" { + name = "memory" + display_name = "Memory" + description = "The amount of memory to allocate to the workspace in GB (up to 16GB)" + type = "number" + default = "2" + icon = "/icon/memory.svg" + mutable = true + validation { + min = 1 + max = 16 + } +} + +data "coder_parameter" "git_repo" { + type = "string" + name = "Git repository" + default = "https://github.com/coder/coder" + description = "Clone a git repo into [base directory]" + mutable = true +} + +data "coder_parameter" "repo_base_dir" { + type = "string" + name = "Repository Base Directory" + default = "~" + description = "The directory specified will be created (if missing) and the specified repo will be cloned into [base directory]/{repo}🪄." + mutable = true +} + +resource "coder_agent" "main" { + count = data.coder_workspace.me.start_count + arch = data.coder_provisioner.me.arch + os = "linux" + dir = "/home/${local.workspace_user}" + env = { + CODER_WORKSPACE_ID = data.coder_workspace.me.id + } + + metadata { + display_name = "CPU Usage" + key = "0_cpu_usage" + script = "coder stat cpu" + interval = 10 + timeout = 1 + } + + metadata { + display_name = "RAM Usage" + key = "1_ram_usage" + script = "coder stat mem" + interval = 10 + timeout = 1 + } + + metadata { + display_name = "Home Disk" + key = "3_home_disk" + script = "coder stat disk --path /home/${lower(data.coder_workspace.me.owner)}" + interval = 60 + timeout = 1 + } +} + +module "git-clone" { + source = "registry.coder.com/modules/git-clone/coder" + version = "1.0.2" + agent_id = local.agent_id + url = data.coder_parameter.git_repo.value + base_dir = local.repo_base_dir +} + +module "code-server" { + source = "registry.coder.com/modules/code-server/coder" + version = "1.0.2" + agent_id = local.agent_id + folder = local.repo_base_dir +} + +module "filebrowser" { + source = "registry.coder.com/modules/filebrowser/coder" + version = "1.0.2" + agent_id = local.agent_id +} + +module "coder-login" { + source = "registry.coder.com/modules/coder-login/coder" + version = "1.0.2" + agent_id = local.agent_id +} + +resource "incus_volume" "home" { + name = "coder-${data.coder_workspace.me.id}-home" + pool = local.pool +} + +resource "incus_volume" "docker" { + name = "coder-${data.coder_workspace.me.id}-docker" + pool = local.pool +} + +resource "incus_cached_image" "image" { + source_remote = "images" + source_image = data.coder_parameter.image.value +} + +resource "incus_instance_file" "agent_token" { + count = data.coder_workspace.me.start_count + instance = incus_instance.dev.name + content = <