homelab infrastructure services

Sheet Configuration#

Sheets are tinsnip's organizational unit for isolating different service deployments. Each sheet provides complete isolation with its own UID ranges, storage paths, and service deployments.

Architecture Overview#

Key Design Principles:

  • One Global Station: Only topsheet has a station (UID 50000) that manages registries for ALL sheets
  • Explicit Registration: Sheet numbers (1-4) are explicitly assigned via tin sheet create
  • Shared Registry Access: All machines mount /mnt/station-prod to access registries
  • UID Isolation: Each sheet's services use unique UID ranges based on the sheet number

Sheet Number Assignment#

Sheets are assigned numbers when registered:

  • Sheet 1-4: User sheets assigned sequentially via tin sheet create
  • Sheet 5: Reserved for topsheet (default/infrastructure sheet)

The sheet number becomes the first digit in the SMEP UID scheme:

  • Sheet 1 services: UIDs 10000-19999
  • Sheet 2 services: UIDs 20000-29999
  • Sheet 3 services: UIDs 30000-39999
  • Sheet 4 services: UIDs 40000-49999
  • Sheet 5 (topsheet): UIDs 50000-59999

Quick Start: Working with Sheets#

Default Setup (Single Sheet)#

Most users only need topsheet:

# First-time setup: Create topsheet station (only needed once)
tin machine station prod <nas-server>

# Create machines on topsheet (no TIN_SHEET needed - topsheet is default)
tin machine create myservice prod <nas-server>
tin machine create myservice dev <nas-server>

Multi-Sheet Setup#

For multi-tenant or organization isolation:

# Step 1: Ensure topsheet station exists (only needed once for all sheets)
tin machine station prod <nas-server>

# Step 2: Register a new sheet
tin sheet create company-a
# Output: Sheet 'company-a' registered as sheet number 1

# Step 3: Create machines on the new sheet
TIN_SHEET=company-a tin machine create app prod <nas-server>
TIN_SHEET=company-a tin machine create app dev <nas-server>

# Step 4: Register another sheet
tin sheet create company-b
# Output: Sheet 'company-b' registered as sheet number 2

# Step 5: Create machines on second sheet
TIN_SHEET=company-b tin machine create app prod <nas-server>

Registry Architecture#

The station (at /mnt/station-prod) maintains three registries accessible to all sheets:

1. Sheet Registry#

Location: /mnt/station-prod/data/sheets

Maps sheet names to numbers (1-4 for user sheets, 5 for topsheet):

topsheet=5
company-a=1
company-b=2

Management:

tin sheet create <name>        # Register new sheet (auto-assigns next number)
tin sheet list                 # Show all registered sheets
tin sheet show <name>          # Show sheet details
tin sheet rm <name>            # Remove sheet (cascades to all machines)

2. Machine Registries#

Location: /mnt/station-prod/data/machines/<sheet>

Each sheet has its own machine registry file mapping machine names to 2-digit numbers:

# /mnt/station-prod/data/machines/company-a
app=01
database=02
cache=03

Services are auto-registered when machines are created.

3. NAS Registry#

Location: /mnt/station-prod/data/nas-credentials/nas-servers

Maps sheets to their NAS servers for convenience:

topsheet=DS412plus.local
company-a=nas1.company-a.com
company-b=nas2.company-b.com

Allows omitting NAS server from commands after initial setup.

Sheet Detection#

Sheet is determined in this priority order:

  1. Environment variable: TIN_SHEET=company-a
  2. System file: /etc/tinsnip-sheet
  3. Default: topsheet

Setting Sheet Context#

Per-command (recommended for multi-sheet):

TIN_SHEET=company-a tin machine create app prod nas1.example.com

Environment variable (for session):

export TIN_SHEET=company-a
tin machine create app prod nas1.example.com
tin machine create app dev nas1.example.com

System-wide (for single sheet setups):

echo "company-a" | sudo tee /etc/tinsnip-sheet
tin machine create app prod nas1.example.com  # Uses company-a automatically

Storage Isolation#

Each sheet uses separate NFS paths on the NAS:

Sheet 'company-a' (number 1):

NAS paths:
  /volume1/tinsnip/company-a/station/prod  (if creating per-sheet station)
  /volume1/tinsnip/company-a/app/prod
  /volume1/tinsnip/company-a/app/dev

Machine mount points:
  /mnt/station-prod  → topsheet station (shared)
  /mnt/app-prod      → /volume1/tinsnip/company-a/app/prod
  /mnt/app-dev       → /volume1/tinsnip/company-a/app/dev

Sheet 'company-b' (number 2):

