AgentStack
SKILL verified Apache-2.0 Self-run

Docker Containerization

skill-jignesh-ponamwar-skills-mcp-docker-containerization · by Jignesh-Ponamwar

>

No reviews yet
0 installs
17 views
0.0% view→install

Install

$ agentstack add skill-jignesh-ponamwar-skills-mcp-docker-containerization

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Docker Containerization? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Docker Containerization Skill

Step 1: Choose the Right Base Image

| Use Case | Base Image | |----------|-----------| | Python production | python:3.12-slim | | Node.js production | node:20-alpine | | Go production (final stage) | gcr.io/distroless/static | | Debugging / dev | python:3.12 or node:20 | | Minimal static binary | scratch |

Rules:

  • Never use latest tag - pin exact versions for reproducibility
  • Prefer -slim or -alpine over full images to reduce attack surface and size
  • Use distroless or scratch for final stages of statically compiled languages

Step 2: Production Dockerfiles

Python Application

# ─── Build Stage ─────────────────────────────────────────────────────────────
FROM python:3.12-slim AS builder

WORKDIR /app

# Install dependencies separately for layer caching
COPY requirements.txt .
RUN pip install --upgrade pip && \
    pip install --no-cache-dir --prefix=/install -r requirements.txt

# ─── Final Stage ─────────────────────────────────────────────────────────────
FROM python:3.12-slim

WORKDIR /app

# Copy installed packages from builder
COPY --from=builder /install /usr/local

# Create non-root user (security hardening)
RUN groupadd --gid 1001 appuser && \
    useradd --uid 1001 --gid appuser --shell /bin/bash --create-home appuser

# Copy application code
COPY --chown=appuser:appuser . .

USER appuser

EXPOSE 8000

# Health check
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
    CMD curl -f http://localhost:8000/health || exit 1

CMD ["python", "-m", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

Node.js Application

# ─── Dependencies Stage ───────────────────────────────────────────────────────
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

# ─── Build Stage (if TypeScript/Next.js) ─────────────────────────────────────
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# ─── Final Stage ─────────────────────────────────────────────────────────────
FROM node:20-alpine AS runner
WORKDIR /app

# Non-root user
RUN addgroup --gid 1001 nodejs && \
    adduser --system --uid 1001 nextjs

# Production dependencies only
COPY --from=deps --chown=nextjs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/public ./public

USER nextjs

EXPOSE 3000
ENV NODE_ENV=production PORT=3000

CMD ["node", "server.js"]

Go Application

# ─── Build Stage ─────────────────────────────────────────────────────────────
FROM golang:1.22-alpine AS builder

WORKDIR /app

# Module download (separate layer for caching)
COPY go.mod go.sum ./
RUN go mod download

# Build (static binary, no CGO)
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo \
    -ldflags="-w -s" -o server ./cmd/server

# ─── Final Stage (distroless - no shell, minimal attack surface) ──────────────
FROM gcr.io/distroless/static:nonroot

WORKDIR /

COPY --from=builder /app/server /server

USER nonroot:nonroot

EXPOSE 8080

ENTRYPOINT ["/server"]

Step 3: .dockerignore

Always create .dockerignore to prevent bloating the build context:

.git
.gitignore
node_modules
.next
__pycache__
*.pyc
.env
.env.*
*.log
.DS_Store
dist/
build/
coverage/
*.test.ts
*.spec.ts
README.md
docker-compose*.yml

Step 4: Docker Compose for Local Development

# docker-compose.yml
services:
  app:
    build:
      context: .
      target: builder  # use build stage for dev (includes dev deps)
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
      - DATABASE_URL=postgresql://postgres:password@db:5432/myapp
      - REDIS_URL=redis://cache:6379
    volumes:
      - .:/app                    # hot reload
      - /app/node_modules         # exclude node_modules from bind mount
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    restart: unless-stopped

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5
    ports:
      - "5432:5432"

  cache:
    image: redis:7-alpine
    command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:

Override for Production

# docker-compose.prod.yml
services:
  app:
    build:
      target: runner  # production stage
    environment:
      - NODE_ENV=production
    volumes: []  # no bind mounts in production
    deploy:
      replicas: 3
      restart_policy:
        condition: on-failure
        max_attempts: 3

Run with: docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d


Step 5: Essential Docker Commands

# Build
docker build -t myapp:1.0 .
docker build --target builder -t myapp:dev .        # specific stage
docker build --no-cache -t myapp:latest .           # force fresh build

# Run
docker run -p 3000:3000 --env-file .env myapp:1.0
docker run -d --name myapp -p 3000:3000 myapp:1.0  # detached

# Docker Compose
docker compose up -d          # start all services
docker compose up --build     # rebuild and start
docker compose logs -f app    # follow logs
docker compose exec app sh    # shell into running container
docker compose down -v        # stop and remove volumes

# Inspect / Debug
docker ps -a                  # list all containers
docker logs myapp             # view container logs
docker exec -it myapp sh      # interactive shell
docker inspect myapp          # full container metadata

# Cleanup
docker system prune -af       # remove all unused images and containers
docker volume prune           # remove unused volumes

Step 6: Security Hardening

# 1. Non-root user (mandatory)
USER appuser

# 2. Read-only filesystem
# docker run --read-only --tmpfs /tmp myapp

# 3. Drop capabilities
# docker run --cap-drop ALL --cap-add NET_BIND_SERVICE myapp

# 4. No new privileges
# docker run --security-opt no-new-privileges myapp

# 5. Scan for vulnerabilities
# docker scout cves myapp:latest
# trivy image myapp:latest

Layer Caching Optimization

Order Dockerfile instructions from least frequently changing to most frequently changing:

# ✅ Optimal order
COPY package*.json ./     # changes infrequently → cache hit most of the time
RUN npm ci                # only re-runs when package.json changes
COPY . .                  # app code changes most often - put last
RUN npm run build

# ❌ Wrong order - kills caching
COPY . .                  # app code changes → invalidates all subsequent layers
RUN npm ci                # runs npm install on every code change!

Common Mistakes

  • Using latest tags - pin exact versions: node:20.12.0-alpine
  • Running as root - always create and switch to a non-root user
  • Copying everything into the image - always have a comprehensive .dockerignore
  • Installing dev dependencies in production - use --only=production or multi-stage builds
  • Secrets in Dockerfile - never ARG API_KEY or ENV SECRET= in Dockerfile; use Docker secrets or runtime env vars
  • Fat final images - use multi-stage builds; copy only the compiled artifact
  • Missing health checks - define HEALTHCHECK so orchestrators know when to restart

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.