Development beginner ⏱ 25 minutes

code-server: VS Code in Your Browser

Run VS Code on your homelab server and access it from any browser. Full IDE anywhere.

By homelabbing.io • 2025-12-17
#code-server#vscode#ide#development#docker

Overview

Imagine coding on your iPad from the beach, or debugging production issues from your phone. Code on a Chromebook with the full power of VS Code. Switch between devices seamlessly with all your extensions, settings, and terminal sessions intact. This isn’t a dream—this is code-server in 2025.

code-server is Visual Studio Code running as a web application, giving you Microsoft’s industry-leading code editor accessible from any device with a browser. No installation required on client devices, no platform restrictions, and all the power of VS Code with its massive extension ecosystem.

Developed by Coder (formerly Coder.com), code-server brings professional development workflows to anywhere with an internet connection. Your homelab becomes your development infrastructure, running on your hardware with your resources. Edit code on your powerful homelab server from a lightweight laptop, share development environments with team members, or provide consistent coding environments across your organization.

What you’ll learn:

  • Installing code-server with Docker
  • Configuring HTTPS for secure remote access
  • Managing extensions and settings
  • Setting up development environments
  • Multi-user workflows and authentication
  • Performance optimization
  • Integration with Git and other tools

Why code-server for your homelab?

Centralize development on powerful hardware. Code from any device—laptop, tablet, phone. Consistent environment across all your devices. Lower-end machines become viable development workstations when the heavy lifting happens on your server. Share development environments with team members without complex setup.


Prerequisites

Before starting, ensure you have:

  • Linux server with Docker installed (2GB+ RAM, 4GB+ recommended for multiple users)
  • Docker and Docker Compose installed and working
  • Storage: 20GB+ for VS Code and extensions
  • Network: Port 8080 or custom port for web access
  • CPU: 2+ cores recommended for good performance

Optional but highly recommended:

  • Domain name for HTTPS access
  • Reverse proxy (Nginx Proxy Manager, Traefik, Caddy)
  • Authentication provider (OAuth, LDAP)
  • Understanding of VS Code extensions and settings

Understanding code-server

What is code-server?

code-server is the official open-source project that runs Visual Studio Code on a remote server, accessible through a web browser. It’s not a fork or a clone—it’s the actual VS Code codebase compiled to run as a web application.

Core features:

  • Full VS Code experience in the browser
  • Compatible with most VS Code extensions
  • Integrated terminal with shell access
  • File system access to server directories
  • Git integration and source control
  • Multi-user support with authentication
  • Custom VS Code marketplace
  • Automatic HTTPS with built-in certificates
  • Progressive Web App (PWA) support

code-server vs. Alternatives

Featurecode-serverVS Code RemoteGitHub CodespacesCoder
Self-HostedYesPartialNo (cloud only)Yes
Browser AccessYesNo (desktop required)YesYes
CostFreeFreePaid tiersFree/Paid
Multi-UserYes (DIY)NoYesYes (managed)
ExtensionsMost workAll workMost workAll work
Setup ComplexityLowVery lowNoneMedium
Best ForHomelabsIndividual remoteQuick cloud devTeams/Orgs

When to choose code-server:

  • You want browser-based access to VS Code
  • You need to code from multiple devices
  • You want centralized development on your server
  • You need to share dev environments
  • You prefer self-hosted over cloud services

Architecture Overview

User Browser (Any Device)
    ↓ HTTPS
[Reverse Proxy (Optional)]
    ↓
[code-server Web Server (Port 8080)]
    ↓
[VS Code Backend]
    ↓
[File System / Git / Terminal / Extensions]

code-server runs VS Code’s core in Node.js on your server, exposing a web interface that communicates with the browser via WebSockets for real-time editing.


Installing code-server

The most flexible and maintainable approach.

Create directory structure:

mkdir -p ~/code-server/{config,projects} && cd ~/code-server

Create docker-compose.yml:

version: '3.8'

