Agent skill
otterstack-usage
Complete guide for using OtterStack - a Git-driven Docker Compose deployment tool with zero-downtime deployments. Use when deploying Docker Compose apps, managing projects, configuring environment variables, or troubleshooting deployments. Triggers on "how to use otterstack", "otterstack commands", "deploy with otterstack", "otterstack project", "otterstack env", or questions about OtterStack usage.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/otterstack-usage
SKILL.md
OtterStack Usage Guide
Complete reference for using OtterStack - a deployment orchestration tool for Docker Compose applications with zero-downtime deployments via Traefik priority-based routing.
What is OtterStack?
OtterStack is a Git-driven deployment orchestrator for Docker Compose applications running on a single VPS. It provides:
- Zero-downtime deployments using Traefik priority-based routing
- Git worktree isolation - each deployment gets its own directory
- Health check validation before traffic switching
- Automatic rollback if deployments fail
- Environment variable management with smart type detection
- Deployment history and retention policies
Core Concepts
- Projects: A project is a Docker Compose application tracked in git
- Worktrees: Each deployment creates an isolated git worktree
- Deployments: Deploy any git ref (commit, branch, tag)
- Priority Routing: New containers start at priority 200, old at 100
- Health Checks: Validates containers before traffic switch (5 min timeout)
Installation
go build ./cmd/otterstack
./otterstack version
Quick Start
1. Add Your First Project
Local repository:
otterstack project add myapp /srv/myapp
Remote repository:
otterstack project add myapp https://github.com/user/repo.git
With Traefik zero-downtime routing:
otterstack project add myapp https://github.com/user/repo.git --traefik-routing
Custom compose file:
otterstack project add myapp /srv/myapp --compose-file docker-compose.prod.yml
2. Configure Environment Variables
OtterStack now has smart environment variable management with auto-discovery!
Option 1: Auto-discovery during project add
# Create .env.<project-name> in current directory
echo "DATABASE_URL=postgres://localhost/mydb" > .env.myapp
echo "API_KEY=secret123" >> .env.myapp
# Add project - OtterStack will auto-discover and load the file
otterstack project add myapp /srv/myapp
# Prompts interactively for any missing variables
Option 2: Set variables manually
otterstack env set myapp DATABASE_URL=postgres://localhost/mydb
otterstack env set myapp API_KEY=secret DEBUG=false
Option 3: Load from file
otterstack env load myapp .env.production
Option 4: Interactive scan (for existing projects)
otterstack env scan myapp
# Scans compose file, prompts for missing variables
List variables:
otterstack env list myapp
otterstack env list myapp --show-values # Show actual values
Get specific variable:
otterstack env get myapp DATABASE_URL
Remove variables:
otterstack env unset myapp DEBUG
3. Deploy
Deploy default branch:
otterstack deploy myapp
Deploy specific ref:
otterstack deploy myapp --ref feature/new-ui
otterstack deploy myapp --ref v1.2.3
otterstack deploy myapp --ref a1b2c3d4
Force deploy (skip validations - use carefully!):
otterstack deploy myapp --force
4. Check Status
List all projects:
otterstack project list
View project details:
otterstack status myapp
Check deployment history:
otterstack deployments myapp
5. Manage Projects
Remove project:
otterstack project remove myapp
Force remove (skip confirmation):
otterstack project remove myapp --force
Environment Variable Management
Smart Type Detection
OtterStack automatically detects variable types from names:
| Pattern | Type | Validation |
|---|---|---|
DATABASE_URL, API_ENDPOINT |
URL | Must have scheme (https://) |
ADMIN_EMAIL, SUPPORT_EMAIL |
Valid email format | |
HTTP_PORT, DB_PORT |
Port | 1-65535 |
WORKER_COUNT, MAX_CONNECTIONS, TIMEOUT |
Integer | Valid number |
DEBUG_ENABLED, FEATURE_FLAG, USE_SSL |
Boolean | Yes/No dialog |
| Everything else | String | Basic validation |
Interactive Prompts
When you run env scan or project add, OtterStack:
- Parses compose file to find all
${VAR}references - Checks stored values to identify missing variables
- Groups prompts: Required first, optional second
- Type-aware UI: Booleans use Yes/No dialogs, others use validated text inputs
- Shows context: "Used by: web, worker"
- Generates
.env.examplefor documentation
Supported Variable Formats
OtterStack parses these Docker Compose formats:
services:
web:
environment:
- DATABASE_URL=${DATABASE_URL} # Required
- API_URL=${API_URL:-https://api.example.com} # Optional with default
- SECRET_KEY=${SECRET_KEY:?Secret key required} # Required with error message
- DEBUG=$DEBUG # Simple form
Zero-Downtime Deployments with Traefik
Prerequisites
- Traefik running and connected to Docker
- Compose file has Traefik labels:
services:
web:
image: myapp:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.web.rule=Host(`myapp.example.com`)"
- Project added with
--traefik-routingflag
How It Works
1. [Old Containers Serving] → Priority: 100
2. [Start New Containers] → No Traefik labels yet
3. [Health Check] → Wait up to 5 minutes
4. [Apply Priority Labels] → New: 200, Old: 100
5. [Traffic Switches] → Traefik routes to higher priority
6. [Stop Old Containers] → Deployment complete
If health checks fail at step 3, old containers keep serving traffic.
Deployment Flow
Without Traefik:
- Start new containers
- Stop old containers immediately
- Brief downtime during switch
With Traefik:
- Start new containers (no traffic)
- Wait for healthy
- Switch traffic priority
- Stop old containers
- Zero downtime!
Command Reference
Project Management
# Add project
otterstack project add <name> <repo-path-or-url> [flags]
--compose-file string Path to compose file (default: docker-compose.yml)
--traefik-routing Enable zero-downtime Traefik routing
# List projects
otterstack project list
# Remove project
otterstack project remove <name> [--force]
# View project status
otterstack status <name>
Environment Variables
# Set variables
otterstack env set <project> KEY=VALUE [KEY=VALUE...]
# Get variable
otterstack env get <project> [KEY]
# List variables
otterstack env list <project> [--show-values]
# Load from file
otterstack env load <project> <file>
# Interactive scan
otterstack env scan <project>
# Remove variables
otterstack env unset <project> KEY [KEY...]
Deployment
# Deploy
otterstack deploy <project> [flags]
--ref string Git ref to deploy (commit, branch, tag)
--force Skip validation checks
# View deployment history
otterstack deployments <project>
Global Flags
--config string Config file (default: $HOME/.otterstack.yaml)
--data-dir string Data directory (default: $HOME/.otterstack)
--verbose Verbose output
--help Show help
--version Show version
Common Workflows
First-Time Project Setup
# 1. Create .env file
cat > .env.myapp <<EOF
DATABASE_URL=postgres://user:pass@localhost/mydb
REDIS_URL=redis://localhost:6379
API_KEY=your-secret-key
EOF
# 2. Add project (auto-discovers .env.myapp)
otterstack project add myapp https://github.com/user/repo.git --traefik-routing
# 3. Verify configuration
otterstack env list myapp
# 4. Deploy
otterstack deploy myapp
Adding Variables to Existing Project
# Option 1: Interactive scan
otterstack env scan myapp
# Option 2: Manual set
otterstack env set myapp NEW_VAR=value
# Option 3: Load from file
otterstack env load myapp .env.new
Deploying a Feature Branch
# Deploy feature branch
otterstack deploy myapp --ref feature/new-ui
# Check status
otterstack status myapp
# If good, merge to main and deploy
git checkout main
git merge feature/new-ui
git push
otterstack deploy myapp --ref main
Rolling Back a Deployment
# Deploy previous commit
otterstack deploy myapp --ref HEAD~1
# Or deploy specific commit
otterstack deploy myapp --ref a1b2c3d
Updating Environment Variables
# Update variable
otterstack env set myapp API_KEY=new-key
# Redeploy for changes to take effect
otterstack deploy myapp
Pre-Deployment Validation
OtterStack validates environment variables before starting deployment:
$ otterstack deploy myapp
Validating environment variables...
❌ ERROR: Missing required environment variables
The following variables are required but not set:
DATABASE_URL
• Required by: web, worker
• Error: Database connection required
API_KEY
• Required by: web
To fix this, you can:
1. Set variables individually:
otterstack env set myapp DATABASE_URL=<value>
otterstack env set myapp API_KEY=<value>
2. Use interactive scan:
otterstack env scan myapp
3. Load from file:
otterstack env load myapp .env.myapp
Error: missing required environment variables
This prevents wasted deployment attempts with incomplete configuration!
Troubleshooting
"Project not found"
# List all projects
otterstack project list
# Verify project name matches exactly
"Lock file exists"
Another deployment is in progress or a previous one failed:
# Wait for deployment to finish, or if stuck:
rm ~/.otterstack/locks/<project>.lock
# Then retry
otterstack deploy myapp
"Missing required environment variables"
# Scan for missing variables
otterstack env scan myapp
# Or check what's missing
otterstack env list myapp
"Health check failed"
Containers didn't become healthy within 5 minutes:
# Check container logs
docker compose -f /path/to/worktree/docker-compose.yml logs
# Check container status
docker compose -f /path/to/worktree/docker-compose.yml ps
# Fix issues, then redeploy
otterstack deploy myapp
"Compose file not found"
# Verify compose file path
cat ~/.otterstack/projects.db | grep compose_file
# Update if wrong
# (Currently requires manual DB edit - future feature)
Environment Variables Not Working
# Verify variables are set
otterstack env list myapp --show-values
# Check compose file syntax
grep -E '\$\{[A-Z_]+\}' docker-compose.yml
# Redeploy after setting variables
otterstack deploy myapp
Best Practices
1. Environment Variables
- ✅ Use
.env.<project-name>files during initial setup - ✅ Run
env scanto catch missing variables early - ✅ Use type-appropriate variable names (DATABASE_URL, HTTP_PORT)
- ✅ Store secrets securely, never commit to git
- ✅ Generate
.env.examplefor documentation - ❌ Don't hardcode values in compose files
- ❌ Don't skip the pre-deployment validation
2. Docker Compose Files
- ✅ Use
${VAR}syntax for environment variables - ✅ Provide defaults with
${VAR:-default}when possible - ✅ Include health checks for all services
- ✅ Use Traefik labels for zero-downtime deployments
- ❌ Don't use
container_name(breaks worktree isolation) - ❌ Don't use
env_file(OtterStack manages env vars)
3. Deployments
- ✅ Deploy to staging/testing first
- ✅ Use
--traefik-routingfor production apps - ✅ Tag important releases:
git tag v1.0.0 - ✅ Keep deployment history: check retention policy
- ✅ Monitor health checks during deployment
- ❌ Don't use
--forcein production unless necessary - ❌ Don't deploy without testing env vars first
4. Project Organization
- ✅ Use descriptive project names
- ✅ Document required env vars in README
- ✅ Keep compose files simple and standard
- ✅ Use semantic versioning for tags
- ❌ Don't mix projects in the same repo
- ❌ Don't commit environment-specific config
Advanced Topics
Worktree Management
OtterStack creates git worktrees for each deployment:
# Worktrees are stored at:
~/.otterstack/worktrees/<project>/<commit-hash>/
# Each worktree is isolated with its own:
# - Git checkout
# - Docker Compose state
# - Environment file
Retention Policy
Old worktrees are cleaned up based on retention policy:
- Failed deployments: Kept for debugging
- Successful deployments: Configurable retention
Direct Compose Access
You can interact with deployed containers directly:
# Find worktree path
WORKTREE=$(ls -t ~/.otterstack/worktrees/myapp | head -1)
# Use docker compose directly
docker compose -f ~/.otterstack/worktrees/myapp/$WORKTREE/docker-compose.yml logs
docker compose -f ~/.otterstack/worktrees/myapp/$WORKTREE/docker-compose.yml exec web bash
Health Check Configuration
Compose file health check example:
services:
web:
image: myapp:latest
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 10s
timeout: 5s
retries: 3
start_period: 30s
Version History
v0.2.0 (2026-01-11)
- ✨ Enhanced environment variable management
- ✨ Auto-discovery of
.env.<project-name>files - ✨ Smart type detection and validation
- ✨ Interactive
env scancommand - ✨ Pre-deployment validation gate
- ✨ Automatic
.env.examplegeneration
Earlier Versions
- v0.2.0-rc.4: Fixed double-locking bug
- v0.2.0-rc.3: Fixed TOCTOU race condition
- v0.2.0-rc.2: Real-time Docker output streaming
Getting Help
# General help
otterstack --help
# Command-specific help
otterstack project --help
otterstack env --help
otterstack deploy --help
# Version info
otterstack version
Related Files
README.md- Overview and quick startIMPROVEMENTS.md- Proposed enhancements based on deployment experienceTROUBLESHOOTING.md- Common issues and solutions.claude/plans/enhanced-env-var-management.md- Implementation plan for env var features
Summary
OtterStack makes Docker Compose deployments simple and safe:
- Add project with
project add - Configure env vars with
env scanor auto-discovery - Deploy with
deploy - Zero downtime with Traefik routing
- Automatic rollback if things fail
The enhanced environment variable management ensures you never deploy with missing configuration, and the interactive prompts make setup a breeze!
Usage in Orchestration
This skill is referenced during Phase 4: Setup and Phase 5: Deployment of the /deploy-otterstack command.
Integration Points
The orchestration command uses this skill's documentation to execute OtterStack commands in three modes:
- Project Setup Mode - Check if project exists and add if needed
- Environment Variable Setup Mode - Load/scan/configure environment variables
- Deployment Mode - Execute deployment with verbose monitoring
Project Setup Mode
When the orchestration command needs to set up a new project:
Check if project exists:
# Local
otterstack project list | grep -q "^${PROJECT_NAME}$"
# VPS
ssh archivist@194.163.189.144 "~/OtterStack/otterstack project list | grep -q '^${PROJECT_NAME}$'"
Add project if missing (local):
otterstack project add ${PROJECT_NAME} /path/to/repo --traefik-routing
Add project if missing (remote/VPS):
# Get remote git URL
REPO_URL=$(git config --get remote.origin.url)
# Add to VPS
ssh archivist@194.163.189.144 "~/OtterStack/otterstack project add ${PROJECT_NAME} ${REPO_URL} --traefik-routing"
Environment Variable Setup Mode
When the orchestration command configures environment variables:
Auto-load from .env file if exists:
if [ -f ".env.${PROJECT_NAME}" ]; then
# Local
otterstack env load ${PROJECT_NAME} .env.${PROJECT_NAME}
# VPS
scp .env.${PROJECT_NAME} archivist@194.163.189.144:/tmp/
ssh archivist@194.163.189.144 "~/OtterStack/otterstack env load ${PROJECT_NAME} /tmp/.env.${PROJECT_NAME}"
fi
Interactive scan for missing variables:
# Local
otterstack env scan ${PROJECT_NAME}
# VPS
ssh archivist@194.163.189.144 "~/OtterStack/otterstack env scan ${PROJECT_NAME}"
Validate all required vars are set:
# Local
otterstack env list ${PROJECT_NAME}
# VPS
ssh archivist@194.163.189.144 "~/OtterStack/otterstack env list ${PROJECT_NAME}"
Set individual variables:
# Local
otterstack env set ${PROJECT_NAME} DATABASE_URL="postgres://..."
# VPS
ssh archivist@194.163.189.144 "~/OtterStack/otterstack env set ${PROJECT_NAME} DATABASE_URL='postgres://...'"
Deployment Mode
When the orchestration command executes deployment:
Deploy with verbose output for monitoring:
# Local
otterstack deploy ${PROJECT_NAME} -v
# VPS
ssh archivist@194.163.189.144 "~/OtterStack/otterstack deploy ${PROJECT_NAME} -v"
Monitor deployment stages: The orchestration command watches for these sequential stages:
- "Fetching latest changes..." → Git operations (remote repos only)
- "Validating compose file..." → Syntax and env var validation
- "Pulling images..." → Docker image downloads
- "Starting services..." → Container creation and startup
- "Waiting for containers to be healthy..." → Health check polling
- "Applying Traefik priority labels..." → Traffic routing setup
- "Deployment successful!" → Completion
Check deployment status:
# Local
otterstack status ${PROJECT_NAME}
# VPS
ssh archivist@194.163.189.144 "~/OtterStack/otterstack status ${PROJECT_NAME}"
View deployment history:
# Local
otterstack deployments ${PROJECT_NAME}
# VPS
ssh archivist@194.163.189.144 "~/OtterStack/otterstack deployments ${PROJECT_NAME}"
Quick Reference for Orchestration
Commands used by /deploy-otterstack:
Pre-flight checks:
# Verify OtterStack is installed
which otterstack || command -v otterstack
# VPS: Test SSH connection
ssh -o ConnectTimeout=5 archivist@194.163.189.144 "echo 'SSH OK'"
# VPS: Verify OtterStack on VPS
ssh archivist@194.163.189.144 "~/OtterStack/otterstack --version"
Project existence check:
# Returns exit code 0 if exists, 1 if not
otterstack project list | grep -q "^${PROJECT_NAME}$" && echo "exists" || echo "missing"
Quick deployment status:
otterstack status ${PROJECT_NAME} 2>&1
Force redeploy if lock stuck:
# Local
rm ~/.otterstack/locks/${PROJECT_NAME}.lock
otterstack deploy ${PROJECT_NAME} -v
# VPS
ssh archivist@194.163.189.144 "rm ~/.otterstack/locks/${PROJECT_NAME}.lock"
ssh archivist@194.163.189.144 "~/OtterStack/otterstack deploy ${PROJECT_NAME} -v"
Get previous deployment SHA (for rollback):
# Local
otterstack deployments ${PROJECT_NAME} | tail -2 | head -1 | awk '{print $2}'
# VPS
ssh archivist@194.163.189.144 "~/OtterStack/otterstack deployments ${PROJECT_NAME} | tail -2 | head -1 | awk '{print \$2}'"
Deploy specific ref (rollback):
# Local
otterstack deploy ${PROJECT_NAME} --ref ${PREVIOUS_SHA} -v
# VPS
ssh archivist@194.163.189.144 "~/OtterStack/otterstack deploy ${PROJECT_NAME} --ref ${PREVIOUS_SHA} -v"
Context Passing
The orchestration command maintains these variables that inform OtterStack commands:
PROJECT_NAME- Name of the project being deployedDEPLOYMENT_TARGET- "local" or "vps"SSH_PREFIX- Empty for local, "ssh archivist@194.163.189.144" for VPSOTTERSTACK_CMD- "otterstack" for local, "~/OtterStack/otterstack" for VPSREPO_PATH- Local repository pathREPO_URL- Git repository URL (for VPS)
Commands are constructed as:
${SSH_PREFIX} ${OTTERSTACK_CMD} [subcommand] [args]
Error Handling
The orchestration command handles these OtterStack error scenarios:
| Error | OtterStack Message | Orchestration Action |
|---|---|---|
| Missing env vars | "variable X is not set" | Run env scan or prompt user |
| Project not found | "project not found" | Add project with project add |
| Lock held | "deployment in progress" | Wait or remove stale lock |
| Validation failed | "compose validation failed" | Invoke debug-vps-deployment |
| Health check failed | "container unhealthy" | Invoke debug-vps-deployment |
Related Commands
/deploy-otterstack- Full orchestration command that uses this skill in Phases 4 and 5
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?