685 lines
15 KiB
Markdown
685 lines
15 KiB
Markdown
# Remote Development with VSCode over Tailscale
|
|
|
|
## Overview
|
|
|
|
This guide describes how to set up Visual Studio Code for remote development on servers using the Tailscale network. This enables development directly on remote machines as if they were local, with full access to files, terminals, and debugging capabilities.
|
|
|
|
## What You'll Learn
|
|
|
|
- How to configure VSCode for remote SSH connections
|
|
- How to set up remote development environments
|
|
- How to manage multiple remote servers efficiently
|
|
- How to troubleshoot common remote development issues
|
|
- Best practices for remote development workflows
|
|
|
|
## Prerequisites
|
|
|
|
- **Ansible + Tailscale setup completed** (see previous guide)
|
|
- **VSCode installed** on the local machine (master node)
|
|
- **Working SSH access** to remote servers via Tailscale
|
|
- **Tailscale running** on both local and remote machines
|
|
|
|
## Verify Prerequisites
|
|
|
|
Before starting, verify the setup:
|
|
|
|
```bash
|
|
# Check Tailscale connectivity
|
|
tailscale status
|
|
|
|
# Test SSH access
|
|
ssh <username>@<tailscale-ip>
|
|
|
|
# Check VSCode is installed
|
|
code --version
|
|
```
|
|
|
|
## Part 1: Install and Configure Remote-SSH Extension
|
|
|
|
### 1. Install the Remote Development Extensions
|
|
|
|
**Option A: Install Remote Development Pack (Recommended)**
|
|
|
|
1. Open VSCode
|
|
2. Press **Ctrl+Shift+X** (or **Cmd+Shift+X** on Mac)
|
|
3. Search for **"Remote Development"**
|
|
4. Install the **Remote Development extension pack** by Microsoft
|
|
|
|
This pack includes:
|
|
|
|
- Remote - SSH
|
|
- Remote - SSH: Editing Configuration Files
|
|
- Remote - Containers
|
|
- Remote - WSL (Windows only)
|
|
|
|
**Option B: Install Individual Extension**
|
|
|
|
1. Search for **"Remote - SSH"**
|
|
2. Install **Remote - SSH** by Microsoft
|
|
|
|
### 2. Verify Installation
|
|
|
|
After installation, the following should be visible:
|
|
|
|
- Remote Explorer icon in the Activity Bar (left sidebar)
|
|
- "Remote-SSH" commands in Command Palette (Ctrl+Shift+P)
|
|
|
|
## Part 2: Configure SSH Connections
|
|
|
|
### 1. Access SSH Configuration
|
|
|
|
**Method A: Through VSCode**
|
|
|
|
1. Press **Ctrl+Shift+P** to open Command Palette
|
|
2. Type **"Remote-SSH: Open SSH Configuration File..."**
|
|
3. Select the SSH config file (usually the first option)
|
|
|
|
**Method B: Direct File Editing**
|
|
```bash
|
|
# Edit SSH config file directly
|
|
nano ~/.ssh/config
|
|
```
|
|
|
|
### 2. Add Server Configurations
|
|
|
|
Add servers to the SSH config file:
|
|
|
|
```
|
|
# Example Node
|
|
Host node1
|
|
HostName <tailscale-ip>
|
|
User <username>
|
|
IdentityFile ~/.ssh/id_rsa
|
|
ForwardAgent yes
|
|
ServerAliveInterval 60
|
|
ServerAliveCountMax 3
|
|
|
|
# Additional nodes (add as needed)
|
|
Host node2
|
|
HostName <tailscale-ip>
|
|
User <username>
|
|
IdentityFile ~/.ssh/id_rsa
|
|
ForwardAgent yes
|
|
ServerAliveInterval 60
|
|
ServerAliveCountMax 3
|
|
```
|
|
|
|
**Configuration Options Explained:**
|
|
|
|
- `Host`: Friendly name for the connection
|
|
- `HostName`: Tailscale IP address
|
|
- `User`: Username on the remote server
|
|
- `IdentityFile`: Path to the SSH private key
|
|
- `ForwardAgent`: Enables SSH agent forwarding for Git operations
|
|
- `ServerAliveInterval`: Keeps connection alive (prevents timeouts)
|
|
- `ServerAliveCountMax`: Number of keepalive attempts
|
|
|
|
### 3. Set Proper SSH Key Permissions
|
|
|
|
```bash
|
|
# Ensure SSH config has correct permissions
|
|
chmod 600 ~/.ssh/config
|
|
|
|
# Verify SSH key permissions
|
|
chmod 600 ~/.ssh/id_rsa
|
|
chmod 644 ~/.ssh/id_rsa.pub
|
|
```
|
|
|
|
## Part 3: Connect to Remote Servers
|
|
|
|
### 1. Connect via Command Palette
|
|
|
|
1. Press **Ctrl+Shift+P**
|
|
2. Type **"Remote-SSH: Connect to Host..."**
|
|
3. Select the server (e.g., `node1`)
|
|
4. VSCode will open a new window connected to the remote server
|
|
|
|
### 2. Connect via Remote Explorer
|
|
|
|
1. Click the **Remote Explorer** icon in Activity Bar
|
|
2. Expand **SSH Targets**
|
|
3. Click the **connect** icon next to the server name
|
|
|
|
### 3. Connect via Quick Menu
|
|
|
|
1. Click the **remote indicator** in bottom-left corner (looks like ><)
|
|
2. Select **"Connect to Host..."**
|
|
3. Choose the server from the list
|
|
|
|
### 4. First Connection Process
|
|
|
|
On first connection, VSCode will:
|
|
|
|
1. **Verify the host key** (click "Continue" if prompted)
|
|
2. **Install VSCode Server** on the remote machine (automatic)
|
|
3. **Open a remote window** with access to the remote file system
|
|
|
|
**Expected Timeline:**
|
|
- First connection: 1-3 minutes (installs VSCode Server)
|
|
- Subsequent connections: 10-30 seconds
|
|
|
|
## Part 4: Remote Development Environment Setup
|
|
|
|
### 1. Open Remote Workspace
|
|
|
|
Once connected:
|
|
|
|
```bash
|
|
# In the VSCode terminal (now running on remote server)
|
|
# Navigate to the project directory
|
|
cd /home/<username>/projects
|
|
|
|
# Open current directory in VSCode
|
|
code .
|
|
|
|
# Or open a specific project
|
|
code /opt/myproject
|
|
```
|
|
|
|
### 2. Install Extensions on Remote Server
|
|
|
|
Extensions must be installed separately on the remote server:
|
|
|
|
**Essential Development Extensions:**
|
|
|
|
1. **Python** (Microsoft) - Python development
|
|
2. **GitLens** (GitKraken) - Enhanced Git capabilities
|
|
3. **Docker** (Microsoft) - Container development
|
|
4. **Prettier** - Code formatting
|
|
5. **ESLint** - JavaScript linting
|
|
6. **Auto Rename Tag** - HTML/XML tag editing
|
|
|
|
**To Install:**
|
|
|
|
1. Go to Extensions (Ctrl+Shift+X)
|
|
2. Find the desired extension
|
|
3. Click **"Install in SSH: node1"** (not local install)
|
|
|
|
### 3. Configure Git on Remote Server
|
|
|
|
```bash
|
|
# In VSCode terminal (remote)
|
|
git config --global user.name "<Full Name>"
|
|
git config --global user.email "<email@example.com>"
|
|
|
|
# Test Git connectivity
|
|
git clone https://github.com/<username>/<repo>.git
|
|
```
|
|
|
|
## Part 5: Remote Development Workflows
|
|
|
|
### 1. File Management
|
|
|
|
**File Explorer:**
|
|
|
|
- Shows remote server's file system
|
|
- Create, edit, delete files directly
|
|
- Drag and drop between local and remote (limited)
|
|
|
|
**File Transfer:**
|
|
```bash
|
|
# Upload files to remote (from local terminal)
|
|
scp localfile.txt <username>@<tailscale-ip>:/home/<username>/
|
|
|
|
# Download files from remote
|
|
scp <username>@<tailscale-ip>:/remote/path/file.txt ./local/path/
|
|
```
|
|
|
|
### 2. Terminal Usage
|
|
|
|
**Integrated Terminal:**
|
|
|
|
- Press **Ctrl+`** to open terminal
|
|
- Runs directly on remote server
|
|
- Multiple terminals supported
|
|
- Full shell access (bash, zsh, etc.)
|
|
|
|
**Common Remote Terminal Commands:**
|
|
```bash
|
|
# Check system resources
|
|
htop
|
|
df -h
|
|
free -h
|
|
|
|
# Install packages
|
|
sudo apt update
|
|
sudo apt install nodejs npm
|
|
|
|
# Start services
|
|
sudo systemctl start nginx
|
|
sudo docker-compose up -d
|
|
```
|
|
|
|
### 3. Port Forwarding
|
|
|
|
**Automatic Port Forwarding:**
|
|
VSCode automatically detects and forwards common development ports.
|
|
|
|
**Manual Port Forwarding:**
|
|
|
|
1. Open **Ports** tab in terminal panel
|
|
2. Click **"Forward a Port"**
|
|
3. Enter port number (e.g., 3000, 8080, 5000)
|
|
4. Access via `http://localhost:port` on the local machine
|
|
|
|
**Example: Web Development**
|
|
```bash
|
|
# Start a web server on remote (port 3000)
|
|
npm start
|
|
|
|
# VSCode automatically suggests forwarding port 3000
|
|
# Access at http://localhost:3000 on the local machine
|
|
```
|
|
|
|
### 4. Debugging Remote Applications
|
|
|
|
**Python Debugging:**
|
|
```json
|
|
// .vscode/launch.json on remote server
|
|
{
|
|
"version": "0.2.0",
|
|
"configurations": [
|
|
{
|
|
"name": "Python: Current File",
|
|
"type": "python",
|
|
"request": "launch",
|
|
"program": "${file}",
|
|
"console": "integratedTerminal"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Node.js Debugging:**
|
|
```json
|
|
// .vscode/launch.json
|
|
{
|
|
"version": "0.2.0",
|
|
"configurations": [
|
|
{
|
|
"name": "Launch Program",
|
|
"type": "node",
|
|
"request": "launch",
|
|
"program": "${workspaceFolder}/app.js"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
## Part 6: Advanced Configuration
|
|
|
|
### 1. Workspace Settings
|
|
|
|
Create remote-specific settings:
|
|
|
|
```json
|
|
// .vscode/settings.json (on remote server)
|
|
{
|
|
"python.defaultInterpreterPath": "/usr/bin/python3",
|
|
"terminal.integrated.shell.linux": "/bin/bash",
|
|
"files.autoSave": "afterDelay",
|
|
"editor.formatOnSave": true,
|
|
"remote.SSH.remotePlatform": {
|
|
"node1": "linux"
|
|
}
|
|
}
|
|
```
|
|
|
|
### 2. Multi-Server Management
|
|
|
|
**Switch Between Servers:**
|
|
|
|
1. Click remote indicator (bottom-left)
|
|
2. Select **"Connect to Host..."**
|
|
3. Choose a different server
|
|
|
|
**Compare Files Across Servers:**
|
|
|
|
1. Open file from server A
|
|
2. Connect to server B in new window
|
|
3. Open corresponding file
|
|
4. Use **"Compare with..."** command
|
|
|
|
### 3. Sync Configuration
|
|
|
|
**Settings Sync:**
|
|
|
|
1. Enable Settings Sync in VSCode
|
|
2. Settings, extensions, and keybindings sync to remote
|
|
3. Consistent experience across all servers
|
|
|
|
## Part 7: Project-Specific Setups
|
|
|
|
### 1. Python Development
|
|
|
|
```bash
|
|
# On remote server
|
|
# Create virtual environment
|
|
python3 -m venv venv
|
|
source venv/bin/activate
|
|
|
|
# Install packages
|
|
pip install flask django requests
|
|
|
|
# VSCode automatically detects Python interpreter
|
|
```
|
|
|
|
**VSCode Python Configuration:**
|
|
```json
|
|
// .vscode/settings.json
|
|
{
|
|
"python.defaultInterpreterPath": "./venv/bin/python",
|
|
"python.linting.enabled": true,
|
|
"python.linting.pylintEnabled": true
|
|
}
|
|
```
|
|
|
|
### 2. Node.js Development
|
|
|
|
```bash
|
|
# On remote server
|
|
# Install Node.js
|
|
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
|
sudo apt-get install -y nodejs
|
|
|
|
# Create project
|
|
mkdir myapp && cd myapp
|
|
npm init -y
|
|
npm install express
|
|
```
|
|
|
|
### 3. Docker Development
|
|
|
|
```bash
|
|
# On remote server
|
|
# Install Docker (if not already done via Ansible)
|
|
sudo apt install docker.io docker-compose
|
|
sudo usermod -aG docker $USER
|
|
|
|
# Create Dockerfile
|
|
cat > Dockerfile << EOF
|
|
FROM node:18
|
|
WORKDIR /app
|
|
COPY package*.json ./
|
|
RUN npm install
|
|
COPY . .
|
|
EXPOSE 3000
|
|
CMD ["npm", "start"]
|
|
EOF
|
|
```
|
|
|
|
**VSCode Docker Integration:**
|
|
|
|
- Install Docker extension on remote
|
|
- Right-click Dockerfile → "Build Image"
|
|
- Manage containers from VSCode interface
|
|
|
|
## Part 8: Troubleshooting Guide
|
|
|
|
### Common Connection Issues
|
|
|
|
**Problem: "Could not establish connection to remote host"**
|
|
|
|
**Solutions:**
|
|
```bash
|
|
# Check Tailscale connectivity
|
|
tailscale status
|
|
ping <tailscale-ip>
|
|
|
|
# Test SSH manually
|
|
ssh <username>@<tailscale-ip>
|
|
|
|
# Check SSH config syntax
|
|
ssh -T node1
|
|
```
|
|
|
|
**Problem: "Permission denied (publickey)"**
|
|
|
|
**Solutions:**
|
|
```bash
|
|
# Check SSH key permissions
|
|
chmod 600 ~/.ssh/id_rsa
|
|
chmod 600 ~/.ssh/config
|
|
|
|
# Verify SSH agent
|
|
ssh-add ~/.ssh/id_rsa
|
|
ssh-add -l
|
|
|
|
# Test SSH connection verbosely
|
|
ssh -v <username>@<tailscale-ip>
|
|
```
|
|
|
|
**Problem: "Host key verification failed"**
|
|
|
|
**Solutions:**
|
|
```bash
|
|
# Remove old host key
|
|
ssh-keygen -R <tailscale-ip>
|
|
|
|
# Or disable host key checking (less secure)
|
|
# Add to SSH config:
|
|
# StrictHostKeyChecking no
|
|
```
|
|
|
|
### VSCode-Specific Issues
|
|
|
|
**Problem: Extensions not working on remote**
|
|
|
|
**Solutions:**
|
|
|
|
1. Install extensions specifically for the remote server
|
|
2. Check extension compatibility with remote development
|
|
3. Reload VSCode window: Ctrl+Shift+P → "Developer: Reload Window"
|
|
|
|
**Problem: Slow performance**
|
|
|
|
**Solutions:**
|
|
- Use `.vscode/settings.json` to exclude large directories:
|
|
```json
|
|
{
|
|
"files.watcherExclude": {
|
|
"**/node_modules/**": true,
|
|
"**/.git/objects/**": true,
|
|
"**/dist/**": true
|
|
}
|
|
}
|
|
```
|
|
|
|
**Problem: Terminal not starting**
|
|
|
|
**Solutions:**
|
|
```bash
|
|
# Check shell path in remote settings
|
|
"terminal.integrated.shell.linux": "/bin/bash"
|
|
|
|
# Or let VSCode auto-detect
|
|
"terminal.integrated.defaultProfile.linux": "bash"
|
|
```
|
|
|
|
### Network and Performance Issues
|
|
|
|
**Problem: Connection timeouts**
|
|
|
|
**Solutions:**
|
|
Add to SSH config:
|
|
```
|
|
ServerAliveInterval 60
|
|
ServerAliveCountMax 3
|
|
TCPKeepAlive yes
|
|
```
|
|
|
|
**Problem: File transfer slow**
|
|
|
|
**Solutions:**
|
|
- Use `.vscodeignore` to exclude unnecessary files
|
|
- Compress large files before transfer
|
|
- Use `rsync` for large file operations:
|
|
```bash
|
|
rsync -avz --progress localdir/ <username>@<tailscale-ip>:remotedir/
|
|
```
|
|
|
|
## Part 9: Best Practices
|
|
|
|
### Security Best Practices
|
|
|
|
1. **Use SSH keys, never passwords**
|
|
2. **Keep SSH agent secure**
|
|
3. **Regular security updates on remote servers**
|
|
4. **Use VSCode's secure connection verification**
|
|
|
|
### Performance Optimization
|
|
|
|
1. **Exclude unnecessary files**:
|
|
```json
|
|
// .vscode/settings.json
|
|
{
|
|
"files.watcherExclude": {
|
|
"**/node_modules/**": true,
|
|
"**/.git/**": true,
|
|
"**/dist/**": true,
|
|
"**/build/**": true
|
|
},
|
|
"search.exclude": {
|
|
"**/node_modules": true,
|
|
"**/bower_components": true,
|
|
"**/*.code-search": true
|
|
}
|
|
}
|
|
```
|
|
|
|
2. **Use remote workspace for large projects**
|
|
3. **Close unnecessary windows and extensions**
|
|
4. **Use efficient development workflows**
|
|
|
|
### Development Workflow
|
|
|
|
1. **Use version control effectively**:
|
|
```bash
|
|
# Always work in Git repositories
|
|
git status
|
|
git add .
|
|
git commit -m "feature: add new functionality"
|
|
git push origin main
|
|
```
|
|
|
|
2. **Environment separation**:
|
|
```bash
|
|
# Development
|
|
ssh node1
|
|
cd /home/<username>/dev-projects
|
|
|
|
# Production
|
|
ssh node2
|
|
cd /opt/production-apps
|
|
```
|
|
|
|
3. **Backup important work**:
|
|
```bash
|
|
# Regular backups via Git
|
|
git push origin main
|
|
|
|
# Or manual backup
|
|
scp -r <username>@<tailscale-ip>:/important/project ./backup/
|
|
```
|
|
|
|
## Part 10: Team Collaboration
|
|
|
|
### Shared Development Servers
|
|
|
|
**SSH Config for Team:**
|
|
```
|
|
# Shared development server
|
|
Host team-dev
|
|
HostName <tailscale-ip>
|
|
User <team-user>
|
|
IdentityFile ~/.ssh/team_dev_key
|
|
ForwardAgent yes
|
|
|
|
# Personal development
|
|
Host my-dev
|
|
HostName <tailscale-ip>
|
|
User <username>
|
|
IdentityFile ~/.ssh/id_rsa
|
|
```
|
|
|
|
### Project Structure
|
|
|
|
```
|
|
/opt/projects/
|
|
├── project-a/
|
|
│ ├── dev/ # Development branch
|
|
│ ├── staging/ # Staging environment
|
|
│ └── docs/ # Documentation
|
|
├── project-b/
|
|
└── shared-tools/ # Common utilities
|
|
```
|
|
|
|
### Access Management
|
|
|
|
```bash
|
|
# Create shared project directory
|
|
sudo mkdir -p /opt/projects
|
|
sudo chown -R :developers /opt/projects
|
|
sudo chmod -R g+w /opt/projects
|
|
|
|
# Add users to developers group
|
|
sudo usermod -a -G developers <username>
|
|
```
|
|
|
|
## Quick Reference
|
|
|
|
### Essential VSCode Remote Commands
|
|
|
|
```bash
|
|
# Command Palette shortcuts
|
|
Ctrl+Shift+P → "Remote-SSH: Connect to Host..."
|
|
Ctrl+Shift+P → "Remote-SSH: Open SSH Configuration File..."
|
|
Ctrl+Shift+P → "Remote-SSH: Kill VS Code Server on Host..."
|
|
|
|
# Terminal
|
|
Ctrl+` → Open integrated terminal
|
|
Ctrl+Shift+` → Create new terminal
|
|
|
|
# File operations
|
|
Ctrl+O → Open file
|
|
Ctrl+S → Save file
|
|
Ctrl+Shift+E → Focus file explorer
|
|
```
|
|
|
|
### SSH Connection Quick Test
|
|
|
|
```bash
|
|
# Test connectivity
|
|
ssh -T node1
|
|
|
|
# Connect with verbose output
|
|
ssh -v <username>@<tailscale-ip>
|
|
|
|
# Check SSH config
|
|
ssh -F ~/.ssh/config node1
|
|
```
|
|
|
|
### Port Forwarding Commands
|
|
|
|
```bash
|
|
# Manual port forwarding
|
|
ssh -L 3000:localhost:3000 <username>@<tailscale-ip>
|
|
|
|
# Background tunnel
|
|
ssh -f -N -L 8080:localhost:80 <username>@<tailscale-ip>
|
|
```
|
|
|
|
## Conclusion
|
|
|
|
This remote development setup provides:
|
|
|
|
- **Full development environment** on remote servers
|
|
- **Seamless file access** and editing capabilities
|
|
- **Integrated debugging** and terminal access
|
|
- **Port forwarding** for web development
|
|
- **Extension ecosystem** available remotely
|
|
- **Secure connections** through Tailscale network
|
|
|
|
The combination of VSCode Remote Development with Tailscale networking creates a powerful, flexible development environment that works from anywhere while maintaining security and performance.
|
|
|
|
Whether developing Python applications, Node.js services, or managing Docker containers, this setup provides a professional remote development experience that rivals local development while leveraging the power and resources of remote servers. |