diff --git a/procedures/vscode-server-mk7-deploy.md b/procedures/vscode-server-mk7-deploy.md new file mode 100644 index 0000000..7cdcfe0 --- /dev/null +++ b/procedures/vscode-server-mk7-deploy.md @@ -0,0 +1,187 @@ +# VS Code: Server Deployment Procedure + +**Generated:** 2026-06-02 +**Maintainer:** Artemis (AI Foreman) + +--- + +## Overview + +This document describes the deployment of [Microsoft VS Code: Server](https://code.visualstudio.com/docs/remote/vscode-server) (via LinuxServer `openvscode-server` Docker image) on **MK7** (Swarm Manager) to replace the previous `code-server` deployment on Neo. The primary driver was to enable **native Remote-SSH** support, which is unavailable in OpenVSX-based alternatives. + +**Key advantage:** MK7's placement on the `192.168.7.x` LAN grants direct access to all fleet nodes and Proxmox VE workers via their LAN IPs. When deployed on Neo (192.168.192.x), the container was isolated from fleet subnets. + +--- + +## Architecture + +| Component | Value | +|-----------|-------| +| **Host** | MK7 (mark-vii.ai.home) | +| **Swarm Mode** | `replicated` with placement constraint `node.hostname == mark-vii.ai.home` | +| **Container IP** | Swarm overlay (10.0.1.x/24) via `traefik-public` network | +| **Published Port** | `8443:3000` (Swarm ingress) | +| **Internal Service Port** | `3000` | +| **Traefik Endpoint** | `vscode.ai.home` → `192.168.7.7:8443` | +| **DNS Record** | `A` record `vscode.ai.home` → `192.168.7.7` (Technitium) | +| **Image** | `lscr.io/linuxserver/openvscode-server:latest` | +| **Marketplace** | Microsoft (official) — Remote-SSH available natively | + +--- + +## Prerequisites + +- MK7 Docker Swarm active with `traefik-public` overlay network +- Traefik reverse proxy running on `traefik.ai.home` +- Technitium DNS authoritative for `ai.home` zone +- SSH key pair (`vscode_ed25519`) deployed to all fleet nodes +- `/home/jarvis/.vscode-ssh` directory created on MK7 host with: + - `config` — SSH aliases for all fleet nodes + - `vscode_ed25519` — private key (mode 600) + - `vscode_ed25519.pub` — public key (mode 644) + +--- + +## Deployment Steps + +### 1. Prepare SSH Key Directory on MK7 + +```bash +mkdir -p /home/jarvis/.vscode-ssh +chmod 700 /home/jarvis/.vscode-ssh +# Copy vscode_ed25519 key pair + config from source node +scp source:/path/to/vscode_ed25519* /home/jarvis/.vscode-ssh/ +chmod 600 /home/jarvis/.vscode-ssh/vscode_ed25519 +chmod 644 /home/jarvis/.vscode-ssh/vscode_ed25519.pub +chmod 644 /home/jarvis/.vscode-ssh/config +``` + +### 2. Compose File (`vscode-server-compose.yaml`) + +```yaml +version: '3.8' + +services: + vscode: + image: lscr.io/linuxserver/openvscode-server:latest + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + # Generate a random hex token: openssl rand -hex 16 + - CONNECTION_TOKEN= + - DEFAULT_WORKSPACE=/config/workspace + ports: + - '8443:3000' + volumes: + - vscode_data:/config/workspace + - type: bind + source: /home/jarvis/.vscode-ssh + target: /config/.ssh + networks: + - traefik-public + deploy: + placement: + constraints: + - node.hostname == mark-vii.ai.home + labels: + - "traefik.enable=true" + - "traefik.http.routers.vscode.rule=Host(`vscode.ai.home`)" + - "traefik.http.routers.vscode.entrypoints=websecure" + - "traefik.http.routers.vscode.tls=true" + - "traefik.http.services.vscode.loadbalancer.server.port=3000" + +volumes: + vscode_data: + driver: local + +networks: + traefik-public: + external: true +``` + +### 3. Deploy via Swarm + +```bash +sudo docker stack deploy -c vscode-server-compose.yaml vscode +``` + +### 4. Verify Startup + +```bash +sudo docker service ls | grep vscode +sudo docker service ps vscode_vscode +sudo docker logs $(docker ps -q -f name=vscode) +``` + +--- + +## Access URLs + +| Mode | URL | Notes | +|------|-----|-------| +| Direct (HTTP) | `http://192.168.7.7:8443/?tkn=` | Lan-only, no SSL | +| Via Traefik (HTTPS) | `https://vscode.ai.home/?tkn=` | Requires DNS + valid Traefik cert | + +**Token location:** Set in compose `CONNECTION_TOKEN` env var. + +--- + +## Fleet Node SSH Config + +The container mounts `/config/.ssh` containing a standard OpenSSH `config` file with all fleet aliases. Remote-SSH extension reads this automatically. + +**Format example:** +```ssh-config +Host artemis + HostName 192.168.15.182 + User jarvis + IdentityFile ~/.ssh/vscode_ed25519 + IdentitiesOnly yes +``` + +**PVE nodes (mk33/34/39):** Present but `User root` — key deployment pending. + +--- + +## Why MK7 Over Neo + +| Factor | Neo (Previous) | MK7 (Current) | +|--------|---------------|----------------| +| Network | Isolated subnet (192.168.192.x) | Core LAN (192.168.7.x) | +| Swarm | Standalone | Manager | +| Traefik | Manual or absent | Already deployed | +| Remote-SSH | Unavailable (OpenVSX) | Available (Microsoft) | +| Fleet Reach | None | Direct SSH to all nodes | + +--- + +## Troubleshooting + +**Port 8443 not reachable externally:** +- Check Swarm ingress: `sudo iptables -t nat -L DOCKER-INGRESS | grep 8443` +- Verify container binding: `sudo ss -tlnp | grep 8443` + +**Container fails to start with mount error:** +- Ensure `/home/jarvis/.vscode-ssh` exists on MK7 host before deploy +- Swarm bind mounts require host path existence at deploy time + +**Token rejected:** +- Tokens must be hex-only characters (0-9, a-f) +- Regenerate with: `openssl rand -hex 16` + +**Traefik route not found:** +- Verify `traefik-public` network exists: `docker network ls | grep traefik` +- Check Traefik dashboard at `https://traefik.ai.home:8080` + +--- + +## References + +- [LinuxServer OpenVSCode-Server Docker](https://github.com/linuxserver/docker-openvscode-server) +- [VS Code: Server Documentation](https://code.visualstudio.com/docs/remote/vscode-server) +- [Remote-SSH Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) + +--- + +*End of document*