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.