Skills docker-helper
install
source · Clone the upstream repo
git clone https://github.com/TerminalSkills/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/TerminalSkills/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/docker-helper" ~/.claude/skills/terminalskills-skills-docker-helper && rm -rf "$T"
manifest:
skills/docker-helper/SKILL.mdsafety · automated scan (high risk)
This is a pattern-based risk scan, not a security review. Our crawler flagged:
- rm -rf on root/home
- pip install
- references .env files
Always read a skill's source content before installing. Patterns alone don't mean the skill is malicious — but they warrant attention.
source content
Docker Helper
Overview
Create, debug, and optimize Docker configurations including Dockerfiles, docker-compose setups, and container troubleshooting. Follows Docker best practices for security, image size, and build speed.
Instructions
When a user asks for help with Docker, determine which task they need:
Task A: Create a Dockerfile
- Identify the application language and framework
- Choose the right base image (prefer
or-slim
variants)-alpine - Use multi-stage builds for compiled languages
- Follow this ordering for optimal layer caching:
# Stage 1: Build FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . RUN npm run build # Stage 2: Runtime FROM node:20-alpine WORKDIR /app RUN addgroup -g 1001 appgroup && adduser -u 1001 -G appgroup -D appuser COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/package.json ./ USER appuser EXPOSE 3000 CMD ["node", "dist/index.js"]
Key rules:
- Copy dependency files first, then source (caching)
- Run as non-root user
- Use
to exclude.dockerignore
,node_modules
,.git.env - Pin base image versions (e.g.,
, notnode:20.11-alpine
)node:latest - Combine RUN commands to reduce layers
Task B: Write docker-compose.yml
version: "3.8" services: app: build: context: . dockerfile: Dockerfile ports: - "3000:3000" environment: - DATABASE_URL=postgres://user:pass@db:5432/myapp depends_on: db: condition: service_healthy restart: unless-stopped db: image: postgres:16-alpine volumes: - pgdata:/var/lib/postgresql/data environment: POSTGRES_USER: user POSTGRES_PASSWORD: pass POSTGRES_DB: myapp healthcheck: test: ["CMD-SHELL", "pg_isready -U user -d myapp"] interval: 5s timeout: 5s retries: 5 volumes: pgdata:
Key rules:
- Use
with health checks, not just service namesdepends_on - Use named volumes for persistent data
- Never hardcode secrets in compose files for production (use env files or secrets)
- Set restart policies
Task C: Debug container issues
Follow this diagnostic sequence:
# 1. Check container status docker ps -a # 2. Read container logs docker logs <container> --tail 50 # 3. Inspect container details docker inspect <container> | jq '.[0].State' # 4. Check resource usage docker stats --no-stream # 5. Get a shell inside the container docker exec -it <container> /bin/sh # 6. Check networking docker network ls docker network inspect <network>
Common issues and fixes:
- Container exits immediately: Check logs; usually a missing env var or config file
- Port already in use:
to find the conflictlsof -i :PORT - Cannot connect between containers: Ensure they are on the same Docker network and use service names as hostnames
- Out of disk space:
to clean up unused images and containersdocker system prune -a - Build fails at COPY: Check
and verify paths are relative to build context.dockerignore
Task D: Optimize image size
# Check current image size docker images | grep myapp # Analyze layers docker history myapp:latest
Optimization checklist:
- Switch to alpine base images
- Use multi-stage builds (build deps stay in builder stage)
- Combine RUN commands with
&& - Remove package manager caches:
rm -rf /var/cache/apk/* - Use
to exclude test files, docs, .git.dockerignore - Do not install dev dependencies in the final image
Examples
Example 1: Create a Dockerfile for a Python FastAPI app
User request: "Create a Dockerfile for my FastAPI project"
Output Dockerfile:
FROM python:3.12-slim AS builder WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir --prefix=/install -r requirements.txt FROM python:3.12-slim WORKDIR /app RUN useradd -r -s /bin/false appuser COPY --from=builder /install /usr/local COPY . . USER appuser EXPOSE 8000 CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Output .dockerignore:
__pycache__ *.pyc .git .env .venv tests/ *.md
Result: Image size ~180MB instead of ~1.2GB with the full Python image.
Example 2: Debug a container that keeps restarting
User request: "My web container keeps restarting, can you help?"
Diagnostic steps:
$ docker ps -a CONTAINER ID IMAGE STATUS NAMES a1b2c3d4e5f6 web:1.0 Restarting (1) 5 sec ago web $ docker logs web --tail 20 Error: ECONNREFUSED 127.0.0.1:5432 at TCPConnectWrap.afterConnect Root cause: The app is trying to connect to PostgreSQL at 127.0.0.1, but in Docker the database is a separate container. Fix: Change DATABASE_URL from localhost to the service name: DATABASE_URL=postgres://user:pass@db:5432/myapp ^^ service name, not localhost
Guidelines
- Always create a
alongside any Dockerfile..dockerignore - Pin base image versions to specific tags, not
.latest - Never store secrets in Docker images or Dockerfiles. Use environment variables or Docker secrets.
- For production, always run as a non-root user.
- When optimizing, measure before and after with
.docker images - If a build is slow, check layer ordering. Dependencies (package.json, requirements.txt) should be copied and installed before source code.
- For local development, use bind mounts for live reloading. For production, use COPY.
- Health checks should test actual application readiness, not just process existence.