Skip to content

Remote Development — SSH, Codespaces, Dev Containers Guide

DodaTech Updated 2026-06-23 9 min read

Remote development lets you use a powerful remote machine, cloud environment, or container for computation while keeping your local editor's interface, extensions, and keybindings. This guide covers the three most popular remote development approaches and when to use each.

What You'll Learn

You'll configure VS Code Remote-SSH for seamless remote editing, set up GitHub Codespaces for cloud-based development environments, build Dev Containers with reproducible configurations, manage port forwarding and secrets, and choose the right remote approach for your team's workflow.

Why Remote Development Matters

Local development breaks when your project needs specific OS dependencies, GPU access, or compute resources your laptop can't provide. Remote development solves this by running the toolchain on a server, container, or cloud environment while you edit with your preferred local setup.

DodaZIP's compression benchmarks run on remote servers with 64-core CPUs and 256GB RAM. Developers edit the benchmarking code locally with Remote-SSH, run tests on the remote machine, and see results in their local terminal.

Learning Path

flowchart LR
  A[Editor Basics] --> B[Remote Development
You are here] B --> C[Dev Containers] C --> D[Codespaces] C --> E[SSH Workflows] style B fill:#f90,color:#fff

VS Code Remote-SSH

The Remote-SSH extension lets you open any folder on a remote machine as if it were local:

# Install Remote-SSH extension
code --install-extension ms-vscode-remote.remote-ssh

# Connect to a remote host
# Ctrl+Shift+P → "Remote-SSH: Connect to Host..."

# Or connect directly from the command line:
code --remote ssh-remote+dev-server /path/to/project

SSH Configuration

# ~/.ssh/config — SSH host configuration
Host dev-server
    HostName 192.168.1.100
    User developer
    Port 2222
    IdentityFile ~/.ssh/id_ed25519_dev
    ForwardAgent yes
    ServerAliveInterval 60
    ServerAliveCountMax 5

Host build-server
    HostName build.internal.company.com
    User ci
    IdentityFile ~/.ssh/id_ed25519_ci
    RemoteForward 9229 localhost:9229
    LocalForward 3000 localhost:3000

Remote-SSH Settings

// VS Code settings for Remote-SSH:
{
  "remote.SSH.showLoginTerminal": true,
  "remote.SSH.allowLocalForwarding": true,
  "remote.SSH.path": "/usr/bin/ssh",
  "remote.SSH.useLocalServer": true,
  "remote.SSH.connectTimeout": 30,
  "remote.SSH.extensions": [
    "ms-python.python",
    "dbaeumer.vscode-eslint",
    "eamodio.gitlens]
  ]
}

Installing Extensions Remotely

# Extensions can be installed locally (for UI) or remotely (for language support)
# Ctrl+Shift+P → "Extensions: Show Local Extensions"
# Ctrl+Shift+P → "Extensions: Show Remote Extensions"

# Remote extensions run on the server and provide language features:
# - Python, Pylance, Jupyter
# - ESLint, Prettier
# - GitLens, GitHub PRs
# - Docker

GitHub Codespaces

Codespaces provide cloud-hosted development environments with a consistent configuration:

// .devcontainer/devcontainer.json — Codespaces configuration
{
  "name": "DodaTech API Development",
  "image": "mcr.microsoft.com/devcontainers/universal:2",
  "features": {
    "ghcr.io/devcontainers/features/python:1": {
      "version": "3.12"
    },
    "ghcr.io/devcontainers/features/docker-in-docker:2": {},
    "ghcr.io/devcontainers/features/node:1": {
      "version": "20"
    }
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "ms-python.black-formatter",
        "dbaeumer.vscode-eslint",
        "eamodio.gitlens",
        "github.copilot",
        "ms-azuretools.vscode-docker]
      ],
      "settings": {
        "editor.formatOnSave": true,
        "python.defaultInterpreterPath": "/usr/local/bin/python"
      }
    }
  },
  "forwardPorts": [3000, 8000, 5432],
  "portsAttributes": {
    "3000": { "label": "Frontend", "onAutoForward": "openBrowser" },
    "8000": { "label": "API", "onAutoForward": "notify" },
    "5432": { "label": "PostgreSQL", "onAutoForward": "silent" }
  },
  "postCreateCommand": "pip install -r requirements.txt && npm install",
  "remoteUser": "codespace"
}

