
If you’re like me, you probably find yourself coding on multiple devices - maybe a desktop at home, a laptop when traveling, or even occasionally on a tablet. For years, keeping development environments in sync was a pain point. Enter VS Code Server, the solution that has completely transformed my development workflow.
Today, I want to show you how to set up your own self-hosted VS Code Server that lets you code from literally any device with a web browser, all while using your powerful home server for the heavy lifting.
Why VS Code Server?
Before we dive into the setup, let’s talk about why you might want this:
- Consistent environment: The same development setup, extensions, and configurations regardless of which device you’re using.
- Resource optimization: Run resource-intensive tasks (builds, tests) on your powerful server instead of your laptop.
- Work from anywhere: Access your development environment from any device with a browser, even an iPad or a borrowed computer.
- Seamless switching: Start working on one device and continue on another without missing a beat.
I’ve been using this setup for months now, and it’s been a game-changer for my productivity. Let’s get into the setup!
Setting Up VS Code Server
There are a few ways to run VS Code Server. I’ll cover the official method and my preferred Docker approach.
Option 1: Official CLI Installation
The VS Code team provides a CLI for setting up the server:
# Download and install the CLI
curl -fsSL https://code.visualstudio.com/sha/download?build=stable&os=cli-alpine-x64 -o vscode_cli.tar.gz
tar -xf vscode_cli.tar.gz
sudo mv code /usr/local/bin/
# Start the server
code serve-web --accept-server-license-terms --host 0.0.0.0
This method is straightforward but requires you to manage the process yourself.
Option 2: Docker Installation (My Preference)
I prefer using Docker for easier updates and management. Here’s my docker-compose.yml
:
version: '3'
services:
code-server:
image: linuxserver/code-server:latest
container_name: code-server
environment:
- PUID=1000
- PGID=1000
- TZ=America/Los_Angeles
- PASSWORD=your_secure_password # Consider using Docker secrets instead
- SUDO_PASSWORD=your_sudo_password # Optional
- PROXY_DOMAIN=code.yourdomain.com # Optional
volumes:
- ./config:/config
- /path/to/your/projects:/projects
- /path/to/your/home:/home/coder
ports:
- 8443:8443
restart: unless-stopped
Run it with:
docker-compose up -d
Your VS Code Server will be available at https://your-server-ip:8443
.
Option 3: Kubernetes Deployment
For those running Kubernetes (like me), here’s a YAML manifest:
apiVersion: apps/v1
kind: Deployment
metadata:
name: vscode-server
namespace: development
spec:
replicas: 1
selector:
matchLabels:
app: vscode-server
template:
metadata:
labels:
app: vscode-server
spec:
containers:
- name: vscode-server
image: linuxserver/code-server:latest
env:
- name: PUID
value: "1000"
- name: PGID
value: "1000"
- name: TZ
value: "America/Los_Angeles"
- name: PASSWORD
valueFrom:
secretKeyRef:
name: vscode-secrets
key: password
ports:
- containerPort: 8443
volumeMounts:
- name: config
mountPath: /config
- name: projects
mountPath: /projects
volumes:
- name: config
persistentVolumeClaim:
claimName: vscode-config
- name: projects
persistentVolumeClaim:
claimName: vscode-projects
---
apiVersion: v1
kind: Service
metadata:
name: vscode-server
namespace: development
spec:
selector:
app: vscode-server
ports:
- port: 8443
targetPort: 8443
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: vscode-server
namespace: development
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- code.yourdomain.com
secretName: vscode-tls
rules:
- host: code.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vscode-server
port:
number: 8443
Accessing VS Code Server Securely
You don’t want to expose your development environment directly to the internet without proper security. Here are my recommendations:
1. Use a Reverse Proxy with SSL
I use Traefik as a reverse proxy with automatic SSL certificate generation:
# traefik.yml dynamic config
http:
routers:
vscode:
rule: "Host(`code.yourdomain.com`)"
service: "vscode"
entryPoints:
- websecure
tls:
certResolver: letsencrypt
services:
vscode:
loadBalancer:
servers:
- url: "http://localhost:8443"
2. Set Up Authentication
The LinuxServer image already includes basic authentication, but you can add another layer with something like Authelia:
# authelia configuration.yml
access_control:
default_policy: deny
rules:
- domain: code.yourdomain.com
policy: two_factor
subject: "group:developers"
3. Use Cloudflare Tunnel
For ultimate security, I use a Cloudflare Tunnel to avoid exposing any ports:
# cloudflared config.yml
tunnel: your-tunnel-id
credentials-file: /etc/cloudflared/creds.json
ingress:
- hostname: code.yourdomain.com
service: http://localhost:8443
originRequest:
noTLSVerify: true
- service: http_status:404
Configuring Your VS Code Server Environment
Once your server is running, it’s time to set it up for optimal productivity:
1. Install Essential Extensions
Here are the must-have extensions I install first:
# From the VS Code terminal
code-server --install-extension ms-python.python
code-server --install-extension ms-azuretools.vscode-docker
code-server --install-extension dbaeumer.vscode-eslint
code-server --install-extension esbenp.prettier-vscode
code-server --install-extension github.copilot
code-server --install-extension golang.go
Or you can install them through the Extensions marketplace in the UI.
2. Configure Settings Sync
To keep your settings in sync between instances:
- Open the Command Palette (Ctrl+Shift+P)
- Search for “Settings Sync: Turn On”
- Sign in with your GitHub or Microsoft account
3. Set Up Git Authentication
For seamless Git operations:
# Generate a new SSH key if needed
ssh-keygen -t ed25519 -C "[email protected]"
# Add to your GitHub/GitLab account
cat ~/.ssh/id_ed25519.pub
# Configure Git
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
Power User Features
Now let’s look at some advanced configurations that make VS Code Server even more powerful:
1. Workspace Launcher
I created a simple HTML page that lists all my projects for quick access:
<!DOCTYPE html>
<html>
<head>
<title>ArgoBox Workspace Launcher</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #1e1e1e;
color: #d4d4d4;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.project-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 15px;
margin-top: 20px;
}
.project-card {
background-color: #252526;
border-radius: 5px;
padding: 15px;
transition: transform 0.2s;
}
.project-card:hover {
transform: translateY(-5px);
background-color: #2d2d2d;
}
a {
color: #569cd6;
text-decoration: none;
}
h1 { color: #569cd6; }
h2 { color: #4ec9b0; }
</style>
</head>
<body>
<h1>ArgoBox Workspace Launcher</h1>
<div class="project-list">
<div class="project-card">
<h2>ArgoBox</h2>
<p>My Kubernetes home lab platform</p>
<a href="/projects/argobox">Open Workspace</a>
</div>
<div class="project-card">
<h2>Blog</h2>
<p>ArgoBox blog and digital garden</p>
<a href="/projects/blog">Open Workspace</a>
</div>
<!-- Add more projects as needed -->
</div>
</body>
</html>
2. Custom Terminal Profile
Add this to your settings.json
for a better terminal experience:
"terminal.integrated.profiles.linux": {
"bash": {
"path": "bash",
"icon": "terminal-bash",
"args": ["-l"]
},
"zsh": {
"path": "zsh"
},
"customProfile": {
"path": "bash",
"args": ["-c", "neofetch && bash -l"],
"icon": "terminal-bash",
"overrideName": true
}
},
"terminal.integrated.defaultProfile.linux": "customProfile"
3. Persistent Development Containers
I use Docker-in-Docker to enable VS Code Dev Containers:
version: '3'
services:
code-server:
# ... other config from above
volumes:
# ... other volumes
- /var/run/docker.sock:/var/run/docker.sock
environment:
# ... other env vars
- DOCKER_HOST=unix:///var/run/docker.sock
Real-World Examples: How I Use VS Code Server
Let me share a few real-world examples of how I use this setup:
Example 1: Coding on iPad During Travel
When traveling with just my iPad, I connect to my VS Code Server to work on my projects. With a Bluetooth keyboard and the amazing iPad screen, it’s a surprisingly good experience. The heavy compilation happens on my server back home, so battery life on the iPad remains excellent.
Example 2: Pair Programming Sessions
When helping friends debug issues, I can generate a temporary access link to my VS Code Server:
# Create a time-limited token
TEMP_TOKEN=$(openssl rand -hex 16)
echo "Token: $TEMP_TOKEN" > /tmp/temp_token
curl -X POST -H "Content-Type: application/json" \
-d "{\"token\":\"$TEMP_TOKEN\", \"expiresIn\":\"2h\"}" \
http://localhost:8443/api/auth/temporary
Example 3: Switching Between Devices
I often start coding on my desktop, then switch to my laptop when moving to another room. With VS Code Server, I just close the browser on one device and open it on another - my entire session, including unsaved changes and terminal state, remains intact.
Monitoring and Maintaining Your VS Code Server
To keep your server running smoothly:
1. Set Up Health Checks
I use Uptime Kuma to monitor my VS Code Server:
# Docker Compose snippet for Uptime Kuma
uptime-kuma:
image: louislam/uptime-kuma:latest
container_name: uptime-kuma
volumes:
- ./uptime-kuma:/app/data
ports:
- 3001:3001
restart: unless-stopped
Add a monitor that checks https://code.yourdomain.com/healthz
endpoint.
2. Regular Backups
Set up a cron job to back up your VS Code Server configuration:
# /etc/cron.daily/backup-vscode-server
#!/bin/bash
tar -czf /backups/vscode-server-$(date +%Y%m%d).tar.gz /path/to/config
3. Update Script
Create a script for easy updates:
#!/bin/bash
# update-vscode-server.sh
cd /path/to/docker-compose
docker-compose pull
docker-compose up -d
docker system prune -f
Troubleshooting Common Issues
Here are solutions to some issues I’ve encountered:
Issue: Extensions Not Installing
If extensions fail to install, try:
# Clear the extensions cache
rm -rf ~/.vscode-server/extensions/*
# Restart the server
docker-compose restart code-server
Issue: Performance Problems
If you’re experiencing lag:
# Adjust memory limits in docker-compose.yml
services:
code-server:
# ... other config
deploy:
resources:
limits:
memory: 4G
reservations:
memory: 1G
Issue: Git Integration Not Working
For Git authentication issues:
# Make sure your SSH key is properly set up
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# Test your connection
ssh -T [email protected]
Why I Prefer Self-Hosted Over GitHub Codespaces
People often ask why I don’t just use GitHub Codespaces. Here’s my take:
- Cost: Self-hosted is essentially free (if you already have a server).
- Privacy: All my code remains on my hardware.
- Customization: Complete control over the environment.
- Performance: My server has 64GB RAM and a 12-core CPU - better than most cloud options.
- Availability: Works even when GitHub is down or when I have limited internet.
Wrapping Up
VS Code Server has truly changed how I approach development. The ability to have a consistent, powerful environment available from any device has increased my productivity and eliminated the friction of context-switching between machines.
Whether you’re a solo developer or part of a team, having a centralized development environment that’s accessible from anywhere is incredibly powerful. And the best part? It uses the familiar VS Code interface that millions of developers already know and love.
Have you tried VS Code Server or similar remote development solutions? I’d love to hear about your setup and experiences in the comments!
This post was last updated on March 10, 2024 with information about the latest VS Code Server features and Docker image updates.