services:
  code-server:
    image: lscr.io/linuxserver/code-server:latest
    container_name: code-server
    restart: unless-stopped
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
      - PASSWORD=${CODE_SERVER_PASSWORD}  # Web UI password
      - SUDO_PASSWORD=${SUDO_PASSWORD}    # Optional: sudo in terminal
      - DEFAULT_WORKSPACE=/config/workspace
    ports:
      - "8080:8443"  # HTTPS by default
    volumes:
      - ./config:/config
      - ./projects:/config/workspace/projects
      # Optional: Mount additional directories
      - ~/docker:/config/workspace/docker:ro  # Read-only access
      - /var/run/docker.sock:/var/run/docker.sock  # Docker access
    networks:
      - code-server

networks:
  code-server:
    driver: bridge

Create .env file:

nano .env
# code-server password (required)
CODE_SERVER_PASSWORD=your_secure_password_here

# sudo password inside code-server terminal
SUDO_PASSWORD=your_sudo_password

Deploy code-server:

# Start service
docker compose up -d

# Check logs
docker compose logs -f code-server

# Verify running
docker compose ps

Access code-server:

Navigate to https://YOUR-SERVER-IP:8080

  • Accept the self-signed certificate warning (or configure proper HTTPS)
  • Enter your password from .env file
  • You’re now in VS Code!

Method 2: Standalone Docker Container

For simpler deployments:

docker run -d   --name=code-server   -e PUID=1000   -e PGID=1000   -e TZ=America/New_York   -e PASSWORD=your_password   -p 8080:8443   -v ~/code-server/config:/config   -v ~/projects:/config/workspace   --restart unless-stopped   lscr.io/linuxserver/code-server:latest

Method 3: Direct Installation (Binary)

For running directly on your server without Docker:

# Download and install
curl -fsSL https://code-server.dev/install.sh | sh

# Start code-server
code-server --bind-addr 0.0.0.0:8080 --auth password

# Password is generated at ~/.config/code-server/config.yaml
cat ~/.config/code-server/config.yaml

Create systemd service:

# /etc/systemd/system/code-server.service
[Unit]
Description=code-server
After=network.target

[Service]
Type=simple
User=youruser
Environment=PASSWORD=your_password
ExecStart=/usr/bin/code-server --bind-addr 0.0.0.0:8080 --user-data-dir /home/youruser/.config/code-server
Restart=on-failure

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable code-server
sudo systemctl start code-server

HTTPS Configuration

Secure access is critical for remote development.

Option 1: Built-in Self-Signed Certificate

code-server includes automatic HTTPS with self-signed certificates (LinuxServer image):

Already enabled by default on port 8443. You’ll see a browser warning—this is expected with self-signed certs.

Pro: Zero configuration Con: Browser warnings, not trusted

Option 2: Reverse Proxy with Let’s Encrypt

The professional approach using Nginx Proxy Manager or Caddy.

Using Nginx Proxy Manager:

  1. Log into Nginx Proxy Manager
  2. Proxy Hosts → Add Proxy Host
  3. Configure:
    • Domain Names: code.homelab.local
    • Scheme: https (code-server uses HTTPS internally)
    • Forward Hostname/IP: code-server (or container IP)
    • Forward Port: 8443
    • Websockets Support: ON (critical!)
    • SSL Certificate: Request new SSL (Let’s Encrypt)
  4. Save

Now access via: https://code.homelab.local

Using Caddy (simplest):

# Caddyfile
code.yourdomain.com {
    reverse_proxy code-server:8443 {
        transport http {
            tls_insecure_skip_verify
        }
    }
}

Caddy automatically handles Let’s Encrypt certificates.

Option 3: Cloudflare Tunnel

Zero-port-forwarding remote access:

# Install cloudflared
docker run -d   --name cloudflared   --restart unless-stopped   cloudflare/cloudflared:latest   tunnel --no-autoupdate run --token YOUR_TUNNEL_TOKEN

Configure tunnel to point to https://code-server:8443

Access from anywhere: https://code-your-subdomain.yourdomain.com


Extensions and Customization

Installing Extensions

Method 1: Via VS Code UI (Recommended)

  1. Click Extensions icon (sidebar)
  2. Search for extension (e.g., “Python”)
  3. Click Install

