Skip to content

Instantly share code, notes, and snippets.

@bpmct
Created March 15, 2025 17:55
Show Gist options
  • Save bpmct/50a076fe60d863cbe4a2d22cd3eef786 to your computer and use it in GitHub Desktop.
Save bpmct/50a076fe60d863cbe4a2d22cd3eef786 to your computer and use it in GitHub Desktop.
Building Coder on Windows - Guide and Automation Script

Building Coder on Windows - Complete Guide

This guide documents the process of setting up a Windows workspace using Coder and building the Coder repository on it.

Prerequisites

  • Access to a Coder deployment (e.g., dev.coder.com)
  • coder CLI installed and authenticated

Step 1: Create a Windows Workspace

# Create the workspace using the windows-with-good-rdp template
coder create --parameter display_enabled=false \
             --parameter gpu_enabled=false \
             --parameter zone="us-central1-a" \
             --template windows-with-good-rdp \
             --org=coder \
             windows-coder-build

When prompted, confirm the creation by typing yes.

Step 2: Set Up SSH Configuration

# Ensure SSH directory exists
mkdir -p ~/.ssh && chmod 700 ~/.ssh

# Configure SSH for Coder
coder config-ssh -y

Step 3: Connect to the Windows Workspace

# Test connection to the workspace
ssh coder.windows-coder-build echo "Connection successful"

Step 4: Windows Environment Setup and Building Coder

Here are the PowerShell commands to run on the Windows workspace:

# Create a working directory
New-Item -Path "C:\build-test" -ItemType Directory -Force
Set-Location -Path "C:\build-test"

# Install Git
Write-Host "Installing Git..."
Invoke-WebRequest -Uri "https://github.com/git-for-windows/git/releases/download/v2.42.0.windows.2/Git-2.42.0.2-64-bit.exe" -OutFile "git-installer.exe"
Start-Process -FilePath "git-installer.exe" -ArgumentList "/VERYSILENT /NORESTART" -Wait

# Clone the Coder repository
$gitPath = "C:\Program Files\Git\bin\git.exe"
Write-Host "Using Git from: $gitPath"
& $gitPath clone https://github.com/coder/coder.git
Set-Location -Path "coder"

# Install Go (portable version)
Write-Host "Installing Go (portable version)..."
Invoke-WebRequest -Uri "https://go.dev/dl/go1.21.0.windows-amd64.zip" -OutFile "C:\build-test\go.zip"

# Create directory for extraction
New-Item -Path "C:\build-test\go3" -ItemType Directory -Force

# Extract Go using .NET
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::ExtractToDirectory("C:\build-test\go.zip", "C:\build-test\go3")

# Set environment variables
$env:Path += ";C:\build-test\go3\go\bin"
$env:GOPATH = "C:\build-test\gopath"
[Environment]::SetEnvironmentVariable("Path", $env:Path, "User")
[Environment]::SetEnvironmentVariable("GOPATH", $env:GOPATH, "User")

# Verify Go installation
Write-Host "Verifying Go installation..."
& "C:\build-test\go3\go\bin\go.exe" version

# Build the Coder project
Write-Host "Building Coder project..."
Set-Location -Path "C:\build-test\coder"
& "C:\build-test\go3\go\bin\go.exe" build -o coder.exe ./cmd/coder

# Verify the build
if (Test-Path "coder.exe") {
    Write-Host "Build successful\! Coder binary created at: $(Get-Location)\coder.exe"
    & .\coder.exe version
} else {
    Write-Host "Build failed. The binary was not created."
}

Step 5: Verify the Build

# Check what's in the build directory
ssh coder.windows-coder-build powershell -Command "Get-ChildItem -Path 'C:\build-test\coder' -File | Where-Object { \$_.Extension -eq '.exe' } | Select-Object Name, Length, LastWriteTime"

# Verify the executable works
ssh coder.windows-coder-build powershell -Command "& 'C:\build-test\coder\coder.exe' version"

Bash Script for Automation

Here's a complete Bash script that automates the entire process:

#\!/bin/bash
set -e

# Step 1: Create the workspace
echo "Creating Windows workspace..."
coder create --parameter display_enabled=false \
             --parameter gpu_enabled=false \
             --parameter zone="us-central1-a" \
             --template windows-with-good-rdp \
             --org=coder \
             windows-coder-build <<< "yes"

# Step 2: Set up SSH
echo "Setting up SSH..."
mkdir -p ~/.ssh && chmod 700 ~/.ssh
coder config-ssh -y

# Step 3: Wait for the workspace to be ready
echo "Waiting for workspace to be ready..."
sleep 60  # Give the workspace time to initialize