Starting a Codespace

# From GitHub repository:
# Code → Codespaces → Create codespace on main

# From CLI (requires gh CLI):
gh codespace create --repo dodatech/api --branch main

# List codespaces:
gh codespace list

# SSH into a codespace:
gh codespace ssh

# Delete a codespace:
gh codespace delete --codespace <name>

Codespace Lifecycle

# Events that trigger lifecycle hooks:
# 1. prebuild (optional) — runs on repo push
# 2. create — first time codespace starts
# 3. postCreate — after container is ready
# 4. postAttach — every time you connect
# 5. postStart — after stop/start cycle

# Lifecycle scripts in devcontainer.json:
"postCreateCommand": "bash scripts/setup-dev.sh"
"postAttachCommand": "bash scripts/start-dev.sh"
"postStartCommand": "bash scripts/migrate-db.sh"

Dev Containers

Dev Containers allow you to define a Docker-based development environment:

# Dockerfile — Development container
FROM ubuntu:22.04

# Install system dependencies
RUN apt-get update && apt-get install -y \
    python3.12 \
    python3-pip \
    nodejs \
    npm \
    git \
    curl \
    build-essential \
    postgresql-client \
    && rm -rf /var/lib/apt/lists/*

# Install Python packages
COPY requirements.txt /tmp/
RUN pip3 install --no-cache-dir -r /tmp/requirements.txt

# Install Node packages
COPY package.json /tmp/
RUN cd /tmp && npm install

# Set working directory
WORKDIR /workspace

# Create non-root user
RUN useradd -m developer
USER developer
// .devcontainer/devcontainer.json — Dev Container configuration
{
  "name": "DodaTech Full Stack Dev",
  "build": {
    "dockerfile": "Dockerfile",
    "context": ".."
  },
  "dockerComposeFile": "docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/workspace",

  "mounts": [
    "source=${env:HOME}${env:USERPROFILE}/.ssh,target=/home/developer/.ssh,type=bind]
  ],

  "containerEnv": {
    "DATABASE_URL": "postgresql://dev:dev@db:5432/dodatech",
    "REDIS_URL": "redis://redis:6379",
    "NODE_ENV": "development"
  },

  "remoteUser": "developer",

  "postCreateCommand": "bash .devcontainer/setup.sh",

  "forwardPorts": [3000, 8000, 5432, 6379]
}
# docker-compose.yml — Multi-service development environment
version: "3.8"
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ..:/workspace:cached
      - ~/.ssh:/home/developer/.ssh:ro
    command: sleep infinity
    ports:
      - "3000:3000"
      - "8000:8000"
    depends_on:
      - db
      - redis

  db:
    image: postgres:16
    environment:
      POSTGRES_USER: dev
      POSTGRES_PASSWORD: dev
      POSTGRES_DB: dodatech
    ports:
      - "5432:5432"
    volumes:
      - postgres-data:/var/lib/postgresql/data

  redis:
    image: redis:7
    ports:
      - "6379:6379"

volumes:
  postgres-data:

Port Forwarding and Service Access

# VS Code Remote-SSH — automatic port forwarding
# When a server starts on port 3000, VS Code prompts to forward it
# Ctrl+Shift+P → "Remote-SSH: Forward Port"

# Manual port forwarding:
# View → Command Palette → "Forward a Port"
# Enter the port number (e.g., 3000)

# Codespaces — ports are forwarded automatically:
# Ports are listed in VS Code's "PORTS" tab
# You can set visibility: private, org, or public

# SSH local port forwarding:
ssh -L 3000:localhost:3000 dev-server

# SSH remote port forwarding:
ssh -R 9229:localhost:9229 dev-server

Security Best Practices

# 1. Use SSH keys, not passwords
ssh-keygen -t ed25519 -C "dev@dodatech.com"
ssh-copy-id dev-server

# 2. Use SSH config for host aliases
# (see SSH configuration section above)

# 3. Never commit .env or secrets files to repos
# Use Codespaces secrets: https://github.com/settings/codespaces

# 4. Use GitHub secrets for Codespaces:
gh secret set DATABASE_URL --repos dodatech/api

# 5. Restrict Codespace access:
# "codespaces: write" permission in GitHub settings
# IP allow lists for Codespaces in GitHub organization settings

Choosing the Right Approach

Criteria Remote-SSH Codespaces Dev Containers
Best for Dedicated dev server Cloud-native teams Reproducible environments
Setup time Minutes Seconds Hours (first time)
Cost Server cost + bandwidth Per-minute billing Free (local Docker)
Internet required Yes Yes No (local)
Team consistency Manual Automatic Automatic
GPU support Yes Limited Yes
Local resources Minimal None needed Docker host required

Common Remote Development Mistakes

1. Ignoring Latency

Remote-SSH over transatlantic connections (200ms+ latency) is painful for real-time editing. Use Codespaces in the closest region. For Remote-SSH, use a server in the same geographic region.

2. Not Using SSH Config

Putting host addresses, ports, and keys in VS Code settings instead of ~/.ssh/config. SSH config is the standard and works with all SSH tools, not just VS Code.

3. Forgetting to Install Extensions Remotely

Language support extensions (Python, ESLint) must be installed on the remote machine. VS Code prompts for this, but confirm with "Extensions: Show Remote Extensions".

4. Hardcoding Secrets in devcontainer.json

Never put database URLs, API keys, or tokens in devcontainer.json. Use environment variables, Codespaces secrets, or a .env file excluded from version control.

5. Not Managing Codespace Costs

Codespaces bill by minute. Stop unused codespaces. Set auto-stop timers (30 minutes default; lower to 15 for personal use). Use prebuilds to reduce startup time.

6. Overlooking Docker Resource Limits

Dev Containers share your host's Docker resources. A container with unlimited memory can starve other containers. Set limits in docker-compose.yml: deploy: resources: limits: memory: 4G.

7. Mixing Multiple Remote Approaches

Using Remote-SSH to connect to Codespaces or running Dev Containers within Remote-SSH is possible but adds complexity. Choose one approach per project and stick with it.

Practice Questions

1. What is the difference between Remote-SSH, Codespaces, and Dev Containers? Remote-SSH connects to a remote server via SSH. Codespaces provides cloud-hosted environments managed by GitHub. Dev Containers run on your local Docker but define the environment in a configuration file.

2. How do you forward a port in a Remote-SSH session? When VS Code detects a server starting on a port, it prompts to forward it. Manually: Ctrl+Shift+P → "Forward a Port" → enter the port number.

3. What file defines a Dev Container or Codespaces configuration? .devcontainer/devcontainer.json. This file specifies the image or Dockerfile, extensions, settings, forwarded ports, and lifecycle commands.

4. How do you securely pass secrets to a Codespace? Use GitHub Codespaces secrets (gh secret set or GitHub.com → Settings → Codespaces). Secrets are injected as environment variables but never visible in configuration files.

5. Challenge: Your team is migrating from local development with manual environment setup to a reproducible remote workflow. Design a Dev Container configuration that includes Python 3.12, Node.js 20, PostgreSQL 16, Redis 7, and automatically installs project dependencies on creation. Answer: Create a docker-compose.yml with app, db, and redis services. Create a Dockerfile with Python 3.12 and Node.js 20 installed. In devcontainer.json, reference the Dockerfile and docker-compose, set postCreateCommand to install pip and npm dependencies, forward ports 3000/8000/5432/6379, and include required VS Code extensions.

FAQ

Do I need a powerful local machine for remote development?

No. Remote development offloads computation to a server, container, or cloud environment. Your local machine only needs to run VS Code and a network connection.

Is remote development secure?

Yes, with proper configuration. Remote-SSH uses SSH encryption. Codespaces runs in isolated containers with network policies. Dev Containers are local. Never hardcode secrets in configuration files.

Can I use remote development for mobile development?

Yes, but with limits. iOS development requires Xcode on macOS. Android development works in Dev Containers with the Android SDK. Codespaces supports Java/Kotlin Android builds.

What internet speed do I need?

Remote-SSH and Codespaces work well with 10+ Mbps. Latency matters more than bandwidth — keep the server geographically close. Everything above 100ms feels sluggish.

Can I use debugging with remote development?

Yes. VS Code's debugger works transparently over Remote-SSH and in Dev Containers. Debugger protocol traffic is forwarded through the SSH or Docker connection. Set breakpoints and inspect variables as if the code were local.

What's Next

VS Code Guide
Cursor AI Editor Guide
GitHub Copilot Guide

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro. Updated 2026-06-23.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro