Skill: ops-docker
Docker and Docker Compose containerization. Trigger when the user wants to dockerize an application or create containers.
Configuration
| Property | Value |
|---|---|
| Context | fork |
| Allowed tools | Read, Write, Edit, Bash, Glob, Grep |
| Keywords | ops, docker |
Detailed description
Docker Containerization
Multi-Stage Dockerfile
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Production
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
EXPOSE 3000
HEALTHCHECK CMD wget -q --spider http://localhost:3000/health || exit 1
CMD ["node", "dist/index.js"]
Docker Compose
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/app
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?required}
POSTGRES_DB: app
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d app"]
interval: 10s
timeout: 5s
retries: 5
volumes:
postgres_data:
Best practices
- Multi-stage builds to reduce size
- Non-root user for security
- .dockerignore to exclude unnecessary files
- Health checks for availability
- Labels for metadata
Automatic triggering
This skill is automatically activated when:
- The matching keywords are detected in the conversation
- The task context matches the skill's domain
Triggering examples
- "I want to ops..."
- "I want to docker..."
Context fork
Fork means the skill runs in an isolated context:
- Does not pollute the main conversation
- Results are returned cleanly
- Ideal for autonomous tasks
Practical examples
1. Example: Multi-stage Dockerfile with Docker Compose
Example: Multi-stage Dockerfile with Docker Compose
Scenario
A Node.js API with PostgreSQL needs an optimized production image and a local dev setup.
Multi-stage Dockerfile
# Dockerfile
# Stage 1: Dependencies
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --ignore-scripts
# Stage 2: Build
FROM node:20-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
RUN npm prune --production
# Stage 3: Production
FROM node:20-alpine AS production
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/package.json ./
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "dist/main.js"]
Docker Compose (local dev)
# docker-compose.yml
services:
api:
build:
context: .
target: deps
volumes:
- .:/app
- /app/node_modules
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://app:secret@db:5432/myapp
NODE_ENV: development
depends_on:
db:
condition: service_healthy
command: npm run dev
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
POSTGRES_DB: myapp
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d myapp"]
interval: 5s
timeout: 3s
retries: 5
volumes:
pgdata:
Key Decisions
- Multi-stage: Final image ~150MB vs ~900MB with full build deps
- Non-root user:
appuserfor security (no root in production) - Healthcheck: Docker monitors container health automatically
- Volume mount: Dev gets live-reload via bind mount, node_modules excluded
- Service dependency:
condition: service_healthyensures DB is ready before API starts