# Step 4: Create PowerShell script for Windows setup
cat > setup_coder_build.ps1 << 'EOPS'
# Create working directory
New-Item -Path "C:\build-test" -ItemType Directory -Force
Set-Location -Path "C:\build-test"

# Install Git
Write-Host "Installing Git..."
Invoke-WebRequest -Uri "https://github.com/git-for-windows/git/releases/download/v2.42.0.windows.2/Git-2.42.0.2-64-bit.exe" -OutFile "git-installer.exe"
Start-Process -FilePath "git-installer.exe" -ArgumentList "/VERYSILENT /NORESTART" -Wait
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")

# Clone repository using Git from its installation path
$gitPath = "C:\Program Files\Git\bin\git.exe"
Write-Host "Using Git from: $gitPath"
& $gitPath clone https://github.com/coder/coder.git
Set-Location -Path "coder"

# Install Go (portable version)
Write-Host "Installing Go..."
Invoke-WebRequest -Uri "https://go.dev/dl/go1.21.0.windows-amd64.zip" -OutFile "C:\build-test\go.zip"

# Extract Go
New-Item -Path "C:\build-test\go3" -ItemType Directory -Force
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::ExtractToDirectory("C:\build-test\go.zip", "C:\build-test\go3")

# Set environment variables
$env:Path += ";C:\build-test\go3\go\bin"
$env:GOPATH = "C:\build-test\gopath"
[Environment]::SetEnvironmentVariable("Path", $env:Path, "User")
[Environment]::SetEnvironmentVariable("GOPATH", $env:GOPATH, "User")

# Verify Go installation
Write-Host "Go version:"
& "C:\build-test\go3\go\bin\go.exe" version

# Build Coder
Write-Host "Building Coder..."
Set-Location -Path "C:\build-test\coder"
& "C:\build-test\go3\go\bin\go.exe" build -o coder.exe ./cmd/coder

# Verify build
if (Test-Path "coder.exe") {
    Write-Host "Build successful\! Binary size: $((Get-Item coder.exe).Length) bytes"
    Write-Host "Version info:"
    & .\coder.exe version
} else {
    Write-Host "Build failed\!"
}
EOPS

# Step 5: Send script to Windows workspace
echo "Transferring build script to workspace..."
cat setup_coder_build.ps1 | ssh coder.windows-coder-build powershell -Command "-"

# Step 6: Verify build results
echo "Checking build results..."
ssh coder.windows-coder-build powershell -Command "if (Test-Path 'C:\build-test\coder\coder.exe') { Write-Host 'Build successful\!'; Get-Item 'C:\build-test\coder\coder.exe' | Select-Object FullName, Length, LastWriteTime; & 'C:\build-test\coder\coder.exe' version } else { Write-Host 'Build not found.' }"

echo "Process complete\!"

Notes and Troubleshooting

  1. Windows RDP Access: The Windows workspace created with the template includes RDP access with these credentials:

    • Username: Administrator
    • Password: coderRDP\!
  2. Build Time: The Coder build process can take between 5-15 minutes depending on the workspace resources and network connectivity.

  3. SSH Connection Issues: If SSH connection stalls, try adding a timeout or forcing a new connection:

    timeout 30 ssh coder.windows-coder-build echo "Connection test"
  4. Alternative Method for Script Execution: If sending a script via standard input doesn't work, you can create a Base64-encoded version:

    SCRIPT_B64=$(base64 -w 0 setup_coder_build.ps1)
    ssh coder.windows-coder-build powershell -Command "[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('$SCRIPT_B64')) | powershell -Command -"
  5. Environment Persistence: Once set up, the environment will persist in the workspace as long as the workspace exists. The Go installation, Git, and the cloned repository will remain intact.

