Update template with copilot

This commit is contained in:
ChenKaiLiuG
2025-11-17 00:11:21 +08:00
parent 5b130bc9d7
commit f98f53e83f
4 changed files with 96 additions and 99 deletions

1
sh/ollama-monitor.sh Normal file
View File

@@ -0,0 +1 @@
#!/bin/bash echo "Starting Ollama monitor service..." # 無限迴圈來持續監控 while true; do # 檢查 ollama 服務的日誌,看看最近是否有新請求或活動 # 'tail -n 1' 抓取最新的日誌行 # 'grep -E' 搜尋包含 'generating' 或 'loading' 的行,代表有活動 if docker logs ollama --since 2m 2>&1 | grep -E -q 'generating|loading'; then echo "$(date) - Ollama is active. Not unloading models." # 如果有活動,等待 1 分鐘後再次檢查 sleep 60 else # 如果 10 分鐘內沒有活動,執行卸載指令 echo "$(date) - Ollama is idle. Unloading models..." docker exec ollama ollama unload -a echo "$(date) - Models unloaded." # 等待 1 分鐘後再次檢查 sleep 60 fi done

0
sh/vllm-monitor.sh Normal file
View File

65
stack/vllm-webui.yml Normal file
View File

@@ -0,0 +1,65 @@
version: '3.8'
services:
vllm:
container_name: vllm
image: vllm/vllm:latest
restart: always
volumes:
- vllm-data:/root/.vllm
- /mnt/970_Containers/ollama_model:/models
# Persist only conversation logs to a host folder (example relative path)
- ./data/vllm_convos:/root/.vllm/conversations
# Default HTTP port for the vllm server - adjust if your image uses a different port
ports:
- "8000:8000"
environment:
# Informational env for other services; change if your webui expects a different var
- VLLM_API_URL=http://vllm:8000
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 2 # adjust to your GPU count
capabilities: [gpu]
open-webui:
container_name: open-webui
image: ghcr.io/open-webui/open-webui:main
restart: always
volumes:
- open-webui-data:/app/backend/data
ports:
- "9070:8080"
# Many web frontends accept a backend URL env; adjust the variable name if needed.
environment:
- VLLM_BASE_URL=http://vllm:8000
networks:
- stack_bridge
vllm-monitor:
image: docker:cli
container_name: vllm-monitor
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /mnt/data/External/ollama_monitor/monitor.sh:/monitor.sh:ro
entrypoint: ["/bin/sh", "/monitor.sh"]
depends_on:
- vllm
volumes:
vllm-data:
open-webui-data:
networks:
stack_bridge:
external: true
# NOTES:
# - This compose file is a starting point. It assumes the vllm image exposes an HTTP API on port 8000
# and that conversation logs live under /root/.vllm/conversations inside the container.
# - If the real vllm image uses different paths or ports, update the paths/ports accordingly.
# - Keep the named volume `vllm-data` to hold other vllm internal state; the host mount
# ./data/vllm_convos will persist conversations specifically on the host.

View File

