Self-Hosting Coder with Docker Compose

What Is Coder?

Coder is a self-hosted platform for creating and managing remote development environments. Define your dev environment as a Terraform template — OS, tools, IDE, resources — and Coder provisions it on demand. Developers connect via VS Code, JetBrains Gateway, or SSH. It replaces GitHub Codespaces, Gitpod, and cloud dev environments with infrastructure you control. Official site.

Updated February 2026: Verified with latest Docker images and configurations.

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed (guide)
  • 4 GB of free RAM (minimum; 8 GB+ recommended)
  • 2+ CPU cores
  • 20 GB of free disk space
  • Docker socket access (Coder manages workspace containers)

Docker Compose Configuration

Create a docker-compose.yml file:

services:
  coder:
    image: ghcr.io/coder/coder:v2.30.3
    container_name: coder
    restart: unless-stopped
    ports:
      - "7080:7080"
    environment:
      # Required: PostgreSQL connection
      CODER_PG_CONNECTION_URL: "postgresql://coder:coderpass@coder-db/coder?sslmode=disable"
      # Required: address Coder listens on
      CODER_HTTP_ADDRESS: "0.0.0.0:7080"
      # Required: external URL workspaces use to reach Coder
      # Must be a real IP or domain — NOT localhost
      CODER_ACCESS_URL: "http://your-server-ip:7080"
    volumes:
      # Docker socket for provisioning workspace containers
      - /var/run/docker.sock:/var/run/docker.sock
    group_add:
      - "999"  # Docker group GID — check with: getent group docker
    depends_on:
      coder-db:
        condition: service_healthy

  coder-db:
    image: postgres:16-alpine
    container_name: coder-db
    restart: unless-stopped
    environment:
      POSTGRES_USER: coder
      POSTGRES_PASSWORD: coderpass  # Change this in production
      POSTGRES_DB: coder
    volumes:
      - coder-db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U coder -d coder"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  coder-db-data:

Important: Replace your-server-ip in CODER_ACCESS_URL with your server’s actual IP or domain. Workspaces use this URL to communicate with Coder — localhost won’t work for Docker-based workspaces.

Start the stack:

docker compose up -d

Initial Setup

  1. Open http://your-server-ip:7080 in your browser
  2. Create the first user account (this becomes the admin)
  3. Navigate to Templates to create your first workspace template

Create a Docker Workspace Template

Coder uses Terraform to define workspace templates. The built-in Docker starter template works out of the box:

  1. Go to TemplatesCreate Template
  2. Select Docker from the starter templates
  3. Click Create Template — Coder provisions a Terraform plan automatically
  4. Go to WorkspacesCreate Workspace → select the Docker template
  5. Your workspace spins up as a Docker container with VS Code ready

Connect Your IDE

VS Code Desktop:

  1. Install the Coder extension
  2. Enter your Coder URL and authenticate
  3. Select a workspace — VS Code connects via SSH

JetBrains Gateway:

  1. Install Coder plugin in Gateway
  2. Enter your Coder URL
  3. Select workspace and IDE (IntelliJ, PyCharm, etc.)

SSH:

# Install Coder CLI
curl -fsSL https://coder.com/install.sh | sh

# Login to your Coder instance
coder login http://your-server-ip:7080

# SSH into a workspace
coder ssh my-workspace

Configuration

Key Environment Variables

VariableRequiredDescription
CODER_PG_CONNECTION_URLYesPostgreSQL connection string
CODER_HTTP_ADDRESSYesListen address and port
CODER_ACCESS_URLYesExternal URL for workspace connectivity
CODER_TLS_ENABLENoEnable built-in TLS (default: false)
CODER_TLS_CERT_FILENoPath to TLS certificate
CODER_TLS_KEY_FILENoPath to TLS private key
CODER_WILDCARD_ACCESS_URLNoWildcard URL for workspace web apps
CODER_MAX_TOKEN_LIFETIMENoMaximum API token lifetime (default: 876600h)
CODER_VERBOSENoEnable verbose logging

Resource Limits per Workspace

In your Terraform template, set resource limits:

resource "docker_container" "workspace" {
  name  = "coder-${data.coder_workspace.me.name}"
  image = "codercom/enterprise-base:ubuntu"

  memory = 4096  # MB
  cpu_shares = 2048

  volumes {
    host_path      = "/home/coder/${data.coder_workspace.me.name}"
    container_path = "/home/coder"
  }
}

OIDC Authentication

For team environments, integrate with your identity provider:

environment:
  CODER_OIDC_ISSUER_URL: "https://auth.example.com"
  CODER_OIDC_CLIENT_ID: "coder"
  CODER_OIDC_CLIENT_SECRET: "your-client-secret"

Reverse Proxy

For HTTPS and custom domain access. Set CODER_ACCESS_URL to match your proxy domain. See Reverse Proxy Setup.

Example Caddy config:

coder.example.com {
    reverse_proxy coder:7080
}

Backup

Back up the PostgreSQL database:

docker exec coder-db pg_dump -U coder coder > coder-backup-$(date +%Y%m%d).sql

Also preserve workspace template files (Terraform configs) and any persistent workspace volumes. See Backup Strategy.

Troubleshooting

Workspaces Can’t Connect to Coder

Symptom: Workspace provisioning succeeds but the workspace can’t reach the Coder server. Fix: CODER_ACCESS_URL must be reachable from inside Docker containers. Use your server’s LAN IP or domain — not localhost or 127.0.0.1. Test: docker run --rm curlimages/curl curl -s http://your-server-ip:7080/api/v2/buildinfo.

Docker Socket Permission Denied

Symptom: Template provisioning fails with Docker socket permission error. Fix: Add the Docker group GID to group_add in docker-compose.yml. Find it with getent group docker | cut -d: -f3. Common values: 999, 998, or docker.

Database Connection Failed

Symptom: Coder fails to start with PostgreSQL connection error. Fix: Ensure coder-db is healthy before Coder starts (the depends_on condition handles this). Check credentials match between Coder’s CODER_PG_CONNECTION_URL and PostgreSQL’s env vars.

High Memory Usage

Symptom: Server running out of memory with multiple workspaces. Fix: Set memory limits in workspace templates. Each workspace is a Docker container — without limits, they can consume all available RAM. Monitor with docker stats.

Resource Requirements

  • RAM: ~200 MB for Coder server + ~500 MB per workspace (varies by template)
  • CPU: 2+ cores for server, additional per workspace
  • Disk: ~500 MB for Coder, 5-20 GB per workspace

Verdict

Coder is the most powerful self-hosted remote development platform available. If you have a team of developers who need reproducible, consistent development environments, Coder delivers. The Terraform-based template system is incredibly flexible — Docker containers, Kubernetes pods, even cloud VMs. For solo developers, it’s overkill — use code-server for VS Code in the browser or OpenVSCode Server for a lighter alternative. Coder’s strength is team-scale infrastructure, and at that scale, it beats GitHub Codespaces on cost and control.

Frequently Asked Questions

How is Coder different from code-server?

code-server runs a single VS Code instance in the browser — one user, one workspace. Coder is a platform that provisions entire development environments (Docker containers, Kubernetes pods, or cloud VMs) with any IDE. Coder manages multiple users, templates, and workspaces. Use code-server for personal browser-based VS Code; use Coder for team development infrastructure.

Is Coder free to self-host?

Yes. Coder is open-source under the AGPL-3.0 license. The self-hosted version includes all core features: workspace templates, IDE integration, SSH access, and user management. Coder also offers a paid Enterprise edition with features like high availability, audit logging, and premium support, but the open-source version is fully functional for most teams.

Can I use JetBrains IDEs with Coder?

Yes. Coder integrates with JetBrains Gateway, which lets you run IntelliJ IDEA, PyCharm, GoLand, WebStorm, and other JetBrains IDEs with the backend running in a Coder workspace. Install the Coder plugin in JetBrains Gateway, connect to your Coder instance, and select a workspace.

How much RAM does each workspace need?

It depends on your template. A minimal workspace with VS Code needs ~500 MB. A workspace with a full development toolchain (Node.js, Python, databases) typically needs 2-4 GB. Set memory limits in your Terraform template to prevent workspaces from consuming all server RAM. The Coder server itself uses about 200 MB.

Can Coder provision workspaces on Kubernetes?

Yes. Coder supports multiple provisioners through Terraform templates: Docker containers (simplest), Kubernetes pods, AWS EC2 instances, Google Cloud VMs, and Azure VMs. The Kubernetes provisioner is popular for teams already running k8s clusters — each workspace becomes a pod with defined resource limits.

How do I persist workspace data between rebuilds?

Mount a persistent volume in your Terraform template. Map a host directory or named Docker volume to /home/coder in the workspace container. Without persistent volumes, workspace data is lost when the workspace is rebuilt. The Docker Compose template above includes a volume mount pattern you can customize.

Comments