Container-based development for isolated, reproducible environments. Use when running npm commands, installing packages, executing code, or managing project dependencies. Trigger phrases include "npm install", "run the build", "start the server", "install package", or any code execution request.
This skill inherits all available tools. When active, it can use any tool Claude has access to.
Execute all package installations and code execution inside Docker containers. This keeps the host machine clean and ensures consistent environments across projects.
Before using this skill, identify your project's container name:
# Find your container name
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
Common naming patterns:
{project-name}-dev-1 (docker-compose){project-name}_dev_1 (older docker-compose)container_name: in docker-compose.ymlNEVER run npm, node, npx, or project scripts directly on the host machine.
Instead, use docker exec or ensure the container is running the dev server.
Before running ANY npm/node command, verify the container is running:
# Check if container is running (replace with your container name)
docker ps --filter "name=YOUR_CONTAINER" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
If container is NOT running:
# Navigate to project root
cd /path/to/your/project
# Start container (common patterns)
docker-compose up -d # Simple setup
docker-compose --profile dev up dev -d # Profile-based setup
docker compose up -d # Docker Compose V2
# Verify it started
docker ps --filter "name=YOUR_CONTAINER"
If container shows "Exited":
# Check why it exited
docker logs YOUR_CONTAINER --tail 20
# Remove and restart
docker-compose down
docker-compose up -d
# List all running containers
docker ps
# Filter by project name
docker ps --filter "name=PROJECT_NAME"
# Check container logs
docker logs CONTAINER_NAME --tail 50
# Follow logs in real-time
docker logs CONTAINER_NAME -f
# Start containers (from project root)
docker-compose up -d
# Start with specific profile
docker-compose --profile dev up -d
# Stop containers
docker-compose down
# Restart
docker-compose restart
# Rebuild after Dockerfile changes
docker-compose up -d --build
# Install a package
docker exec -it CONTAINER_NAME npm install PACKAGE_NAME
# Install dev dependency
docker exec -it CONTAINER_NAME npm install -D PACKAGE_NAME
# Run tests
docker exec -it CONTAINER_NAME npm test
# Run type checking
docker exec -it CONTAINER_NAME npm run typecheck
# Run linting
docker exec -it CONTAINER_NAME npm run lint
# Run build
docker exec -it CONTAINER_NAME npm run build
# Open shell inside container
docker exec -it CONTAINER_NAME /bin/sh
# Run with environment variable
docker exec -it -e MY_VAR=value CONTAINER_NAME command
| Operation | Use docker exec? | Reason |
|---|---|---|
npm install | ✅ Yes | Packages install in container |
npm run dev | ❌ No | Already running via docker-compose |
npm test | ✅ Yes | Tests run in container environment |
npm run build | ✅ Yes | Build happens in container |
git commands | ❌ No | Git runs on host (manages files) |
| File editing | ❌ No | Volume mount syncs automatically |
| Database migrations | ✅ Yes | Uses container's Node environment |
┌─────────────────────────────────────────────────────────────┐
│ HOST (macOS/Linux/Windows) │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Docker Container │ │
│ │ │ │
│ │ Node/Python/Go/etc. │ │
│ │ └── dependencies (container-only) │ │
│ │ └── Dev server (exposed port) │ │
│ │ │ │
│ │ Volume Mounts: │ │
│ │ └── .:/app (source code sync) │ │
│ │ └── node_modules:/app/node_modules (persist deps) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ Port X mapped │
│ │ │
│ ▼ │
│ http://localhost:PORT │
└─────────────────────────────────────────────────────────────┘
Typical docker-compose.yml volume configuration:
volumes:
- .:/app # Source code (synced)
- /app/node_modules # Dependencies (container-only)
What this means:
node_modules/ in container is separate from any on host# Check if container exists (including stopped)
docker ps -a --filter "name=PROJECT_NAME"
# If exited, check why
docker logs CONTAINER_NAME
# Remove stopped containers and restart
docker-compose down
docker-compose up -d
# Find what's using the port
lsof -i :PORT
# or
netstat -tulpn | grep PORT
# Kill the process or change port in docker-compose.yml
# Rebuild container with fresh dependencies
docker-compose down
docker-compose build --no-cache
docker-compose up -d
# Check volume mounts
docker inspect CONTAINER_NAME | grep -A 10 "Mounts"
# Restart container
docker-compose restart
# Fix ownership issues (Linux)
docker exec -it CONTAINER_NAME chown -R node:node /app
# Or run as root temporarily
docker exec -u root -it CONTAINER_NAME command
version: '3.8'
services:
dev:
build:
context: .
dockerfile: Dockerfile.dev
container_name: myproject-dev
ports:
- "3000:3000"
volumes:
- .:/app
- /app/node_modules
environment:
- NODE_ENV=development
command: npm run dev -- --host 0.0.0.0
volumes:
node_modules:
FROM node:20-alpine
WORKDIR /app
# Install dependencies first (better caching)
COPY package*.json ./
RUN npm ci
# Copy source code
COPY . .
# Expose port
EXPOSE 3000
# Start dev server
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"]
docker exec for all npm/node operationspackage.json or Dockerfile--host 0.0.0.0 so host can access the serverWhen Claude Code needs to:
| Task | Action |
|---|---|
| Install dependency | docker exec -it CONTAINER npm install PKG |
| Run tests | docker exec -it CONTAINER npm test |
| Check types | docker exec -it CONTAINER npm run typecheck |
| Build project | docker exec -it CONTAINER npm run build |
| Start dev server | Container already runs it via docker-compose |
| Edit files | Edit directly (volume mount syncs) |
| Git operations | Run on host (not in container) |
To auto-detect container name, check these sources:
docker-compose.yml → container_name: fielddocker ps → running containers.claude/settings.local.json → project-specific config{directory-name}-dev-1For project-specific Docker configuration, create .claude/settings.local.json with your container name.