Works just like desktop VS Code!

Method 2: Via Command Line

# Inside code-server terminal
code-server --install-extension ms-python.python
code-server --install-extension dbaeumer.vscode-eslint
code-server --install-extension esbenp.prettier-vscode

Method 3: Pre-install in Docker

# docker-compose.yml
services:
  code-server:
    # ... existing config ...
    environment:
      - VSCODE_EXTENSION_IDS=ms-python.python,dbaeumer.vscode-eslint

Essential Extensions for Development

General Development:

GitLens (eamodio.gitlens)
Prettier (esbenp.prettier-vscode)
ESLint (dbaeumer.vscode-eslint)
Live Share (ms-vsliveshare.vsliveshare)
Docker (ms-azuretools.vscode-docker)
Remote - SSH (ms-vscode-remote.remote-ssh)

Language-Specific:

Python (ms-python.python)
Go (golang.go)
Rust (rust-lang.rust-analyzer)
JavaScript/TypeScript (built-in)
C/C++ (ms-vscode.cpptools)
Java (redhat.java)

Productivity:

Todo Tree (gruntfuggly.todo-tree)
Bracket Pair Colorizer (built-in in newer versions)
Path Intellisense (christian-kohler.path-intellisense)
Auto Rename Tag (formulahendry.auto-rename-tag)

Settings Sync

Enable Settings Sync:

  1. Click gear icon → Turn on Settings Sync
  2. Sign in with GitHub/Microsoft account
  3. Select what to sync:
    • Settings
    • Extensions
    • Keybindings
    • UI State
    • Snippets
  4. Click Turn On

Now your settings follow you across all code-server instances and desktop VS Code!

Custom Themes and Fonts

Install themes:

Search Extensions for “theme” or popular ones:

  • One Dark Pro
  • Dracula Official
  • GitHub Theme
  • Material Theme

Configure fonts:

// Settings → User Settings (JSON)
{
  "editor.fontFamily": "'Fira Code', 'Cascadia Code', monospace",
  "editor.fontLigatures": true,
  "editor.fontSize": 14,
  "terminal.integrated.fontSize": 13
}

Install Fira Code in container:

# Exec into container
docker exec -it code-server bash

# Install font
apt-get update && apt-get install -y fonts-firacode

Development Workflows

Setting Up Development Environments

Node.js development:

# Install Node.js in container
docker exec -it code-server bash
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt-get install -y nodejs
node --version
npm --version

Python development:

# Install Python and pip
apt-get update
apt-get install -y python3 python3-pip python3-venv
python3 --version

# Create virtual environment
cd /config/workspace/my-project
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Docker-in-Docker development:

Mount Docker socket for container management:

# docker-compose.yml
volumes:
  - /var/run/docker.sock:/var/run/docker.sock

# Install Docker CLI in container
docker exec -it code-server bash
curl -fsSL https://get.docker.com | sh
docker ps  # Should work!

Git Integration

Configure Git:

# Inside code-server terminal
git config --global user.name "Your Name"
git config --global user.email "[email protected]"

# Set up SSH keys for GitHub/GitLab
ssh-keygen -t ed25519 -C "[email protected]"
cat ~/.ssh/id_ed25519.pub  # Add to GitHub

Clone repositories:

cd /config/workspace
git clone [email protected]:username/repo.git

Use Source Control panel:

  1. Click Source Control icon
  2. Stage changes, commit, push/pull
  3. View diffs, history, branches
  4. Works exactly like desktop VS Code

Terminal Workflows

Access terminal:

Press Ctrl+ or View → Terminal

Multiple terminals:

Click + icon or split terminal for side-by-side shells

Persistent sessions with tmux:

# Install tmux in container
apt-get install -y tmux

# Start tmux session
tmux new -s dev

# Detach: Ctrl+b, then d
# Reattach: tmux attach -t dev

Your sessions persist even if you close the browser!

Remote Port Forwarding

VS Code can forward ports from your server to your local machine:

  1. Ports panel (usually in terminal area)
  2. Click Forward Port
  3. Enter port number (e.g., 3000 for development server)
  4. Access at http://localhost:3000 on your local machine