NAS paths:
  /volume1/tinsnip/company-b/app/prod
  /volume1/tinsnip/company-b/app/dev

Machine mount points:
  /mnt/station-prod  → topsheet station (shared)
  /mnt/app-prod      → /volume1/tinsnip/company-b/app/prod
  /mnt/app-dev       → /volume1/tinsnip/company-b/app/dev

UID and Port Isolation#

The SMEP scheme ensures complete UID/port isolation:

Format: S-M-E-P where:

  • S = Sheet number (1-5)
  • M = Machine number (00-99, auto-assigned)
  • E = Environment (0=prod, 1=test, 2=dev, etc.)
  • P = Port index (0-9)

Examples:

Sheet 1 (company-a):

  • app-prod user: UID 10100 (sheet=1, service=01, env=0, port=0)
  • app-dev user: UID 10120 (sheet=1, service=01, env=2, port=0)
  • Ports: 10100-10109 for app-prod, 10120-10129 for app-dev

Sheet 2 (company-b):

  • app-prod user: UID 20100 (sheet=2, service=01, env=0, port=0)
  • app-dev user: UID 20120 (sheet=2, service=01, env=2, port=0)
  • Ports: 20100-20109 for app-prod, 20120-20129 for app-dev

Topsheet (sheet 5):

  • app-prod user: UID 50100 (sheet=5, service=01, env=0, port=0)
  • Ports: 50100-50109 for app-prod

Complete Multi-Sheet Example#

Setting up two isolated organizations:

# === Initial Setup (Once) ===
# Create topsheet station for registry infrastructure
tin machine station prod DS412plus.local

# === Company A Setup ===
# Register sheet
tin sheet create company-a

# Create machines
TIN_SHEET=company-a tin machine create web prod nas-a.example.com
TIN_SHEET=company-a tin machine create api prod nas-a.example.com
TIN_SHEET=company-a tin machine create db prod nas-a.example.com

# Deploy services
TIN_SHEET=company-a tin service deploy web-prod nginx
TIN_SHEET=company-a tin service deploy api-prod myapi
TIN_SHEET=company-a tin service deploy db-prod postgres

# === Company B Setup ===
# Register sheet
tin sheet create company-b

# Create machines (different NAS, same service names - no conflict!)
TIN_SHEET=company-b tin machine create web prod nas-b.example.com
TIN_SHEET=company-b tin machine create api prod nas-b.example.com
TIN_SHEET=company-b tin machine create db prod nas-b.example.com

# Deploy services
TIN_SHEET=company-b tin service deploy web-prod nginx
TIN_SHEET=company-b tin service deploy api-prod myapi
TIN_SHEET=company-b tin service deploy db-prod postgres

Result:

  • Company A: UIDs 10100, 10200, 10300 / Ports 10100+, 10200+, 10300+
  • Company B: UIDs 20100, 20200, 20300 / Ports 20100+, 20200+, 20300+
  • Complete storage, UID, and port isolation
  • Both can have services with identical names without conflict

Sheet Limits#

  • Maximum sheets: 4 user sheets + 1 topsheet = 5 total
  • Rationale: Single-digit sheet number in SMEP scheme
  • Workaround: For >4 sheets, deploy separate tinsnip infrastructure

NAS Configuration#

tinsnip automatically creates NFS exports with correct permissions during tin machine create. No manual NAS configuration required.

Behind the scenes (for reference):

# On NAS, tinsnip creates exports like:
/volume1/tinsnip/company-a/app/prod  host(rw,async,no_subtree_check,all_squash,anonuid=10100,anongid=10100)
/volume1/tinsnip/company-b/app/prod  host(rw,async,no_subtree_check,all_squash,anonuid=20100,anongid=20100)

The all_squash with anonuid ensures all writes from the machine appear as the correct service UID on the NAS.

Troubleshooting#

"Sheet not registered" error#

[ERROR] Sheet 'mysheet' not registered

Solution: Register the sheet first:

tin sheet create mysheet

"Service registry not found" error#

[ERROR] Machine registry not found: /mnt/station-prod/data/machines/mysheet

Solution: Ensure topsheet station exists and sheet is registered:

# Check if station mounted
mount | grep station-prod

# If not, create it
tin machine station prod <nas-server>

# Then register sheet
tin sheet create mysheet

UID conflicts between sheets#

UIDs should never conflict if sheets are properly registered. Verify sheet numbers:

tin sheet list

Cannot access registries#

All machines need /mnt/station-prod mounted. Verify:

mount | grep station-prod
ls -la /mnt/station-prod/data/

If missing, ensure topsheet station was created with tin machine station prod <nas-server>.