From 615d41206a47ffe69199c003f86c75dd7f88d356 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 29 Mar 2026 02:17:29 +0000 Subject: [PATCH] Initial Commit --- README.md | 52 ++++++++++++ main.tf | 237 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 289 insertions(+) create mode 100644 README.md create mode 100644 main.tf diff --git a/README.md b/README.md new file mode 100644 index 0000000..e2d4ccd --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +--- +display_name: Docker Workspaces with GPU & DooD +description: Provision Docker-based Coder workspaces with GPU support, Docker-out-of-Docker, Go, and Bun. +icon: ../../../site/static/icon/docker.png +maintainer_github: coder +verified: true +tags: [docker, container, gpu, golang, bun, sdkman] +--- + +# Feature-Rich Docker Workspaces + +Provision powerful Docker containers as [Coder workspaces](https://coder.com/docs/workspaces) with this advanced template. It features GPU passthrough, Docker-out-of-Docker (DooD), and automatically installs essential development tools on startup. + + + +## Prerequisites + +### Infrastructure + +The VM you run Coder on must have a running Docker socket and the `coder` user must be added to the Docker group: + +```sh +# Add coder user to Docker group +sudo adduser coder docker + +# Restart Coder server +sudo systemctl restart coder + +# Test Docker +sudo -u coder docker ps +``` + +## Features & Architecture + +This template provisions the following resources and features: + +- **Base Image**: `codercom/enterprise-base:ubuntu` +- **GPU Support**: Passes all host GPUs to the workspace (`gpus = "all"`) for AI/ML and hardware acceleration. +- **Docker-out-of-Docker (DooD)**: Mounts the host's `/var/run/docker.sock` so you can build and run containers seamlessly from inside your workspace. +- **Auto-Provisioned Tools**: The workspace startup script automatically handles: + - System package updates (`apt-get update` & `apt-get upgrade`) + - Docker CLI + - Nixpacks + - Bun + - Golang + - SDKMAN! & Maven +- **Persistent Storage**: Uses a persistent host directory mapped to `/home/coder` to ensure your files survive workspace restarts. +- **Rich Telemetry**: Displays CPU, RAM, Disk, Load Average, and GPU utilization directly in the Coder UI. +- **IDE Support**: Native integration with code-server (Browser VS Code) and JetBrains IDEs. + +> **Note** +> While your `/home/coder` directory is persistent, the container's root filesystem is ephemeral. The startup script handles reinstalling your system-level tools (Go, Bun, SDKMAN!, etc.) on each start. To speed up boot times, you may want to bake these tools into a custom Docker image. diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..ea952f1 --- /dev/null +++ b/main.tf @@ -0,0 +1,237 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + } + docker = { + source = "kreuzwerker/docker" + } + } +} + +locals { + username = data.coder_workspace_owner.me.name +} + +variable "docker_socket" { + default = "" + description = "(Optional) Docker socket URI" + type = string +} + +provider "docker" { + host = var.docker_socket != "" ? var.docker_socket : null +} + +data "coder_provisioner" "me" {} +data "coder_workspace" "me" {} +data "coder_workspace_owner" "me" {} + +resource "coder_agent" "main" { + arch = data.coder_provisioner.me.arch + os = "linux" + startup_script = <<-EOT + set -e + + # 1. Standard Permissions Fix + sudo chown -R $(whoami) /home/coder + + # 2. Install Docker CLI (client only) to talk to the socket + if ! command -v docker >/dev/null 2>&1; then + echo "Installing Docker CLI..." + curl -fsSL https://get.docker.com | sh + fi + + # 3. Allow user to use the Docker socket (Docker-out-of-Docker) + # We set strict permissions on the socket file to ensure access + if [ -e /var/run/docker.sock ]; then + sudo chmod 666 /var/run/docker.sock + fi + + # 4. Install Nixpacks + if ! command -v nixpacks >/dev/null 2>&1; then + echo "Installing Nixpacks..." + curl -sSL https://nixpacks.com/install.sh | bash + fi + + # 5. Install Bun + if ! command -v bun >/dev/null 2>&1; then + echo "Installing Bun..." + curl -fsSL https://bun.sh/install | bash + fi + + # 6. Update System Packages + echo "Updating system packages..." + sudo apt-get update + sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y + + # 7. Install Golang + if ! command -v go >/dev/null 2>&1; then + echo "Installing Golang..." + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y golang zip unzip + fi + + # 8. Install SDKMAN! & Maven + if [ ! -d "$HOME/.sdkman" ]; then + echo "Installing SDKMAN!..." + export SDKMAN_DIR="$HOME/.sdkman" + curl -s "https://get.sdkman.io" | bash + + echo "Installing Maven via SDKMAN!..." + source "$HOME/.sdkman/bin/sdkman-init.sh" + sdk install maven + fi + + # 9. Initialize Home Directory + if [ ! -f ~/.init_done ]; then + cp -rT /etc/skel ~ + touch ~/.init_done + fi + EOT + + env = { + GIT_AUTHOR_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) + GIT_AUTHOR_EMAIL = "${data.coder_workspace_owner.me.email}" + GIT_COMMITTER_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) + GIT_COMMITTER_EMAIL = "${data.coder_workspace_owner.me.email}" + } + + 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}" + interval = 60 + timeout = 1 + } + + metadata { + display_name = "GPU Usage" + key = "8_gpu_usage" + script = "nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits | awk '{sum+=$1} END {print sum/NR \"%\"}'" + interval = 10 + timeout = 1 + } + + metadata { + display_name = "CPU Usage (Host)" + key = "4_cpu_usage_host" + script = "coder stat cpu --host" + interval = 10 + timeout = 1 + } + + metadata { + display_name = "Memory Usage (Host)" + key = "5_mem_usage_host" + script = "coder stat mem --host" + interval = 10 + timeout = 1 + } + + metadata { + display_name = "Load Average (Host)" + key = "6_load_host" + script = <