#\!/bin/bash
# Complete script to create a Windows workspace in Coder and build the Coder repo
set -e
echo "==== Starting Windows workspace creation and Coder build process ===="
# Step 1: Create the workspace
echo "Creating Windows workspace..."
coder create --parameter display_enabled=false \
--parameter gpu_enabled=false \
--parameter zone="us-central1-a" \
--template windows-with-good-rdp \
--org=coder \
windows-coder-build <<< "yes"
# Step 2: Set up SSH
echo "Setting up SSH configuration..."
mkdir -p ~/.ssh && chmod 700 ~/.ssh
coder config-ssh -y
# Step 3: Wait for the workspace to be ready
echo "Waiting for workspace to be ready..."
sleep 60 # Give the workspace time to initialize
# Try connecting to verify the workspace is available
echo "Testing connection to workspace..."
ssh coder.windows-coder-build echo "Connection successful" || {
echo "Connection failed. Waiting another 60 seconds...";
sleep 60;
ssh coder.windows-coder-build echo "Retry connection" || {
echo "Connection still failed. Please check workspace status manually.";
exit 1;
}
}
# Step 4: Create PowerShell script for Windows setup
echo "Creating Windows setup script..."
cat > setup_coder_build.ps1 << 'EOPS'
# Create a working directory
Write-Host "Creating working directory..."
New-Item -Path "C:\build-test" -ItemType Directory -Force
Set-Location -Path "C:\build-test"
# Install Git
Write-Host "Installing Git..."
Invoke-WebRequest -Uri "https://github.com/git-for-windows/git/releases/download/v2.42.0.windows.2/Git-2.42.0.2-64-bit.exe" -OutFile "git-installer.exe"
Start-Process -FilePath "git-installer.exe" -ArgumentList "/VERYSILENT /NORESTART" -Wait
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
# Verify Git installation
try {
$gitPath = "C:\Program Files\Git\bin\git.exe"
if (Test-Path $gitPath) {
Write-Host "Git installed successfully at: $gitPath"
& $gitPath --version
} else {
Write-Host "Git installation path not found. Searching for git..."
$gitCmd = Get-Command "git" -ErrorAction SilentlyContinue
if ($gitCmd) {
Write-Host "Git found at: $($gitCmd.Source)"
git --version
} else {
Write-Host "Git not found in PATH. Using absolute path for next steps."
}
}
} catch {
Write-Host "Error checking Git: $_"
}
# Clone the Coder repository
Write-Host "Cloning the Coder repository..."
& $gitPath clone https://github.com/coder/coder.git
if (Test-Path "coder") {
Write-Host "Repository cloned successfully."
Set-Location -Path "coder"
} else {
Write-Host "Failed to clone repository."
exit 1
}
# Install Go (portable version)
Write-Host "Installing Go (portable version)..."
Invoke-WebRequest -Uri "https://go.dev/dl/go1.21.0.windows-amd64.zip" -OutFile "C:\build-test\go.zip"
# Create directory for extraction
Write-Host "Extracting Go archive..."
New-Item -Path "C:\build-test\go3" -ItemType Directory -Force
# Extract Go using .NET
try {
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::ExtractToDirectory("C:\build-test\go.zip", "C:\build-test\go3")
Write-Host "Go archive extracted successfully."
} catch {
Write-Host "Error extracting Go archive: $_"
exit 1
}
# Set environment variables
$env:Path += ";C:\build-test\go3\go\bin"
$env:GOPATH = "C:\build-test\gopath"
[Environment]::SetEnvironmentVariable("Path", $env:Path, "User")
[Environment]::SetEnvironmentVariable("GOPATH", $env:GOPATH, "User")
# Verify Go installation
$goExe = "C:\build-test\go3\go\bin\go.exe"
if (Test-Path $goExe) {
Write-Host "Go installation successful. Version:"
& $goExe version
} else {
Write-Host "Go executable not found at expected location."
exit 1
}
# Build the Coder project
Write-Host "Building Coder project (this may take several minutes)..."
Set-Location -Path "C:\build-test\coder"
Write-Host "Current directory: $(Get-Location)"
# Download dependencies first
Write-Host "Downloading Go dependencies..."
& $goExe mod download
# Build the binary
Write-Host "Building Coder binary..."
& $goExe build -o coder.exe ./cmd/coder
# Verify the build
if (Test-Path "coder.exe") {
$fileInfo = Get-Item "coder.exe"
Write-Host "Build successful\! Coder binary created:"
Write-Host " - Path: $($fileInfo.FullName)"
Write-Host " - Size: $($fileInfo.Length) bytes"
Write-Host " - Created: $($fileInfo.LastWriteTime)"
# Run version command
Write-Host "Checking version information:"
& .\coder.exe version
} else {
Write-Host "Build failed. The binary was not created."
exit 1
}
Write-Host "Setup and build complete\!"
EOPS
# Step 5: Send script to Windows workspace and execute it
echo "Transferring and executing build script on workspace..."
cat setup_coder_build.ps1 | ssh coder.windows-coder-build powershell -Command "-"
# Step 6: Verify the build result
echo "Verifying build result..."
ssh coder.windows-coder-build powershell -Command "if (Test-Path 'C:\build-test\coder\coder.exe') {
Write-Host 'BUILD SUCCESSFUL\!' -ForegroundColor Green
Get-Item 'C:\build-test\coder\coder.exe' | Format-List Name, Length, LastWriteTime
Write-Host 'Coder version:' -ForegroundColor Cyan
& 'C:\build-test\coder\coder.exe' version
} else {
Write-Host 'BUILD FAILED: Binary not found' -ForegroundColor Red
}"
echo "==== Process completed ===="
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment