added models, model-swap, ...
This commit is contained in:
121
pyinfra/framework/compose/coder/templates/code-server/main.tf
Normal file
121
pyinfra/framework/compose/coder/templates/code-server/main.tf
Normal file
@@ -0,0 +1,121 @@
|
||||
# code-server workspace template — one dev container per project, with
|
||||
# browser VS Code and Claude Code (extension + CLI) ready on first open.
|
||||
#
|
||||
# Source of truth is the repo copy at
|
||||
# pyinfra/framework/compose/coder/templates/code-server/main.tf; pyinfra
|
||||
# ships it to /srv/docker/coder/templates/, mounted read-only into the
|
||||
# server container at /templates. Push after edits:
|
||||
# cd /srv/docker/coder
|
||||
# docker compose exec coder coder templates push code-server \
|
||||
# --directory /templates/code-server --yes
|
||||
|
||||
terraform {
|
||||
required_providers {
|
||||
coder = {
|
||||
source = "coder/coder"
|
||||
}
|
||||
docker = {
|
||||
source = "kreuzwerker/docker"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "coder" {}
|
||||
|
||||
# Talks to the host daemon via the socket mounted into the server
|
||||
# container (default unix:///var/run/docker.sock) — workspace containers
|
||||
# are siblings of the compose stacks, not children.
|
||||
provider "docker" {}
|
||||
|
||||
data "coder_workspace" "me" {}
|
||||
data "coder_workspace_owner" "me" {}
|
||||
|
||||
resource "coder_agent" "main" {
|
||||
arch = "amd64"
|
||||
os = "linux"
|
||||
|
||||
# Claude Code CLI — native installer, lands in ~/.local/bin inside the
|
||||
# persisted home volume, so this is a no-op after the first start. The
|
||||
# code-server extension bundles its own CLI, but having `claude` on
|
||||
# PATH enables tmux-based long runs in the workspace terminal.
|
||||
startup_script = <<-EOT
|
||||
set -e
|
||||
command -v claude >/dev/null 2>&1 || curl -fsSL https://claude.ai/install.sh | bash
|
||||
EOT
|
||||
|
||||
env = {
|
||||
GIT_AUTHOR_NAME = data.coder_workspace_owner.me.full_name
|
||||
GIT_AUTHOR_EMAIL = data.coder_workspace_owner.me.email
|
||||
GIT_COMMITTER_NAME = data.coder_workspace_owner.me.full_name
|
||||
GIT_COMMITTER_EMAIL = data.coder_workspace_owner.me.email
|
||||
}
|
||||
|
||||
metadata {
|
||||
display_name = "CPU"
|
||||
key = "cpu"
|
||||
script = "coder stat cpu"
|
||||
interval = 10
|
||||
timeout = 1
|
||||
}
|
||||
metadata {
|
||||
display_name = "RAM"
|
||||
key = "mem"
|
||||
script = "coder stat mem"
|
||||
interval = 10
|
||||
timeout = 1
|
||||
}
|
||||
}
|
||||
|
||||
# Browser VS Code inside the workspace, surfaced as a dashboard app.
|
||||
# Extensions install from Open VSX — anthropic.claude-code is the
|
||||
# official Claude Code extension
|
||||
# (https://open-vsx.org/extension/Anthropic/claude-code). OAuth creds
|
||||
# land in ~/.claude inside the home volume and survive rebuilds.
|
||||
module "code_server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "~> 1.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
|
||||
extensions = [
|
||||
"anthropic.claude-code",
|
||||
]
|
||||
}
|
||||
|
||||
# Home survives workspace stop/start AND template-driven rebuilds —
|
||||
# ignore_changes keeps Terraform from recreating the volume (and wiping
|
||||
# ~/.claude, extensions, repos) when template metadata shifts.
|
||||
resource "docker_volume" "home" {
|
||||
name = "coder-${data.coder_workspace.me.id}-home"
|
||||
lifecycle {
|
||||
ignore_changes = all
|
||||
}
|
||||
}
|
||||
|
||||
resource "docker_container" "workspace" {
|
||||
# start_count is 0 when the workspace is stopped — the container is
|
||||
# deleted but the home volume above persists. This is what idle
|
||||
# autostop reclaims: RAM back to the inference stacks.
|
||||
count = data.coder_workspace.me.start_count
|
||||
image = "codercom/enterprise-base:ubuntu"
|
||||
name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}"
|
||||
hostname = data.coder_workspace.me.name
|
||||
|
||||
# Agent bootstrap, rewritten to reach the control plane through the
|
||||
# docker bridge (the workspace is a sibling container; "localhost"
|
||||
# inside it isn't the Coder server).
|
||||
entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")]
|
||||
env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"]
|
||||
|
||||
host {
|
||||
host = "host.docker.internal"
|
||||
ip = "host-gateway"
|
||||
}
|
||||
|
||||
volumes {
|
||||
container_path = "/home/coder"
|
||||
volume_name = docker_volume.home.name
|
||||
read_only = false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user