Great for testing web apps running in code-server!


Multi-User Setup

Creating Multiple Instances

Separate containers per user:

# docker-compose.yml
version: '3.8'

services:
  code-server-alice:
    image: lscr.io/linuxserver/code-server:latest
    container_name: code-server-alice
    environment:
      - PASSWORD=alice_password
      - DEFAULT_WORKSPACE=/config/workspace
    ports:
      - "8081:8443"
    volumes:
      - ./users/alice:/config
    restart: unless-stopped

  code-server-bob:
    image: lscr.io/linuxserver/code-server:latest
    container_name: code-server-bob
    environment:
      - PASSWORD=bob_password
      - DEFAULT_WORKSPACE=/config/workspace
    ports:
      - "8082:8443"
    volumes:
      - ./users/bob:/config
    restart: unless-stopped

Access:

  • Alice: https://code.homelab.local:8081
  • Bob: https://code.homelab.local:8082

Shared Projects with Permissions

Share read-only code:

volumes:
  - ./shared-code:/config/workspace/shared:ro  # Read-only
  - ./alice-private:/config/workspace/private   # Read-write

Collaborative development:

Use a shared Git repository:

  1. All users clone the same repo
  2. Push/pull changes via Git
  3. Use branches for feature work
  4. Code review via pull requests

Performance Optimization

Resource Limits

# docker-compose.yml
services:
  code-server:
    # ... existing config ...
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 4G
        reservations:
          cpus: '1.0'
          memory: 2G

Recommended resources per user:

  • Casual use: 1 CPU, 2GB RAM
  • Active development: 2 CPUs, 4GB RAM
  • Heavy workloads: 4+ CPUs, 8GB+ RAM

Caching and Extensions

Disable telemetry:

// settings.json
{
  "telemetry.telemetryLevel": "off",
  "update.mode": "none"
}

Optimize extension performance:

Disable unused extensions:

  1. Extensions panel
  2. Click gear on extension
  3. Disable

Pre-install extensions:

Build custom image with extensions:

FROM lscr.io/linuxserver/code-server:latest

RUN code-server 
    --install-extension ms-python.python 
    --install-extension dbaeumer.vscode-eslint 
    --install-extension esbenp.prettier-vscode

Network Optimization

Enable compression:

Most reverse proxies handle this automatically.

Use WebSocket compression:

Nginx Proxy Manager enables this by default when “Websockets Support” is ON.


Security Best Practices

Authentication

Strong passwords:

# Generate secure password
openssl rand -base64 32

OAuth2 authentication:

Use oauth2-proxy for GitHub/Google login:

# docker-compose.yml
services:
  oauth2-proxy:
    image: quay.io/oauth2-proxy/oauth2-proxy:latest
    command:
      - --provider=github
      - --email-domain=*
      - --upstream=https://code-server:8443
      - --http-address=0.0.0.0:4180
      - --cookie-secret=RANDOM_SECRET_HERE
      - --client-id=YOUR_GITHUB_OAUTH_CLIENT_ID
      - --client-secret=YOUR_GITHUB_OAUTH_SECRET
    ports:
      - "4180:4180"

Users must authenticate with GitHub before accessing code-server.

File System Security

Limit access to sensitive directories:

volumes:
  # DON'T mount system directories read-write!
  # BAD:
  # - /:/host

  # GOOD: Only what's needed
  - ./projects:/config/workspace/projects
  - ./docker-files:/config/workspace/docker:ro  # Read-only

Run as non-root:

environment:
  - PUID=1000  # Your user ID
  - PGID=1000  # Your group ID

Network Security

Firewall rules:

# Only allow from local network
sudo ufw allow from 192.168.1.0/24 to any port 8080

# Or only allow via reverse proxy
sudo ufw deny 8080

VPN-only access:

Require Tailscale/WireGuard connection:

# Bind to VPN interface only
# In code-server config:
bind-addr: 100.64.0.1:8080  # Tailscale IP

Audit and Logging

Monitor access logs:

# View code-server logs
docker logs code-server | grep "Accepted connection"

# Failed login attempts
docker logs code-server | grep "Invalid password"

Set up fail2ban (if using binary install):

# /etc/fail2ban/filter.d/code-server.conf
[Definition]
failregex = ^.*"Invalid password".*from <HOST>.*$

Troubleshooting

Cannot Connect to code-server

Check container status:

docker ps | grep code-server
docker logs code-server

Verify port binding:

sudo netstat -tulpn | grep 8080
# Should show docker-proxy listening

Test from server:

curl -k https://localhost:8080
# Should return HTML

Firewall issues:

sudo ufw status
sudo ufw allow 8080

Extensions Won’t Install

Check marketplace connectivity:

# Inside code-server terminal
curl https://marketplace.visualstudio.com

Use alternative marketplace:

# docker-compose.yml
environment:
  - EXTENSIONS_GALLERY='{"serviceUrl": "https://open-vsx.org/vscode/gallery", "itemUrl": "https://open-vsx.org/vscode/item"}'

Manual installation:

  1. Download .vsix file from marketplace
  2. Extensions → … → Install from VSIX
  3. Upload file

Performance Issues

High CPU usage:

# Check processes inside container
docker exec code-server top

# Limit CPU
docker update --cpus="2.0" code-server

Memory issues:

# Check memory usage
docker stats code-server

# Increase memory limit
docker update --memory="4g" code-server

Slow typing/lag:

  • Check network latency: ping YOUR-SERVER-IP
  • Try wired connection instead of WiFi
  • Reduce extension count
  • Disable CPU-intensive extensions (AI assistants, etc.)

WebSocket Connection Errors

“WebSocket close with status code 1006”

Fix in reverse proxy:

Nginx Proxy Manager: Enable Websockets Support

Nginx config:

location / {
    proxy_pass https://code-server:8443;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

Caddy (handles automatically):

reverse_proxy code-server:8443

Integration Examples

With Gitea/GitHub

Set up SSH keys:

# Generate key in code-server
ssh-keygen -t ed25519
cat ~/.ssh/id_ed25519.pub

# Add to Gitea/GitHub
# Then clone repos via SSH
git clone [email protected]:username/repo.git

With Docker Compose Projects

Edit and deploy compose files:

# Mount docker socket
volumes:
  - /var/run/docker.sock:/var/run/docker.sock
  - ~/docker-projects:/config/workspace/docker-projects

In code-server terminal:

cd /config/workspace/docker-projects/app
docker compose up -d
docker compose logs -f

With CI/CD Pipelines

Trigger builds on save:

Use webhooks or file watchers to trigger CI/CD when you save files.

Example with Gitea Actions:

# .gitea/workflows/deploy-on-push.yml
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: ./deploy.sh

Push from code-server → Auto-deploy!


Conclusion

code-server brings the full power of Visual Studio Code to any device with a browser. You’ve learned:

  • Installing code-server with Docker
  • Configuring HTTPS for secure access
  • Managing extensions and settings
  • Setting up development environments
  • Multi-user workflows
  • Performance tuning and security

Key Takeaways

  • Universal access: Code from any device, anywhere
  • Full VS Code: Nearly all features and extensions work
  • Self-hosted: Your code stays on your infrastructure
  • Flexible: Single user or team environments
  • Efficient: Centralized computing on powerful hardware

Next Steps

  1. Set up Settings Sync to sync across instances
  2. Configure proper HTTPS via reverse proxy
  3. Install essential extensions for your workflow
  4. Integrate with Git (Gitea, GitHub, GitLab)
  5. Automate deployments from code-server
  6. Explore Live Share for collaborative coding
  • Coder - Enterprise-grade code-server alternative
  • Gitea - Self-hosted Git for your code
  • Nginx Proxy Manager - HTTPS and reverse proxy
  • Tailscale - Secure remote access
  • Docker Basics - Understanding containers

Resources


Document Version: 1.0 Last Updated: December 16, 2025 Based on: code-server 4.20+ Estimated Completion Time: 40 minutes

Happy coding from anywhere!