@@ -3,62 +3,57 @@ terraform {
coder = { coder = {
source = "coder/coder" source = "coder/coder"
} }
docker = {
source = "kreuzwerker/docker"
}
} }
} }
locals { locals {
username = data.coder_workspace_owner.me.name username = data.coder_workspace_owner.me.name
} user_id = data.coder_workspace_owner.me.id
variable "docker_socket" {
default = ""
description = "(Optional) Docker socket URI"
type = string
}
provider "docker" {
# Defaulting to null if the variable is an empty string lets us have an optional variable without having to set our own default
host = var.docker_socket != "" ? var.docker_socket : null
} }
data "coder_provisioner" "me" {} data "coder_provisioner" "me" {}
data "coder_workspace" "me" {} data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {} data "coder_workspace_owner" "me" {}
# 環境變數GitHub token for Copilot
variable "github_token" {
description = "GitHub token for Copilot authentication (optional)"
type = string
sensitive = true
default = ""
}
resource "coder_agent" "main" { resource "coder_agent" "main" {
arch = data.coder_provisioner.me.arch arch = data.coder_provisioner.me.arch
os = "linux" os = "linux"
startup_script = <<-EOT startup_script = <<-EOT
set -e set -e
# Prepare user home with default files on first start. # 初始化使用者目錄
if [ ! -f ~/.init_done ]; then if [ ! -f ~/.init_done ]; then
cp -rT /etc/skel ~ cp -rT /etc/skel ~ || true
touch ~/.init_done touch ~/.init_done
fi fi
# Add any commands that should be executed at workspace startup (e.g install requirements, start a program, etc) here # 確保必要目錄存在
mkdir -p ~/.config ~/.cache ~/.local/share
# 安裝 VSCode Server extensions可選
# code-server --install-extension github.copilot
# code-server --install-extension ms-vscode.cpptools
EOT EOT
# These environment variables allow you to make Git commits right away after creating a # Git 認證配置
# workspace. Note that they take precedence over configuration defined in ~/.gitconfig!
# You can remove this block if you'd prefer to configure Git manually or using
# dotfiles. (see docs/dotfiles.md)
env = { env = {
GIT_AUTHOR_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) 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_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_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name)
GIT_COMMITTER_EMAIL = "${data.coder_workspace_owner.me.email}" GIT_COMMITTER_EMAIL = "${data.coder_workspace_owner.me.email}"
# GitHub Copilot 認證
GITHUB_TOKEN = var.github_token != "" ? var.github_token : ""
} }
# The following metadata blocks are optional. They are used to display # 監控指標
# information about your workspace in the dashboard. You can remove them
# if you don't want to display any information.
# For basic resources, you can use the `coder stat` command.
# If you need more control, you can write your own script.
metadata { metadata {
display_name = "CPU Usage" display_name = "CPU Usage"
key = "0_cpu_usage" key = "0_cpu_usage"
@@ -102,7 +97,6 @@ resource "coder_agent" "main" {
metadata { metadata {
display_name = "Load Average (Host)" display_name = "Load Average (Host)"
key = "6_load_host" key = "6_load_host"
# get load avg scaled by number of cores
script = <<EOT script = <<EOT
echo "`cat /proc/loadavg | awk '{ print $1 }'` `nproc`" | awk '{ printf "%0.2f", $1/$2 }' echo "`cat /proc/loadavg | awk '{ print $1 }'` `nproc`" | awk '{ printf "%0.2f", $1/$2 }'
EOT EOT
@@ -125,12 +119,15 @@ resource "coder_agent" "main" {
module "code-server" { module "code-server" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/code-server/coder" source = "registry.coder.com/coder/code-server/coder"
# This ensures that the latest non-breaking version of the module gets downloaded, you can also pin the module version to prevent breaking changes in production.
version = "~> 1.0" version = "~> 1.0"
agent_id = coder_agent.main.id agent_id = coder_agent.main.id
order = 1 order = 1
# code-server 會自動使用:
# - 認證:繼承 Coder 的 OIDC (GitHub) 認證
# - 自動存檔code-server 內建 auto-save
# - Extensions支援 GitHub Copilot需要 GitHub token
} }
# See https://registry.coder.com/modules/coder/jetbrains # See https://registry.coder.com/modules/coder/jetbrains
@@ -143,69 +140,3 @@ module "jetbrains" {
folder = "/home/coder" folder = "/home/coder"
tooltip = "You need to [install JetBrains Toolbox](https://coder.com/docs/user-guides/workspace-access/jetbrains/toolbox) to use this app." tooltip = "You need to [install JetBrains Toolbox](https://coder.com/docs/user-guides/workspace-access/jetbrains/toolbox) to use this app."
} }
resource "docker_volume" "home_volume" {
name = "coder-${data.coder_workspace.me.id}-home"
# Protect the volume from being deleted due to changes in attributes.
lifecycle {
ignore_changes = all
}
# Add labels in Docker to keep track of orphan resources.
labels {
label = "coder.owner"
value = data.coder_workspace_owner.me.name
}
labels {
label = "coder.owner_id"
value = data.coder_workspace_owner.me.id
}
labels {
label = "coder.workspace_id"
value = data.coder_workspace.me.id
}
# This field becomes outdated if the workspace is renamed but can
# be useful for debugging or cleaning out dangling volumes.
labels {
label = "coder.workspace_name_at_creation"
value = data.coder_workspace.me.name
}
}
resource "docker_container" "workspace" {
count = data.coder_workspace.me.start_count
image = "codercom/enterprise-base:ubuntu"
# Uses lower() to avoid Docker restriction on container names.
name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}"
# Hostname makes the shell more user friendly: coder@my-workspace:~$
hostname = data.coder_workspace.me.name
# Use the docker gateway if the access URL is 127.0.0.1
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_volume.name
read_only = false
}
# Add labels in Docker to keep track of orphan resources.
labels {
label = "coder.owner"
value = data.coder_workspace_owner.me.name
}
labels {
label = "coder.owner_id"
value = data.coder_workspace_owner.me.id
}
labels {
label = "coder.workspace_id"
value = data.coder_workspace.me.id
}
labels {
label = "coder.workspace_name"
value = data.coder_workspace.me.name
}
}