Coder on a VPS: Self-Hosted Remote Development Environments for Teams

Coder on a VPS: Self-Hosted Remote Development Environments for Teams

Coder is an open-source platform for creating and managing remote development environments — each developer gets an isolated workspace (a Docker container or VM) with a consistent toolchain, running on your VPS infrastructure. Engineers connect via VS Code, JetBrains Gateway, or a web browser. Coder eliminates “works on my machine” problems, enables development on powerful server hardware from lightweight laptops, and provides consistent environments that mirror production.

Why Remote Dev Environments

  • Consistency: Every developer uses the same Docker image, tools, and configuration — no setup docs, no drift
  • Performance: Develop on VPS CPU/RAM instead of MacBook Air limitations
  • Security: Code never leaves the server — laptops only transmit keystrokes and screen rendering
  • Access anywhere: Browser-based VS Code works from any device, including iPad
  • Onboarding speed: New developer gets a working environment in 2 minutes, not 2 days

Step 1: Install Coder

<code"># Single binary install
curl -L https://coder.com/install.sh | sh

# Or Docker:
mkdir -p /opt/coder && cd /opt/coder
nano docker-compose.yml
<code">version: '3.8'

services:
  coder:
    image: ghcr.io/coder/coder:latest
    container_name: coder
    restart: always
    ports:
      - "127.0.0.1:7080:7080"
    environment:
      CODER_PG_CONNECTION_URL: postgresql://coder:${POSTGRES_PASSWORD}@coder-db/coder?sslmode=disable
      CODER_HTTP_ADDRESS: "0.0.0.0:7080"
      CODER_ACCESS_URL: https://coder.yourdomain.com
      CODER_WILDCARD_ACCESS_URL: "*.coder.yourdomain.com"
      CODER_TELEMETRY_ENABLE: "false"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      coder-db:
        condition: service_healthy

  coder-db:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: coder
      POSTGRES_USER: coder
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - coder_db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U coder"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  coder_db:
<code">echo "POSTGRES_PASSWORD=StrongCoderDbPassword!" > .env
chmod 600 .env
docker compose up -d

Step 2: Nginx Reverse Proxy

<code">sudo nano /etc/nginx/sites-available/coder
<code">server {
    listen 80;
    server_name coder.yourdomain.com *.coder.yourdomain.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name coder.yourdomain.com *.coder.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/coder.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/coder.yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:7080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 86400s;   # Long timeout for persistent dev connections
    }
}
<code">sudo certbot --nginx -d coder.yourdomain.com
# For wildcard cert (required for *.coder.yourdomain.com):
# sudo certbot certonly --dns-cloudflare -d coder.yourdomain.com -d "*.coder.yourdomain.com"
sudo systemctl reload nginx

Step 3: Create Admin Account and First Template

<code"># Create first admin user
docker exec -it coder coder server create-admin-user \
    --email admin@yourdomain.com \
    --username admin \
    --password AdminPassword!

# Install Coder CLI locally
curl -L https://coder.com/install.sh | sh
coder login https://coder.yourdomain.com

Step 4: Create a Workspace Template

Templates define the development environment. Create a Docker-based template:

<code">mkdir -p /opt/coder-templates/node-dev && cd /opt/coder-templates/node-dev
nano main.tf
<code">terraform {
  required_providers {
    coder = {
      source = "coder/coder"
    }
    docker = {
      source = "kreuzwerker/docker"
    }
  }
}

data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}

resource "coder_agent" "main" {
  arch           = "amd64"
  os             = "linux"
  startup_script = <<-EOT
    # Install dependencies
    set -e
    curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
    apt-get install -y nodejs
    npm install -g typescript ts-node nodemon

    # Clone user's dotfiles if provided
    if [ -n "$DOTFILES_URI" ]; then
      coder dotfiles -y "$DOTFILES_URI"
    fi

    echo "Dev environment ready!"
  EOT

  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
  }
}

# VS Code in browser
resource "coder_app" "code-server" {
  agent_id     = coder_agent.main.id
  slug         = "code-server"
  display_name = "VS Code"
  url          = "http://localhost:13337/?folder=/home/coder"
  icon         = "/icon/code.svg"
  subdomain    = true
  share        = "owner"
}

resource "docker_image" "workspace" {
  name = "codercom/enterprise-node:ubuntu"
}

resource "docker_container" "workspace" {
  count = data.coder_workspace.me.start_count
  image = docker_image.workspace.image_id
  name  = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}"
  hostname = data.coder_workspace.me.name

  command = ["sh", "-c", coder_agent.main.init_script]

  env = [
    "CODER_AGENT_TOKEN=${coder_agent.main.token}",
  ]

  volumes {
    container_path = "/home/coder"
    volume_name    = docker_volume.home.name
    read_only      = false
  }

  # Resource limits
  memory = 2048   # 2 GB RAM per workspace
  cpu_shares = 512
}

resource "docker_volume" "home" {
  name = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}-home"
}
<code"># Push template to Coder
coder templates push node-dev --directory /opt/coder-templates/node-dev

Step 5: Create a Workspace

<code"># From CLI
coder create myworkspace --template node-dev

# Or from web UI:
# https://coder.yourdomain.com → Create Workspace → select template → name → Create

# Connect via VS Code extension:
# Install "Coder" extension in VS Code → Sign in → Connect to workspace

# Connect via SSH:
coder ssh myworkspace

# Open browser-based VS Code:
# https://myworkspace--code-server.coder.yourdomain.com

Step 6: Team Management

<code"># Create users (admin only)
coder users create \
    --email developer@company.com \
    --username jsmith \
    --login-type password

# Set resource quotas per user (admin):
# Admin → Users → select user → Workspace Quotas
# Max workspaces: 2
# Max CPU cores: 4
# Max memory: 8 GB

# Create organizations for team isolation:
# Admin → Organizations → New Organization → assign users and templates

Getting Started

Coder itself uses 200–400 MB RAM. Each developer workspace uses 0.5–2 GB RAM plus their running services. A 16 GB Ubuntu VPS at VPS.DO supports 4–8 concurrent developer workspaces. For teams with 2–4 developers, a single 8 GB VPS provides a cost-effective remote development platform — developers use lightweight laptops while building on server hardware with persistent file storage.

Conclusion

Coder on a VPS delivers self-hosted remote development environments where each developer gets an isolated, consistent workspace accessible from VS Code, JetBrains, or a browser. The Terraform-based template system makes it trivial to define and share standardized development environments — Node.js, Python, Go, or any stack — with consistent tooling, avoiding setup friction and “works on my machine” debugging. For teams prioritizing consistency, security, and access to more powerful hardware than laptops provide, Coder is the self-hosted answer to cloud-hosted dev environments.

Fast • Reliable • Affordable VPS - DO It Now!

Get top VPS hosting with VPS.DO’s fast, low-cost plans. Try risk-free with our 7-day no-questions-asked refund and start today!