Development Environments
Create fast, reproducible development environments with Noid.
Overview
Noid enables developers to:
- Spin up environments instantly from golden snapshots
- Test safely without affecting local machine
- Share configurations via checkpoints
- Reset quickly to clean state
Quick Dev Environment
# Create development VM
noid create dev-env --vcpus 4 --memory 8192
# Set as active
noid use dev-env
# Install development tools
noid exec -- apt-get update
noid exec -- apt-get install -y git nodejs npm python3 docker.io
# Clone project
noid exec -- git clone https://github.com/user/project.git /workspace
# Install dependencies
noid exec -- sh -c "cd /workspace && npm install"
# Create clean state checkpoint
noid checkpoint dev-env clean-state
# Run development server
noid exec -- sh -c "cd /workspace && npm run dev"
Golden Snapshot for Teams
Create a shared development environment:
#!/bin/bash
# setup-dev-golden.sh
VM_NAME="dev-base"
# Create base VM
noid create $VM_NAME --vcpus 4 --memory 8192
# Install common tools
noid exec $VM_NAME -- apt-get update
noid exec $VM_NAME -- apt-get install -y \
git \
curl \
wget \
vim \
nodejs \
npm \
python3 \
python3-pip \
docker.io \
postgresql-client \
redis-tools
# Install development dependencies
noid exec $VM_NAME -- npm install -g typescript ts-node nodemon
noid exec $VM_NAME -- pip3 install black pylint pytest
# Configure git
noid exec $VM_NAME -- git config --global init.defaultBranch main
# Create golden checkpoint
noid checkpoint $VM_NAME golden \
--label "Development environment $(date +%Y-%m-%d)"
echo "✓ Golden snapshot created: dev-base/golden"
echo " Team members can now clone with:"
echo " noid restore dev-base golden --as my-dev-env"
Per-Feature Environments
Create isolated environment for each feature:
# Feature 1: New authentication system
noid restore dev-base golden --as feature-auth
noid use feature-auth
noid exec -- git clone https://github.com/user/project.git /workspace
noid exec -- sh -c "cd /workspace && git checkout -b feature/auth"
noid exec -- sh -c "cd /workspace && npm run dev"
# Feature 2: Database migration
noid restore dev-base golden --as feature-migration
noid use feature-migration
noid exec -- git clone https://github.com/user/project.git /workspace
noid exec -- sh -c "cd /workspace && git checkout -b feature/migration"
noid exec -- sh -c "cd /workspace && npm run dev"
# List all feature environments
noid list
Testing Workflow
Test changes in isolation:
import { NoidClient } from '@noid/sdk';
async function testPullRequest(prNumber: number) {
const noid = new NoidClient({
serverUrl: process.env.NOID_SERVER!,
token: process.env.NOID_TOKEN!,
});
const vmName = `test-pr-${prNumber}`;
try {
// Create test environment
await noid.restore('dev-base', 'golden', { as: vmName });
// Clone and checkout PR
await noid.exec(vmName, 'git clone https://github.com/user/project.git /workspace');
await noid.exec(vmName, `cd /workspace && gh pr checkout ${prNumber}`);
// Install dependencies
await noid.exec(vmName, 'cd /workspace && npm install');
// Run tests
const testResult = await noid.exec(vmName, 'cd /workspace && npm test');
if (testResult.exitCode !== 0) {
console.error('Tests failed!');
console.error(testResult.stderr);
return false;
}
// Run linter
const lintResult = await noid.exec(vmName, 'cd /workspace && npm run lint');
if (lintResult.exitCode !== 0) {
console.error('Linting failed!');
console.error(lintResult.stderr);
return false;
}
console.log('✓ All checks passed');
return true;
} finally {
// Cleanup
await noid.destroyVM(vmName);
}
}
// Test PR #123
testPullRequest(123);
Multi-Service Development
Run entire stack in VMs:
# Create services
noid restore dev-base golden --as db-vm
noid restore dev-base golden --as api-vm
noid restore dev-base golden --as frontend-vm
# Start database
noid exec db-vm -- sh -c "
apt-get install -y postgresql
service postgresql start
createdb myapp
"
# Start API (with DB connection)
noid exec api-vm -- sh -c "
git clone https://github.com/user/api.git /api
cd /api
DATABASE_URL='postgresql://db-vm:5432/myapp' npm start
"
# Start frontend
noid exec frontend-vm -- sh -c "
git clone https://github.com/user/frontend.git /app
cd /app
API_URL='http://api-vm:3000' npm start
"
Database Testing
Test migrations safely:
# Create test database environment
noid restore dev-base golden --as db-test
# Set up database
noid exec db-test -- sh -c "
apt-get install -y postgresql
service postgresql start
createdb testdb
psql testdb < /workspace/schema.sql
"
# Create pre-migration checkpoint
noid checkpoint db-test before-migration
# Run migration
noid exec db-test -- sh -c "cd /workspace && npm run migrate"
# Test application
noid exec db-test -- sh -c "cd /workspace && npm test"
# If tests fail, rollback
noid restore db-test before-migration
# If tests pass, create post-migration checkpoint
noid checkpoint db-test after-migration
Code Review Environment
Share environment with reviewers:
# Developer: Create review environment
noid create review-feature-x
noid exec review-feature-x -- sh -c "
git clone https://github.com/user/project.git /workspace
cd /workspace && git checkout feature-x
npm install && npm run build
"
# Create checkpoint
noid checkpoint review-feature-x ready-for-review \
--label "Feature X - ready for review"
# Reviewer: Restore checkpoint
noid restore review-feature-x ready-for-review --as my-review
noid use my-review
# Review the code
noid exec -- sh -c "cd /workspace && code ."
# Test the feature
noid exec -- sh -c "cd /workspace && npm start"
CI/CD Integration
# .github/workflows/test.yml
name: Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Setup Noid
run: |
curl -L https://noid.one/install.sh | sh
noid auth setup --token ${{ secrets.NOID_TOKEN }}
- name: Create test environment
run: |
noid restore dev-base golden --as ci-${{ github.run_id }}
- name: Run tests
run: |
noid exec ci-${{ github.run_id }} -- sh -c "
git clone ${{ github.repository }} /workspace
cd /workspace
git checkout ${{ github.sha }}
npm install
npm test
"
- name: Cleanup
if: always()
run: |
noid destroy ci-${{ github.run_id }}
Development Scripts
Start Development
#!/bin/bash
# dev-start.sh
PROJECT_NAME="my-project"
VM_NAME="dev-${USER}"
# Check if VM exists
if noid list | grep -q "$VM_NAME"; then
echo "Resuming existing environment..."
noid use $VM_NAME
else
echo "Creating new environment..."
noid restore dev-base golden --as $VM_NAME
noid use $VM_NAME
# Clone project
noid exec -- git clone https://github.com/user/$PROJECT_NAME.git /workspace
noid exec -- sh -c "cd /workspace && npm install"
fi
# Attach to console
noid console
Clean Rebuild
#!/bin/bash
# dev-rebuild.sh
VM_NAME="dev-${USER}"
echo "Destroying current environment..."
noid destroy $VM_NAME
echo "Creating fresh environment..."
noid restore dev-base golden --as $VM_NAME
noid use $VM_NAME
echo "✓ Clean environment ready"
VS Code Integration
Connect VS Code to Noid VM:
# Install VS Code Remote SSH extension
# Get VM IP
VM_IP=$(noid list | grep my-dev-vm | awk '{print $3}')
# Configure SSH
cat >> ~/.ssh/config << EOF
Host noid-dev
HostName $VM_IP
User root
StrictHostKeyChecking no
EOF
# Connect
code --remote ssh-remote+noid-dev /workspace
Tips & Best Practices
1. Use Descriptive Names
# Good
noid create feature-auth-v2
noid create bug-fix-memory-leak
noid create experiment-new-db
# Bad
noid create test1
noid create vm2
2. Checkpoint Often
# Before risky changes
noid checkpoint dev-env before-refactor
# After setup
noid checkpoint dev-env configured
# Working state
noid checkpoint dev-env working-$(date +%Y%m%d)
3. Clean Up Regularly
# List old VMs
noid list
# Destroy unused VMs
noid destroy old-vm-1 old-vm-2
# Keep golden snapshots, destroy derivatives
Next Steps
- AI Agent Sandboxing - AI agent use case
- TypeScript SDK - SDK documentation
- Checkpoints Guide - Advanced checkpoints