This commit is contained in:
2025-08-24 21:47:21 -04:00
parent f7f0ff3a28
commit bf247b0950
10 changed files with 123 additions and 34 deletions

View File

@@ -43,13 +43,13 @@ resource "coder_app" "pgadmin" {
agent_id = coder_agent.main.id
slug = "pgadmin"
display_name = "pgAdmin"
url = "http://localhost:${var.pgadmin_port}"
url = "http://pgadmin-${local.workspace_id}:80"
icon = "/icon/postgresql.svg"
subdomain = true
share = "owner"
healthcheck {
url = "http://localhost:${var.pgadmin_port}/misc/ping"
url = "http://pgadmin-${local.workspace_id}:80/misc/ping"
interval = 15
threshold = 5
}
@@ -61,13 +61,13 @@ resource "coder_app" "qdrant" {
agent_id = coder_agent.main.id
slug = "qdrant-dashboard"
display_name = "Qdrant Dashboard"
url = "http://localhost:6333/dashboard"
url = "http://qdrant-${local.workspace_id}:6333/dashboard"
icon = "/icon/database.svg"
subdomain = true
share = "owner"
healthcheck {
url = "http://localhost:6333/health"
url = "http://qdrant-${local.workspace_id}:6333/health"
interval = 20
threshold = 5
}
@@ -205,7 +205,7 @@ resource "coder_app" "db_tester" {
slug = "db-tester"
display_name = "Database Tester"
icon = "/icon/terminal.svg"
command = "bash"
command = "bash -c 'echo \"=== Database Connection Test ===\"; echo \"PostgreSQL: postgres-${local.workspace_id}:5432\"; echo \"Redis: redis-${local.workspace_id}:6379\"; echo \"Qdrant: qdrant-${local.workspace_id}:6333\"; echo; echo \"Test PostgreSQL:\"; pg_isready -h postgres-${local.workspace_id} -p 5432 -U postgres || echo \"PostgreSQL not ready\"; echo; echo \"Test Redis:\"; redis-cli -h redis-${local.workspace_id} -p 6379 ping || echo \"Redis not ready\"; echo; echo \"Test Qdrant:\"; curl -f http://qdrant-${local.workspace_id}:6333/health || echo \"Qdrant not ready\"; echo; read -p \"Press Enter to exit...\"'"
}
# Development Logs Viewer

View File

@@ -14,7 +14,7 @@ resource "coder_script" "claude_code_setup" {
icon = "/icon/claude.svg"
run_on_start = true
script = file("${path.module}/scripts/claude-install.sh")
script = "bash /home/coder/resources/tf/scripts/claude-install.sh"
}
# =============================================================================
@@ -28,7 +28,7 @@ resource "coder_script" "cursor_setup" {
icon = "/icon/cursor.svg"
run_on_start = true
script = file("${path.module}/scripts/cursor-setup.sh")
script = "bash /home/coder/resources/tf/scripts/cursor-setup.sh"
}
# =============================================================================
@@ -42,7 +42,7 @@ resource "coder_script" "windsurf_setup" {
icon = "/icon/windsurf.svg"
run_on_start = true
script = file("${path.module}/scripts/windsurf-setup.sh")
script = "bash /home/coder/resources/tf/scripts/windsurf-setup.sh"
}
# =============================================================================
@@ -55,7 +55,7 @@ resource "coder_script" "dev_extensions" {
icon = "/icon/tools.svg"
run_on_start = true
script = file("${path.module}/scripts/dev-tools.sh")
script = "bash /home/coder/resources/tf/scripts/dev-tools.sh"
}
# =============================================================================
@@ -68,5 +68,5 @@ resource "coder_script" "git_hooks_setup" {
icon = "/icon/git.svg"
run_on_start = true
script = file("${path.module}/scripts/git-hooks.sh")
script = "bash /home/coder/resources/tf/scripts/git-hooks.sh"
}

View File

@@ -18,8 +18,12 @@ if ! command -v npm >/dev/null 2>&1; then
exit 1
fi
echo "📥 Installing Claude Code globally via npm..."
npm install -g @anthropic-ai/claude
echo "📥 Installing Claude Code CLI via npm..."
# Use specific working version of claude CLI
npm install -g @anthropic-ai/claude-cli@latest || npm install -g @anthropic-ai/claude-code@latest || {
echo "⚠️ Official Claude package not available, installing alternative..."
npm install -g claude-ai-cli || echo "❌ All Claude installations failed"
}
# Verify installation
if command -v claude >/dev/null 2>&1; then

View File

@@ -176,7 +176,9 @@ cat > /home/coder/.cursor-server/data/User/snippets/global.code-snippets << 'CUR
CURSOR_SNIPPETS_END
# Set proper ownership
chown -R coder:coder /home/coder/.cursor-server
if id -u coder >/dev/null 2>&1; then
chown -R coder:coder /home/coder/.cursor-server
fi
echo "✅ Cursor IDE support configured"
echo "🎯 Cursor will use optimized settings for this development environment"

View File

@@ -1,7 +1,26 @@
#!/bin/bash
set -e
echo "🔧 Installing development extensions and tools..."
# Function to safely install packages with error handling
safe_install() {
local package_name="$1"
local install_command="$2"
local fallback_command="$3"
echo "📦 Installing $package_name..."
if eval "$install_command"; then
echo "$package_name installed successfully"
return 0
else
echo "⚠️ $package_name installation failed"
if [ -n "$fallback_command" ]; then
echo "🔄 Trying fallback installation..."
eval "$fallback_command" || echo "❌ Fallback also failed for $package_name"
fi
return 1
fi
}
# Ensure we're running as root for system packages
if [ "$EUID" -ne 0 ]; then
echo "This script needs to run as root for system package installation"
@@ -44,10 +63,15 @@ install_development_tools() {
rm lazygit.tar.gz lazygit
fi
# btop for system monitoring
# btop for system monitoring (fallback to htop if btop unavailable)
if ! command -v btop &> /dev/null; then
echo "📊 Installing btop..."
apt-get install btop -y
if apt-get install btop -y 2>/dev/null; then
echo "✅ btop installed successfully"
else
echo "⚠️ btop not available, installing htop as fallback..."
apt-get install htop -y
fi
fi
# fd-find for better file searching
@@ -75,7 +99,11 @@ install_development_tools() {
# eza for better ls (modern replacement for exa)
if ! command -v eza &> /dev/null; then
echo "📁 Installing eza..."
curl -L "https://github.com/eza-community/eza/releases/latest/download/eza_x86_64-unknown-linux-gnu.tar.gz" | tar xz -C /usr/local/bin
if ! curl -L "https://github.com/eza-community/eza/releases/latest/download/eza_x86_64-unknown-linux-gnu.tar.gz" | tar xz -C /usr/local/bin 2>/dev/null; then
echo "⚠️ eza installation failed, skipping..."
else
echo "✅ eza installed successfully"
fi
fi
}

View File

@@ -76,7 +76,9 @@ PRE_PUSH_END
chmod +x .git/hooks/pre-push
# Set proper ownership for the coder user
chown -R coder:coder .git/hooks
if id -u coder >/dev/null 2>&1; then
chown -R coder:coder .git/hooks
fi
echo "✅ Git hooks and metadata capture configured"
echo "📝 Git metadata will be automatically captured on commits"

View File

@@ -59,7 +59,9 @@ cat > /home/coder/.windsurf/data/User/keybindings.json << 'WINDSURF_KEYS_END'
WINDSURF_KEYS_END
# Set proper ownership
chown -R coder:coder /home/coder/.windsurf
if id -u coder >/dev/null 2>&1; then
chown -R coder:coder /home/coder/.windsurf
fi
echo "✅ Windsurf IDE support configured"
echo "🌊 Windsurf AI features enabled with optimized settings"

View File

@@ -7,9 +7,12 @@ echo "🚀 Initializing development environment as user: $(whoami)"
# =============================================================================
if ! id -u coder >/dev/null 2>&1; then
echo "👤 Creating coder user..."
useradd -m -s /bin/bash -u 1000 coder
useradd -m -s /bin/bash coder
usermod -aG sudo coder
echo "coder ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
elif [ "$(id -u coder)" != "1000" ]; then
echo "👤 Coder user exists but with different UID, updating..."
usermod -u 1000 coder
fi
# =============================================================================
@@ -22,8 +25,12 @@ mkdir -p /home/coder/.config
mkdir -p /tmp/git-metadata
mkdir -p /workspaces
# Ensure proper ownership
chown -R coder:coder /home/coder /workspaces
# Ensure proper ownership (only if coder user exists, excluding read-only bind mounts)
if id -u coder >/dev/null 2>&1; then
chown -R coder:coder /home/coder/.local /home/coder/.config /home/coder/bin /workspaces
# Set ownership for coder home directory files (not subdirectories that might be bind mounted)
find /home/coder -maxdepth 1 -type f -exec chown coder:coder {} \; 2>/dev/null || true
fi
# =============================================================================
# Switch to coder user for remaining operations
@@ -69,24 +76,54 @@ apt-get install -y make tree jq curl wget unzip build-essential postgresql-clien
# =============================================================================
echo "🟢 Setting up Node.js and npm..."
# Clean any existing npm caches with wrong ownership (as root before switching users)
rm -rf /home/coder/.npm /home/coder/.npm-global 2>/dev/null || true
rm -rf /root/.npm 2>/dev/null || true
# Pre-create directories with proper ownership including lib and bin subdirectories
mkdir -p /home/coder/.npm /home/coder/.npm-global/{lib,bin,lib/node_modules}
chown -R coder:coder /home/coder/.npm /home/coder/.npm-global 2>/dev/null || true
# Create Node.js setup script
cat > /tmp/node_setup.sh << 'NODE_SCRIPT_END'
#!/bin/bash
# Create bash profile first
echo 'export NVM_DIR="$HOME/.nvm"' >> ~/.bashrc
echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> ~/.bashrc
echo '[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"' >> ~/.bashrc
# Clean any npmrc files that might conflict with nvm
rm -f ~/.npmrc 2>/dev/null || true
# Verify npm directories exist and are owned by coder
ls -la ~/.npm ~/.npm-global || echo "npm directories ready"
if ! command -v nvm &> /dev/null; then
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
export NVM_DIR="/home/coder/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
fi
# Load nvm properly
export NVM_DIR="/home/coder/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"
nvm install ${NODE_VERSION}
nvm use ${NODE_VERSION}
nvm alias default ${NODE_VERSION}
# Create npm-global lib directory structure
mkdir -p ~/.npm-global/{lib,bin}
# Configure npm to use user-writable directories
npm config set prefix ~/.npm-global
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
export PATH=~/.npm-global/bin:$PATH
# Verify npm configuration
echo "📋 npm configuration:"
npm config get prefix
npm config get cache
echo "📦 Installing npm packages..."
npm install -g repomix create-next-app nodemon concurrently @types/node typescript eslint prettier
npm install -g create-next-app@latest
NODE_SCRIPT_END
chmod +x /tmp/node_setup.sh
@@ -98,8 +135,19 @@ rm /tmp/node_setup.sh
# =============================================================================
echo "🐍 Setting up Python and uv..."
# Install Python version
apt-get install -y python${PYTHON_VERSION} python${PYTHON_VERSION}-dev python${PYTHON_VERSION}-venv
# Install Python version (add deadsnakes PPA for newer Python versions)
if [[ "${PYTHON_VERSION}" > "3.10" ]]; then
echo "📦 Adding deadsnakes PPA for Python ${PYTHON_VERSION}..."
apt-get install -y software-properties-common
add-apt-repository ppa:deadsnakes/ppa -y
apt-get update
fi
apt-get install -y python${PYTHON_VERSION} python${PYTHON_VERSION}-dev python${PYTHON_VERSION}-venv || {
echo "⚠️ Python ${PYTHON_VERSION} not available, falling back to default Python 3"
apt-get install -y python3 python3-dev python3-venv
export PYTHON_VERSION="3"
}
# Create Python setup script
cat > /tmp/python_setup.sh << 'PYTHON_SCRIPT_END'

View File

@@ -38,7 +38,7 @@ resource "docker_container" "postgres" {
"POSTGRES_MAX_CONNECTIONS=${var.postgres_max_connections}"
]
# Network configuration
# Network configuration - internal only, accessible via Coder port forwarding
networks_advanced {
name = docker_network.workspace.name
}
@@ -170,8 +170,6 @@ resource "docker_container" "qdrant" {
name = docker_network.workspace.name
}
# Ports accessible within workspace network - no host exposure needed
# Data persistence
volumes {
volume_name = docker_volume.qdrant_data[0].name
@@ -237,8 +235,6 @@ resource "docker_container" "pgadmin" {
name = docker_network.workspace.name
}
# Port accessible within workspace network - no host exposure needed
# Data persistence
volumes {
volume_name = docker_volume.pgadmin_data[0].name

View File

@@ -31,8 +31,8 @@ resource "coder_agent" "main" {
"ENABLE_SERVICES" = tostring(data.coder_parameter.enable_services.value)
}
# Load startup script from external file
startup_script = file("${path.module}/scripts/workspace-setup.sh")
# Reference bind-mounted startup script
startup_script = "bash /home/coder/resources/tf/scripts/workspace-setup.sh"
# Performance and resource monitoring
metadata {
@@ -122,6 +122,13 @@ resource "docker_container" "workspace" {
read_only = false
}
# Bind mount code-tools directory for live script updates
volumes {
host_path = "/home/trav/code-tools"
container_path = "/home/coder/resources"
read_only = true
}
# Docker socket for Docker-in-Docker
volumes {
host_path = "/var/run/docker.sock"