homelab infrastructure services
1# Example Development Workflows
2
3This guide demonstrates practical workflows for teams using tinsnip with cross-platform development environments.
4
5## Scenario Setup
6
7### Hardware & Users
8- **u1**: Developer on Windows
9- **u2**: Developer on macOS
10- **s1**: Ubuntu server (shared development environment)
11- **DS412plus**: Synology NAS for persistent storage
12
13### Service Architecture
14```
15Production Services (E=0):
16- p1-prod (10100): Core service
17- p2-prod (10200): API service
18- p3-prod (10300): Database service
19
20Test Services (E=1):
21- t3-test (10310): Test instance of p3
22
23Development Work:
24- u1 creating d4 service (depends on p2-prod and t3-test)
25- u2 modifying t3 service
26```
27
28## Prerequisites
29
30### On s1 (Ubuntu Server)
31
32```bash
33# Install tinsnip
34curl -fsSL "https://tangled.sh/dynamicalsystem.com/tinsnip/raw/main/install.sh?$(date +%s)" | bash
35cd ~/.local/opt/dynamicalsystem.tinsnip
36
37# Create user accounts for developers
38sudo useradd -m -s /bin/bash -G sudo,docker u1
39sudo useradd -m -s /bin/bash -G sudo,docker u2
40sudo passwd u1
41sudo passwd u2
42
43# Fix npm permissions for each user
44for user in u1 u2; do
45 sudo -u $user -i bash << 'EOF'
46 mkdir ~/.npm-global
47 npm config set prefix '~/.npm-global'
48 echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
49EOF
50done
51```
52
53### On Developer Machines
54
55**Windows (u1) - PowerShell:**
56```powershell
57# Install VSCode
58winget install Microsoft.VisualStudioCode
59
60# Install Remote-SSH extension
61code --install-extension ms-vscode-remote.remote-ssh
62
63# Configure SSH
64New-Item -Path ~/.ssh/config -ItemType File -Force
65Add-Content ~/.ssh/config @"
66Host s1-dev
67 HostName s1.example.com
68 User u1
69 LocalForward 10420 localhost:10420
70 LocalForward 10421 localhost:10421
71 LocalForward 10200 localhost:10200
72 LocalForward 10350 localhost:10350
73"@
74```
75
76**macOS (u2) - Terminal:**
77```bash
78# Install VSCode
79brew install --cask visual-studio-code
80
81# Install Remote-SSH extension
82code --install-extension ms-vscode-remote.remote-ssh
83
84# Configure SSH
85cat >> ~/.ssh/config << EOF
86Host s1-dev
87 HostName s1.example.com
88 User u2
89 LocalForward 10330 localhost:10330
90 LocalForward 10331 localhost:10331
91 ControlMaster auto
92 ControlPath ~/.ssh/cm-%r@%h:%p
93EOF
94```
95
96## Workflow 1: u1 Creates New Service (d4)
97
98### Step 1: Create Service Infrastructure
99
100```bash
101# SSH to s1
102ssh s1-dev
103
104# Create d4 development environment
105cd ~/.local/opt/dynamicalsystem.tinsnip
106tin machine create d4 dev DS412plus
107
108# Output:
109# Service user: d4-dev
110# UID: 10420
111# Ports: 10420-10429
112# NFS mount: /mnt/d4-dev
113```
114
115### Step 2: Set Up Service Code
116
117```bash
118# As u1 on s1
119cd /mnt/d4-dev/service
120
121# Create service structure
122cat > docker-compose.yml << 'EOF'
123version: '3.8'
124
125services:
126 d4:
127 build: .
128 container_name: d4-dev
129 ports:
130 - "10420:8000"
131 - "10421:8001" # Admin UI
132 environment:
133 - TIN_SERVICE_NAME=d4
134 - TIN_SERVICE_ENV=dev
135 - TIN_SERVICE_UID=10420
136 - P2_API_URL=http://p2-prod:10200
137 - T3_DB_URL=postgres://t3-test:10310/d4_dev
138 volumes:
139 - ./src:/app/src:delegated # Hot reload
140 - /mnt/d4-dev/data:/data
141 - /mnt/d4-dev/config:/config
142 networks:
143 - tinsnip-network
144
145networks:
146 tinsnip-network:
147 external: true
148EOF
149
150# Create Dockerfile
151cat > Dockerfile << 'EOF'
152FROM node:18-alpine
153WORKDIR /app
154COPY package*.json ./
155RUN npm ci
156COPY . .
157CMD ["npm", "run", "dev"]
158EOF
159```
160
161### Step 3: VSCode Development
162
163**On Windows (u1):**
164```powershell
165# Open VSCode with Remote-SSH
166code --folder-uri vscode-remote://ssh-remote+s1-dev/mnt/d4-dev/service
167
168# This opens VSCode connected to s1
169# All file edits happen directly on s1
170# Terminal runs on s1
171```
172
173### Step 4: Claude Code Integration
174
175In VSCode integrated terminal (running on s1):
176```bash
177# Start Claude Code in the service directory
178cd /mnt/d4-dev/service
179claude code
180
181# Ask Claude Code to help with the service
182# "Create an Express API that connects to p2 service and t3 database"
183# "Add error handling for the external service calls"
184# "Generate TypeScript interfaces for the API responses"
185```
186
187### Step 5: Test Service
188
189```bash
190# In VSCode terminal (on s1)
191docker compose up -d
192docker compose logs -f
193
194# In Windows browser (port forwarded via SSH)
195# http://localhost:10420 - Main service
196# http://localhost:10421 - Admin UI
197```
198
199## Workflow 2: u2 Modifies Existing Service (t3)
200
201### Step 1: Create Staging Environment
202
203```bash
204# SSH to s1
205ssh s1-dev
206
207# Create t3 staging environment for modifications
208cd ~/.local/opt/dynamicalsystem.tinsnip
209tin machine create t3 staging DS412plus
210
211# Output:
212# Service user: t3-staging
213# UID: 10330
214# Ports: 10330-10339
215```
216
217### Step 2: Copy Current t3 Code
218
219```bash
220# Clone t3 from test to staging
221sudo cp -r /mnt/t3-test/service/* /mnt/t3-staging/service/
222sudo chown -R t3-staging:t3-staging /mnt/t3-staging/service
223```
224
225### Step 3: VSCode Development
226
227**On macOS (u2):**
228```bash
229# Open VSCode with Remote-SSH
230code --folder-uri vscode-remote://ssh-remote+s1-dev/mnt/t3-staging/service
231```
232
233### Step 4: Make Modifications with Claude Code
234
235In VSCode integrated terminal:
236```bash
237cd /mnt/t3-staging/service
238claude code
239
240# Work with Claude Code
241# "Add caching layer to the database queries"
242# "Implement connection pooling"
243# "Add metrics endpoint for Prometheus"
244```
245
246### Step 5: Test Changes
247
248```bash
249# Build and run
250docker compose build --no-cache
251docker compose up -d
252
253# Run tests
254docker compose exec t3 npm test
255
256# Check metrics endpoint
257curl http://localhost:10332/metrics
258```
259
260## Workflow 3: Integration Testing
261
262### Create Integration Environment
263
264```bash
265# On s1, create shared integration environment
266tin machine create integration demo DS412plus
267# UID: 10440, Ports: 10440-10449
268```
269
270### Deploy Both Services
271
272```bash
273# Deploy u2's t3 changes
274cd /mnt/integration-demo/service
275cp -r /mnt/t3-staging/service/t3 ./
276cd t3
277docker compose up -d
278
279# Deploy u1's d4 service pointing to new t3
280cd /mnt/integration-demo/service
281cp -r /mnt/d4-dev/service/d4 ./
282cd d4
283
284# Update d4 to use staging t3
285sed -i 's/t3-test:10310/t3-staging:10330/g' docker-compose.yml
286docker compose up -d
287```
288
289### Run Integration Tests
290
291```bash
292# Create test script
293cat > /mnt/integration-demo/test.sh << 'EOF'
294#!/bin/bash
295echo "Testing d4 -> t3 integration..."
296
297# Test d4 API
298curl -f http://localhost:10440/health || exit 1
299
300# Test t3 connection
301curl -f http://localhost:10440/api/database/status || exit 1
302
303echo "Integration tests passed!"
304EOF
305
306chmod +x /mnt/integration-demo/test.sh
307./test.sh
308```
309
310## Workflow 4: Collaborative Debugging
311
312### Using tmux for Shared Sessions
313
314```bash
315# u1 starts tmux session on s1
316ssh s1-dev
317tmux new -s debug-d4
318
319# Split panes
320# Ctrl-b % (vertical split)
321# Ctrl-b " (horizontal split)
322
323# Pane 1: Docker logs
324docker compose logs -f d4
325
326# Pane 2: Claude Code
327claude code
328
329# Pane 3: Testing
330watch curl http://localhost:10420/health
331```
332
333```bash
334# u2 joins the session
335ssh s1-dev
336tmux attach -t debug-d4
337
338# Both developers see the same screen
339# Can take turns typing
340```
341
342### Shared Claude Code Context
343
344```bash
345# Create shared context file
346cat > /mnt/integration-demo/CLAUDE.md << 'EOF'
347# Integration Context
348
349## Services
350- d4: New service by u1, ports 10420-10429
351- t3: Modified by u2, ports 10330-10339
352
353## Dependencies
354- d4 -> p2 (10200) for API
355- d4 -> t3 (10330) for database
356
357## Current Issues
358- Connection timeout between d4 and t3
359- Need to add retry logic
360
361## Test Command
362curl http://localhost:10440/api/test
363EOF
364
365# Both developers can reference
366cd /mnt/integration-demo
367claude code
368# "Read CLAUDE.md and help debug the connection timeout"
369```
370
371## Workflow 5: Service Promotion
372
373### Test to Production Pipeline
374
375```bash
376# 1. Freeze staging changes
377cd /mnt/t3-staging/service
378git add .
379git commit -m "Add caching and connection pooling"
380git push origin t3-staging
381
382# 2. Deploy to test environment
383tin machine create t3 test DS412plus
384cd /mnt/t3-test/service
385git pull origin t3-staging
386docker compose up -d
387
388# 3. Run test suite
389docker compose exec t3 npm run test:integration
390
391# 4. Promote to production (if tests pass)
392cd /mnt/t3-prod/service
393git pull origin t3-staging
394docker compose up -d --scale t3=2 # Rolling update
395```
396
397## Tips and Tricks
398
399### 1. Port Forwarding Alias
400
401**Windows PowerShell:**
402```powershell
403function Connect-Dev {
404 ssh -L 10420:localhost:10420 `
405 -L 10421:localhost:10421 `
406 -L 10200:localhost:10200 `
407 -L 10350:localhost:10350 `
408 u1@s1.example.com
409}
410```
411
412**macOS/Linux Bash:**
413```bash
414alias s1dev='ssh -L 10330:localhost:10330 -L 10331:localhost:10331 s1-dev'
415```
416
417### 2. Quick Service Status
418
419```bash
420# Create status script
421cat > ~/status.sh << 'EOF'
422#!/bin/bash
423echo "=== Service Status ==="
424for service in d4-dev t3-staging integration-demo; do
425 if [[ -d /mnt/$service/service ]]; then
426 echo -n "$service: "
427 cd /mnt/$service/service
428 docker compose ps --format "table {{.State}}" | tail -n1
429 fi
430done
431EOF
432chmod +x ~/status.sh
433```
434
435### 3. Claude Code Templates
436
437```bash
438# Create templates for common tasks
439mkdir -p ~/.claude-templates
440
441cat > ~/.claude-templates/debug-docker.md << 'EOF'
442Analyze these Docker logs and identify the issue:
443```
444[PASTE LOGS]
445```
446Service configuration:
447```yaml
448[PASTE docker-compose.yml]
449```
450EOF
451
452# Use template
453cat ~/.claude-templates/debug-docker.md | claude code
454```
455
456### 4. VSCode Workspace Settings
457
458Create `.vscode/settings.json` in each service:
459```json
460{
461 "terminal.integrated.cwd": "/mnt/d4-dev/service",
462 "files.watcherExclude": {
463 "**/node_modules/**": true,
464 "**/data/**": true
465 },
466 "docker.host": "unix:///var/run/docker.sock",
467 "remote.autoForwardPorts": true,
468 "remote.autoForwardPortsSource": "process"
469}
470```
471
472## Troubleshooting
473
474### Permission Denied on Docker
475
476```bash
477# Add user to docker group
478sudo usermod -aG docker u1
479newgrp docker
480```
481
482### NFS Mount Issues
483
484```bash
485# Check NFS exports on NAS
486ssh admin@DS412plus
487showmount -e localhost
488
489# Test mount manually
490sudo mount -t nfs DS412plus:/volume1/topsheet/gazette/test /tmp/test
491```
492
493### Port Already in Use
494
495```bash
496# Find process using port
497sudo lsof -i :10420
498sudo netstat -tulpn | grep 10420
499
500# Kill process if needed
501sudo kill $(sudo lsof -t -i:10420)
502```
503
504### Claude Code Not Found
505
506If `claude code` command is not available:
5071. Ensure you're using the desktop app or have API access configured
5082. Alternative: Use Claude.ai web interface with copy/paste
5093. Or use API integration scripts as shown in the examples
510
511## Summary
512
513This workflow enables:
514- **Cross-platform development** (Windows/macOS developers on Linux server)
515- **Service isolation** using tinsnip's SMEP convention
516- **Fast iteration** with VSCode Remote-SSH and Docker
517- **AI assistance** with Claude Code integration
518- **Predictable networking** with SMEP port allocation
519- **Persistent storage** via NFS mounts
520
521The key is using s1 as a shared development server with isolated environments per developer and service, while maintaining local IDE experience through VSCode Remote-SSH.